客户端使用情况

您可以重构经过条件式编译的代码,以便从 HAL 接口动态读取值。例如:

#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
//some code fragment
#endif

随后,框架代码便可以调用一个在 <configstore/Utils.h> 中定义的适当效用函数(根据其类型)。

ConfigStore 示例

以下示例显示了读取 TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS(在 ConfigStore HAL 中定义为 forceHwcForVirtualDisplays(),返回类型为 OptionalBool)的情形:

#include <configstore/Utils.h>
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;

static bool vsyncPhaseOffsetNs = getBool<ISurfaceFlingerConfigs,
        ISurfaceFlingerConfigs::forceHwcForVirtualDisplays>(false);

效用函数(上例中的 getBool)会与 configstore 服务进行通信以获取接口函数代理的句柄,然后通过 HIDL/hwbinder 来调用句柄,从而检索该值。

效用函数

<configstore/Utils.h> (configstore/1.0/include/configstore/Utils.h) 会为每个原始返回类型(包括 Optional[Bool|String|Int32|UInt32|Int64|UInt64])提供效用函数,如下所示:

类型 函数(已省略模板参数)
OptionalBool bool getBool(const bool defValue)
OptionalInt32 int32_t getInt32(const int32_t defValue)
OptionalUInt32 uint32_t getUInt32(const uint32_t defValue)
OptionalInt64 int64_t getInt64(const int64_t defValue)
OptionalUInt64 uint64_t getUInt64(const uint64_t defValue)
OptionalString std::string getString(const std::string &defValue)

defValue 是在 HAL 实现没有为配置项指定值时返回的默认值。每个函数都需要使用两个模板参数:

  • I. 接口类名称。
  • Func. 用于获取配置项的成员函数指针。

由于配置值是只读属性且不会发生更改,因此效用函数会在内部缓存配置值。使用同一链接单元中的缓存值可以更有效地执行后续调用。

使用 configstore-utils

ConfigStore HAL 旨在向前兼容次要版本升级,这意味着当 HAL 进行升级并且某些框架代码使用新引入的项时,您仍然可以使用 /vendor 中旧的次要版本的 ConfigStore 服务。

为了实现向前兼容性,请确保在实现过程中遵循以下准则:

  1. 当只有旧版服务可用时,新项使用默认值。例如:
    service = V1_1::IConfig::getService(); // null if V1_0 is installed
    value = DEFAULT_VALUE;
      if(service) {
        value = service->v1_1API(DEFAULT_VALUE);
      }
    
  2. 客户端使用引入 ConfigStore 项的最早的接口。例如:
    V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED
    
    V1_0::IConfig::getService()->v1_0API(); // OK
    
  3. 可以为旧版接口检索新版服务。在以下示例中,如果已安装版本为 v1_1,则必须为 getService() 返回 v1_1 服务:
    V1_0::IConfig::getService()->v1_0API();
    

    注意当前 AOSP 实现符合此要求。

configstore-utils 库中的访问函数用于访问 ConfigStore 项时,#1 由实现保证,#2 由编译器错误保证。基于这些原因,我们强烈建议尽量使用 configstore-utils