Android UpdateEngine模块流程(含序列图)-腾讯云开发者社区-腾讯云 (2024)

My Table
  • 1. 概述
  • 2. API接口调用
    • 2.1. APP调用UpdateEngine示例代码
  • 3. UpdateEngine.java流程
    • 3.1. 构造函数
    • 3.2. applyPayload
    • 3.3. bind
  • 4. Action机制
    • 4.1. ActionProcessor类
  • 5. 序列图:update engine交互接口和Action机制流程
  • 6. UpdateEngine模块流程
    • 6.1. InstallPlanAction
    • 6.2. DownloadAction
    • 6.3. FilesystemVerifierAction
    • 6.4. PostinstallRunnerAction
    • 6.5. 4个Action流程小结
  • 7. 序列图:InstallPlanAction和DownloadAction流程
  • 8. 序列图:FilesystemVerifierAction和PostinstallRunnerAction流程
  • 9. update_engine模块启动流程
    • 9.1. update_engine.rc启动
    • 9.2. main.cc入口函数
    • 9.3. UpdateEngineDaemon初始化
  • 10. 升级脚本
  • 11. 调试技巧
    • 11.1. update_engine升级包的hash值计算
    • 11.2. update_engine升级信息获取
    • 11.3. update_engine错误码errorcode
  • 12. 参考文档

Android A/B升级又称静默升级,它是一种在系统运行过程中进行的升级功能。为了减小系统运行负荷,整个升级过程会保持在一个较低的IO状态,所以升级时间比recovery升级明显要长。本文是基于Android 12 AOSP源码,对update engine模块的流程进行梳理,最主要的内容是绘制的几张序列图。

1. 概述

update_engine升级会依次执行四个主要的升级动作:InstallAction,DownloadAction,FilesystemVerfierAction,PostinstallRunnerAction。启动DownloadAction和PostinstallRunnerAction耗时最长。

DownloadAction是执行具体的升级拷贝动作,将镜像文件中的内容拷贝到缓冲区,然后写入到指定分区,这一步的时间不容易缩减。

PostinstallRunnerAction是根据post install script进行预编译工作,将target_slot标记为active。

源码:system/update_engine/

Android 10引入动态分区概念,即VAB升级;Android 12引入VABC升级,即增加了一个compression压缩概念

2. API接口调用

2.1. APP调用UpdateEngine示例代码

原生的升级参考示例APK:packages/apps/Car/SystemUpdater adb shell am start com.android.car.systemupdater/.SystemUpdaterActivity

//以下是简单的demo app截取代码private String[] mUpdateHeader = null;private UpdateEngine mUpdateEngine = null;//创建对象mUpdateEngine = new UpdateEngine();File file = new File(filePath); //升级包文件String fileName = file.getName();PayloadSpec payloadSpec = getUpdateHeader(file);
final long size = payloadSpec.getSize();final long offset = payloadSpec.getOffset();final String url = payloadSpec.getUrl();List<String> specList = payloadSpec.getProperties();mUpdateHeader = specList.toArray(new String[specList.size()]);//bind绑定mUpdateEngine.bind(new UpdateEngineCallback() { //重写onStatusUpdate接口 @Override public void onStatusUpdate(int aStatus, float aPercent) { float iaPercent = aPercent * 100; miUpdateProgress = Math.round(iaPercent); LU.w(tag, "onStatusUpdate() aStatus== " + aStatus + " iaPercent==" + iaPercent + " " + miUpdateProgress); sendMessage(UPDATE_BEING, aStatus); } //重写onPayloadApplicationComplete接口 @Override public void onPayloadApplicationComplete(int errCode) { LU.w(tag, "onPayloadApplicationComplete() errCode== " + errCode); sendTimeMessage(UPDATE_RESULT, errCode); }});//调用applyPayload,传入升级需要的参数mUpdateEngine.applyPayload(url, offset, size, mUpdateHeader);

