Szybka kolejka wiadomości z AIDL

Począwszy od Androida 12, szybkiej kolejki wiadomości można używać z interfejsami AIDL korzystającymi z zaplecza NDK. Umożliwia to procesom komunikację bez narzutów i ograniczeń związanych z transakcjami segregatorów po krótkiej konfiguracji. Korzystanie ze stabilnego AIDL umożliwia komunikację między systemami a procesami dostawcy.

Obsługiwane typy ładunków

Komunikaty przesyłane pomiędzy procesami w kolejce komunikatów pamięci współdzielonej muszą mieć ten sam układ pamięci poza granicami procesów i nie mogą zawierać wskaźników. Próba utworzenia kolejki AidlMessageQueue o nieobsługiwanym typie spowoduje błąd kompilacji.

Obsługiwane typy kolejek

Te same typy kolejek z HIDL, często nazywane smakami, są obsługiwane w AIDL. 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

Jak używać

Zdefiniuj interfejs AIDL, który będzie przekazywać MQDescriptor do innego procesu. MQDescriptor może być używany wszędzie tam, gdzie może znajdować się element pakowany.

Wymagane argumenty szablonu dla 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 komunikatów jest prawie identyczny z procesem przy użyciu języka HIDL , tyle że przy użyciu 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 odbierający utworzy drugą stronę kolejki z deskryptorem otrzymanym 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()) {
   ...
}

Używanie AidlMessageQueue po instalacji jest takie samo jak HIDL MessageQueue . Wszystkie interfejsy API opisane w Korzystanie z MessageQueue są w pełni obsługiwane przez AidlMessageQueue z jednym wyjątkiem:

const MQDescriptor<T, flavor>* getDesc() zostaje zastąpione przez MQDescriptor<T, U> dupeDesc() , która zwraca AIDL MQDescriptor .