Zur Vorbereitung auf die HAL-Implementierung können Sie grundlegenden ConfigStore-Schnittstellencode generieren und ihn dann an Ihre Anforderungen anpassen.
Schnittstellencode generieren
Führen Sie hidl-gen aus, um Boilerplate-Code für die Schnittstelle zu generieren.
Beispiel: So generieren Sie 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
Android.mk ändern
Ä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. Beispiel: Sie können 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 den Code in eine neue Datei verschieben (z. B. surfaceflinger.mk) und diese Datei dann in Android.mk einfügen.
Funktionen implementieren
Um die Funktionen zur Implementierung der HAL auszufüllen, rufen Sie die Funktion _hidl_cb mit verschiedenen Werten auf (abhängig von den Build-Flags). Beispiel: Sie können die Funktionen für surfaceflinger in hardware/interfaces/configstore/1.0/default/SurfaceFlingerConfigs.cpp ausfü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
}
Die Implementierung darf keine Funktion mit dem Namen
HIDL_FETCH_interface-name enthalten (z. B.
HIDL_FETCH_ISurfaceFlingerConfigs). Diese Funktion ist für den
HIDL-Passthrough-Modus erforderlich, der von
configstore nicht verwendet wird (und verboten ist). ConfigStore muss immer im Binder-Modus ausgeführt werden.
Als Dienst registrieren
Registrieren Sie schließlich alle Schnittstellenimplementierungen für den Dienst configstore. Beispiel: Sie können 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();
Vorabzugriff sicherstellen
Damit ein Framework-Modul vorab auf den HAL-Dienst zugreifen kann, sollte der Config HAL-Dienst so früh wie möglich gestartet werden, direkt nachdem hwservicemanager bereit ist. Da der Config HAL-Dienst keine externen Dateien liest, ist er voraussichtlich schnell nach dem Start bereit.