Szybkie przesyłanie wiadomości przy użyciu AIDL

Od Androida 12 kolejka szybkich wiadomości może być używana z interfejsami AIDL za pomocą backendu NDK. Umożliwia to procesom komunikowanie się bez narzutu i ograniczeń transakcji bindera po krótkiej konfiguracji. Korzystanie z Stabilnego AIDL umożliwia komunikację między systemem a procesami dostawcy.

Obsługiwane typy ładunków

Wiadomości wysyłane między procesami w kole wiadomości w wspólnej pamięci muszą mieć ten sam układ pamięci w całości procesu i nie mogą zawierać wskaźników. Próba utworzenia AidlMessageQueue z nieobsługiwanym typem spowoduje błąd kompilacji.

Obsługiwane typy kolejek

AIDL obsługuje te same typy kolejek z HIDL, które są często nazywane „smakami”. Są one używane jako argumenty szablonu dla kolejek i deskryptorów.

Typy HIDL Typy AIDL
android::hardware::kSynchronizedReadWrite android.hardware.common.fmq.SynchronizedReadWrite
android::hardware::kUnsynchronizedWrite android.hardware.common.fmq.UnsynchronizedWrite

Instrukcje korzystania

Zdefiniuj interfejs AIDL, który przekaże MQDescriptor do innego procesu. MQDescriptor można używać wszędzie tam, gdzie można używać obiektów Parcelable.

Wymagane argumenty szablonu MQDescriptor to typ ładunku i rodzaj kolejki.

import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite

void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);

Proces konfigurowania każdej strony kolejki wiadomości jest prawie taki sam jak proces z użyciem HIDL z użyciem typów AIDL.

#include <fmq/AidlMessageQueue.h>
...
using ::android::AidlMessageQueue;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
...
ndk::ScopedAStatus MyInterface::getQueue(MQDescriptor<int32_t, SynchronizedReadWrite>* mqDesc) {
    *mqDesc = mFmqSynchronized->dupeDesc();
    return ndk::ScopedAStatus::ok();
}
...
// Create the first side of the queue before servicing getQueue() in this example
mFmqSynchronized =
  new AidlMessageQueue<int32_t, SynchronizedReadWrite>(kNumElementsInQueue);

Proces odbioru utworzy drugą stronę kolejki z wykorzystaniem deskryptora otrzymanego z interfejsu AIDL.

MQDescriptor<int32_t, SynchronizedReadWrite> desc;
auto ret = service->getQueue(true, &desc);
if (!ret.isOk()) {
   ...
}
// By default the constructor will reset the read and write pointers of the queue.
// Add a second `false` argument to avoid resetting the pointers.
mQueue = new (std::nothrow) AidlMessageQueue<int32_t, SynchronizedReadWrite>(desc);
if (!mQueue->isValid()) {
   ...
}

Po skonfigurowaniu AidlMessageQueue można go używać tak samo jak HIDL MessageQueue. Wszystkie interfejsy API opisane w artykule Korzystanie z MessageQueue są w pełni obsługiwane w usłudze AidlMessageQueue z jednym wyjątkiem:

const MQDescriptor<T, flavor>* getDesc() jest zastępowany przez MQDescriptor<T, U> dupeDesc(), który zwraca identyfikator AIDL MQDescriptor.