تنفيذ الخدمة

للتحضير لتطبيق 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 جاهزًا. نظرًا لأن خدمة config HAL لا تقرأ الملفات الخارجية، فمن المتوقع أن تكون جاهزة بسرعة بعد تشغيلها.