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

目录
相关文章
|
1月前
|
算法 搜索推荐 Android开发
android的A/B到底是什么?OTA升级又是什么?
android的A/B到底是什么?OTA升级又是什么?
112 0
|
1月前
|
存储 安全 文件存储
Android OTA升级后输入法异常和应用丢失的分析
Android OTA升级后输入法异常和应用丢失的分析
31 1
|
1月前
|
Java API Android开发
Android系统升级A/B分区OTA升级应用层调用UpdateEngine代码
Android系统升级A/B分区OTA升级应用层调用UpdateEngine代码
57 0
|
Android开发
android 标准OTA升级流程
标准的OTA升级流程包括一下几个步骤: 1.Android设备首先会与OTA服务器进行交互,如果有更新会推送给客户。推送的信息常常会包含OTA更新包的下载地址和一些版本信息。 2.Update程序会将更新包下载到cache分区下,并提醒用户安装更新。
2385 0
|
7天前
|
安全 Java Android开发
安卓开发中的新趋势:Kotlin与Jetpack的完美结合
【6月更文挑战第20天】在不断进化的移动应用开发领域,Android平台以其开放性和灵活性赢得了全球开发者的青睐。然而,随着技术的迭代,传统Java语言在Android开发中逐渐显露出局限性。Kotlin,一种现代的静态类型编程语言,以其简洁、安全和高效的特性成为了Android开发中的新宠。同时,Jetpack作为一套支持库、工具和指南,旨在帮助开发者更快地打造优秀的Android应用。本文将探讨Kotlin与Jetpack如何共同推动Android开发进入一个新的时代,以及这对开发者意味着什么。
|
2天前
|
Java 开发工具 Android开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
在移动应用开发的广阔天地中,Android和iOS两大平台各自占据着半壁江山。本文将深入探讨这两个平台在开发过程中的关键差异点,包括编程语言、开发工具、用户界面设计、性能优化以及市场覆盖等方面。通过对这些关键因素的比较分析,旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和目标受众做出明智的平台选择。
|
2天前
|
编解码 Android开发 iOS开发
深入探索Android与iOS开发的差异与挑战
【6月更文挑战第24天】在移动应用开发的广阔舞台上,Android和iOS两大操作系统扮演着主角。它们各自拥有独特的开发环境、工具集、用户基础及市场策略。本文将深度剖析这两个平台的开发差异,并探讨开发者面临的挑战,旨在为即将踏入或已在移动开发领域奋斗的开发者提供一份实用指南。
22 13
|
1天前
|
监控 Android开发 iOS开发
探索Android与iOS开发的差异:平台、工具和用户体验的比较
【6月更文挑战第25天】在移动应用开发的广阔天地中,Android和iOS两大平台各领风骚,它们在开发环境、工具选择及用户体验设计上展现出独特的风貌。本文将深入探讨这两个操作系统在技术实现、市场定位和用户交互方面的关键差异,旨在为开发者提供一个全景式的视图,帮助他们在面对项目决策时能够更加明智地选择适合自己项目需求的平台。
|
4天前
|
XML Java 开发工具
Android Studio开发Android TV
【6月更文挑战第19天】
|
1天前
|
缓存 测试技术 Shell
详细解读Android开发命令行完全攻略
详细解读Android开发命令行完全攻略