ConfigStore HAL

在 Android 10 中,ConfigStore HAL 使用 build 标志在 vendor 分区中存储配置值,system 分区中的服务使用 HIDL 访问这些值(在 Android 9 中也是如此)。不过,由于内存耗用量高且难以使用,ConfigStore HAL 已被废弃。

ConfigStore HAL 保留在 AOSP 中以支持旧版 vendor 分区。在搭载 Android 10 或更高版本的设备上,surfaceflinger 会先读取系统属性;如果没有为 `SurfaceFlingerProperties.sysprop` 中的配置项定义任何系统属性,`surfaceflinger` 会回退到 ConfigStore HAL。

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

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

为什么不使用系统属性?

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

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

我们曾尝试在不牺牲兼容性的情况下克服这些限制,但依然会担心系统属性的设计不支持访问只读配置项。最终,我们判定系统属性更适合在所有 Android 中实时共享一些动态更新内容,因此需要采用一个专用于访问只读配置项的新系统。

ConfigStore HAL 设计

基本设计很简单:

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 进行重大修订,因为被分隔的接口不再向后兼容。