Zur Vorbereitung der HAL-Implementierung können Sie grundlegenden ConfigStore-Schnittstellencode generieren und ihn dann entsprechend Ihren Anforderungen ändern.
Generieren von Schnittstellencode
Um Boilerplate-Code für die Schnittstelle zu generieren, führen Sie hidl-gen
aus. So generieren Sie beispielsweise Code für 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
Ändern von Android.mk
Ändern Sie als Nächstes die Datei Android.mk
, um die Implementierungsdatei ( <modulename>Configs.cpp
) zu LOCAL_SRC_FILES
hinzuzufügen und Build-Flags Makrodefinitionen zuzuordnen. Beispielsweise können Sie surfaceflinger
in hardware/interface/configstore/1.0/default/Android.mk
ändern:
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
Wenn Android.mk
mehrere ifeq-endif
Blöcke enthält, sollten Sie erwägen, Ihren Code in eine neue Datei (d. h. surfaceflinger.mk
) zu verschieben und diese Datei dann aus Android.mk
einzubinden.
Funktionen implementieren
Um die Funktionen zur Implementierung des HAL zu füllen, rufen Sie die Funktion _hidl_cb
mit unterschiedlichen Werten zurück (abhängig von Build-Flags). Beispielsweise können Sie die Funktionen für surfaceflinger
in hardware/interfaces/configstore/1.0/default/SurfaceFlingerConfigs.cpp
füllen:
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 }
Stellen Sie sicher, dass die Implementierung keine Funktion mit dem Namen HIDL_FETCH_ interface-name
enthält (z. B. HIDL_FETCH_ISurfaceFlingerConfigs
). Diese Funktion wird für den HIDL-Passthrough-Modus benötigt, der von configstore
nicht verwendet (und verboten) wird. ConfigStore muss immer im binderisierten Modus ausgeführt werden.
Registrierung als Dienst
Registrieren Sie abschließend alle Schnittstellenimplementierungen beim configstore
Dienst. Beispielsweise können Sie surfaceflinger
Implementierungen in hardware/interfaces/configstore/1.0/default/service.cpp
registrieren:
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();
Gewährleistung eines frühen Zugriffs
Um sicherzustellen, dass ein Framework-Modul frühzeitig auf den HAL-Dienst zugreifen kann, sollte der Konfigurations-HAL-Dienst so früh wie möglich starten, direkt nachdem hwservicemanager
bereit ist. Da der Konfigurations-HAL-Dienst keine externen Dateien liest, wird erwartet, dass er nach dem Start schnell bereit ist.