Android 8 יוצרת מחדש את הארכיטקטורה של Android OS כדי להגדיר ממשקים ברורים בין
פלטפורמת Android שלא תלויה במכשיר וקוד ספציפי למכשיר ולספק.
מערכת Android כבר מגדירה הרבה ממשקים כאלה בצורה של ממשקי HAL,
מוגדרות ככותרות C ב-hardware/libhardware
. HIDL מחליף את
ממשקי HAL עם ממשקים יציבים בעלי גרסאות, שיכולים להיות מבוססי לקוח
ממשקי HIDL בצד השרת ב-C++ (כמתואר בהמשך) או
Java.
הדפים בקטע הזה מתארים הטמעות C++ של ממשקי HIDL,
כולל פרטים על הקבצים שנוצרו באופן אוטומטי מה-HIDL .hal
על ידי המהדר (compiler) hidl-gen
, אופן האריזה של הקבצים האלה
איך לשלב את הקבצים האלה עם קוד C++ שמשתמש בהם.
הטמעות של לקוחות ושרתים
לממשקי HIDL יש הטמעות לקוח ושרת:
- לקוח של ממשק HIDL הוא הקוד שמשתמש באמצעות קריאה ל-methods.
- שרת הוא הטמעה של ממשק HIDL מקבל שיחות מלקוחות ומחזיר תוצאות (במקרה הצורך).
במעבר מ-libhardware
HALs ל-HIDL HALs, בתקן HAL
הופך לשרת, והתהליך של קריאה ל-HAL הופך
עם הלקוח. הטמעות ברירת מחדל יכולות להציג גם נתונים של צדדים שלישיים וגם נתונים מקושרים
דפי HAL, ועשויים להשתנות עם הזמן:
איור 1. התקדמות הפיתוח של יישומי HAL מדור קודם.
יצירת לקוח HAL
בתור התחלה, צריך לכלול את ספריות ה-HAL בקובץ ה-makefile:
- יצרן:
LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
- סונג:
shared_libs: [ …, android.hardware.nfc@1.0 ]
לאחר מכן, יש לכלול את קובצי הכותרות עם HAL:
#include <android/hardware/nfc/1.0/IFoo.h> … // in code: sp<IFoo> client = IFoo::getService(); client->doThing();
יצירת שרת HAL
כדי ליצור הטמעת HAL, נדרשים קובצי .hal
שמייצגים את מדד ה-HAL, וכבר יצרו קובצי makefile ל-HAL באמצעות
-Lmakefile
או -Landroidbp
דרך hidl-gen
(./hardware/interfaces/update-makefiles.sh
עושה את הפעולה הזו למשתמשים פנימיים
קובצי HAL וכדאי להיעזר בהם). כשמעבירים HALs מ-
libhardware
, ניתן לבצע חלק גדול מהעבודה הזו בקלות באמצעות c2hal.
כדי ליצור את הקבצים הדרושים להטמעת HAL:
PACKAGE=android.hardware.nfc@1.0 LOC=hardware/interfaces/nfc/1.0/default/ m -j hidl-gen hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE
כדי שטכנולוגיית HAL תפעל במצב Passthrough, צריך
הפונקציה HIDL_FETCH_IModuleName
שנמצאת
/(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl(OPTIONAL_IDENTIFIER).so
כאשר OPTIONAL_IDENTIFIER הוא מחרוזת המזהה את נתיב המעבר
יישום בפועל. הדרישות של מצב ההעברה
של הפקודות שלמעלה, שגם יוצרות את android.hardware.nfc@1.0-impl
אבל ניתן להשתמש בכל תוסף. למשל
האפליקציה android.hardware.nfc@1.0-impl-foo
משתמשת ב-foo
כדי
להבדיל את עצמו.
אם טקסט HAL הוא גרסה משנית או הרחבה של גרסה אחרת
HAL, יש להשתמש ב-HAL הבסיסי כדי לתת שם לקובץ הבינארי. לדוגמה,
הטמעות של android.hardware.graphics.mapper@2.1
עדיין להיות בקובץ בינארי שנקרא
android.hardware.graphics.mapper@2.0-impl(OPTIONAL_IDENTIFIER)
.
בדרך כלל, OPTIONAL_IDENTIFIER כאן יכלול את ערך HAL בפועל
. מתן שם לקובץ הבינארי כמו זה, מאפשר ללקוחות של 2.0 לאחזר אותו ישירות,
ולקוחות 2.1 יכולים לשדרג את ההטמעה.
בשלב הבא, ממלאים את החלקים החסרים בפונקציונליות ומגדירים דימון (daemon). דוגמה daemon code (תמיכה בהעברה):
#include <hidl/LegacySupport.h> int main(int /* argc */, char* /* argv */ []) { return defaultPassthroughServiceImplementation<INfc>("nfc"); }
defaultPassthroughServiceImplementation
שיחות
dlopen()
עבור ספריית -impl
שסופקה ומשמשת בתור
שירות מקושר. דוגמה לקוד daemon (לשירות מקושר בלבד):
int main(int /* argc */, char* /* argv */ []) { // This function must be called before you join to ensure the proper // number of threads are created. The threadpool never exceeds // size one because of this call. ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); sp<INfc> nfc = new Nfc(); const status_t status = nfc->registerAsService(); if (status != ::android::OK) { return 1; // or handle error } // Adds this thread to the threadpool, resulting in one total // thread in the threadpool. We could also do other things, but // would have to specify 'false' to willJoin in configureRpcThreadpool. ::android::hardware::joinRpcThreadpool(); return 1; // joinRpcThreadpool should never return }
הדימון הזה בדרך כלל גר ב-$PACKAGE + "-service-suffix"
(למשך
לדוגמה, android.hardware.nfc@1.0-service
), אבל הוא יכול להיות בכל מקום.
המדיניות של
מחלקה של HAL היא המאפיין hal_<module>
(למשל,
hal_nfc)
צריך להחיל את המאפיין הזה על הדימון שמריץ
HAL מסוים (אם אותו תהליך מטפל במספר תכונות HAL, יש כמה מאפיינים
ניתן להחיל עליו).