Pour vous préparer à l'implémentation de HAL, vous pouvez générer du code d'interface ConfigStore de base, puis le modifier en fonction de vos besoins.
Générer du code d'interface
Pour générer du code récurrent pour l'interface, exécutez hidl-gen
.
Par exemple, afin de générer du code pour 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
Modifier Android.mk
Modifiez ensuite le fichier Android.mk
pour ajouter le fichier d'implémentation (<modulename>Configs.cpp
) à LOCAL_SRC_FILES
et mapper les options de compilation en définitions de macro. Par exemple, vous pouvez modifier surfaceflinger
dans 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
inclut plusieurs blocs ifeq-endif
, envisagez de déplacer votre code dans un nouveau fichier (surfaceflinger.mk
), puis d'inclure ce fichier à partir de Android.mk
.
Implémenter des fonctions
Pour remplir les fonctions permettant d'implémenter le HAL, rappelez la fonction _hidl_cb
avec des valeurs différentes (en fonction des indicateurs de compilation). Par exemple, vous pouvez renseigner les fonctions pour surfaceflinger
dans 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 }
Assurez-vous que l'implémentation ne contient pas de fonction nommée HIDL_FETCH_interface-name
(par exemple, HIDL_FETCH_ISurfaceFlingerConfigs
). Cette fonction est nécessaire pour le mode passthrough HIDL, qui n'est pas utilisé (et interdit) par configstore
. ConfigStore doit toujours s'exécuter en mode lié.
S'inscrire en tant que service
Enfin, enregistrez toutes les implémentations d'interface auprès du service configstore
. Par exemple, vous pouvez enregistrer les implémentations surfaceflinger
dans 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();
Obtenir un accès anticipé
Pour s'assurer qu'un module de framework peut accéder de manière anticipée au service HAL, le service HAL de configuration doit démarrer le plus tôt possible, juste après que hwservicemanager
est prêt. Comme le service HAL de configuration ne lit pas de fichiers externes, il devrait être prêt rapidement après son lancement.