Per preparare l'implementazione HAL, puoi generare il codice dell'interfaccia di base di ConfigStore, quindi modificarlo per soddisfare le tue esigenze.
Generazione del codice dell'interfaccia
Per generare codice standard per l'interfaccia, eseguire hidl-gen
. Ad esempio, per generare codice per 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
Modifica di Android.mk
Quindi, modifica il file Android.mk
per aggiungere il file di implementazione ( <modulename>Configs.cpp
) a LOCAL_SRC_FILES
e per mappare i flag di build nelle definizioni delle macro. Ad esempio, puoi modificare surfaceflinger
in 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
Se Android.mk
include diversi blocchi ifeq-endif
, considera di spostare il codice in un nuovo file (ovvero, surfaceflinger.mk
), quindi includi quel file da Android.mk
.
Funzioni di implementazione
Per riempire le funzioni per implementare l'HAL, richiamare la funzione _hidl_cb
con valori diversi (condizionati dai flag di build). Ad esempio, puoi riempire le funzioni per surfaceflinger
in 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 }
Assicurarsi che l'implementazione non contenga una funzione denominata HIDL_FETCH_ interface-name
(ad esempio, HIDL_FETCH_ISurfaceFlingerConfigs
). Questa funzione è necessaria per la modalità passthrough HIDL, che non è utilizzata (e vietata) da configstore
. ConfigStore deve sempre essere eseguito in modalità binderizzata.
Registrazione come servizio
Infine, registra tutte le implementazioni dell'interfaccia nel servizio configstore
. Ad esempio, puoi registrare le implementazioni di surfaceflinger
in 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();
Garantire l'accesso anticipato
Per garantire che un modulo framework possa ottenere l'accesso anticipato al servizio HAL, il servizio HAL di configurazione dovrebbe essere avviato il prima possibile, subito dopo che hwservicemanager
è pronto. Poiché il servizio HAL di configurazione non legge i file esterni, dovrebbe essere pronto rapidamente dopo l'avvio.