您可以重构经过条件式编译的代码,以便从 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 服务。
为了实现向前兼容性,请确保在实现过程中遵循以下准则:
- 当只有旧版服务可用时,新项使用默认值。例如:
service = V1_1::IConfig::getService(); // null if V1_0 is installed value = DEFAULT_VALUE; if(service) { value = service->v1_1API(DEFAULT_VALUE); }
- 客户端使用包含 ConfigStore 项的第一个接口。例如:
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
- 可以为旧版接口检索新版服务。在以下示例中,如果已安装版本为 v1_1,必须为
getService()
返回 v1_1 服务:V1_0::IConfig::getService()->v1_0API();
当 configstore-utils
库中的访问函数用于访问 ConfigStore 项时,#1 由实现保证,#2 由编译器错误保证。基于这些原因,强烈建议尽可能使用 configstore-utils
。