תור הודעות מהיר באמצעות AIDL

החל מ-Android 12, אפשר להשתמש ב-Fast Message Queue עם ממשקי AIDL באמצעות הקצה העורפי NDK. כך תהליכים יכולים לתקשר בלי התקורה וההגבלות של טרנזקציות של מקשרים, אחרי הגדרה קצרה. שימוש ב-Stable AIDL מאפשר תקשורת בין תהליכי המערכת לבין תהליכי הספק.

סוגי המטען הייעודי (Payload) הנתמכים

ההודעות שנשלחות בין תהליכים בתור הודעות הזיכרון המשותף צריכות להיות עם אותה פריסת זיכרון מעבר לגבולות התהליכים, והן לא יכולות להכיל מצביעים. ניסיון ליצור AidlMessageQueue עם סוג שאינו נתמך יגרום לשגיאת הידור.

סוגי התורים הנתמכים

ב-AIDL יש תמיכה באותם סוגי תורים מ-HIDL, שנקראים לרוב 'טעמים'. ארגומנטים אלה משמשים כארגומנטים בתבנית עבור תורים ומתארים.

סוגי HIDL סוגי AIDL
android::hardware::kSynchronizedReadWrite android.hardware.common.fmq.SynchronizedReadWrite
android::hardware::kUnsynchronizedWrite android.hardware.common.fmq.UnsynchronizedWrite

איך משתמשים

מגדירים את ממשק AIDL שיעביר את MQDescriptor לתהליך השני. אפשר להשתמש ב-MQDescriptor בכל מקום שבו אפשר להשתמש ב-Parcelable.

הארגומנטים הנדרשים של התבנית עבור MQDescriptor הם סוג של מטען ושיוך לתור.

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

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

תהליך ההגדרה של כל צד של תור ההודעות כמעט זהה לתהליך באמצעות HIDL, רק באמצעות סוגי 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);

תהליך הקבלה ייצור את הצד השני של התור באמצעות המתאר שהתקבל מממשק 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()) {
   ...
}

השימוש ב-AidlMessageQueue אחרי ההגדרה זהה לשימוש ב-HIDL MessageQueue. כל ממשקי ה-API שמפורטים בקטע שימוש ב-MessageQueue נתמכים במלואם ב-AidlMessageQueue, מלבד אחד:

const MQDescriptor<T, flavor>* getDesc() מוחלף ב-MQDescriptor<T, U> dupeDesc() שמחזיר את ה-AIDL‏ MQDescriptor.