To prepare for the HAL implementation, you can generate basic configstore interface code then modify it to meet your needs.
To generate boilerplate code for the interface, run hidl-gen
.
For example, to generate code for 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
Note: Don't run hidl-gen
with
-Landroidbp-impl
as this generates Android.bp
. The
module must be built with Android.mk
to access build flags.
Next, modify Android.mk
file to add implementation file
(<modulename>Configs.cpp
) to LOCAL_SRC_FILES
and
to map build flags into macro definitions. For example, you can modify
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
If Android.mk
includes several ifeq-endif
blocks,
consider moving your code into a new file (i.e., surfaceflinger.mk
)
then include that file from Android.mk
.
To fill the functions to implement the HAL, call back the
_hidl_cb
function with different values (conditioned on build
flags). For example, you can fill the functions for 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 }
Ensure the implementation does not contain a function named
HIDL_FETCH_<interface name>
(e.g.,
HIDL_FETCH_ISurfaceFlingerConfigs
). This function is needed for
HIDL passthrough mode, which is unused (and prohibited) by
configstore
. ConfigStore must always run in binderized mode.
Finally, register all interface implementations to the
configstore
service. For example, you can register
surfaceflinger
implementations 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();
To ensure a framework module can get early access the HAL service, the config
HAL service should start as early as possible, just after
hwservicemanager
is ready. As the config HAL service does not read
external files, it is expected to be ready quickly after it is launched.