Wdróż usługę

Aby przygotować się do implementacji HAL, możesz wygenerować podstawowy kod interfejsu ConfigStore, a następnie zmodyfikować go zgodnie z potrzebami.

Generowanie kodu interfejsu

Aby wygenerować szablonowy kod interfejsu, uruchom hidl-gen. Aby na przykład wygenerować kod dla 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

Modyfikuj plik Android.mk

Następnie zmodyfikuj plik Android.mk, aby dodać plik implementacji (<modulename>Configs.cpp) do pliku LOCAL_SRC_FILES i przypisać flagi kompilacji do definicji makr. Możesz na przykład zmienić parametr surfaceflinger w pliku 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

Jeśli Android.mk zawiera kilka bloków ifeq-endif, rozważ przeniesienie kodu do nowego pliku (czyli surfaceflinger.mk), a potem dołącz ten plik z Android.mk.

Wdrażanie funkcji

Aby wypełnić funkcje w celu implementacji HAL, wywołaj funkcję _hidl_cb z różnymi wartościami (uwarunkowanymi na flagach kompilacji). Możesz na przykład wypełnić funkcje surfaceflinger w 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
}

Upewnij się, że implementacja nie zawiera funkcji o nazwie HIDL_FETCH_interface-name (na przykład HIDL_FETCH_ISurfaceFlingerConfigs). Ta funkcja jest potrzebna do obsługi trybu przekazywania HIDL, który jest nieużywany (i zabroniony) przez configstore. Magazyn konfiguracji musi zawsze działać w trybie powiązania.

Rejestrowanie się jako usługa

Na koniec zarejestruj wszystkie implementacje interfejsu w usłudze configstore. Możesz na przykład zarejestrować implementacje surfaceflinger w tych usługach: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();

Zapewnij wcześniejszy dostęp

Aby zapewnić modułowi frameworku wczesny dostęp do usługi HAL, usługa konfiguracji HAL powinna być uruchamiana jak najwcześniej, zaraz po tym, jak usługa hwservicemanager będzie gotowa. Usługa konfiguracji HAL nie odczytuje plików zewnętrznych, więc powinna być gotowa wkrótce po uruchomieniu.