前言
V-AB 升级方案其实早在 7.0 就已经引入了,只是并未强制启用,依旧兼容了之前 /cache 分区升级的方式。
所以一开始按照老思路来,解决完各种权限后最终发现 log 提示找不到 /cache 分区。后来查阅资料发现,
相较于 Android 10.0,Android 11.0 的 Recovery 分区与 cache 分区已删除。
AB 方案介绍
AB 方案就是双分区双系统,每个镜像都是双份,分别对应两个分区。
V-AB 方案介绍
V-AB 是指终端中的镜像并不都是对应两个物理分区,而是在 SUPER 内部划分两个逻辑分区,但是只有
一份实体镜像数据(A 有实体数据 B 为虚拟设备,或者 A 为虚拟设备 B 有实体数据)。在 V-AB 方案中将
A 分区命名为 A-SLOT,B 分区命名为 B-SLOT。在两个 SLOT 之间螺旋式切换升级,升级时终端设备运
行在一个 SLOT 上,后台对另一个空闲 SLOT 进行升级。升级时 A/B 槽的状态请参见表 1-1。V-AB 升级
方案的架构图请参见图 1-1。
操作 | A-SLOT | B-SLOT |
首次开机 | 运行当前系统 | 空闲 |
第一次升级 | 运行当前系统 | 对 B 进行升级 |
升级重启后 | 空闲 | 运行当前系统 |
第二次升级 | 对 A 进行升级 | 运行当前系统 |
升级重启后 | 运行当前系统 | 空闲 |
表1-1 升级时 A/B 槽的状态
图1-1 V-AB 升级方案架构图
SUPER 虚框内的 System_b、System_ext_b、Vendor_b、Product_b,手机开机时在 SUPER 分区内是没有镜
像数据的,只划分出逻辑设备 B-SLOT。当升级 B-SLOT 完成时 B-SLOT 才有数据,而 A-SLOT 的数据被
删除,只保留 A-SLOT 逻辑设备节点,在 SUPER 内部只有一份镜像文件。
V-AB 方案升级流程
图1-2 V-AB 升级流程
V-AB 方案升级步骤如下:
步骤 1 触发升级动作后,检查用户空间是否能够满足升级需求。
− 如果满足,下载升级包 update.zip。
− 如果不满足,终止升级。
步骤 2 升级程序 updata_engine 对升级包 update.zip 进行校验。
− 如果校验通过,继续执行升级流程。
− 如果校验不通过,终止升级。
步骤 3 升级程序 updata_engine 将准备升级的 SLOT 标记为 unsuccessful 状态。
步骤 4 对升级镜像 payload.bin 进行校验。
− 如果校验通过,继续升级。
− 如果校验不通过,终止升级。
步骤 5 升级程序对准备升级的 SLOT 进行升级,对 SUPER 中的两个逻辑分区进行 snapshot 动作。
步骤 6 升级程序对升级完成分区中的数据进行校验,校验完成后提示用户重启。
步骤 7 重启后升级程序对 SUPER 中的逻辑分区 B-SLOT 进行 merge 动作。merge 完成后删除 delta 数
据,启动新的系统程序。
----结束
V-AB 实现关键要点
分区配置与命名
除了 SUPER 分区外其他分区都配置为双份,并且分区命名后缀必须为_a、_b 字符。相较于 Android
10.0,Android 11.0 的 Recovery 分区与 cache 分区已删除。
SUPER 为单一物理分区,在 SUPER 分区内部有两个逻辑分区。
在实现 SUPER 分区时需要配置单物理分区,内部划分双逻辑分区,且只有一个逻辑分区有镜像数
据。SUPER 分区的大小配置为“单份 image+4M metadata”数据的大小。在升级过程中 SUPER 分区
是在重启之后才执行的 merge 动作,也就是重启之后才对 SUPER 分区进行升级。如果 SUPER 分区
升级失败也能够实现系统回滚,回滚保护机制能切换为之前的系统。
实现 bootcontrol hal,为支持 V-AB 方案扩展了 bootcontrol1.1 hal。
作为 V-AB 升级过程中的 HAL 层 bootcontrol,在升级过程中起到承上启下的作用。升级时通过
bootcontrol 接口将升级状态数据写入 misc。开机启动时 bootloader 通过读取 misc 的数据,来控制系
统启动 A-SLOT 或 B-SLOT 的逻辑分区。 在 Android 11.0 项目上,为支持 V-AB 方案,扩展了 boot control1.1 接口。
升级 SUPER 分区时需要记录升级 SUPER 分区的升级状态的接口。
打包指令
指令上没啥变化,和之前 Q 版本一致
整包 make -j16 otapackage 差异包 ./build/tools/releasetools/ota_from_target_files -v -i v1.zip --block -p out/host/linux-x86 -k build/target/product/security/testkey v2.zip update.zip
修改清单
device/mediatek/system/common/device.mk device/mediatek/sepolicy/basic/non_plat/update_engine.te system/sepolicy/prebuilts/api/30.0/private/domain.te system/sepolicy/private/domain.te
user 版本默认是不编译 update_engine_client 的,为了使用指令快速验证 OTA,我们将次模块编译打开。
alps\device\mediatek\system\common\device.mk
PRODUCT_PACKAGES += \ update_engine \ update_engine_client \ update_engine_sideload \ update_verifier PRODUCT_HOST_PACKAGES += \ delta_generator \ shflags \ brillo_update_payload \ bsdiff \ simg2img PRODUCT_PACKAGES_DEBUG += \ update_engine_client \ bootctl
编译成功后指令文件位于 ./out/target/product/xxx/system/bin/update_engine_client
烧写后 adb shell 执行 update_engine_client --help 可查看具体参数定义
执行升级指令如下
update_engine_client --payload=file:///sdcard/payload.bin --update --headers=" FILE_HASH=EL4p2lSCrEoyjczfBEi7J6mVZLZvP4PBgwyxn5t1/WI= FILE_SIZE=657924722 METADATA_HASH=dLph3Mh2Rh2qEU3qdh25vJg3Q+LbXMT1kkVCm17mQeQ= METADATA_SIZE=50204"
将 OTA 编译后得到的 full_xxxxx-ota-mp1V8241.zip 拷贝并解压就得到指令中对应的 payload.bin 文件
和所需要的文件大小、hash等信息值 payload_properties.txt
–payload 对应要升级的 bin 文件,我这里放置到 sdcard 跟目录了,所以是 /sdcard/payload.bin
–headers 对应 payload_properties.txt 中信息,注意复制中换行
执行升级对应的 log 如下
2021-06-20 13:36:39.625 718-718/? I/update_engine: [INFO:main.cc(54)] A/B Update Engine starting 2021-06-20 13:36:39.815 718-718/? I/update_engine: [INFO:boot_control_android.cc(70)] Loaded boot control hidl hal. 2021-06-20 13:36:39.863 718-718/? I/update_engine: [INFO:daemon_state_android.cc(43)] Booted in dev mode. 2021-06-20 13:36:40.016 718-718/? I/update_engine: [INFO:daemon_state_android.cc(44)] Booted non-official build. 2021-06-20 13:36:40.088 718-718/? I/update_engine: [INFO:update_attempter_android.cc(1010)] Scheduling CleanupPreviousUpdateAction. 2021-06-20 13:36:40.162 718-718/? I/update_engine: [INFO:action_processor.cc(51)] ActionProcessor: starting CleanupPreviousUpdateAction 2021-06-20 13:36:40.201 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(82)] Starting/resuming CleanupPreviousUpdateAction 2021-06-20 13:36:58.232 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(137)] Boot completed, waiting on markBootSuccessful() 2021-06-20 13:36:58.246 718-718/? I/update_engine: EnsureMetadataMounted does nothing in Android mode. 2021-06-20 13:36:58.288 718-718/? I/update_engine: Read merge statistics file failed: No such file or directory 2021-06-20 13:36:58.335 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(206)] Waiting for any previous merge request to complete. This can take up to several minutes. 2021-06-20 13:36:58.392 718-718/? E/update_engine: [ERROR:cleanup_previous_update_action.cc(240)] Previous update has not been completed, not cleaning up 2021-06-20 13:36:58.413 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(397)] Not reporting merge stats because state is Initiated 2021-06-20 13:36:58.444 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished last action CleanupPreviousUpdateAction with code ErrorCode::kSuccess 2021-06-20 13:36:58.475 718-718/? I/update_engine: [INFO:update_attempter_android.cc(522)] Processing Done. 2021-06-20 13:36:58.486 718-718/? I/update_engine: [INFO:update_attempter_android.cc(662)] Terminating cleanup previous update. 2021-06-20 13:37:33.922 718-718/? I/update_engine: [INFO:prefs.cc(122)] update-state-next-operation not present in /data/misc/update_engine/prefs 2021-06-20 13:37:33.935 718-718/? I/update_engine: [INFO:update_attempter_android.cc(280)] Using this install plan: 2021-06-20 13:37:33.948 718-718/? I/update_engine: [INFO:install_plan.cc(91)] InstallPlan: new_update, version: , source_slot: A, target_slot: B, url: file:///sdcard/payload.bin, payload: (size: 657924722, metadata_size: 50204, metadata signature: , hash: 10BE29DA5482AC4A328DCCDF0448BB27A99564B66F3F83C1830CB19F9B75FD62, payload type: unknown), hash_checks_mandatory: false, powerwash_required: false, switch_slot_on_reboot: true, run_post_install: true, is_rollback: false, write_verity: true 2021-06-20 13:37:33.960 718-718/? I/update_engine: [INFO:metrics_utils.cc(363)] Number of Reboots during current update attempt = 0 2021-06-20 13:37:33.972 718-718/? I/update_engine: [INFO:metrics_utils.cc(371)] Payload Attempt Number = 1 2021-06-20 13:37:33.984 718-718/? I/update_engine: [INFO:metrics_utils.cc(388)] Update Monotonic Timestamp Start = 1/1/1970 0:01:05 GMT 2021-06-20 13:37:33.994 718-718/? I/update_engine: [INFO:metrics_utils.cc(397)] Update Boot Timestamp Start = 1/1/1970 0:01:05 GMT 2021-06-20 13:37:34.001 718-718/? I/update_engine: [INFO:update_attempter_android.cc(648)] Scheduling an action processor start. 2021-06-20 13:37:34.009 718-718/? I/update_engine: [INFO:action_processor.cc(51)] ActionProcessor: starting UpdateBootFlagsAction 2021-06-20 13:37:34.017 718-718/? I/update_engine: [INFO:update_boot_flags_action.cc(45)] Marking booted slot as good. 2021-06-20 13:37:34.035 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished UpdateBootFlagsAction with code ErrorCode::kSuccess 2021-06-20 13:37:34.043 718-718/? I/update_engine: [INFO:action_processor.cc(143)] ActionProcessor: starting CleanupPreviousUpdateAction 2021-06-20 13:37:34.051 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(82)] Starting/resuming CleanupPreviousUpdateAction 2021-06-20 13:37:34.057 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(137)] Boot completed, waiting on markBootSuccessful() 2021-06-20 13:37:34.065 718-718/? I/update_engine: EnsureMetadataMounted does nothing in Android mode. 2021-06-20 13:37:34.072 718-718/? I/update_engine: Read merge statistics file failed: No such file or directory 2021-06-20 13:37:34.079 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(206)] Waiting for any previous merge request to complete. This can take up to several minutes. 2021-06-20 13:37:34.086 718-718/? E/update_engine: [ERROR:cleanup_previous_update_action.cc(240)] Previous update has not been completed, not cleaning up 2021-06-20 13:37:34.093 718-718/? I/update_engine: [INFO:cleanup_previous_update_action.cc(397)] Not reporting merge stats because state is Initiated 2021-06-20 13:37:34.100 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished CleanupPreviousUpdateAction with code ErrorCode::kSuccess 2021-06-20 13:37:34.106 718-718/? I/update_engine: [INFO:action_processor.cc(143)] ActionProcessor: starting InstallPlanAction 2021-06-20 13:37:34.112 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished InstallPlanAction with code ErrorCode::kSuccess 2021-06-20 13:37:34.118 718-718/? I/update_engine: [INFO:action_processor.cc(143)] ActionProcessor: starting DownloadAction 2021-06-20 13:37:34.124 718-718/? I/update_engine: [INFO:install_plan.cc(91)] InstallPlan: new_update, version: , source_slot: A, target_slot: B, url: file:///sdcard/payload.bin, payload: (size: 657924722, metadata_size: 50204, metadata signature: , hash: 10BE29DA5482AC4A328DCCDF0448BB27A99564B66F3F83C1830CB19F9B75FD62, payload type: unknown), hash_checks_mandatory: false, powerwash_required: false, switch_slot_on_reboot: true, run_post_install: true, is_rollback: false, write_verity: true 2021-06-20 13:37:34.130 718-718/? I/update_engine: [INFO:download_action.cc(199)] Marking new slot as unbootable 2021-06-20 13:37:34.138 718-718/? I/update_engine: [INFO:multi_range_http_fetcher.cc(45)] starting first transfer 2021-06-20 13:37:34.146 718-718/? I/update_engine: [INFO:multi_range_http_fetcher.cc(74)] starting transfer of range 0+657924722 2021-06-20 13:37:34.148 718-718/? I/update_engine: type=1400 audit(0.0:139): avc: denied { dac_read_search } for capability=2 scontext=u:r:update_engine:s0 tcontext=u:r:update_engine:s0 tclass=capability permissive=1 2021-06-20 13:37:34.161 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 0/? operations, 16384/657924722 bytes downloaded (0%), overall progress 0% 2021-06-20 13:37:34.152 718-718/? I/update_engine: type=1400 audit(0.0:141): avc: denied { read } for name="primary" dev="tmpfs" ino=27616 scontext=u:r:update_engine:s0 tcontext=u:object_r:mnt_user_file:s0 tclass=lnk_file permissive=1 2021-06-20 13:37:34.174 718-718/? I/update_engine: [INFO:delta_performer.cc(520)] Manifest size in payload matches expected value from Omaha 2021-06-20 13:37:34.182 718-718/? I/update_engine: [INFO:delta_performer.cc(1693)] Verifying using certificates: /system/etc/security/otacerts.zip 2021-06-20 13:37:34.191 718-718/? I/update_engine: [INFO:payload_verifier.cc(102)] signature blob size = 267 2021-06-20 13:37:34.198 718-718/? I/update_engine: [INFO:payload_verifier.cc(118)] Truncating the signature to its unpadded size: 256. 2021-06-20 13:37:34.204 718-718/? I/update_engine: [INFO:payload_verifier.cc(129)] Verified correct signature 1 out of 1 signatures. 2021-06-20 13:37:34.210 718-718/? I/update_engine: [INFO:payload_metadata.cc(224)] Metadata hash signature matches value in Omaha response. 2021-06-20 13:37:34.220 718-718/? I/update_engine: [INFO:delta_performer.cc(1728)] Detected a 'full' payload. 2021-06-20 13:37:34.231 718-718/? I/update_engine: [INFO:prefs.cc(122)] dynamic-partition-metadata-updated not present in /data/misc/update_engine/prefs 2021-06-20 13:37:34.237 718-718/? I/update_engine: [INFO:delta_performer.cc(985)] Preparing partitions for new update. last hash = , new hash = EL4p2lSCrEoyjczfBEi7J6mVZLZvP4PBgwyxn5t1/WI=dLph3Mh2Rh2qEU3qdh25vJg3Q+LbXMT1kkVCm17mQeQ= 2021-06-20 13:37:34.306 718-718/? I/update_engine: EnsureMetadataMounted does nothing in Android mode. 2021-06-20 13:37:34.313 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(676)] Erasing AVB footer of system_other partition before update. 2021-06-20 13:37:34.320 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(577)] AVB is not enabled on system_other. Skip erasing. 2021-06-20 13:37:34.326 718-718/? I/update_engine: Update has been initiated, now canceling 2021-06-20 13:37:34.332 718-718/? I/update_engine: Removing all update state. 2021-06-20 13:37:34.338 718-718/? W/update_engine: Cannot read /metadata/ota/snapshot-boot: No such file or directory 2021-06-20 13:37:34.346 718-718/? W/update_engine: Failed to get flashing status 2021-06-20 13:37:34.353 718-718/? W/update_engine: Cannot read /metadata/ota/snapshot-boot: No such file or directory 2021-06-20 13:37:35.367 718-718/? I/update_engine: Successfully unmapped snapshot vendor_b 2021-06-20 13:37:35.375 718-718/? I/update_engine: Successfully unmapped snapshot product_b 2021-06-20 13:37:35.410 718-718/? I/update_engine: Successfully unmapped snapshot system_b 2021-06-20 13:37:35.500 718-718/? I/update_engine: Remaining free space for COW: 2580234240 bytes 2021-06-20 13:37:35.519 718-718/? I/update_engine: For partition product_b, device size = 245547008, snapshot size = 245547008, cow partition size = 246513664, cow file size = 0 2021-06-20 13:37:35.528 718-718/? I/update_engine: [liblp]Partition product_b-cow will resize from 0 bytes to 246513664 bytes 2021-06-20 13:37:35.534 718-718/? I/update_engine: Successfully created snapshot partition for product_b 2021-06-20 13:37:35.540 718-718/? I/update_engine: Remaining free space for COW: 2333720576 bytes 2021-06-20 13:37:35.563 718-718/? I/update_engine: For partition vendor_b, device size = 278073344, snapshot size = 278073344, cow partition size = 279166976, cow file size = 0 2021-06-20 13:37:35.572 718-718/? I/update_engine: [liblp]Partition vendor_b-cow will resize from 0 bytes to 279166976 bytes 2021-06-20 13:37:35.578 718-718/? I/update_engine: Successfully created snapshot partition for vendor_b 2021-06-20 13:37:35.584 718-718/? I/update_engine: Remaining free space for COW: 2054553600 bytes 2021-06-20 13:37:35.648 718-718/? I/update_engine: For partition system_b, device size = 1190064128, snapshot size = 1190064128, cow partition size = 1194717184, cow file size = 0 2021-06-20 13:37:35.657 718-718/? I/update_engine: [liblp]Partition system_b-cow will resize from 0 bytes to 1194717184 bytes 2021-06-20 13:37:35.662 718-718/? I/update_engine: Successfully created snapshot partition for system_b 2021-06-20 13:37:35.667 718-718/? I/update_engine: Allocating CoW images. 2021-06-20 13:37:35.672 718-718/? I/update_engine: Successfully created snapshot for product_b 2021-06-20 13:37:35.677 718-718/? I/update_engine: Successfully created snapshot for system_b 2021-06-20 13:37:35.683 718-718/? I/update_engine: Successfully created snapshot for vendor_b 2021-06-20 13:37:35.689 718-718/? I/update_engine: Successfully unmapped snapshot product_b 2021-06-20 13:37:35.744 718-718/? I/update_engine: Mapped COW device for product_b at /dev/block/dm-3 2021-06-20 13:37:35.753 718-718/? I/update_engine: Zero-filling COW device: /dev/block/dm-3 2021-06-20 13:37:35.782 718-718/? I/update_engine: Successfully unmapped snapshot vendor_b 2021-06-20 13:37:35.813 718-718/? I/update_engine: Mapped COW device for vendor_b at /dev/block/dm-3 2021-06-20 13:37:35.820 718-718/? I/update_engine: Zero-filling COW device: /dev/block/dm-3 2021-06-20 13:37:35.858 718-718/? I/update_engine: Successfully unmapped snapshot system_b 2021-06-20 13:37:35.891 718-718/? I/update_engine: Mapped COW device for system_b at /dev/block/dm-3 2021-06-20 13:37:35.899 718-718/? I/update_engine: Zero-filling COW device: /dev/block/dm-3 2021-06-20 13:37:35.925 718-718/? I/update_engine: [liblp]Updated logical partition table at slot 1 on device super 2021-06-20 13:37:35.932 718-718/? I/update_engine: Successfully created all snapshots for target slot _b 2021-06-20 13:37:35.938 718-718/? I/update_engine: [INFO:delta_performer.cc(1002)] PreparePartitionsForUpdate done. 2021-06-20 13:37:35.952 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:35.959 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] boot_b is not in super partition metadata. 2021-06-20 13:37:35.966 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:35.974 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:35.982 718-718/? I/update_engine: Successfully unmapped snapshot system_b 2021-06-20 13:37:36.014 718-718/? I/update_engine: [libfs_mgr]Created logical partition system_b-base on device /dev/block/dm-3 2021-06-20 13:37:36.046 718-718/? I/update_engine: Mapped COW device for system_b at /dev/block/dm-7 2021-06-20 13:37:36.085 718-718/? I/update_engine: Mapped system_b as snapshot device at /dev/block/dm-9 2021-06-20 13:37:36.094 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(173)] Succesfully mapped system_b to device mapper (force_writable = 1); device path at /dev/block/dm-9 2021-06-20 13:37:36.105 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.115 718-718/? I/update_engine: Successfully unmapped snapshot vendor_b 2021-06-20 13:37:36.147 718-718/? I/update_engine: [libfs_mgr]Created logical partition vendor_b-base on device /dev/block/dm-10 2021-06-20 13:37:36.180 718-718/? I/update_engine: Mapped COW device for vendor_b at /dev/block/dm-11 2021-06-20 13:37:36.219 718-718/? I/update_engine: Mapped vendor_b as snapshot device at /dev/block/dm-12 2021-06-20 13:37:36.227 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(173)] Succesfully mapped vendor_b to device mapper (force_writable = 1); device path at /dev/block/dm-12 2021-06-20 13:37:36.240 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.247 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] preloader_b is not in super partition metadata. 2021-06-20 13:37:36.254 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.262 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.269 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] md1img_b is not in super partition metadata. 2021-06-20 13:37:36.276 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.287 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.295 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] spmfw_b is not in super partition metadata. 2021-06-20 13:37:36.302 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.310 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.317 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] scp_b is not in super partition metadata. 2021-06-20 13:37:36.325 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.335 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.341 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] sspm_b is not in super partition metadata. 2021-06-20 13:37:36.348 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.357 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.364 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] gz_b is not in super partition metadata. 2021-06-20 13:37:36.371 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.379 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.385 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] lk_b is not in super partition metadata. 2021-06-20 13:37:36.392 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.401 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.408 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] dtbo_b is not in super partition metadata. 2021-06-20 13:37:36.414 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.426 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.434 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] tee_b is not in super partition metadata. 2021-06-20 13:37:36.440 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.448 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.454 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] vbmeta_b is not in super partition metadata. 2021-06-20 13:37:36.461 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.471 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.477 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] vbmeta_system_b is not in super partition metadata. 2021-06-20 13:37:36.484 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.492 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.499 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(948)] vbmeta_vendor_b is not in super partition metadata. 2021-06-20 13:37:36.505 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot A in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.513 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(319)] Loaded metadata from slot B in /dev/block/platform/bootdevice/by-name/super 2021-06-20 13:37:36.521 718-718/? I/update_engine: Successfully unmapped snapshot product_b 2021-06-20 13:37:36.552 718-718/? I/update_engine: [libfs_mgr]Created logical partition product_b-base on device /dev/block/dm-13 2021-06-20 13:37:36.586 718-718/? I/update_engine: Mapped COW device for product_b at /dev/block/dm-14 2021-06-20 13:37:36.626 718-718/? I/update_engine: Mapped product_b as snapshot device at /dev/block/dm-15 2021-06-20 13:37:36.638 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(173)] Succesfully mapped product_b to device mapper (force_writable = 1); device path at /dev/block/dm-15 2021-06-20 13:37:36.645 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new boot sha256: qOu0clVzMeWRGb5qmAg4KQx8lPZsRExxef5V/tlZRfg= size: 33554432 2021-06-20 13:37:36.651 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new system sha256: gkmjI/zQsuc4lijSzqPrJp6Ee+KOosLK7Xo7p0rlnBM= size: 1190064128 2021-06-20 13:37:36.657 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new vendor sha256: 1U/3goHzk9O4KitXEJOz8q1XfOFiKOMQ8tyKfAAYS44= size: 278073344 2021-06-20 13:37:36.662 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new preloader sha256: yutVrm+dfG8qSIlcSO5EQZi7/c2Nzs5NOYJsl6YObus= size: 237568 2021-06-20 13:37:36.669 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new md1img sha256: MHyfXRKbKYXXQv02cHDIbxYDq24HkmPDgR03Y9ZjdYM= size: 55320576 2021-06-20 13:37:36.674 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new spmfw sha256: CR6ZAuQzDvxgq9QXZD7q0Xhmd0VaoKUb4VgSfLL8SRc= size: 65536 2021-06-20 13:37:36.680 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new scp sha256: SFdoWNx3hD3Ust3nUAPQqfs18T9FYNcU/MnK/hI2yz4= size: 557056 2021-06-20 13:37:36.686 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new sspm sha256: cAV+KVAckounV6Ul4DVvS7O/Q3hksJ3+4tIVEYX+o0g= size: 438272 2021-06-20 13:37:36.693 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new gz sha256: OGcy94/b1I9qywvDFLiz75u1cebZFJVqIx5I8r95tUU= size: 2600960 2021-06-20 13:37:36.699 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new lk sha256: aOdoDRvTh6/bDsuaFtPMD3LGZG2XIQ1CHwX1ETr6cdY= size: 888832 2021-06-20 13:37:36.707 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new dtbo sha256: r+TMK8PXRzAa5Sn2cFz7ituqMmosdIG2xatYy2EaJ6s= size: 45056 2021-06-20 13:37:36.712 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new tee sha256: q3Xylq4v484FPdg3sJxKj7Ca6Ak/RUNSbTLI3ILz3mo= size: 139264 2021-06-20 13:37:36.718 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new vbmeta sha256: bTaeRfXuBryz52zd+W+O8HE2/SwufmdG8XfzsKeXX6k= size: 4096 2021-06-20 13:37:36.724 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new vbmeta_system sha256: z1ReCaQPeQUZ5GJQGJkI43rSuESH7q0ZCyxZPsNU4ug= size: 4096 2021-06-20 13:37:36.730 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new vbmeta_vendor sha256: pXHgSp3WYt+9QMN62wV/gjwbBNzj+UfFmMp/HyJTOOg= size: 4096 2021-06-20 13:37:36.736 718-718/? I/update_engine: [INFO:delta_performer.cc(451)] PartitionInfo new product sha256: h4gFK/IXRhBR1S2tedtSSsKsWpsiuUszJICluLu2aGE= size: 245547008 2021-06-20 13:37:36.742 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/boot_b partition without O_DSYNC 2021-06-20 13:37:36.751 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:37:36.759 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 16 operations to partition "boot" 2021-06-20 13:37:36.769 718-718/? I/update_engine: [INFO:delta_performer.cc(657)] Starting to apply update payload operations 2021-06-20 13:37:38.321 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/dm-9 partition without O_DSYNC 2021-06-20 13:37:38.332 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:37:38.338 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 568 operations to partition "system" 2021-06-20 13:37:47.700 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 88/874 operations (10%), 66535424/657924722 bytes downloaded (10%), overall progress 10% 2021-06-20 13:37:59.109 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 186/874 operations (21%), 131596288/657924722 bytes downloaded (20%), overall progress 20% 2021-06-20 13:38:12.117 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 263/874 operations (30%), 203948032/657924722 bytes downloaded (30%), overall progress 30% 2021-06-20 13:38:23.775 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 350/874 operations (40%), 264536064/657924722 bytes downloaded (40%), overall progress 40% 2021-06-20 13:38:36.430 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 455/874 operations (52%), 327745536/657924722 bytes downloaded (49%), overall progress 50% 2021-06-20 13:38:47.123 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 542/874 operations (62%), 388988928/657924722 bytes downloaded (59%), overall progress 60% 2021-06-20 13:38:54.513 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/dm-12 partition without O_DSYNC 2021-06-20 13:38:54.521 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:38:54.526 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 133 operations to partition "vendor" 2021-06-20 13:39:01.187 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 629/874 operations (71%), 460554240/657924722 bytes downloaded (70%), overall progress 70% 2021-06-20 13:39:10.996 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 717/874 operations (82%), 517799936/657924722 bytes downloaded (78%), overall progress 80% 2021-06-20 13:39:11.238 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/preloader_b partition without O_DSYNC 2021-06-20 13:39:11.248 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:11.254 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "preloader" 2021-06-20 13:39:11.291 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/md1img_b partition without O_DSYNC 2021-06-20 13:39:11.303 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:11.309 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 27 operations to partition "md1img" 2021-06-20 13:39:15.106 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/spmfw_b partition without O_DSYNC 2021-06-20 13:39:15.116 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.123 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "spmfw" 2021-06-20 13:39:15.146 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/scp_b partition without O_DSYNC 2021-06-20 13:39:15.156 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.164 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "scp" 2021-06-20 13:39:15.219 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/sspm_b partition without O_DSYNC 2021-06-20 13:39:15.227 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.234 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "sspm" 2021-06-20 13:39:15.290 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/gz_b partition without O_DSYNC 2021-06-20 13:39:15.301 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.308 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 2 operations to partition "gz" 2021-06-20 13:39:15.421 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/lk_b partition without O_DSYNC 2021-06-20 13:39:15.432 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.437 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "lk" 2021-06-20 13:39:15.524 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/dtbo_b partition without O_DSYNC 2021-06-20 13:39:15.535 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.542 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "dtbo" 2021-06-20 13:39:15.554 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/tee_b partition without O_DSYNC 2021-06-20 13:39:15.564 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.569 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "tee" 2021-06-20 13:39:15.596 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/vbmeta_b partition without O_DSYNC 2021-06-20 13:39:15.606 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.613 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "vbmeta" 2021-06-20 13:39:15.622 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/vbmeta_system_b partition without O_DSYNC 2021-06-20 13:39:15.634 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.641 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "vbmeta_system" 2021-06-20 13:39:15.651 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/platform/bootdevice/by-name/vbmeta_vendor_b partition without O_DSYNC 2021-06-20 13:39:15.659 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.665 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 1 operations to partition "vbmeta_vendor" 2021-06-20 13:39:15.675 718-718/? I/update_engine: [INFO:delta_performer.cc(385)] Opening /dev/block/dm-15 partition without O_DSYNC 2021-06-20 13:39:15.685 718-718/? I/update_engine: [INFO:delta_performer.cc(128)] Caching writes. 2021-06-20 13:39:15.691 718-718/? I/update_engine: [INFO:delta_performer.cc(397)] Applying 118 operations to partition "product" 2021-06-20 13:39:23.741 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 795/874 operations (90%), 592134144/657924722 bytes downloaded (90%), overall progress 90% 2021-06-20 13:39:35.736 718-718/? I/update_engine: [INFO:delta_performer.cc(209)] Completed 874/874 operations (100%), 657924722/657924722 bytes downloaded (100%), overall progress 100% 2021-06-20 13:39:35.743 718-718/? I/update_engine: [INFO:delta_performer.cc(1665)] Extracted signature data of size 267 at 657873984 2021-06-20 13:39:35.749 718-718/? I/update_engine: [INFO:multi_range_http_fetcher.cc(115)] Terminating transfer. 2021-06-20 13:39:35.756 718-718/? I/update_engine: [INFO:multi_range_http_fetcher.cc(177)] Received transfer terminated. 2021-06-20 13:39:35.762 718-718/? I/update_engine: [INFO:multi_range_http_fetcher.cc(129)] TransferEnded w/ code 200 2021-06-20 13:39:35.768 718-718/? I/update_engine: [INFO:multi_range_http_fetcher.cc(163)] Done w/ all transfers 2021-06-20 13:39:36.100 718-718/? I/update_engine: [INFO:delta_performer.cc(1693)] Verifying using certificates: /system/etc/security/otacerts.zip 2021-06-20 13:39:36.109 718-718/? I/update_engine: [INFO:payload_verifier.cc(102)] signature blob size = 267 2021-06-20 13:39:36.115 718-718/? I/update_engine: [INFO:payload_verifier.cc(118)] Truncating the signature to its unpadded size: 256. 2021-06-20 13:39:36.121 718-718/? I/update_engine: [INFO:payload_verifier.cc(129)] Verified correct signature 1 out of 1 signatures. 2021-06-20 13:39:36.126 718-718/? I/update_engine: [INFO:delta_performer.cc(1915)] Payload hash matches value in payload. 2021-06-20 13:39:36.132 718-718/? I/update_engine: [INFO:download_action.cc(400)] Collections of histograms for UpdateEngine.DownloadAction. Histogram: UpdateEngine.DownloadAction.InstallOperation::REPLACE.Duration recorded 874 samples, mean = 114.1 0 -O (8 = 0.9%) 10 -----O (31 = 3.5%) {0.9%} 18 ---O (16 = 1.8%) {4.5%} 32 ------O (33 = 3.8%) {6.3%} 57 ----------------------------------------------O (273 = 31.2%) {10.1%} 101 ------------------------------------------------------------------------O (426 = 48.7%) {41.3%} 179 -------------O (77 = 8.8%) {90.0%} 317 -O (8 = 0.9%) {98.9%} 561 O (2 = 0.2%) {99.8%} 993 ... 2021-06-20 13:39:36.142 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished DownloadAction with code ErrorCode::kSuccess 2021-06-20 13:39:36.150 718-718/? I/update_engine: [INFO:action_processor.cc(143)] ActionProcessor: starting FilesystemVerifierAction 2021-06-20 13:39:36.156 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 0 (boot) on device /dev/block/platform/bootdevice/by-name/boot_b 2021-06-20 13:39:36.306 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of boot: qOu0clVzMeWRGb5qmAg4KQx8lPZsRExxef5V/tlZRfg= 2021-06-20 13:39:36.322 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 1 (system) on device /dev/block/dm-9 2021-06-20 13:39:44.426 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of system: gkmjI/zQsuc4lijSzqPrJp6Ee+KOosLK7Xo7p0rlnBM= 2021-06-20 13:39:44.772 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 2 (vendor) on device /dev/block/dm-12 2021-06-20 13:39:46.671 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of vendor: 1U/3goHzk9O4KitXEJOz8q1XfOFiKOMQ8tyKfAAYS44= 2021-06-20 13:39:46.761 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 3 (preloader) on device /dev/block/platform/bootdevice/by-name/preloader_b 2021-06-20 13:39:46.771 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of preloader: yutVrm+dfG8qSIlcSO5EQZi7/c2Nzs5NOYJsl6YObus= 2021-06-20 13:39:46.777 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 4 (md1img) on device /dev/block/platform/bootdevice/by-name/md1img_b 2021-06-20 13:39:47.012 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of md1img: MHyfXRKbKYXXQv02cHDIbxYDq24HkmPDgR03Y9ZjdYM= 2021-06-20 13:39:47.036 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 5 (spmfw) on device /dev/block/platform/bootdevice/by-name/spmfw_b 2021-06-20 13:39:47.044 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of spmfw: CR6ZAuQzDvxgq9QXZD7q0Xhmd0VaoKUb4VgSfLL8SRc= 2021-06-20 13:39:47.050 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 6 (scp) on device /dev/block/platform/bootdevice/by-name/scp_b 2021-06-20 13:39:47.061 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of scp: SFdoWNx3hD3Ust3nUAPQqfs18T9FYNcU/MnK/hI2yz4= 2021-06-20 13:39:47.069 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 7 (sspm) on device /dev/block/platform/bootdevice/by-name/sspm_b 2021-06-20 13:39:47.081 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of sspm: cAV+KVAckounV6Ul4DVvS7O/Q3hksJ3+4tIVEYX+o0g= 2021-06-20 13:39:47.091 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 8 (gz) on device /dev/block/platform/bootdevice/by-name/gz_b 2021-06-20 13:39:47.115 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of gz: OGcy94/b1I9qywvDFLiz75u1cebZFJVqIx5I8r95tUU= 2021-06-20 13:39:47.127 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 9 (lk) on device /dev/block/platform/bootdevice/by-name/lk_b 2021-06-20 13:39:47.146 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of lk: aOdoDRvTh6/bDsuaFtPMD3LGZG2XIQ1CHwX1ETr6cdY= 2021-06-20 13:39:47.154 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 10 (dtbo) on device /dev/block/platform/bootdevice/by-name/dtbo_b 2021-06-20 13:39:47.167 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of dtbo: r+TMK8PXRzAa5Sn2cFz7ituqMmosdIG2xatYy2EaJ6s= 2021-06-20 13:39:47.175 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 11 (tee) on device /dev/block/platform/bootdevice/by-name/tee_b 2021-06-20 13:39:47.186 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of tee: q3Xylq4v484FPdg3sJxKj7Ca6Ak/RUNSbTLI3ILz3mo= 2021-06-20 13:39:47.195 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 12 (vbmeta) on device /dev/block/platform/bootdevice/by-name/vbmeta_b 2021-06-20 13:39:47.203 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of vbmeta: bTaeRfXuBryz52zd+W+O8HE2/SwufmdG8XfzsKeXX6k= 2021-06-20 13:39:47.210 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 13 (vbmeta_system) on device /dev/block/platform/bootdevice/by-name/vbmeta_system_b 2021-06-20 13:39:47.217 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of vbmeta_system: z1ReCaQPeQUZ5GJQGJkI43rSuESH7q0ZCyxZPsNU4ug= 2021-06-20 13:39:47.223 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 14 (vbmeta_vendor) on device /dev/block/platform/bootdevice/by-name/vbmeta_vendor_b 2021-06-20 13:39:47.231 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of vbmeta_vendor: pXHgSp3WYt+9QMN62wV/gjwbBNzj+UfFmMp/HyJTOOg= 2021-06-20 13:39:47.238 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(117)] Hashing partition 15 (product) on device /dev/block/dm-15 2021-06-20 13:39:48.922 718-718/? I/update_engine: [INFO:filesystem_verifier_action.cc(237)] Hash of product: h4gFK/IXRhBR1S2tedtSSsKsWpsiuUszJICluLu2aGE= 2021-06-20 13:39:49.003 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished FilesystemVerifierAction with code ErrorCode::kSuccess 2021-06-20 13:39:49.009 718-718/? I/update_engine: [INFO:action_processor.cc(143)] ActionProcessor: starting PostinstallRunnerAction 2021-06-20 13:39:49.027 718-718/? I/update_engine: [INFO:postinstall_runner_action.cc(174)] Performing postinst (system/bin/otapreopt_script at /postinstall/system/bin/otapreopt_script) installed on device /dev/block/dm-9 and mountable device /dev/block/dm-9 2021-06-20 13:39:49.042 718-718/? I/update_engine: [INFO:postinstall_runner_action.cc(181)] Format file for new system/bin/otapreopt_script is: data 2021-06-20 13:42:07.332 718-718/? I/update_engine: [INFO:subprocess.cc(157)] Subprocess output: Complete or error. 2021-06-20 13:42:07.351 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(873)] Snapshot writes are done. 2021-06-20 13:42:07.359 718-718/? I/update_engine: Wipe is not scheduled. Deleting forward merge indicator. 2021-06-20 13:42:07.383 718-718/? I/update_engine: [INFO:postinstall_runner_action.cc(371)] All post-install commands succeeded 2021-06-20 13:42:07.391 718-718/? I/update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished last action PostinstallRunnerAction with code ErrorCode::kSuccess 2021-06-20 13:42:07.401 718-718/? I/update_engine: [INFO:update_attempter_android.cc(522)] Processing Done. 2021-06-20 13:42:07.409 718-718/? I/update_engine: [INFO:update_attempter_android.cc(535)] Update successfully applied, waiting to reboot. 2021-06-20 13:42:07.419 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(263)] Destroying [product_b, system_b, vendor_b] from device mapper 2021-06-20 13:42:07.445 718-718/? I/update_engine: [libfs_mgr]Unmapped logical partition product_b 2021-06-20 13:42:07.489 718-718/? I/update_engine: Successfully unmapped snapshot product_b 2021-06-20 13:42:07.498 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(249)] Successfully unmapped product_b from device mapper. 2021-06-20 13:42:07.517 718-718/? I/update_engine: [libfs_mgr]Unmapped logical partition system_b 2021-06-20 13:42:07.573 718-718/? I/update_engine: Successfully unmapped snapshot system_b 2021-06-20 13:42:07.582 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(249)] Successfully unmapped system_b from device mapper. 2021-06-20 13:42:07.621 718-718/? I/update_engine: [libfs_mgr]Unmapped logical partition vendor_b 2021-06-20 13:42:07.665 718-718/? I/update_engine: Successfully unmapped snapshot vendor_b 2021-06-20 13:42:07.673 718-718/? I/update_engine: [INFO:dynamic_partition_control_android.cc(249)] Successfully unmapped vendor_b from device mapper. 2021-06-20 13:42:07.684 718-718/? I/update_engine: [INFO:metrics_reporter_android.cc(131)] Current update attempt downloads 627 bytes data 2021-06-20 13:42:07.698 718-718/? I/update_engine: [INFO:metrics_utils.cc(380)] Updated Marker = 1/1/1970 0:05:38 GMT
这里是将 selinux 修改为 permissive 验证的,可参考Android11.0® MTK6771 user版本关闭 SELinux
正经出货版本我们需要解决对应的 selinux 权限问题,以下是 update_engine 执行所缺少权限
update_engine: type=1400 audit(0.0:134): avc: denied { dac_read_search } for capability=2 scontext=u:r:update_engine:s0 tcontext=u:r:update_engine:s0 tclass=capability permissive=0 update_engine: type=1400 audit(0.0:135): avc: denied { dac_override } for capability=1 scontext=u:r:update_engine:s0 tcontext=u:r:update_engine:s0 tclass=capability permissive=0 update_engine: type=1400 audit(0.0:180): avc: denied { search } for name="/" dev="fuse" ino=720897 scontext=u:r:update_engine:s0 tcontext=u:object_r:fuse:s0 tclass=dir permissive=0 update_engine: type=1400 audit(0.0:109): avc: denied { search } for name="0" dev="tmpfs" ino=13411 scontext=u:r:update_engine:s0 tcontext=u:object_r:mnt_user_file:s0 tclass=dir permissive=0 update_engine: type=1400 audit(0.0:108): avc: denied { read } for name="primary" dev="tmpfs" ino=36806 scontext=u:r:update_engine:s0 tcontext=u:object_r:mnt_user_file:s0 tclass=lnk_file permissive=0 update_engine: type=1400 audit(0.0:108): avc: denied { read } for name="update.zip" dev="fuse" ino=557088 scontext=u:r:update_engine:s0 tcontext=u:object_r:fuse:s0 tclass=file permissive=0 update_engine: type=1400 audit(0.0:104): avc: denied { open } for path="/storage/emulated/0/update.zip" dev="fuse" ino=2760730 scontext=u:r:update_engine:s0 tcontext=u:object_r:fuse:s0 tclass=file permissive=0
加入如下 allow 权限
device\mediatek\sepolicy\basic\non_plat\update_engine.te
allow update_engine update_engine:capability { dac_read_search dac_override }; allow update_engine fuse:dir { search }; allow update_engine fuse:file { read open }; allow update_engine mnt_user_file:dir { search }; allow update_engine mnt_user_file:lnk_file { read };
编译时 capability 违背 neverallow 规则,出错解决参考 android 11添加property遇到的selinux问题
system\sepolicy\prebuilts\api\30.0\private\domain.te
system\sepolicy\private\domain.te
@@ -311,8 +311,10 @@ define(`dac_override_allowed', `{ vold vold_prepare_subdirs zygote + update_engine }') -neverallow ~dac_override_allowed self:global_capability_class_set dac_override; +neverallow ~{dac_override_allowed update_engine} self:global_capability_class_set dac_override; # Since the kernel checks dac_read_search before dac_override, domains that # have dac_override should also have dac_read_search to eliminate spurious # denials. Some domains have dac_read_search without having dac_override, so @@ -323,6 +325,7 @@ neverallow ~{ iorap_prefetcherd traced_perf traced_probes + update_engine userdebug_or_eng(`heapprofd') } self:global_capability_class_set dac_read_search;
接下来就是 android 层调用 UpdateEngine api 进行升级验证了
UpdateEngine 是系统 hide 类,想在 AS 中直接引用是不行的,这样就只能在源码环境下,通过 Android.mk 配置编译了。
但这样调试起来效率太低,而且 UI 设计太局限。我们的想法肯定是在 AS 中直接编译打包出 apk 扔到系统里打包就行。
这里采用最简单的方式 反射 进行尝试还真成功了。以下是核心升级代码。
frameworks 对应源码路径
frameworks/base/core/java/android/os/UpdateEngine.java
frameworks/base/core/java/android/os/UpdateEngineCallback.java
升级代码调用流程很简单
1、创建 UpdateEngineCallback 的对象 mUpdateEngineCallback
2、创建 UpdateEngine 的对象 mUpdateEngine, 创建后服务开启
3、使用mUpdateEngine.bind(mUpdateEngineCallback) 因为bind方法时接受的callback对象,而我们创建的类继承了callback,传入当前类的对象即可
4、调用 applyPayload(String url,long offset,long size,String[] headerKeyValuePairs) 方法具体执行升级
5、在重写的onStatusUpdate(int status, float percent)方法中根据拿到的状态执行进度逻辑
在重写的onPayloadApplicationComplete(int errorCode);方法中执行升级完成后的逻辑
因为反射指定 UpdateEngineCallback 回调,为了导包一致,在 AS 中新建包 android/os, 复制 UpdateEngineCallback.java
AS/app/src/main/java/android/os/ROTAUpdateManager.java
package android.os; import android.app.ProgressDialog; import android.content.Context; import android.os.Handler; import android.os.PowerManager; import android.util.Log; import android.view.WindowManager; import android.widget.Toast; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class ROTAUpdateManager { private String TAG = "ROTAUpdateManager"; //UpdateEngine mUpdateEngine; private final UpdateParser.ParsedUpdate parsedUpdate; private static final String updateFilePath = "/sdcard/update.zip"; private static final String REBOOT_REASON = "reboot-ab-update"; private Context mContext; private Handler mHandler; private PowerManager mPowerManager; public ROTAUpdateManager(Context context, Handler handler) throws IOException { //mUpdateEngine = new UpdateEngine(); this.mContext = context; this.mHandler = handler; mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); parsedUpdate = UpdateParser.parse(new File(updateFilePath)); } public void startUpdateSystem() throws Exception { //try { Class<?> aClass = Class.forName("android.os.UpdateEngine"); Class<?> callClass = Class.forName("android.osnouse.UpdateEngineCallback"); Constructor<?> constructor = aClass.getDeclaredConstructor(); constructor.setAccessible(true); Object mUpdateEngine = constructor.newInstance();//UpdateEngine mUpdateEngine = new UpdateEngine(); //mUpdateEngine.bind(mUpdateEngineCallback); Method bindMethod = aClass.getDeclaredMethod("bind", callClass, Handler.class); bindMethod.setAccessible(true);// 绑定callback bindMethod.invoke(mUpdateEngine, new UpdateEngineCallback() { @Override public void onStatusUpdate(int status, float percent) { Log.d(TAG, "onStatusUpdate status = " + status + "; percent = " + percent); handleStatusUpdate(status, percent); } @Override public void onPayloadApplicationComplete(int errorCode) { Log.e(TAG, "onPayloadApplicationComplete errorCode = " + errorCode); handlePayloadApplicationComplete(errorCode); } }, mHandler); //mUpdateEngine.applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) Method payloadMethod = aClass.getDeclaredMethod("applyPayload", String.class, long.class, long.class, String[].class);// 进行升级 payloadMethod.setAccessible(true); payloadMethod.invoke(mUpdateEngine, parsedUpdate.mUrl, parsedUpdate.mOffset, parsedUpdate.mSize, parsedUpdate.mProps); // }catch (Exception e) { // e.printStackTrace(); // } } private void showToast(String msg){ Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show(); } private void handleStatusUpdate(int status, float percent){ switch (status){ case UpdateStatusConstants.UPDATE_AVAILABLE: break; case UpdateStatusConstants.VERIFYING: showToast("update engine is verifying an update"); break; case UpdateStatusConstants.DOWNLOADING: int progress = Float.valueOf(percent * 100).intValue(); break; case UpdateStatusConstants.FINALIZING: int value = Float.valueOf(percent * 100).intValue(); break; case UpdateStatusConstants.UPDATED_NEED_REBOOT: mHandler.postDelayed(new Runnable() { @Override public void run() { mPowerManager.reboot(REBOOT_REASON); } },2000); break; } } private void handlePayloadApplicationComplete(int errorCode){ switch (errorCode){ case ErrorCodeConstants.SUCCESS: break; case ErrorCodeConstants.FILESYSTEM_COPIER_ERROR: showToast("filesystem copier error"); break; case ErrorCodeConstants.POST_INSTALL_RUNNER_ERROR: showToast("an error in running post-install hooks."); break; case ErrorCodeConstants.PAYLOAD_MISMATCHED_TYPE_ERROR: showToast("a mismatching payload"); break; case ErrorCodeConstants.INSTALL_DEVICE_OPEN_ERROR: showToast("an error in opening devices"); break; case ErrorCodeConstants.KERNEL_DEVICE_OPEN_ERROR: showToast("an error in opening kernel device"); break; case ErrorCodeConstants.DOWNLOAD_TRANSFER_ERROR: showToast("an error in fetching the payload"); break; case ErrorCodeConstants.PAYLOAD_HASH_MISMATCH_ERROR: showToast(" a mismatch in payload hash"); break; case ErrorCodeConstants.PAYLOAD_SIZE_MISMATCH_ERROR: showToast("a mismatch in payload size"); break; case ErrorCodeConstants.DOWNLOAD_PAYLOAD_VERIFICATION_ERROR: showToast("failing to verify payload signatures"); break; case ErrorCodeConstants.NOT_ENOUGH_SPACE: showToast("there is not enough space on the device to apply the update"); break; } } public static final class UpdateStatusConstants { /** * Update status code: update engine is in idle state. */ public static final int IDLE = 0; /** * Update status code: update engine is checking for update. */ public static final int CHECKING_FOR_UPDATE = 1; /** * Update status code: an update is available. */ public static final int UPDATE_AVAILABLE = 2; /** * Update status code: update engine is downloading an update. */ public static final int DOWNLOADING = 3; /** * Update status code: update engine is verifying an update. */ public static final int VERIFYING = 4; /** * Update status code: update engine is finalizing an update. */ public static final int FINALIZING = 5; /** * Update status code: an update has been applied and is pending for * reboot. */ public static final int UPDATED_NEED_REBOOT = 6; /** * Update status code: update engine is reporting an error event. */ public static final int REPORTING_ERROR_EVENT = 7; /** * Update status code: update engine is attempting to rollback an * update. */ public static final int ATTEMPTING_ROLLBACK = 8; /** * Update status code: update engine is in disabled state. */ public static final int DISABLED = 9; } public static final class ErrorCodeConstants { /** * Error code: a request finished successfully. */ public static final int SUCCESS = 0; /** * Error code: a request failed due to a generic error. */ public static final int ERROR = 1; /** * Error code: an update failed to apply due to filesystem copier * error. */ public static final int FILESYSTEM_COPIER_ERROR = 4; /** * Error code: an update failed to apply due to an error in running * post-install hooks. */ public static final int POST_INSTALL_RUNNER_ERROR = 5; /** * Error code: an update failed to apply due to a mismatching payload. */ public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6; /** * Error code: an update failed to apply due to an error in opening devices. */ public static final int INSTALL_DEVICE_OPEN_ERROR = 7; /** * Error code: an update failed to apply due to an error in opening kernel device. */ public static final int KERNEL_DEVICE_OPEN_ERROR = 8; /** * Error code: an update failed to apply due to an error in fetching the payload. */ public static final int DOWNLOAD_TRANSFER_ERROR = 9; /** * Error code: an update failed to apply due to a mismatch in payload hash. */ public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10; /** * Error code: an update failed to apply due to a mismatch in payload size. */ public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11; /** * Error code: an update failed to apply due to failing to verify payload signatures. */ public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12; /** * Error code: an update failed to apply due to a downgrade in payload timestamp. */ public static final int PAYLOAD_TIMESTAMP_ERROR = 51; /** * Error code: an update has been applied successfully but the new slot * hasn't been set to active. */ public static final int UPDATED_BUT_NOT_ACTIVE = 52; /** * Error code: there is not enough space on the device to apply the update. User should * be prompted to free up space and re-try the update. */ public static final int NOT_ENOUGH_SPACE = 60; /** * Error code: the device is corrupted and no further updates may be applied. */ public static final int DEVICE_CORRUPTED = 61; }
AS/app/src/main/java/android/os/UpdateEngineCallback.java
package android.os; public abstract class UpdateEngineCallback { public abstract void onStatusUpdate(int status, float percent); public abstract void onPayloadApplicationComplete(int errorCode); }
AS/app/src/main/java/android/os/UpdateParser.java
package android.os; import android.util.Log; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Enumeration; import java.util.Locale; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** Parse an A/B update zip file. */ public class UpdateParser { private static final String TAG = "ROTAUpdateManager"; private static final String PAYLOAD_BIN_FILE = "payload.bin"; private static final String PAYLOAD_PROPERTIES = "payload_properties.txt"; private static final String FILE_URL_PREFIX = "file://"; private static final int ZIP_FILE_HEADER = 30; private UpdateParser() { } /** * Parse a zip file containing a system update and return a non null ParsedUpdate. */ static ParsedUpdate parse(File file) throws IOException { long payloadOffset = 0; long payloadSize = 0; boolean payloadFound = false; String[] props = null; try (ZipFile zipFile = new ZipFile(file)) { Enumeration<? extends ZipEntry> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); long fileSize = entry.getCompressedSize(); if (!payloadFound) { payloadOffset += ZIP_FILE_HEADER + entry.getName().length(); if (entry.getExtra() != null) { payloadOffset += entry.getExtra().length; } } if (entry.isDirectory()) { continue; } else if (entry.getName().equals(PAYLOAD_BIN_FILE)) { payloadSize = fileSize; payloadFound = true; } else if (entry.getName().equals(PAYLOAD_PROPERTIES)) { try (BufferedReader buffer = new BufferedReader( new InputStreamReader(zipFile.getInputStream(entry)))) { props = buffer.lines().toArray(String[]::new); } } if (!payloadFound) { payloadOffset += fileSize; } //if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, String.format("Entry %s", entry.getName())); //} } } return new ParsedUpdate(file, payloadOffset, payloadSize, props); } /** Information parsed from an update file. */ static class ParsedUpdate { final String mUrl; final long mOffset; final long mSize; final String[] mProps; ParsedUpdate(File file, long offset, long size, String[] props) { mUrl = FILE_URL_PREFIX + file.getAbsolutePath(); mOffset = offset; mSize = size; mProps = props; } /** Verify the update information is correct. */ boolean isValid() { return mOffset >= 0 && mSize > 0 && mProps != null; } @Override public String toString() { return String.format(Locale.getDefault(), "ParsedUpdate: URL=%s, offset=%d, size=%s, props=%s", mUrl, mOffset, mSize, Arrays.toString(mProps)); } } }
执行一句代码搞定
new ROTAUpdateManager(this, mHandler).startUpdateSystem();
参考文章
Android9.0系统OTA升级update_engine
Android Update Engine分析(一)Makefile