Как добавить классы и объекты ConfigStore

Вы можете добавить новые элементы ConfigStore (то есть методы интерфейса) для существующего класса интерфейса. Если класс интерфейса не определен, необходимо добавить новый класс, прежде чем добавлять элемент ConfigStore для этого класса. В этом разделе в качестве примера используется элемент конфигурации disableInitBlank для healthd, добавляемый в класс интерфейса IChargerConfigs.

Добавьте классы интерфейса

Если для метода интерфейса, который вы хотите добавить, не определен класс интерфейса, вам нужно добавить класс интерфейса, прежде чем вы сможете добавить связанные элементы ConfigStore.

  1. Создайте файл интерфейса HAL. Версия ConfigStore – 1.0, поэтому определите интерфейсы ConfigStore в hardware/interfaces/configstore/1.0. Пример для hardware/interfaces/configstore/1.0/IChargerConfigs.hal:
    package android.hardware.configstore@1.0;
    
    interface IChargerConfigs {
        // TO-BE-FILLED-BELOW
    };
    
  2. Обновите Android.bp и Android.mk для общей библиотеки ConfigStore и заголовочных файлов, чтобы включить новый HAL интерфейса. Пример:
    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
    
    Эти команды обновляют Android.bp и Android.mk в hardware/interfaces/configstore/1.0.
  3. Создайте заглушку C++ для реализации серверного кода. Пример:
    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
    
    Эта команда создает два файла: ChargerConfigs.h и ChargerConfigs.cpp, в каталоге hardware/interfaces/configstore/1.0/default.
  4. Откройте файлы реализации .h и .cpp и удалите код, связанный с функцией HIDL_FETCH_name (например, HIDL_FETCH_IChargerConfigs). Эта функция нужна для сквозного режима HIDL, который не используется ConfigStore.
  5. Зарегистрируйте реализацию в сервисе ConfigStore. Например, в следующем коде: 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. Измените файл Android.mk, чтобы добавить файл реализации (modulenameConfigs.cpp) в LOCAL_SRC_FILES и сопоставить флаги сборки с определениями макросов. Например, в следующем коде: 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. При необходимости добавьте запись манифеста. Если его нет, используется название экземпляра ConfigStore по умолчанию. Например, в device/google/marlin/manifest.xml:
        <hal format="hidl">
            <name>android.hardware.configstore</name>
            ...
            <interface>
                <name>IChargerConfigs</name>
                <instance>default</instance>
            </interface>
        </hal>
    
  8. При необходимости добавьте правило sepolicy (если у клиента нет разрешений на вызовы hwbinder к hal_configstore). Например, в system/sepolicy/private/healthd.te:
    ... // other rules
    binder_call(healthd, hal_configstore)
    

Как добавить новые объекты ConfigStore

Чтобы добавить новый элемент ConfigStore:

  1. Откройте файл HAL и добавьте необходимый метод интерфейса для элемента. (Файлы .hal для ConfigStore находятся в hardware/interfaces/configstore/1.0.) Например, в hardware/interfaces/configstore/1.0/IChargerConfigs.hal:
    package android.hardware.configstore@1.0;
    
    interface IChargerConfigs {
        ... // Other interfaces
        disableInitBlank() generates(OptionalBool value);
    };
    
  2. Реализуйте метод в соответствующих файлах реализации HAL интерфейса (.h и .cpp). Поместите реализации по умолчанию в hardware/interfaces/configstore/1.0/default. Например, в hardware/interfaces/configstore/1.0/default/ChargerConfigs.h:
    struct ChargerConfigs : public IChargerConfigs {
        ... // Other interfaces
        Return<void> disableInitBlank(disableInitBlank_cb _hidl_cb) override;
    };
    
    А в 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();
    }
    

Как использовать элементы ConfigStore

Чтобы использовать объект ConfigStore:

  1. Добавьте необходимые заголовочные файлы. Например, в system/core/healthd/healthd.cpp:
    #include <android/hardware/configstore/1.0/IChargerConfigs.h>
    #include <configstore/Utils.h>
    
  2. Получите доступ к элементу ConfigStore, используя подходящую функцию шаблона в android.hardware.configstore-utils. Например, в следующем коде: 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);
    
    В этом примере элемент ConfigStore disableInitBlank извлекается и сохраняется в переменной (это полезно, когда к переменной нужно обращаться несколько раз). Значение, полученное из ConfigStore, кэшируется внутри созданной функции шаблона, чтобы его можно было быстро получить из кэшированного значения, не обращаясь к сервису ConfigStore для последующих вызовов созданной функции шаблона.
  3. Добавьте зависимость от ConfigStore и библиотеки configstore-utils в Android.mk или Android.bp. Например, в следующем коде: system/core/healthd/Android.mk
    LOCAL_SHARED_LIBRARIES := \
        android.hardware.configstore@1.0 \
        android.hardware.configstore-utils \
        ... (other libraries) \