You can add new ConfigStore items (i.e., interface methods) for an existing interface class. If the interface class is not defined, you must add a new class before you can add a ConfigStore item for that class. This section uses the example of a disableInitBlank configuration item for healthd being added to the IChargerConfigs interface class.

Note: Before continuing, ensure you are familiar with general HIDL concepts, HIDL C++ development workflow, HIDL Code Style, and ConfigStore design.

Adding interface classes

If no interface class is defined for the interface method you want to add, you must first add the interface class before you can add the associated ConfigStore items.

  1. Create a HAL interface file. The ConfigStore version is 1.0, so define ConfigStore interfaces in hardware/interfaces/configstore/1.0. For example, in hardware/interfaces/configstore/1.0/IChargerConfigs.hal:
    package android.hardware.configstore@1.0;
    
    interface IChargerConfigs {
        // TO-BE-FILLED-BELOW
    };
    
  2. Update Android.bp and Android.mk for ConfigStore shared library and header files to include the new interface HAL. For example:
    hidl-gen -o hardware/interfaces/configstore/1.0/default -Lmakefile -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0::IChargerConfigs
    hidl-gen -o hardware/interfaces/configstore/1.0/default -Landroidbp -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0::IChargerConfigs
    
    These commands update Android.bp and Android.mk in hardware/interfaces/configstore/1.0.
  3. Generate the C++ stub for implementing the server code. For example:
    hidl-gen -o hardware/interfaces/configstore/1.0/default -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0::IChargerConfigs
    
    This command creates two files, ChargerConfigs.h and ChargerConfigs.cpp, in hardware/interfaces/configstore/1.0/default.
  4. Open the .h and .cpp implementation files and remove code related to the function HIDL_FETCH_name (e.g., HIDL_FETCH_IChargerConfigs). This function is needed for HIDL passthrough mode, which is unused by ConfigStore.
  5. Register the implementation to the ConfigStore service. For example, in hardware/interfaces/configstore/1.0/default/service.cpp:
    #include <android/hardware/configstore/1.0/IChargerConfigs.h>
    #include "ChargerConfigs.h"
    
    using android::hardware::configstore::V1_0::IChargerConfigs;
    using android::hardware::configstore::V1_0::implementation::ChargerConfigs;
    
    int main() {
        ... // other code
        sp<IChargerConfigs> chargerConfigs = new ChargerConfigs;
        status = chargerConfigs->registerAsService();
        LOG_ALWAYS_FATAL_IF(status != OK, "Could not register IChargerConfigs");
        ... // other code
    }
    
  6. Modify Android.mk file to add implementation file (modulenameConfigs.cpp) to LOCAL_SRC_FILES and to map build flags into macro definitions. For example, in hardware/interfaces/configstore/1.0/default/Android.mk:
    LOCAL_SRC_FILES += ChargerConfigs.cpp
    
    ifeq ($(strip $(BOARD_CHARGER_DISABLE_INIT_BLANK)),true)
    LOCAL_CFLAGS += -DCHARGER_DISABLE_INIT_BLANK
    endif
    
  7. (Optional) Add manifest entry. If it doesn't exist, default to the "default" instance name of ConfigStore. For example, in device/google/marlin/manifest.xml:
        <hal format="hidl">
            <name>android.hardware.configstore</name>
            ...
            <interface>
                <name>IChargerConfigs</name>
                <instance>default</instance>
            </interface>
        </hal>
    
  8. Add the sepolicy rule if needed (i.e., if the client does not have permissions for making hwbinder calls to the hal_configstore). For example, in system/sepolicy/private/healthd.te:
    ... // other rules
    binder_call(healthd, hal_configstore)
    

Adding new ConfigStore items

To add a new ConfigStore item:

  1. Open the HAL file and add required interface method for the item. (The .hal files for ConfigStore reside in hardware/interfaces/configstore/1.0.) For example, in hardware/interfaces/configstore/1.0/IChargerConfigs.hal:
    package android.hardware.configstore@1.0;
    
    interface IChargerConfigs {
        ... // Other interfaces
        disableInitBlank() generates(OptionalBool value);
    };
    
  2. Implement the method in the corresponding interface HAL implementation files (.h and .cpp). Place default implementations in hardware/interfaces/configstore/1.0/default.

    Note: Running hidl-gen with -Lc++-impl generates skeleton code for the newly added interface method. However, as it also overwrites implementations for all existing interface methods, use the -o option appropriately.

    For example, in hardware/interfaces/configstore/1.0/default/ChargerConfigs.h:
    struct ChargerConfigs : public IChargerConfigs {
        ... // Other interfaces
        Return<void> disableInitBlank(disableInitBlank_cb _hidl_cb) override;
    };
    
    And in hardware/interfaces/configstore/1.0/default/ChargerConfigs.cpp:
    Return<void> ChargerConfigs::disableInitBlank(disableInitBlank_cb _hidl_cb) {
        bool value = false;
    #ifdef CHARGER_DISABLE_INIT_BLANK
        value = true;
    #endif
        _hidl_cb({true, value});
        return Void();
    }
    

Using ConfigStore items

To use a ConfigStore item:

  1. Include required header files. For example, in system/core/healthd/healthd.cpp:
    #include <android/hardware/configstore/1.0/IChargerConfigs.h>
    #include <configstore/Utils.h>
    
  2. Access the ConfigStore item using the appropriate template function in android.hardware.configstore-utils. For example, in system/core/healthd/healthd.cpp:
    using namespace android::hardware::configstore;
    using namespace android::hardware::configstore::V1_0;
    
    static int64_t disableInitBlank = getBool<
            IChargerConfigs,
            &IChargerConfigs::disableInitBlank>(false);
    
    In this example, the ConfigStore item disableInitBlank is retrieved and stored to a variable (useful when the variable needs to be accessed multiple times). The value retrieved from the ConfigStore is cached inside the instantiated template function so it can be retrieved quickly from the cached value without contacting the ConfigStore service for later calls to the instantiated template function.
  3. Add the dependency on ConfigStore and configstore-utils library in Android.mk or Android.bp. For example, in system/core/healthd/Android.mk:
    LOCAL_SHARED_LIBRARIES := \
        android.hardware.configstore@1.0 \
        android.hardware.configstore-utils \
        ... (other libraries) \