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"
可以编码为由三个字符串组成的数组)。 - 覆盖。由于只读系统属性是以一次写入属性的形式实现的,因此如果供应商/ODM 想要替换 AOSP 定义的只读值,则必须先导入自己的只读值,然后再导入 AOSP 定义的只读值。这反过来会导致供应商定义的可重写值被 AOSP 定义的值替换。
- 地址空间要求。系统属性在每个进程中都会占用相对较大的地址空间。系统属性按
prop_area
单元进行分组,每个单元的固定大小为 128 KB,即使目前只访问单元中的一个系统属性,也会将整个单元分配到进程地址空间。这可能会导致地址空间非常宝贵的 32 位设备出现问题。
我们曾尝试在不牺牲兼容性的情况下克服这些限制,但依然会担心系统属性的设计不支持访问只读配置项。最终,我们判定系统属性更适合在所有 Android 中实时共享一些动态更新内容,因此需要采用一个专用于访问只读配置项的新系统。
ConfigStore HAL 设计
基本设计很简单:
图 1. ConfigStore HAL 设计
- 以 HIDL 描述 build 标志(目前用于对框架进行条件式编译)。
- 供应商和原始设备制造商 (OEM) 通过实现 HAL 服务为 build 标志提供 SoC 和设备特定值。
- 修改框架,以使用 HAL 服务在运行时查找配置项的值。
当前由框架引用的配置项会包含在具有版本号的 HIDL 软件包 (android.hardware.configstore@1.0
) 中。供应商/OEM 通过实现此软件包中的接口为配置项提供值,而框架会在需要获取配置项的值时使用这些接口。
安全注意事项
在同一接口中定义的 build 标志会受到相同 SELinux 政策的影响。如果一个或多个 build 标志应具有不同的 SELinux 政策,则必须将这些标志分隔到其他接口。这可能需要对 android.hardware.configstore package
进行重大修订,因为被分隔的接口不再向后兼容。