הטמעת השירות

כדי להתכונן להטמעה עם HAL, אתם יכולים ליצור קוד בסיסי של ממשק ConfigStore ולשנות אותו בהתאם לצרכים שלכם.

יצירת קוד ממשק

כדי ליצור קוד תבנית לממשק, מריצים את hidl-gen. לדוגמה, כדי ליצור קוד עבור surfaceflinger:

hidl-gen -o hardware/interfaces/configstore/1.0/default \
    -Lc++-impl \
    -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport \
    android.hardware.config@1.0::ISurfaceFlingerConfigs

שינוי הקובץ Android.mk

בשלב הבא, משנים את הקובץ Android.mk כדי להוסיף את קובץ ההטמעה (<modulename>Configs.cpp) לקובץ LOCAL_SRC_FILES, ולמפות את דגלי ה-build להגדרות מאקרו. לדוגמה, אפשר לשנות את surfaceflinger ב-hardware/interface/configstore/1.0/default/Android.mk:

LOCAL_SRC_FILES += SurfaceFlingerConfigs.cpp
ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),)
    LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS)
endif

ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true)
    LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
endif

אם Android.mk כולל כמה בלוקים של ifeq-endif, מומלץ להעביר את הקוד לקובץ חדש (כלומר surfaceflinger.mk) ואז לכלול את הקובץ הזה מ-Android.mk.

הטמעת פונקציות

כדי למלא את הפונקציות להטמעת ה-HAL, צריך לבצע קריאה חוזרת לפונקציה _hidl_cb עם ערכים שונים (בהתאם לדגלים של ה-build). לדוגמה, אפשר למלא את הפונקציות של surfaceflinger ב-hardware/interfaces/configstore/1.0/default/SurfaceFlingerConfigs.cpp:

Return<void> SurfaceFlingerConfigs::numFramebufferSurfaceBuffers(
        numFramebufferSurfaceBuffers_cb _hidl_cb) {
    #if NUM_FRAMEBUFFER_SURFACE_BUFFERS 2
    _hidl_cb(NumBuffers.TWO);
    #else if NUM_FRAMEBUFFER_SURFACE_BUFFERS 3
    _hidl_cb(NumBuffers.THREE);
    #else
    _hidl_cb(NumBuffers.USE_DEFAULT);
    #endif
}

Return<void> SurfaceFlingerConfigs::runWithoutSyncFramework(
        runWithoutSyncFramework_cb _hidl_cb) {
    #ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
    _hidl_cb({true /* specified */, true /* value */});
    #else
    // when macro not defined, we can give any value to the second argument.
    // It will simply be ignored in the framework side.
    _hidl_cb({false /* specified */, false /* value */});
    #endif
}

חשוב לוודא שההטמעה לא מכילה פונקציה בשם HIDL_FETCH_interface-name (לדוגמה, HIDL_FETCH_ISurfaceFlingerConfigs). הפונקציה הזו נדרשת למצב העברה של HIDL, שלא נעשה בו שימוש (ואסור להשתמש בו) על ידי configstore. ConfigStore תמיד צריך לפעול במצב binderized.

הרשמה כשירות

לבסוף, צריך לרשום את כל הטמעות הממשק בשירות configstore. לדוגמה, אפשר לרשום הטמעות של surfaceflinger ב-hardware/interfaces/configstore/1.0/default/service.cpp:

configureRpcThreadpool(maxThreads, true);
sp<ISurfaceFlingerConfigs> surfaceFlingerConfigs = new SurfaceFlingerConfigs;
status_t status = surfaceFlingerConfigs->registerAsService();

sp<IBluetoothConfigs> bluetoothConfigs = new BluetoothConfigs;
status = bluetoothConfigs->registerAsService();

// register more interfaces here
joinRpcThreadpool();

הקפידו לקבל גישה מוקדמת

כדי להבטיח שמודול של framework יוכל לקבל גישה מוקדמת לשירות HAL, צריך להפעיל את שירות HAL של ההגדרות מוקדם ככל האפשר, מיד אחרי ש-hwservicemanager מוכן. מכיוון ששירות ה-HAL של התצורה לא קורא קובצי חיצוניים, הוא אמור להיות מוכן במהירות אחרי ההפעלה.