product 分区

Android 9 及更高版本支持使用 Android 构建系统构建 product 分区。之前,Android 8.x 强制将 SoC 专属组件从 system 分区分隔到了 vendor 分区,不会为从 Android 构建系统构建的原始设备制造商 (OEM) 专属组件提供专用空间。Android 9 及更高版本提供了适用于不同分区上的特权应用的其他权限和列入白名单功能

product 分区简介

许多 OEM 会自定义 AOSP 系统映像,以实现自己的功能并满足运营商的要求。不过,如果进行这类自定义,则无法针对多个软件 SKU 使用单个系统映像。映像必须各不相同,才能支持不同的语言区域、运营商等自定义。如果使用单独的 product 分区来包含自定义项,则可以针对多个软件 SKU 使用单个系统映像(system 分区会托管可在众多软件 SKU 之间共享的通用代码)。vendor 分区会继续托管 SoC 专属 BSP 代码,这类代码可以基于指定 SoC 在多台设备之间共享。

使用单独的分区存在一些弊端,例如,难以管理磁盘空间(应该预留一定的空间满足未来增长的空间需求),以及难以在各分区之间维护稳定的应用二进制接口 (ABI)。在决定使用 product 分区之前,请花些时间考虑一下您的 AOSP 实现的具体情况和可行的缓解策略(例如,在无线下载 (OTA) 更新期间对设备进行重新分区;此操作不是由 Google 来完成,而是由某些 OEM 来完成)。动态分区是一个很好的解决方案。

product 分区和权限

在 Android 9 及更高版本中,权限和列入白名单过程的更改会影响您在 product 分区上授予特权应用权限的方式。permissions.xml 文件必须与特权应用位于同一个分区中。在特权应用所在的 system 分区中放置 permissions.xml 文件不会将这些权限扩展到 product 分区中的特权应用,即使前者是后者的扩展也不例外。如需详细了解相关权限和列入白名单的操作流程,请参阅特许权限许可名单

旧版 /oem 与 /product

product 分区具有两种属性,具体取决于 product 接口强制执行情况。此外,product 分区与旧式 oem 分区不同:

分区 属性
oem
  • 不可更新;通常在出厂时刷写一次。
  • 根据品牌信息和颜色等细微差异进行构建。具有不同的 oem 分区内容并不意味着产品软件是不同的。
  • system 分区不依赖于 oem 分区。(仅当在 oem 分区中找到特定文件时才使用该分区)。
  • 仅在 system 分区上使用公共 API。
product
  • 可更新
  • 搭配系统图像(该分区与系统映像一起更新)
  • 按产品或产品系列构建。
  • system 分区可以依赖于 product 分区。
  • 可以使用非公共 API,因为它们同时更新。
product(强制执行的接口)
  • 可更新
  • 已与系统映像分离。
  • 按产品或产品系列构建。
  • system 分区不依赖于 product 分区。
  • 无法使用隐藏 API,但只能在 system 分区上使用公共 API 和系统 API。

出于这些原因,Android 9 支持 product 分区,同时针对依赖于旧式 oem 分区的设备保留了对该分区的支持。为了将 product 分区与 system 分区分离开来,Android 11 支持强制执行 product 接口

/product 组件

product 分区包含以下组件:

  • 产品专用的系统属性 (/product/build.prop)
  • 产品专用的 RRO (/product/overlay/*.apk)
  • 产品专用的应用 (/product/app/*.apk)
  • 产品专用的特权应用 (/product/priv-app/*.apk)
  • 产品专用的内容库 (/product/lib/*)
  • 产品专用的 Java 库 (/product/framework/*.jar)
  • 产品专用的 Android 框架系统配置(/product/etc/sysconfig/*/product/etc/permissions/*
  • 产品专用的媒体文件 (/product/media/audio/*)
  • 产品专用的 bootanimation 文件

不得使用 custom_images

您不能使用 custom_images。它们缺乏对以下方面的支持:

  • 将模块安装到特定目标分区中custom_images 支持将工件复制到映像中,但无法通过将目标分区指定为构建规则的一部分,将模块安装到特定分区中。
  • Soong 支持。无法使用 Soong 构建系统构建 custom_images
  • OTA 更新支持custom_images 用作出厂 ROM 映像,无法接收 OTA 更新。

维护分区之间的 ABI

Android 9 中的 product 分区是 system 分区的扩展。由于 productsystem 分区之间的 ABI 稳定性较弱,因此必须同时升级这两者,而且 ABI 应基于系统 SDK。如果系统 SDK 不涵盖 productsystem 之间的所有 API 接口,原始设备制造商必须在这两个分区之间维护自己的 ABI。

product 分区和 system 分区可以相互依赖。不过,在没有 product 分区的情况下,对通用系统映像 (GSI) 的测试必须能够正常运行。

强制执行 product 接口时,product 分区会与 system 分区分离开来。product 分区仅使用 system 分区中允许的接口。

product 分区不能对 vendor 分区有任何依赖。product 分区与 vendor 分区之间不允许有任何直接交互。(这一规则将由 SEpolicy 强制执行。)

实现 product 分区

在实现新 product 分区之前,请先了解 AOSP 中的相关 product 分区变化。接下来,为了设置 product,请添加以下 board 构建标志或 product 构建标志:

  • BOARD_USES_PRODUCTIMAGE
  • BOARD_PRODUCTIMAGE_PARTITION_SIZE
  • BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
  • PRODUCT_PRODUCT_PROPERTIES(适用于 /product/build.prop)。这些标记必须位于 $(call inherit-product path/to/device.mk) 内,例如 PRODUCT_PRODUCT_PROPERTIES += product.abc=ok 内。

向 product 分区中安装模块

使用以下构建标记向 product 分区中安装模块。

  • Android.bp 中的 product_specific: true
  • Android.mk 中的 LOCAL_PRODUCT_MODULE := true

启用启动时验证功能

为防止 product 分区被恶意软件篡改,您应该为该分区启用 Android 启动时验证 (AVB)(就像为 vendor 分区和 system 分区启用一样)。如需启用 AVB,请添加以下构建标志:BOARD_AVB_PRODUCT_ADD_HASHTREE_FOOTER_ARGS