Fila de mensagens rápida com AIDL

A partir do Android 12, o Fast Message Queue pode ser usado com interfaces AIDL usando o back-end do NDK. Isso permite que os processos se comuniquem sem a sobrecarga e as restrições das transações do fichário após uma breve configuração. O uso de AIDL estável permite a comunicação entre o sistema e os processos do fornecedor.

Tipos de carga suportados

As mensagens enviadas entre os processos na fila de mensagens da memória compartilhada devem ter o mesmo layout de memória entre os limites do processo e não podem conter ponteiros. Tentar criar um AidlMessageQueue com um tipo que não é compatível causará um erro de compilação.

Tipos de fila suportados

Os mesmos tipos de fila do HIDL, geralmente chamados de tipos, são suportados com o AIDL. Eles são usados ​​como argumentos de modelo para as filas e descritores.

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

Como usar

Defina a interface AIDL que passará o MQDescriptor para o outro processo. MQDescriptor pode ser usado em qualquer lugar que um parcelable possa estar.

Os argumentos de modelo necessários para MQDescriptor são tipo de carga útil e tipo de fila.

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

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

O processo de configurar cada lado da fila de mensagens é quase idêntico ao processo usando HIDL , apenas usando os tipos 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);

O processo receptor criará o outro lado da fila com o descritor recebido da interface 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()) {
   ...
}

Usar o AidlMessageQueue após a configuração é o mesmo que o HIDL MessageQueue . Todas as APIs descritas em Usando o MessageQueue são totalmente suportadas com AidlMessageQueue com uma exceção:

const MQDescriptor<T, flavor>* getDesc() é substituído por MQDescriptor<T, U> dupeDesc() que retorna o AIDL MQDescriptor .