您可以使用 build/make/tools/releasetools
中提供的 ota_from_target_files
工具,针对使用 A/B 系统更新或非 A/B 系统更新的设备构建完整 OTA 软件包和增量 OTA 软件包。该工具将 Android 构建系统生成的 target-files.zip
文件作为输入文件。
对于搭载 Android 11 或更高版本的设备,您可以为具有不同 SKU 的多台设备构建一个 OTA 软件包。为此,需要将目标设备配置为使用动态指纹并更新 OTA 元数据,以便在前提条件和后置条件条目中添加设备名称和指纹。
Android 8.0 废弃了非 A/B 设备基于文件的 OTA 软件包,而必须改用基于块的 OTA 软件包。如需为搭载 Android 7.x 或更低版本的设备生成基于块的 OTA 软件包,请将 --block
选项传递给 ota_from_target_files
参数。
构建完整更新
完整更新是指 OTA 软件包将对设备的整个最终状态(system 分区、boot 分区和 recovery 分区)进行更新。不管设备的当前状态如何,只要设备能够接收和应用软件包,软件包就会安装 build。例如,以下命令使用发布工具为 tardis
设备构建 target-files.zip
归档文件。
. build/envsetup.sh && lunch tardis-eng
mkdir dist_output
make dist DIST_DIR=dist_output
make dist
会构建完整的 OTA 软件包(在 $OUT
中)。生成的 .zip
文件包含为 tardis
设备构建 OTA 软件包所需的所有内容。您还可以将 ota_from_target_files
构建为 Python 二进制文件,并调用它来构建完整软件包或增量软件包。
ota_from_target_files dist_output/tardis-target_files.zip ota_update.zip
ota_from_target_files
路径在 $PATH
中设置,并且生成的 Python 二进制文件位于 out/
目录中。
ota_update.zip
现已准备就绪,可以发送到测试设备(所有内容均使用测试密钥进行签名)。对于用户设备,请生成并使用自己的私钥,详情请参阅对需要发布的 build 进行签名。
构建增量更新
增量更新是指 OTA 软件包将对设备上的现有数据应用二进制补丁。采用增量更新的软件包通常较小,因为它们无需包含未更改的文件。此外,由于更改的文件通常与之前的版本非常相似,因此软件包中只需包含针对两个文件之间的不同之处进行的编码。
只有当设备具有构建相应软件包所使用的源 build 时,您才能在设备上安装增量更新软件包。如需构建增量更新,您需要上一个 build(您要更新的那个 build)中的 target_files.zip
文件以及新 build 中的 target_files.zip
文件。例如,以下命令可使用发布工具为 tardis
设备构建增量更新。
ota_from_target_files -i PREVIOUS-tardis-target_files.zip dist_output/tardis-target_files.zip incremental_ota_update.zip
此 build 与上一个 build 非常相似,而且增量更新软件包(incremental_ota_update.zip
,约 1MB)比对应的完整更新软件包 (60MB) 小得多。
仅当设备运行的上一个 build 与相应增量更新软件包的起点 build 完全一样时,才向其分发该增量更新软件包。您必须刷写 PREVIOUS-tardis-target_files.zip
或 PREVIOUS-tardis-img.zip
中的映像(均使用 make dist
构建,将使用 fastboot update
进行刷写),而不是 PRODUCT_OUT
目录下的映像(使用 make
进行构建,将使用 fastboot flashall
进行刷写)。尝试在具有其他某个 build 的设备上安装增量更新软件包会导致安装错误。如果安装失败,设备同样会保持正常运行状态(运行旧系统);软件包在触及它要更新的所有文件之前,会验证其上一个状态,因此设备不会滞留在半升级状态。
为了提供最佳用户体验,请在每 3-4 次增量更新之后提供 1 次完整更新。这样有助于用户及时更新到最新版本,并避免冗长的增量更新安装序列。
为多个 SKU 构建 OTA 软件包
Android 11 或更高版本支持为具有不同 SKU 的多台设备使用单个 OTA 软件包。为此,需要将目标设备配置为使用动态指纹并更新 OTA 元数据(使用 OTA 工具),以便在前提条件和后置条件条目中添加设备名称和指纹。
关于 SKU
SKU 的格式是组合 build 参数值的变体,通常是当前 build_fingerprint
参数的未声明子集。原始设备制造商 (OEM) 可以为 SKU 使用由 CDD 批准的构建参数的任意组合,同时仍对这些 SKU 使用单个映像。例如,以下 SKU 具有多个变体:
SKU = <product><device><modifierA><modifierB><modifierC>
modifierA
是设备级(例如 Pro、Premium 或 Plus)modifierB
是硬件变体(例如无线装置)modifierC
是区域,可以是一般区域(如 NA、EMEA 或 CHN),也可以是特定于国家/地区或语言的区域(如 JPN、ENG 或 CHN)
许多 OEM 都针对多个 SKU 使用单个映像,然后在设备启动后在运行时衍生出最终的产品名称和设备指纹。此过程简化了平台开发流程,使进行了小规模自定义但产品名称不同的设备(如 tardis
和 tardispro
)可以共用常见的映像。
使用动态指纹
指纹是一个定义好的构建参数的串联,如 ro.product.brand
、ro.product.name
和 ro.product.device
。设备的指纹衍生自 system 分区指纹,用作在设备中运行的映像(和字节)的唯一标识符。如需创建动态指纹,请使用设备 build.prop
文件中的动态逻辑,在设备启动时获取引导加载程序变量的值,然后使用这些数据为该设备创建动态指纹。
例如,如需为 tardis
和 tardispro
设备使用动态指纹,请按如下说明更新相应文件。
更新
odm/etc/build_std.prop
文件,在其中添加以下代码行。ro.odm.product.device=tardis
更新
odm/etc/build_pro.prop
文件,在其中添加以下代码行。ro.odm.product.device=tardispro
更新
odm/etc/build.prop
文件,在其中添加以下代码行。ro.odm.product.device=tardis import /odm/etc/build_${ro.boot.product.hardware.sku}.prop
这些代码行会根据 ro.boot.product.hardware.sku
引导加载程序属性(只读)的值动态设置设备名称、指纹和 ro.build.fingerprint
值。
更新 OTA 软件包元数据
OTA 软件包中包含用于描述软件包的元数据文件 (META-INF/com/android/metadata
),其中包括 OTA 软件包的前提条件和后置条件。例如,以下代码是某个以 tardis
设备为目标的 OTA 软件包的元数据文件。
post-build=google/tardis/tardis:11/RP1A.200521.001/6516341:userdebug/dev-keys
post-build-incremental=6516341
post-sdk-level=30
post-security-patch-level=2020-07-05
post-timestamp=1590026334
pre-build=google/tardis/tardis:11/RP1A.200519.002.A1/6515794:userdebug/dev-keys
pre-build-incremental=6515794
pre-device=tardis
pre-device
、pre-build-incremental
和 pre-build
值定义了设备必须具备哪种状态后才能安装 OTA 软件包。post-build-incremental
和 post-build
值定义了设备在安装 OTA 软件包后的预期状态。pre-
和 post-
字段的值衍生自下列对应的构建属性。
pre-device
值衍生自ro.product.device
build 属性。pre-build-incremental
和post-build-incremental
值衍生自ro.build.version.incremental
build 属性。pre-build
和post-build
值衍生自ro.build.fingerprint
构建属性。
在搭载 Android 11 或更高版本的设备上,您可以在 OTA 工具中使用 --boot_variable_file
标志指定一个文件的路径,该文件包含用于创建设备动态指纹的运行时变量的值。然后,这些数据将被用来更新 OTA 元数据,以在 pre-
和 post-
条件中添加设备名称和指纹(使用竖线字符 | 作为分隔符)。--boot_variable_file
标志的语法和说明如下。
- 语法:
--boot_variable_file <path>
- 说明:指定一个文件的路径,该文件包含
ro.boot.*
属性的可能值。该属性用于在某些ro.product.*
属性被 import 语句覆盖时计算可能的运行时指纹。该文件每行需要填写一个属性,每行的格式如下:prop_name=value1,value2
。
例如,当属性为 ro.boot.product.hardware.sku=std,pro
时,tardis
和 tardispro
设备的 OTA 元数据如下所示。
post-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-device=tardis|tardispro
如需在搭载 Android 10 的设备上支持此功能,请参阅参考实现。此变更列表会有条件地解析 build.prop
文件中的 import
语句,使属性替换项能被系统识别出来并反映在最终 OTA 元数据中。