تنفيذ الخدمة

للاستعداد لتنفيذ طبقة تجريد الأجهزة (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 دائمًا في وضع binderized.

التسجيل كخدمة

أخيرًا، سجِّل جميع عمليات تنفيذ الواجهة في خدمة 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 للإعدادات لا تقرأ الملفات الخارجية، من المتوقّع أن تصبح جاهزة بسرعة بعد تشغيلها.