Aby przygotować się do implementacji HAL, możesz wygenerować podstawowy kod interfejsu ConfigStore, a następnie dostosować go do swoich potrzeb.
Wygeneruj kod interfejsu
Aby wygenerować stały kod interfejsu, uruchom hidl-gen
.
Aby na przykład wygenerować kod dla adresu 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
, dodając plik implementacji (<modulename>Configs.cpp
) do LOCAL_SRC_FILES
i mapować flagi kompilacji na definicje makr. Możesz na przykład 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 (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
(np. HIDL_FETCH_ISurfaceFlingerConfigs
). Ta funkcja jest potrzebna w trybie przekazywania HIDL, który nie jest używany (i niedozwolony) przez configstore
. Magazyn konfiguracji musi zawsze działać w trybie powiązania.
Rejestrowanie jako usługi
Na koniec zarejestruj wszystkie implementacje interfejsu w usłudze configstore
. Możesz na przykład 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();
Zadbaj o wcześniejszy dostęp
Aby moduł platformy mógł uzyskać wcześniejszy dostęp do usługi HAL, usługa konfiguracji HAL powinna się uruchomić jak najwcześniej, zaraz po tym, jak interfejs hwservicemanager
będzie gotowy. Usługa konfiguracji HAL nie odczytuje plików zewnętrznych, dlatego powinna być gotowa od razu po uruchomieniu.