تنفيذ الخدمة

للاستعداد لتنفيذ 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 وربط علامات الإصدار بتعريفات وحدات ماكرو. على سبيل المثال، يمكنك تعديل 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 بقيم مختلفة (مشروطة بعلامات الإنشاء). على سبيل المثال، يمكنك ملء الدوال لـ 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();

ضمان استخدام المنتج قبل إطلاقه

لضمان استفادة وحدة إطار العمل من خدمة HAL قبل إطلاقها، يجب أن تبدأ خدمة HAL للإعدادات في أقرب وقت ممكن، بعد إعداد hwservicemanager مباشرةً. نظرًا لأن خدمة تهيئة HAL لا تقرأ الملفات الخارجية، فمن المتوقع أن تكون جاهزة بسرعة بعد إطلاقها.