Wdrażanie Usługi

Aby przygotować się do wdrożenia HAL, możesz wygenerować podstawowy kod interfejsu ConfigStore, a następnie zmodyfikować go do swoich potrzeb.

Generowanie kodu interfejsu

Aby wygenerować standardowy kod interfejsu, uruchom hidl-gen . Na przykład, aby 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

Modyfikowanie pliku Android.mk

Następnie zmodyfikuj plik Android.mk , aby dodać plik implementacyjny ( <modulename>Configs.cpp ) do LOCAL_SRC_FILES i zamapować flagi kompilacji na definicje makr. Na przykład możesz zmodyfikować surfaceflinger w 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 (to znaczy surfaceflinger.mk ), a następnie dołącz ten plik z Android.mk .

Implementowanie funkcji

Aby wypełnić funkcje w celu zaimplementowania warstwy HAL, wywołaj funkcję _hidl_cb z różnymi wartościami (uwarunkowanymi flagami kompilacji). Na przykład możesz 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 w trybie przekazywania HIDL, który jest nieużywany (i zabroniony) przez configstore . ConfigStore musi zawsze działać w trybie powiązanym.

Rejestracja jako usługa

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

Zapewnienie wczesnego dostępu

Aby mieć pewność, że moduł frameworku będzie mógł uzyskać wcześniejszy dostęp do usługi HAL, konfiguracja usługi HAL powinna rozpocząć się tak wcześnie, jak to możliwe, zaraz po tym, jak hwservicemanager będzie gotowy. Ponieważ usługa konfiguracyjna HAL nie czyta plików zewnętrznych, oczekuje się, że będzie gotowa szybko po uruchomieniu.