הטמעת השירות

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

הרשמה כשירות

לסיום, צריך לרשום את כל ההטמעות של הממשק בשירות 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, שירות config עם ה-HAL צריך להתחיל מוקדם ככל האפשר, מיד כש-hwservicemanager יהיה מוכן. מכיוון ששירות ה-config HAL לא קורא קבצים חיצוניים, הוא צפוי להיות מוכן זמן קצר לאחר ההפעלה.