Antrean Pesan Cepat dengan AIDL

Mulai Android 12, Fast Message Queue dapat digunakan dengan antarmuka AIDL menggunakan backend NDK. Hal ini memungkinkan proses untuk 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

  • FixedSize Jenis AIDL parcelable (tidak tersedia dari backend cpp)
  • Jenis union AIDL (tidak tersedia dari backend cpp)
  • Jenis enum AIDL
  • Jenis integral AIDL

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 AIDL parcelable dan union di backend cpp tidak dapat digunakan dengan Fast Message Queue karena diwarisi dari android::Parcelable, yang memiliki fungsi virtual.

Jenis antrean yang didukung

Jenis antrean yang sama dari HIDL, yang sering disebut varian, 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 meneruskan MQDescriptor ke proses lain. MQDescriptor dapat digunakan di mana saja parcelable dapat digunakan.

Argumen template yang diperlukan untuk MQDescriptor adalah jenis payload dan jenis 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 sama 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 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()) {
   ...
}

Penggunaan 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 AIDL MQDescriptor.