主要内容:

  1. UpdateEngine.bind(new UpdateEngineCallback()…)接口
  2. onStatusUpdate用于接收状态码和进度
  3. onPayloadApplicationComplete用于接收升级结果
  4. UpdateEngine.applyPayload

3. UpdateEngine.java流程

代码:frameworks/base/core/java/android/os/UpdateEngine.java 代码:frameworks/base/core/java/android/os/UpdateEngineCallback.java

3.1. 构造函数

UpdateEngine.java作为APP调用的API接口提供者,然后从java到C++,就是通过binder调用(即BinderUpdateEngineAndroidService将UpdateEnginer注册到serviceManager中)

private static final String UPDATE_ENGINE_SERVICE = "android.os.UpdateEngineService";//构造函数public UpdateEngine() { //获取到UpdateEngine Service mUpdateEngine = IUpdateEngine.Stub.asInterface( ServiceManager.getService(UPDATE_ENGINE_SERVICE));}

3.2. applyPayload

申请升级,传递参数

public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) { try { mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); }}

3.3. bind

//frameworks/base/core/java/android/os/UpdateEngine.java //UpdateEngineCallback在UpdateEngineCallback.java中 //APP应用调用方式参考packages/apps/Car/SystemUpdater/src/com/android/car/systemupdater/UpdateLayoutFragment.java public boolean bind(final UpdateEngineCallback callback, final Handler handler) { synchronized (mUpdateEngineCallbackLock) { //Binder机制,对应到server端是system/update_engine/binder_service_android.cc mUpdateEngineCallback = new IUpdateEngineCallback.Stub() { @Override public void onStatusUpdate(final int status, final float percent) { if (handler != null) { handler.post(new Runnable() { @Override public void run() { callback.onStatusUpdate(status, percent); } }); } else { callback.onStatusUpdate(status, percent); } }
 @Override public void onPayloadApplicationComplete(final int errorCode) { if (handler != null) { handler.post(new Runnable() { @Override public void run() { callback.onPayloadApplicationComplete(errorCode); } }); } else { callback.onPayloadApplicationComplete(errorCode); } } }; try { //mUpdateEngineCallback注册到BinderUpdateEngineAndroidService通过这个bind回调通知 return mUpdateEngine.bind(mUpdateEngineCallback); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }

4. Action机制

Update Engine代码中,默认定义了4个Action,分别为:InstallPlanAction, DownloadAction, FilesystemVerifierAction, PostinstallRunnerAction

ActionProcessor通过StartProcessing()操作开始工作,先挑选队列中的第一个Action作为当前Action。然后当前Action调用PerformAction()开始工作,Action结束后会调用ActionProcessor的ActionComplete()接口通知当前Action已经完成。随后ActionProcessor通过StartNextActionOrFinish()挑选队列中的下一个Action进行操作。循环往复,直到队列中的所有Action都完成操作

4.1. ActionProcessor类

代码路径:system/update_engine/common/action_processor.cc

ActionProcessor工作的中心是管理Action,所以基本上所有操作是围绕Action队列进行的,包括:

  • Action入队操作:EnqueueAction
  • 开始和停止处理:StartProcessing/StopProcessing
  • 暂停和恢复处理:SuspendProcessing/ResumeProcessing
  • 当前Action结束的收尾工作:ActionComplete
  • 选择下一Action操作:StartNextActionOrFinish

5. 序列图:update engine交互接口和Action机制流程

6. UpdateEngine模块流程

6.1. InstallPlanAction

代码路径:system/update_engine/payload_consumer/ Action和Action的消息通过ActionPipe传递,每个Action都有两个ActionPipe,一个out,一个in

6.2. DownloadAction

参考:Android Update Engine分析(六)服务端核心之Action详解 参考:Android Update Engine分析(七) DownloadAction之FileWriter

DownloadAction获取InstallPlanAction传递过来的install_plan_信息,并构建http_fetcher_用于升级数据下载,http_fetcher_下载部分数据后会通过ReceivedBytes()通知DownloadAction收到了数据。

DownloadAction会使用DeltaPerformer类对象writer_的Write()方法解析下载的数据,并将其更新到相应分区中。

所以http_fetcher_下载数据,writer_将解析下载的数据并更新,然后http_fetcher_继续下载数据,writer_继续解析新下载的数据并更新到分区,这样的操作一直到所有数据下载完成,此时所有的升级数据也会被写入相应分区。

从升级包读取数据代码流程:(针对错误码9) update_engine/payload_consumer/download_action.cc - DownloadAction::PerformAction() (1)创建DeltaPerformer对象 (2) ——-> DownloadAction::StartDownloading()

——> system/update_engine/common/file_fetcher.cc - FileFetcher::BeginTransfer开始传输 (1)如果不支持该file url,则调用TransferComplete(this, false)终止传输,返回错误码kDownloadTransferError=9 (2)如果该url打不开,则同样调用TransferComplete(this, false)终止传输,返回错误码kDownloadTransferError=9 (3)开始读取数据,此时传输进度为0,已拷贝字节是0, 调用FileFetcher::ScheduleRead

FileFetcher::OnReadDoneCallback 如果

——-> FileFetcher::ScheduleRead 每次写入bytes_to_read字节,正常写入16*1024个字节,如果bytes_to_read非0(即未读取结束),调用

——> FileFetcher::OnReadDoneCallback (1)如果全部写入(即bytes_read为0)则调用TransferComplete函数 (2)否则调用ReceivedBytes函数,并且叠加bytes_copied_变量已拷贝字节数 在调用该函数结束后,会继续调用FileFetcher::ScheduleRead函数

——> android/system/update_engine/payload_consumer/update_attempter_android.cc - DownloadAction::ReceivedBytes (1)调用UpdateAttempter::BytesReceived —–》然后调用UpdateAttempter::ProgressUpdate上传进度给上层APP应用 —–》UpdateAttempter::BroadcastStatus() —–》 BinderUpdateEngineAndroidService::SendStatusUpdate通过Bind跨进程回调 —–》 UpdateEngineCallback.java - onStatusUpdate上传进度给上层APP应用

  • 上报应用进度的间隔时间: const int kBroadcastThresholdSeconds = 10;

(2)执行writer_->Write写入数据到分区 (3)调用TerminateProcessing()

——> FileFetcher::TerminateTransfer()

——> DownloadAction::TransferTerminated传入true

——> DownloadAction::TransferComplete(HttpFetcher* fetcher, bool successful)传输完成 如果传输失败会返回错误码kDownloadTransferError=9

==============

数据写入分区的流程:

system/update_engine/payload_consumer/delta_performer.cc - DeltaPerformer::OpenCurrentPartition()打开当前要下载写入数据的分区 (参考日志:Opening /dev/block/by-name/boot_a partition without O_DSYNC

(1)调用两次FileDescriptorPtr OpenFile打开分区路径进行读写(第一次打开当前系统分区source_path_,第二次打开升级对应的分区target_path_) (参考打印日志:Caching writes) (2)然后会打印该分区需要的operations操作数量 (参考日志:Applying 15 operations to partition "boot"

PS:关于partition对象的信息在脚本system/update_engine/scripts/update_payload/update_metadata_pb2.py

————-> DeltaPerformer::Write写数据 (1)第一个while循环,判断manifest_valid_为true则执行,调用CopyDataToBuffer,下一个分区大于0,则调用UpdateOverallProgress打印进度 如果next_operation_num_>0即仍有operation未执行,则调用UpdateOverallProgress打印进度

(2)第二个while循环,判断下一个operation数量小于总的operations数量(next_operation_num_ < num_total_operations_),则执行 调用CopyDataToBuffer,while结束一次循环,next_operation_num_加一 a.operation结束后,调用CloseCurrentPartition() b.调用OpenCurrentPartition()成功则继续,失败返回错误码kInstallDeviceOpenError=7 c.调用CopyDataToBuffer d.调用UpdateOverallProgress打印进度 (参考日志:Completed 132/1883 operations (7%), 89047040/1040519397 bytes downloaded (8%), overall progress 7%

(参考日志:Starting to apply update payload operations

——-> DeltaPerformer::UpdateOverallProgress ——-> DeltaPerformer::LogProgress 打印downloadAction的进度 (参考日志:Completed 132/1883 operations (7%), 89047040/1040519397 bytes downloaded (8%), overall progress 7%)

  • operations操作日志打印间隔:const unsigned DeltaPerformer::kProgressLogTimeoutSeconds = 30;

Write()函数主要包含了以下几个操作:

  1. 更新数据接收进度信息;
  2. 解析升级包的头部数据,得到DeltaArchiveManifest数据;
  3. 对DeltaArchiveManifest结构进行检查;
  4. 从DeltaArchiveManifest中提取分区信息;
  5. 更新升级的状态信息
  6. 提取各分区的InstallOperation,并检查payload数据的hash
  7. 执行InstallOperation的更新操作;
  8. 提取升级数据的signature;

6.3. FilesystemVerifierAction

DownloadAction结束后,ActionProcessor会调用FilesystemVerifierAction进行文件系统的Hash校验工作,具体操作是逐个打开install_plan_里partitions成员包含的分区,以流文件的方式逐块读取(块大小为128*1024,即128K)分区内的数据并计算得到相应的Hash,再将计算得到的Hash同预先存放的Hash(install_plan_里partitions对应分区的target_hash)进行比较。所有分区的Hash比较完成后,ActionProcessor调度下一个Action执行。

换句话说,升级包制作程序会用升级前后的分区进行对比,因此升级包制作程序能够计算升级后的分区Hash信息并存放到升级包文件中。Update Engine下载升级包文件后通过解析可以得到预期升级完成后分区的Hash信息。

当升级数据下载完成并更新到磁盘后,分区内容理论上应该和预期升级完成后的分区是一样的,因此其Hash也应该一样。此时,读取升级分区的数据并计算得到实际Hash值,将其同下载的升级包里面的Hash进行比较。这就是FilesystemVerifierAction的工作任务。

6.4. PostinstallRunnerAction

升级在PostinstallRunnerAction任务的这一步并没有执行特别的script,而只是将target_slot标记为活动(active)分区而已

6.5. 4个Action流程小结

在调用ApplyPayload()进行升级时,UpdateAttempterAndroid类默认会在BuildUpdateActions()函数内构建4个Action:

  • InstallPlanAction: install_plan_action
  • DownloadAction: download_action
  • FilesystemVerifierAction: dst_filesystem_verifier_action
  • PostinstallRunnerAction: postinstall_runner_action

这4个Action随后会通过BondActions()操作,将上一个Action的OutputObject与下一个Action的InputObject连接起来,类似管道那样,其中传递的信息就是install_plan_,包含了升级信息数据。

构建的4个Action操作也会进入ActionProcessor的Action队列,当调用StartProcessing()后,ActionProcessor会逐个取出Action队列的Action,然后调用每个Action的PerformAction()操作。

当一个Action结束后,会通知ActionProcessor调用ActionComplete()选择下一个Action执行,直到ActionProcessor的Action队列中不再有任务为止

在DownloadAction开始数据下载前,会将target_slot设置为不可启动(unbootable)的状态;在PostInstallRunnerAction成功执行post install script后,又会重新将target_slot设置为活动(active)状态。

PostInstallRunnerAction任务执行结束后,ActionProcessor的Action队列为空,整个Action队列的调度操作结束。

此时ActionProcessor通知update_attempter_对象执行ProcessingDone()操作。该操作会在系统中写入一个标记Update Complete的BootId,然后将UpdateStatus设置为UPDATED_NEED_REBOOT并通知Update Engine的客户端进程。

7. 序列图:InstallPlanAction和DownloadAction流程

Android UpdateEngine模块流程(含序列图)-腾讯云开发者社区-腾讯云 (2)

8. 序列图:FilesystemVerifierAction和PostinstallRunnerAction流程

Android UpdateEngine模块流程(含序列图)-腾讯云开发者社区-腾讯云 (3)

9. update_engine模块启动流程

9.1. update_engine.rc启动

update_engine.rc文件:

service update_engine /system/bin/update_engine --logtostderr --logtofile --foreground class late_start user root group root system wakelock inet cache media_rw writepid /dev/cpuset/system-background/tasks disabledon property:ro.boot.slot_suffix=* enable update_engine

Android.bp文件

cc_binary { name: "update_engine", defaults: [ "ue_defaults", "libupdate_engine_android_exports", ], static_libs: ["libupdate_engine_android"], required: ["cacerts_google"], srcs: ["main.cc"], init_rc: ["update_engine.rc"],}.....

9.2. main.cc入口函数

  1. main.cc入口

升级日志信息获取:

adb pull /data/misc/update_engine_logadb pull /data/misc/update_engine/
int main(int argc, char** argv) { //升级日志获取 //adb pull /data/misc/update_engine_log //adb pull /data/misc/update_engine/ DEFINE_bool(logtofile, false, "Write logs to a file in log_dir."); DEFINE_bool(logtostderr, false, "Write logs to stderr instead of to a file in log_dir."); DEFINE_bool(foreground, false, "Don't daemon()ize; run in foreground.");
 chromeos_update_engine::Terminator::Init(); brillo::FlagHelper::Init(argc, argv, "A/B Update Engine"); // We have two logging flags "--logtostderr" and "--logtofile"; and the logic // to choose the logging destination is: // 1. --logtostderr --logtofile -> logs to both // 2. --logtostderr -> logs to system debug // 3. --logtofile or no flags -> logs to file bool log_to_system = FLAGS_logtostderr; bool log_to_file = FLAGS_logtofile || !FLAGS_logtostderr; chromeos_update_engine::SetupLogging(log_to_system, log_to_file);
 if (!FLAGS_foreground) PLOG_IF(FATAL, daemon(0, 0) == 1) << "daemon() failed"; LOG(INFO) << "A/B Update Engine starting"; ...... chromeos_update_engine::UpdateEngineDaemon update_engine_daemon; //实际实现逻辑在父类daemon.cc的run函数 int exit_code = update_engine_daemon.Run(); chromeos_update_engine::Subprocess::Get().FlushBufferedLogsAtExit(); LOG(INFO) << "A/B Update Engine terminating with exit code " << exit_code; return exit_code;}
  1. Daemon::Run()
//system/update_engine/daemon.hclass UpdateEngineDaemon : public brillo::Daemon { ....}//external/libbrillo/brillo/daemons/daemon.ccint Daemon::Run() { //调用到UpdateEngineDaemon的OnInit int exit_code = OnInit(); if (exit_code != EX_OK) return exit_code; message_loop_.PostTask( base::Bind(&Daemon::OnEventLoopStartedTask, base::Unretained(this))); message_loop_.Run(); OnShutdown(&exit_code_); ...... return exit_code_;}

9.3. UpdateEngineDaemon初始化

接着上面调用到UpdateEngineDaemon::OnInit()

int UpdateEngineDaemon::OnInit() { // Register the |subprocess_| singleton with this Daemon as the signal // handler. subprocess_.Init(this); //调用到父类的OnInit int exit_code = Daemon::OnInit();
 if (exit_code != EX_OK) return exit_code; ...... //创建DaemonStateAndroid对象 DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid(); daemon_state_.reset(daemon_state_android); //初始化 //1.CreateBootControl //2.CreateHardware //3.new Prefs() //4.new CertificateChecker //5.new UpdateAttempterAndroid,构造函数将bootcontrol,hardware,prefs传递给该类 LOG_IF(ERROR, !daemon_state_android->Initialize()) << "Failed to initialize system state.";#endif // USE_OMAHA
#if USE_BINDER // Create the Binder Service.#if USE_OMAHA binder_service_ = new BinderUpdateEngineBrilloService{real_system_state};#else // !USE_OMAHA//创建BinderUpdateEngineAndroidService对象 binder_service_ = new BinderUpdateEngineAndroidService{ daemon_state_android->service_delegate()};#endif // USE_OMAHA auto binder_wrapper = android::BinderWrapper::Get(); //将BinderUpdateEngineBrilloService注册到serviceManager中 if (!binder_wrapper->RegisterService(binder_service_->ServiceName(), binder_service_)) { LOG(ERROR) << "Failed to register binder service."; } //将该对象传递给DaemonStateAndroid对象 daemon_state_->AddObserver(binder_service_.get());#endif // USE_BINDER#if USE_DBUS // Create the DBus service. dbus_adaptor_.reset(new UpdateEngineAdaptor(real_system_state)); daemon_state_->AddObserver(dbus_adaptor_.get()); dbus_adaptor_->RegisterAsync(base::Bind(&UpdateEngineDaemon::OnDBusRegistered, base::Unretained(this))); LOG(INFO) << "Waiting for DBus object to be registered.";#else // !USE_DBUS //主要调用update_attempter_->Init()初始化方法 daemon_state_->StartUpdater();#endif // USE_DBUS return EX_OK;}

10. 升级脚本

源码:system/update_engine/scripts/update_device.py

升级命令:python update_device.py --file usb_ota_update.zip

升级包解压后文件目录:

usb_ota_update.zip目录2021/12/06 14:55 <DIR> .2021/12/06 14:55 <DIR> ..2021/12/06 14:54 <DIR> META-INF2009/01/01 00:00 891,093,819 payload.bin2009/01/01 00:00 155 payload_properties.txt

11. 调试技巧

11.1. update_engine升级包的hash值计算

升级包解压后在payload_properties.txt文件可以看到payload.bin和metadata的文件大小和hash值

该hash值是通过sha256sum计算后,再base64编码成字符串

参考:Android Update Engine分析(十) 生成 payload 和 metadata 的哈希

实际操作:

$ cat ../../../payload_properties.txt //payload.bin升级包数据FILE_HASH=Kw0egs8dY9Qm1sULkpkAPF+0PiKx14Uo0fHGZO3vNAk=FILE_SIZE=2515281637//压缩后的 manifest 数据METADATA_HASH=z+5Qz8UIBrhCtMDgo+5IG4/rQqFUqmN/FMFyIWhaIEU=METADATA_SIZE=179557$ ls -l payload.bin -rw-r--r-- 1 wsun17 domain users 2515281637 Jan 1 2009 payload.bin //文件大小对应$ sha256sum payload.bin | awk '{print $1}' | xxd -r -ps | base64Kw0egs8dY9Qm1sULkpkAPF+0PiKx14Uo0fHGZO3vNAk= //计算后的文件hash值对应$ dd if=payload.bin bs=1 count=179557 2>/dev/null | sha256sum | awk '{print $1}' | xxd -r -ps | base64 //计算后的metadata hash值对应z+5Qz8UIBrhCtMDgo+5IG4/rQqFUqmN/FMFyIWhaIEU=

11.2. update_engine升级信息获取

adb rootadb pull /data/misc/update_engine_logadb pull /data/misc/update_engine/
:/data/misc/update_engine/prefs # ls -thltotal 38K-rw------- 1 root root 1 2021-01-01 00:11 total-bytes-downloaded-rw------- 1 root root 17 2021-01-01 00:11 system-updated-marker-rw------- 1 root root 1 2021-01-01 00:11 delta-update-failures-rw------- 1 root root 36 2021-01-01 00:11 update-completed-on-boot-id-rw------- 1 root root 4 2021-01-01 00:11 post-install-succeeded-rw------- 1 root root 4 2021-01-01 00:09 verity-written-rw------- 1 root root 1 2021-01-01 00:08 update-state-next-data-length-rw------- 1 root root 9 2021-01-01 00:08 update-state-next-data-offset-rw------- 1 root root 4 2021-01-01 00:08 update-state-next-operation-rw------- 1 root root 112 2021-01-01 00:08 update-state-sha-256-context-rw------- 1 root root 264 2021-01-01 00:08 update-state-signature-blob-rw------- 1 root root 112 2021-01-01 00:08 update-state-signed-sha-256-context-rw------- 1 root root 6 2021-01-01 00:02 manifest-metadata-size-rw------- 1 root root 3 2021-01-01 00:02 manifest-signature-size-rw------- 1 root root 4 2021-01-01 00:02 dynamic-partition-metadata-updated-rw------- 1 root root 1 2021-01-01 00:02 resumed-update-failures-rw------- 1 root root 88 2021-01-01 00:02 update-check-response-hash-rw------- 1 root root 36 1970-01-01 08:00 boot-id-rw------- 1 root root 24 1970-01-01 08:00 previous-version:/data/misc/update_engine/prefs # cat boot-ide2ecfeb4-d097-449c-8c7b-e8aee5067cc6:/data/misc/update_engine/prefs # cat previous-versioneng.user.20211201.031118:/data/misc/update_engine/prefs # cat update-check-response-hashLBhFc9jN99sOu9/VKy7COfkBXtXzlDt5fHdx1kQyU3c=vsNI/ZuKzDY0uOuXZIOjr42UHrzJ86isJSEtAwlFf9k=

11.3. update_engine错误码errorcode

//android/system/update_engine/common/error_code.h// Action exit codes.enum class ErrorCode : int { kSuccess = 0, //升级成功 kError = 1, //升级失败 kOmahaRequestError = 2, //请求action错误(action机制用于控制升级每个步骤) kOmahaResponseHandlerError = 3, //返回handler action错误 kFilesystemCopierError = 4, //文件系统拷贝错误 kPostinstallRunnerError = 5, //预编译运行步骤错误(PostinstallRunner是一个升级步骤) kPayloadMismatchedType = 6, //NOT NEED kInstallDeviceOpenError = 7, //安装设备打开错误 kKernelDeviceOpenError = 8, //内核设备打开错误 kDownloadTransferError = 9, //下载传输错误 kPayloadHashMismatchError = 10, //升级包hash未匹配错误 kPayloadSizeMismatchError = 11, //升级包size未匹配错误 kDownloadPayloadVerificationError = 12, //下载过程升级包校验错误 kDownloadNewPartitionInfoError = 13, //下载过程新分区信息错误 kDownloadWriteError = 14, //下载过程数据写入错误 kNewRootfsVerificationError = 15, //升级分区hash校验失败 kNewKernelVerificationError = 16, //升级kernel校验失败 kSignedDeltaPayloadExpectedError = 17, //NOT NEED kDownloadPayloadPubKeyVerificationError = 18, //下载过程升级包public key公钥校验错误 kPostinstallBootedFromFirmwareB = 19, //NOT NEED kDownloadStateInitializationError = 20, //下载状态初始化错误 kDownloadInvalidMetadataMagicString = 21, //NOT NEED kDownloadSignatureMissingInManifest = 22, //下载过程manifest缺少签名错误 kDownloadManifestParseError = 23, //下载过程manifest分析错误 kDownloadMetadataSignatureError = 24, //下载过程元数据签名错误 kDownloadMetadataSignatureVerificationError = 25, //下载过程元数据签名校验错误 kDownloadMetadataSignatureMismatch = 26, //下载过程元数据签名不匹配错误 kDownloadOperationHashVerificationError = 27, //下载过程操作hash校验错误 kDownloadOperationExecutionError = 28, //下载过程操作执行错误 kDownloadOperationHashMismatch = 29, //下载过程操作hash不匹配错误 kOmahaRequestEmptyResponseError = 30, //请求action无返回错误 kOmahaRequestXMLParseError = 31, //请求action分析xml错误 kDownloadInvalidMetadataSize = 32, //下载过程非法元数据大小 kDownloadInvalidMetadataSignature = 33, //下载过程非法元数据签名 kOmahaResponseInvalid = 34, //返回action非法错误 kOmahaUpdateIgnoredPerPolicy = 35, //NOT NEED(含义是接收已回滚版本,忽略此次升级) kOmahaUpdateDeferredPerPolicy = 36, //NOT NEED(含义是因更新策略延迟,忽略此次升级) kOmahaErrorInHTTPResponse = 37, //HTTP返回错误 kDownloadOperationHashMissingError = 38, //下载过程操作时缺失hash错误 kDownloadMetadataSignatureMissingError = 39, //下载过程元数据签名缺失错误 kOmahaUpdateDeferredForBackoff = 40, //NOT NEED(含义是忽略本次升级) kPostinstallPowerwashError = 41, //NOT NEED(回滚报错,该版本已去除版本回滚限制) kUpdateCanceledByChannelChange = 42, //通道变化升级取消 kPostinstallFirmwareRONotUpdatable = 43, //NOT NEED(需要升级固件firmware时才会取消,因为无法从FW B分区启动到FW A分区) kUnsupportedMajorPayloadVersion = 44, //获取manifest偏移量错误 kUnsupportedMinorPayloadVersion = 45, //未manifest可支持更小版本错误 kOmahaRequestXMLHasEntityDecl = 46, //请求action xml hash非法错误 kFilesystemVerifierError = 47, //文件系统校验错误(FilesystemVerifier是一个升级步骤) kUserCanceled = 48, //用户取消 kNonCriticalUpdateInOOBE = 49, //NOT NEED(Ignoring a non-critical Omaha update before OOBE completion.) kOmahaUpdateIgnoredOverCellular = 50, //NOT NEED(未设置设备策略,因此用户首选项需要覆盖是否允许通过蜂窝网络进行更新) kPayloadTimestampError = 51, //升级包时间戳错误 (payload.bin是OTA镜像打包文件) kUpdatedButNotActive = 52, //升级分区非action状态错误 kNoUpdate = 53, //无升级(There are no updates. Aborting.) kRollbackNotPossible = 54, //NOT NEED kFirstActiveOmahaPingSentPersistenceError = 55, //NOT NEED(用于旧设备的Omaha校验) kVerityCalculationError = 56, //校验计算错误(在FilesystemVerifier步骤中进行分区校验时)

12. 参考文档

  • Android A/B system - update_engine
  • android9 update_engine升级
  • updateEngine的内部启动流程
  • Android Update Engine分析(五)服务端核心之Action机制
  • Android Update Engine分析(六)服务端核心之Action详解
  • Android Update Engine分析(七) DownloadAction之FileWriter
  • Android 12 AOSP源码
  • fs_mgr模块-system文件系统管理的主模块
  • Android官方文档VAB-dm-snapshot
  • 我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1ds259apwo697

本文参与腾讯云自媒体分享计划,分享自作者个人站点/博客。

如有侵权请联系 cloudcommunity@tencent.com 删除

Android UpdateEngine模块流程(含序列图)-腾讯云开发者社区-腾讯云 (2024)
Top Articles
Latest Posts
Article information

Author: Trent Wehner

Last Updated:

Views: 6238

Rating: 4.6 / 5 (56 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Trent Wehner

Birthday: 1993-03-14

Address: 872 Kevin Squares, New Codyville, AK 01785-0416

Phone: +18698800304764

Job: Senior Farming Developer

Hobby: Paintball, Calligraphy, Hunting, Flying disc, Lapidary, Rafting, Inline skating

Introduction: My name is Trent Wehner, I am a talented, brainy, zealous, light, funny, gleaming, attractive person who loves writing and wants to share my knowledge and understanding with you.