Wdrażanie usługi

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

Generowanie kodu interfejsu

Aby wygenerować kod szablonowy interfejsu, uruchom hidl-gen. Aby na przykład wygenerować kod dla zmiennej 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 implementacji (<modulename>Configs.cpp) do LOCAL_SRC_FILES i zmapować flagi kompilacji na definicje makr. Możesz na przykład zmodyfikować 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 następnie dołącz ten plik z Android.mk.

Implementowanie funkcji

Aby wypełnić funkcje implementujące HAL, wywołaj funkcję _hidl_cb z różnymi wartościami (w zależności od flag kompilacji). Możesz na przykład wypełnić funkcje dla 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 (np. HIDL_FETCH_ISurfaceFlingerConfigs). Ta funkcja jest potrzebna w przypadku trybu przekazywania HIDL, który nie jest używany (i jest zabroniony) przez configstore. Usługa ConfigStore musi zawsze działać w trybie powiązanym.

Rejestracja jako usługa

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

Zapewnij sobie wcześniejszy dostęp

Aby moduł platformy mógł uzyskać wczesny dostęp do usługi HAL, usługa HAL konfiguracji powinna zostać uruchomiona jak najszybciej, zaraz po tym, jak hwservicemanager będzie gotowy. Usługa HAL konfiguracji nie odczytuje plików zewnętrznych, więc powinna być gotowa do działania krótko po uruchomieniu.