Implementa el servicio

Para prepararte para la implementación de HAL, puedes generar un código de interfaz básico de ConfigStore y, luego, modificarlo para satisfacer tus necesidades.

Generar código de interfaz

A fin de generar código estándar para la interfaz, ejecuta hidl-gen. Por ejemplo, si quieres generar código para surfaceflinger, haz lo siguiente:

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

Cómo modificar Android.mk

A continuación, modifica el archivo Android.mk para agregar el archivo de implementación (<modulename>Configs.cpp) a LOCAL_SRC_FILES y asignar marcas de compilación a definiciones de macro. Por ejemplo, puedes modificar surfaceflinger en 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

Si Android.mk incluye varios bloques ifeq-endif, considera mover el código a un archivo nuevo (es decir, surfaceflinger.mk) y, luego, incluir ese archivo desde Android.mk.

Implementa funciones

Para completar las funciones que permiten implementar la HAL, llama a la función _hidl_cb con diferentes valores (condicionada por marcas de compilación). Por ejemplo, puedes completar las funciones para surfaceflinger en 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
}

Asegúrate de que la implementación no contenga una función llamada HIDL_FETCH_interface-name (por ejemplo, HIDL_FETCH_ISurfaceFlingerConfigs). Esta función es necesaria para el modo de transferencia HIDL, que configstore no usa (y prohíbe). El ConfigStore siempre debe ejecutarse en modo Binder.

Registrarse como servicio

Por último, registra todas las implementaciones de la interfaz en el servicio configstore. Por ejemplo, puedes registrar implementaciones de surfaceflinger en 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();

Garantiza el acceso anticipado

Para garantizar que un módulo de framework pueda obtener acceso anticipado al servicio de HAL, el servicio de HAL de configuración debe iniciarse lo antes posible, justo después de que hwservicemanager esté listo. Como el servicio de HAL de configuración no lee archivos externos, se espera que esté listo rápidamente después de que se inicie.