Android11.0 V-A/B无缝OTA升级update_engine

简介: Android11.0 V-A/B无缝OTA升级update_engine

前言


V-AB 升级方案其实早在 7.0 就已经引入了,只是并未强制启用,依旧兼容了之前 /cache 分区升级的方式。


Android recovery更新简单流程及注意点


所以一开始按照老思路来,解决完各种权限后最终发现 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 槽的状态


gvkzpq.png


图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 方案升级流程


gvAIUJ.png


图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

目录
相关文章
|
7月前
|
Web App开发 移动开发 小程序
"项目中mpaas升级到10.2.3 适配Android 14之后 app中的H5以及小程序都访问不了,
"项目中mpaas升级到10.2.3 适配Android 14之后 app中的H5以及小程序都访问不了,显示“网络不给力,请稍后再试”,预发内网版本不能使用,线上版本可以正常使用,这个是什么原因啊,是某些参数没有配置吗,还是说是一些参数改错了?
118 2
|
7月前
|
算法 搜索推荐 Android开发
android的A/B到底是什么?OTA升级又是什么?
android的A/B到底是什么?OTA升级又是什么?
261 0
|
7月前
|
数据库 Android开发
Android 通过升级SettingsProvider数据强制覆盖用户的设置项
Android 通过升级SettingsProvider数据强制覆盖用户的设置项 【5月更文挑战第7天】
203 5
|
4月前
|
安全 Java Android开发
【Android P】OTA升级包定制,移除不需要更新的分区,重新打包签名
如何解压OTA升级包、编辑升级包内容(例如移除不需要更新的分区)、重新打包、签名以及验证OTA文件的过程。
366 2
【Android P】OTA升级包定制,移除不需要更新的分区,重新打包签名
|
4月前
|
编解码 Android开发 UED
【性能狂飙!】揭秘Android应用极速变身秘籍:内存瘦身+用户体验升级,打造丝滑流畅新境界!
【8月更文挑战第12天】构建高效Android应用需全方位优化,尤其重视内存管理和用户体验。通过弱引用降低内存占用,懒加载资源减少启动负担。运用Kotlin协程确保UI流畅不阻塞,响应式设计适配多屏需求。这些策略共同提升了应用性能与用户满意度。
58 1
|
5月前
|
Dart API 开发工具
Flutter Android 14 强制升级说明 2024
猫哥我也是心大,当群友问我 flutter 如何升级编译 Android 14 时才发现需要提交新版本。
121 0
Flutter Android 14 强制升级说明 2024
|
6月前
|
存储 Linux 开发工具
Linux手动升级替换Android Studio
【6月更文挑战第22天】
137 8
|
6月前
|
Android开发
如何 将Android Studio升级至最新版(4.0)
如何 将Android Studio升级至最新版(4.0)
1062 0
|
7月前
|
存储 缓存 Android开发
Android系统分区与升级
Android系统分区与升级
125 4