在 Android 10 中,ConfigStore HAL 使用构建标记将配置值存储在 vendor
分区中,而 system
分区中的服务使用 HIDL 访问这些值(Android 9 也是如此)。但是,由于内存消耗高且难以使用,ConfigStore HAL 已被弃用。
ConfigStore HAL 保留在 AOSP 中以支持旧版供应商分区。在运行 Android 10 或更高版本的设备上,surfaceflinger
首先读取系统属性;如果 `SurfaceFlingerProperties.sysprop` 中的配置项未定义系统属性,则 surfaceflinger
会回退到 ConfigStore HAL。
Android 8.0 将单体 Android 操作系统拆分为通用分区(system.img
)和硬件特定分区(vendor.img
和 odm.img
)。由于此更改,必须从安装到系统分区的模块中删除条件编译,并且此类模块必须在运行时确定系统配置(并根据该配置表现出不同的行为)。
ConfigStore HAL 提供了一组 API,用于访问用于配置 Android 框架的只读配置项。此页面描述了 ConfigStore HAL 的设计(以及为什么不使用系统属性来实现此目的);本节中的其他页面详细介绍了 HAL 接口、服务实现 和 客户端使用,所有这些都以 surfaceflinger
为例。有关 ConfigStore 接口类的帮助,请参阅 添加接口类和项。
为什么不使用系统属性?
我们考虑过使用系统属性,但发现了一些根本问题,包括
- 值的长度限制。 系统属性对其值的长度有严格的限制(92 字节)。此外,由于这些限制已作为 C 宏直接暴露给 Android 应用,因此增加长度可能会导致向后兼容性问题。
- 没有类型支持。 所有值本质上都是字符串,API 只是将字符串解析为
int
或bool
。其他复合数据类型(例如,数组和结构体)应由客户端进行编码/解码(例如,"aaa,bbb,ccc"
可以编码为包含三个字符串的数组)。 - 覆盖。 由于只读系统属性被实现为一次写入属性,因此想要覆盖 AOSP 定义的只读值的供应商/ODM 必须在 AOSP 定义的只读值之前导入他们自己的只读值。反过来,这会导致供应商定义的、可重写的值被 AOSP 定义的值覆盖。
- 地址空间要求。 系统属性在每个进程中占用相对大量的地址空间。系统属性被分组在
prop_area
单元中,每个单元的大小固定为 128 KB,即使仅访问其中的单个系统属性,所有这些单元也会被分配给进程地址空间。这可能会在地址空间宝贵的 32 位设备上引起问题。
我们曾尝试在不牺牲兼容性的情况下克服这些限制,但仍然担心系统属性并非旨在支持访问只读配置项。最终,我们认为系统属性更适合在整个 Android 中实时共享少量动态更新的项,并且需要一个新的系统来专门访问只读配置项。
ConfigStore HAL 设计
基本设计很简单
图 1. ConfigStore HAL 设计
- 在 HIDL 中描述构建标志(目前用于有条件地编译框架)。
- 供应商和 OEM 通过实现 HAL 服务来为构建标志提供 SoC 和设备特定的值。
- 修改框架以使用 HAL 服务在运行时查找配置项的值。
框架当前引用的配置项包含在版本化的 HIDL 包(android.hardware.configstore@1.0
)中。供应商/OEM 通过实现此包中的接口来为配置项提供值,并且框架在需要获取配置项的值时使用这些接口。
安全注意事项
在同一接口中定义的构建标志受相同的 SELinux 策略影响。如果一个或多个构建标志应具有不同的 SELinux 策略,则必须将它们分离到另一个接口。这可能需要对 android.hardware.configstore package
进行重大修订,因为分离的接口不再向后兼容。