Implementare il servizio

Per prepararti all'implementazione di HAL, puoi generare il codice di interfaccia di ConfigStore di base, quindi modificarlo in base alle tue esigenze.

Genera codice dell'interfaccia

Per generare il codice boilerplate per l'interfaccia, esegui hidl-gen. Ad esempio, per generare il codice per 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

Modificare Android.mk

A questo punto, modifica il file Android.mk per aggiungere il file di implementazione (<modulename>Configs.cpp) a LOCAL_SRC_FILES e per mappare i flag di compilazione alle definizioni di macro. Ad esempio, puoi modificare surfaceflinger in 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

Se Android.mk include diversi blocchi ifeq-endif, valuta la possibilità di spostare il codice in un nuovo file (ossia surfaceflinger.mk), quindi includi il file da Android.mk.

Implementare le funzioni

Per compilare le funzioni per implementare l'HAL, richiama la funzione _hidl_cb con valori diversi (in base ai flag di compilazione). Ad esempio, puoi compilare le funzioni per surfaceflinger in 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
}

Assicurati che l'implementazione non contenga una funzione denominata HIDL_FETCH_interface-name (ad esempio HIDL_FETCH_ISurfaceFlingerConfigs). Questa funzione è necessaria per la modalità di passaggio HIDL, che non è utilizzata (e vietata) da configstore. ConfigStore deve sempre essere eseguito in modalità con binder.

Registrati come servizio

Infine, registra tutte le implementazioni dell'interfaccia al servizioconfigstore. Ad esempio, puoi registrare le implementazioni di surfaceflinger in 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();

Garantire l'accesso in anteprima

Per garantire che un modulo del framework possa ottenere l'accesso in anteprima al servizio HAL, il servizio HAL di configurazione deve essere avviato il prima possibile, subito dopo che hwservicemanager è pronto. Poiché il servizio HAL di configurazione non legge i file esterni, dovrebbe essere pronto rapidamente dopo il lancio.