تنفيذ الخدمة

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