Para preparar la implementación del HAL, puedes generar código básico de la interfaz de ConfigStore y, luego, modificarlo para que se adapte a tus necesidades.
Genera código de interfaz
Para generar código estándar para la interfaz, ejecuta hidl-gen
.
Por ejemplo, para 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
Modifica 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 para asignar marcas de compilación a definiciones de macros. 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 tu código a un archivo nuevo (es decir, surfaceflinger.mk
) y, luego, incluye ese archivo desde Android.mk
.
Implementa funciones
Para completar las funciones que implementan el HAL, llama a la función _hidl_cb
con diferentes valores (condicionados 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 de HIDL, que configstore
no usa (y prohíbe). ConfigStore siempre debe ejecutarse en modo binderizado.
Cómo 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();
Cómo garantizar el acceso anticipado
Para garantizar que un módulo del framework pueda obtener acceso anticipado al servicio HAL, el servicio HAL de configuración debe iniciarse lo antes posible, justo después de que hwservicemanager
esté listo. Como el servicio HAL de config no lee archivos externos, se espera que esté listo rápidamente después de su lanzamiento.