Configstore HAL

Android O 将整个 Android 操作系统拆分为通用分区 (system.img) 和特定于硬件的分区(vendor.img 和 odm.img)。受这种变更的影响,您必须从安装到系统分区的模块中移除条件式编译,而且此类模块现在必须在运行时确定系统配置(并根据相应配置采取不同的行为)。

ConfigStore HAL 提供了一组 API,可供访问用于配置 Android 框架的只读配置项。本页介绍了 ConfigStore HAL 的设计(以及不使用系统属性来访问只读配置项的原因);本部分的其他页面详细介绍了 HAL 接口服务实现客户端使用情况,所有这些均以 surfaceflinger 为例。如需获得 ConfigStore 接口类的相关帮助,请参阅添加接口类和项

为什么不使用系统属性?

我们考虑过使用系统属性,但发现了以下几个重大问题,例如:

  • 值的长度受限:系统属性对其值的长度具有严格限制(92 个字节)。此外,由于这些限制已作为 C 宏直接提供给 Android 应用,增加长度会导致出现向后兼容性问题。
  • 无类型支持:所有值本质上都是字符串,而 API 仅仅是将字符串解析为 intbool。其他复合数据类型(数组、结构体等)应由客户端进行编码/解码(例如,“aaa,bbb,ccc”可以解码为由三个字符串组成的数组)。
  • 覆盖:由于只读系统属性是以一次写入属性的形式实现的,因此如果供应商/原始设计制造商 (ODM) 想要覆盖 AOSP 定义的只读值,则必须先于 AOSP 定义的只读值导入自己的只读值,而这反过来又会导致供应商定义的可重写值被 AOSP 定义的值所覆盖。
  • 地址空间要求:系统属性在每个进程中都会占用较大的地址空间。系统属性在 prop_area 单元中以 128KB 的固定大小进行分组,即使目前只访问该单元中的一个系统属性,其中的所有属性也将会分配到进程地址空间。这可能会导致对地址空间需求较高的 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 进行重大升级,因为被分隔的接口不再向后兼容。