Dienst implementieren

Zur Vorbereitung auf die HAL-Implementierung können Sie einfachen ConfigStore-Schnittstellencode generieren und ihn dann an Ihre Anforderungen anpassen.

Benutzeroberflächencode generieren

Führen Sie hidl-gen aus, um Boilerplate-Code für die Benutzeroberfläche zu generieren. 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

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 den Makrodefinitionen zuzuordnen. Sie können beispielsweise 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 (surfaceflinger.mk) verschieben und diese Datei dann in Android.mk einbinden.

Funktionen implementieren

Rufen Sie die Funktion _hidl_cb mit verschiedenen Werten auf, um die Funktionen zur Implementierung der HAL auszufüllen (abhängig von den Build-Flags). Sie können beispielsweise die Funktionen für surfaceflinger in hardware/interfaces/configstore/1.0/default/SurfaceFlingerConfigs.cpp einfügen:

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 namens 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 (und verboten) wird. ConfigStore muss immer im Binder-Modus ausgeführt werden.

Als Dienst registrieren

Registrieren Sie abschließend alle Benutzeroberflächenimplementierungen beim configstore-Dienst. Sie können surfaceflinger-Implementierungen beispielsweise in folgenden hardware/interfaces/configstore/1.0/default/service.cpp-Objekten 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 sichern

Damit ein Framework-Modul Vorabzugriff auf den HAL-Dienst erhalten kann, sollte der HAL-Konfigurationsdienst so früh wie möglich gestartet werden, kurz nachdem hwservicemanager bereit ist. Da der Konfigurations-HAL-Dienst keine externen Dateien liest, wird erwartet, dass er schnell nach dem Start einsatzbereit ist.