Antrean Pesan Cepat dengan AIDL

Mulai Android 12, Fast Message Queue dapat digunakan dengan antarmuka AIDL menggunakan backend NDK. Hal ini memungkinkan proses berkomunikasi tanpa overhead dan batasan transaksi binder setelah beberapa penyiapan singkat. Penggunaan AIDL Stabil memungkinkan komunikasi antara proses sistem dan vendor.

Jenis payload yang didukung

Pesan yang dikirim antar-proses dalam antrean pesan memori bersama harus memiliki tata letak memori yang sama di seluruh batas proses dan tidak boleh berisi pointer. Mencoba membuat AidlMessageQueue dengan jenis yang tidak didukung akan menyebabkan error kompilasi.

Jenis antrean yang didukung

Jenis antrean yang sama dari HIDL, yang sering disebut ragam, didukung dengan AIDL. Ini digunakan sebagai argumen template untuk antrean dan deskriptor.

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

Cara menggunakan

Tentukan antarmuka AIDL yang akan meneruskan MQDescriptor ke proses lain. MQDescriptor dapat digunakan di mana pun parcelable dapat digunakan.

Argumen template yang diperlukan untuk MQDescriptor adalah jenis payload dan ragam antrean.

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

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

Proses penyiapan setiap sisi antrean pesan hampir identik dengan proses menggunakan HIDL, hanya menggunakan jenis 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);

Proses penerimaan akan membuat sisi lain antrean dengan deskriptor yang diterima dari antarmuka 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()) {
   ...
}

Menggunakan AidlMessageQueue setelah penyiapan sama dengan MessageQueue HIDL. Semua API yang dijelaskan di Menggunakan MessageQueue didukung sepenuhnya dengan AidlMessageQueue dengan satu pengecualian:

const MQDescriptor<T, flavor>* getDesc() diganti dengan MQDescriptor<T, U> dupeDesc() yang menampilkan MQDescriptor AIDL.