HIDL C++,HIDL C++

אנדרואיד O מעצב מחדש את מערכת ההפעלה אנדרואיד כדי להגדיר ממשקים ברורים בין פלטפורמת אנדרואיד בלתי תלויה במכשיר לבין קוד ספציפי למכשיר ולספק. אנדרואיד כבר מגדירה ממשקים רבים כאלה בצורה של ממשקי HAL, המוגדרים ככותרות C hardware/libhardware . HIDL מחליף ממשקי HAL אלה בממשקים יציבים עם גרסאות, שיכולים להיות ממשקי HIDL בצד הלקוח והשרת ב-C++ (מתואר להלן) או ב-Java .

הדפים בסעיף זה מתארים יישומי C++ של ממשקי HIDL, כולל פרטים על הקבצים שנוצרו אוטומטית מקבצי HIDL .hal על ידי מהדר hidl-gen , כיצד קבצים אלה נארזים וכיצד לשלב קבצים אלה עם קוד C++ אשר משתמש בהם.

הטמעת לקוח ושרת

לממשקי HIDL יש מימושי לקוח ושרת:

  • לקוח של ממשק HIDL הוא הקוד שמשתמש בממשק על ידי קריאה לשיטות עליו.
  • שרת הוא יישום של ממשק HIDL שמקבל שיחות מלקוחות ומחזיר תוצאות (במידת הצורך).

במעבר מ- libhardware HALs ל-HIDL HALs, יישום HAL הופך לשרת והתהליך הקריאה ל-HAL הופך ללקוח. יישומי ברירת מחדל יכולים לשרת הן HALs מעבר והן משולבות, ויכולות להשתנות עם הזמן:

איור 1. התקדמות פיתוח עבור HALs מדור קודם.

יצירת לקוח 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 יעבוד במצב מעבר, אתה חייב שהפונקציה 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 יכולים לשדר את היישום.

לאחר מכן, מלא את התווים עם פונקציונליות והגדר דמון. קוד דמון לדוגמה (תומך במעבר):

#include <hidl/LegacySupport.h>

int main(int /* argc */, char* /* argv */ []) {
    return defaultPassthroughServiceImplementation<INfc>("nfc");
}

defaultPassthroughServiceImplementation dlopen() את ספריית -impl שסופקה ותספק אותה כשירות מקשר. קוד דמון לדוגמה (עבור שירות מקשר טהור):

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 will never exceed
    // 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 ), אבל זה יכול להיות בכל מקום. ה- sepolicy עבור מחלקה ספציפית של HALs היא התכונה hal_<module> (לדוגמה, hal_nfc) . יש להחיל תכונה זו על הדמון המריץ HAL מסוים (אם אותו תהליך משרת מספר HALs, ניתן להחיל עליו מספר תכונות).