הטמעת השירות

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

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

כדי ליצור קוד boilerplate לממשק, מריצים את הפקודה 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 in 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). הפונקציה הזו נדרשת למצב העברה (passthrough) של HIDL, שלא נמצא בשימוש (ואסור) ב-configstore. ההפעלה של ConfigStore חייבת להיות תמיד במצב binderized.

הרשמה כשירות

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