上一篇我们讲到了服务端启动的流程,本篇主要讲解主要升级流程,UpdateAttempterAndroid类包含的内容较多,所以单独讲解,这个文件看了很长时间,大概方法都已经了解,但是想了很久从哪儿开始梳理这个流程,不仅仅是我能看懂,而且能讲出来的很清晰,这是我想做到的,别问,问就是重点
一、update_attempter_android.h 简要分析
1、继承和构造函数
1class UpdateAttempterAndroid 2 : public ServiceDelegateAndroidInterface, 3 public ActionProcessorDelegate, 4 public DownloadActionDelegate, 5 public PostinstallRunnerAction::DelegateInterface { 6 public: 7 using UpdateStatus = update_engine::UpdateStatus; 8 9 UpdateAttempterAndroid(DaemonStateInterface* daemon_state, 10 PrefsInterface* prefs, 11 BootControlInterface* boot_control_, 12 HardwareInterface* hardware_); 13 ~UpdateAttempterAndroid() override;
UpdateAttempterAndroid继承了四个类
ServiceDelegateAndroidInterface
BinderUpdateEngineAndroidService具体执行的方法,由ServiceDelegateAndroidInterface类service_delegate执行,而具体执行的时候会执行子类UpdateAttempterAndroid的方法
ActionProcessorDelegate
Action机制的管理者
DownloadActionDelegate
具体升级业务DownloadAction
PostinstallRunnerAction
具体升级业务PostinstallRunnerAction
构造函数包含:DaemonStateInterface PrefsInterface BootControlInterface HardwareInterface
由上一篇分析我们知道,这些参数都是由DaemonStateAndroid传进来的指针对象
2、父类ServiceDelegateAndroidInterface的方法
1 // ServiceDelegateAndroidInterface overrides. 2 // 通过binder_service 调用的方法,也就是客户端直接发出的方法 3 bool ApplyPayload(const std::string& payload_url, 4 int64_t payload_offset, 5 int64_t payload_size, 6 const std::vector<std::string>& key_value_pair_headers, 7 brillo::ErrorPtr* error) override; 8 bool SuspendUpdate(brillo::ErrorPtr* error) override; 9 bool ResumeUpdate(brillo::ErrorPtr* error) override; 10 bool CancelUpdate(brillo::ErrorPtr* error) override; 11 bool ResetStatus(brillo::ErrorPtr* error) override; 12 bool VerifyPayloadApplicable(const std::string& metadata_filename, 13 brillo::ErrorPtr* error) override;
3、父类ActionProcessorDelegate的方法
1 // ActionProcessorDelegate methods: 2 // 需要使用到的ActionProcessor的方法 3 void ProcessingDone(const ActionProcessor* processor, 4 ErrorCode code) override; 5 void ProcessingStopped(const ActionProcessor* processor) override; 6 void ActionCompleted(ActionProcessor* processor, 7 AbstractAction* action, 8 ErrorCode code) override;
4、父类DownloadAction和PostinstallRunnerAction的方法
1 // DownloadActionDelegate overrides. 2 // DownloadAction相关的方法 3 void BytesReceived(uint64_t bytes_progressed, 4 uint64_t bytes_received, 5 uint64_t total) override; 6 bool ShouldCancel(ErrorCode* cancel_reason) override; 7 void DownloadComplete() override; 8 9 // PostinstallRunnerAction::DelegateInterface 10 // PostinstallRunnerAction相关的方法 11 void ProgressUpdate(double progress) override;
5、私有方法
1 private: 2 //friend关键字其实做这样的事情:在一个类中指明其他的类(或者)函数能够直接访问该类中的private和protected成员。 3 friend class UpdateAttempterAndroidTest; 4 5 // Asynchronously marks the current slot as successful if needed. If already 6 // marked as good, CompleteUpdateBootFlags() is called starting the action 7 // processor. 8 // 如果需要,将当前插槽异步标记为成功。 如果已经标记为良好,则调用CompleteUpdateBootFlags()启动操作处理器。 9 void UpdateBootFlags(); 10 11 // Called when the boot flags have been updated. 12 // 引导标志已更新时调用。 13 void CompleteUpdateBootFlags(bool success); 14 15 // Schedules an event loop callback to start the action processor. This is 16 // scheduled asynchronously to unblock the event loop. 17 // 调度事件循环回调以启动动作处理器。 这是异步安排的,以取消阻塞事件循环。 18 void ScheduleProcessingStart(); 19 20 // Notifies an update request completed with the given error |code| to all 21 // observers. 22 //通知更新请求已完成,并带有给定错误| code | 对所有观察者。 23 void TerminateUpdateAndNotify(ErrorCode error_code); 24 25 // Sets the status to the given |status| and notifies a status update to 26 // all observers. 27 // 将状态设置为给定的| status | 并将状态更新通知所有观察者。 28 void SetStatusAndNotify(UpdateStatus status); 29 30 // Helper method to construct the sequence of actions to be performed for 31 // applying an update from the given |url|. 32 // Helper方法,用于根据给定的| url |构造要应用更新的操作序列。 33 void BuildUpdateActions(const std::string& url); 34 35 // Writes to the processing completed marker. Does nothing if 36 // |update_completed_marker_| is empty. 37 // 写入处理完成标记,如果update_completed_marker_ 是空的,那什么都不做 38 bool WriteUpdateCompletedMarker(); 39 40 // Returns whether an update was completed in the current boot. 41 // 返回更新是否在当前引导中完成。 42 bool UpdateCompletedOnThisBoot(); 43 44 // prefs相关的方法 45 // Prefs to use for metrics report 46 // |kPrefsPayloadAttemptNumber|: number of update attempts for the current 47 // payload_id. 48 // |KprefsNumReboots|: number of reboots when applying the current update. 49 // |kPrefsSystemUpdatedMarker|: end timestamp of the last successful update. 50 // |kPrefsUpdateTimestampStart|: start timestamp of the current update. 51 // |kPrefsCurrentBytesDownloaded|: number of bytes downloaded for the current 52 // payload_id. 53 // |kPrefsTotalBytesDownloaded|: number of bytes downloaded in total since 54 // the last successful update. 55 56 // Metrics report function to call: 57 // |ReportUpdateAttemptMetrics| 58 // |ReportSuccessfulUpdateMetrics| 59 // Prefs to update: 60 // |kPrefsSystemUpdatedMarker| 61 void CollectAndReportUpdateMetricsOnUpdateFinished(ErrorCode error_code); 62 63 // Metrics report function to call: 64 // |ReportAbnormallyTerminatedUpdateAttemptMetrics| 65 // |ReportTimeToRebootMetrics| 66 // Prefs to update: 67 // |kPrefsBootId|, |kPrefsPreviousVersion| 68 void UpdatePrefsAndReportUpdateMetricsOnReboot(); 69 70 // Prefs to update: 71 // |kPrefsPayloadAttemptNumber|, |kPrefsUpdateTimestampStart| 72 void UpdatePrefsOnUpdateStart(bool is_resume); 73 74 // Prefs to delete: 75 // |kPrefsNumReboots|, |kPrefsPayloadAttemptNumber|, 76 // |kPrefsSystemUpdatedMarker|, |kPrefsUpdateTimestampStart|, 77 // |kPrefsCurrentBytesDownloaded| 78 void ClearMetricsPrefs(); 79 80 //daemon_state_指针,在成员变量中 81 DaemonStateInterface* daemon_state_; 82 83 // DaemonStateAndroid pointers. 84 // DaemonStateAndroid传入的指针 85 PrefsInterface* prefs_; 86 BootControlInterface* boot_control_; 87 HardwareInterface* hardware_; 88 89 // Last status notification timestamp used for throttling. Use monotonic 90 // TimeTicks to ensure that notifications are sent even if the system clock is 91 // set back in the middle of an update. 92 // 于限制的最后状态通知时间戳。 使用单调TimeTicks,以确保即使在更新过程中重新设置系统时钟,也可以发送通知。 93 base::TimeTicks last_notify_time_; 94 95 // The list of actions and action processor that runs them asynchronously. 96 // Only used when |ongoing_update_| is true. 97 // actions_ action的列表,状态在ongoing_update_ = true的时候执行 98 std::vector<std::shared_ptr<AbstractAction>> actions_; 99 // processor_ ActionProcessor管理者 100 std::unique_ptr<ActionProcessor> processor_; 101 102 // Pointer to the DownloadAction in the actions_ vector. 103 // DownloadAction的指针 104 std::shared_ptr<DownloadAction> download_action_; 105 106 // Whether there is an ongoing update. This implies that an update was started 107 // but not finished yet. This value will be true even if the update was 108 // suspended. 109 bool ongoing_update_{false}; 110 111 // The InstallPlan used during the ongoing update. 112 InstallPlan install_plan_; 113 114 // For status: 115 UpdateStatus status_{UpdateStatus::IDLE}; 116 double download_progress_{0.0}; 117 118 // The offset in the payload file where the CrAU part starts. 119 int64_t base_offset_{0}; 120 121 // Only direct proxy supported. 122 DirectProxyResolver proxy_resolver_; 123 124 // Helper class to select the network to use during the update. 125 std::unique_ptr<NetworkSelectorInterface> network_selector_; 126 127 // Whether we have marked the current slot as good. This step is required 128 // before applying an update to the other slot. 129 bool updated_boot_flags_ = false; 130 131 std::unique_ptr<ClockInterface> clock_; 132 133 std::unique_ptr<MetricsReporterInterface> metrics_reporter_; 134 135 DISALLOW_COPY_AND_ASSIGN(UpdateAttempterAndroid);
是的,方法就是这么多,别问,问都是重点,多我们就继续拆分成模块分析就行了
二、update_attempter_android.cc 分析
先从最后启动服务端的时候执行的
1bool DaemonStateAndroid::StartUpdater() { 2 // The DaemonState in Android is a passive daemon. It will only start applying 3 // an update when instructed to do so from the exposed binder API. 4 update_attempter_->Init(); 5 return true; 6}
开始接着分析
1、init 和 UpdateCompletedOnThisBoot方法
1//首先还是层接daemon_state_android.cc执行的StartUpdater中执行init 2void UpdateAttempterAndroid::Init() { 3 // In case of update_engine restart without a reboot we need to restore the 4 // reboot needed state. 5 //判断是不是已经更新完成了 6 if (UpdateCompletedOnThisBoot()) { 7 //如果是,给客户端返回状态为UPDATED_NEED_REBOOT 8 SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT); 9 } else { 10 //如果没有更新完成,返回状态IDLE,表示为空闲状态 11 SetStatusAndNotify(UpdateStatus::IDLE); 12 UpdatePrefsAndReportUpdateMetricsOnReboot(); 13 } 14} 15 16//判断是不是升级成功 对比当前机器的boot_id 和升级完成需要重启的boot_id 17//如果对比相同,那么判定为升级成功 18bool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() { 19 // In case of an update_engine restart without a reboot, we stored the boot_id 20 // when the update was completed by setting a pref, so we can check whether 21 // the last update was on this boot or a previous one. 22 string boot_id; 23 TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 24 25 string update_completed_on_boot_id; 26 return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) && 27 prefs_->GetString(kPrefsUpdateCompletedOnBootId, 28 &update_completed_on_boot_id) && 29 update_completed_on_boot_id == boot_id); 30} 31 32// Save the update start time. Reset the reboot count and attempt number if the 33// update isn't a resume; otherwise increment the attempt number. 34// 保存更新开始时间。 如果更新不是恢复操作,请重置重启次数和尝试次数; 否则增加尝试次数。 35void UpdateAttempterAndroid::UpdatePrefsOnUpdateStart(bool is_resume) { 36 if (!is_resume) { 37 metrics_utils::SetNumReboots(0, prefs_); 38 metrics_utils::SetPayloadAttemptNumber(1, prefs_); 39 } else { 40 int64_t attempt_number = 41 metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_); 42 metrics_utils::SetPayloadAttemptNumber(attempt_number + 1, prefs_); 43 } 44 Time update_start_time = clock_->GetMonotonicTime(); 45 metrics_utils::SetUpdateTimestampStart(update_start_time, prefs_); 46}
2、ApplyPayload方法
好吧,重点开始了,别问,问就是重点,拆分下来大概为以下几部主要流程:
1、判断升级状态
2、解析传入的参数
3、将传入的参数设定到install_plan_结构体
4、创建升级的各种action
5、回调给客户端当前升级状态
6、更新启动分区的标识
1//进入我们的正菜,这里其实就是核心方法开始执行了 2//url:升级包(Payload)的路径,ab升级只能使用内置存储,必须在目录 /data/ota_package/xxx 而且需要以file://开头,比如file://data/ota_package/update.zip 3//offset:这是payload 在update.zip中的偏移量,需要从升级包文件中计算出来 4//Size:这是payload文件的大小,可以在payload_properties.txt中找到 5//headerKeyValuePairs:这是metadata,可以在升级包中的payload_properties.txt中找到, 6//headerKeyValuePairs参数 时用来传输metadata数据给update_engine服务端,存储在payload_properties.txt,通过脚本system/update_engine/scripts/brillo_update_payload 7// 生成,数据格式如下: 8//String[] pairs = { 9// "FILE_HASH=f1KT8nZAvNCx7hesGI0xaqVm9CIWzQvXGfg2T2Cp+ME=", 10// "FILE_SIZE=781070526", 11// "METADATA_HASH=lMosFzUjtB1ODkiSTw4xgNt6WkYuGV70GzTkdNTtlMU=", 12// "METADATA_SIZE=89254" 13//}; 14bool UpdateAttempterAndroid::ApplyPayload( 15 const string& payload_url, 16 int64_t payload_offset, 17 int64_t payload_size, 18 const vector<string>& key_value_pair_headers, 19 brillo::ErrorPtr* error) { 20 //1、判断升级状态 21 //判断是否已经升级完成,如果是,那么不需要在走下面的升级流程 22 if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) { 23 return LogAndSetError( 24 error, FROM_HERE, "An update already applied, waiting for reboot"); 25 } 26 //判断是不是正在升级,ongoing_update_ 是正在升级的意思,如果是正在升级,不需要走下面的升级流程 27 if (ongoing_update_) { 28 return LogAndSetError( 29 error, FROM_HERE, "Already processing an update, cancel it first."); 30 } 31 //检查状态是不是IDIE 32 DCHECK(status_ == UpdateStatus::IDLE); 33 //2、解析传入的参数 34 //创建map集合 35 std::map<string, string> headers; 36 for (const string& key_value_pair : key_value_pair_headers) { 37 string key; 38 string value; 39 if (!brillo::string_utils::SplitAtFirst( 40 key_value_pair, "=", &key, &value, false)) { 41 return LogAndSetError( 42 error, FROM_HERE, "Passed invalid header: " + key_value_pair); 43 } 44 //将传入的key value放入到headers 这个map集合中 45 if (!headers.emplace(key, value).second) 46 return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key); 47 } 48 49 // Unique identifier for the payload. An empty string means that the payload 50 // can't be resumed. 51 // 根据headers中的FileHash 和 MetadataHash 组成payload_id 52 string payload_id = (headers[kPayloadPropertyFileHash] + 53 headers[kPayloadPropertyMetadataHash]); 54 55 // Setup the InstallPlan based on the request. 56 //创建install_plan_ 查询了install_plan.h的代码,InstallPlan是一个struct结构体 57 //既然是结构体,那么就包含了很多需要设定的参数,以下就是设定他的一些参数 58 //3、将传入的参数设定到install_plan_结构体 59 install_plan_ = InstallPlan(); 60 install_plan_.download_url = payload_url; 61 install_plan_.version = ""; 62 base_offset_ = payload_offset; 63 InstallPlan::Payload payload; 64 payload.size = payload_size; 65 if (!payload.size) { 66 if (!base::StringToUint64(headers[kPayloadPropertyFileSize], 67 &payload.size)) { 68 payload.size = 0; 69 } 70 } 71 if (!brillo::data_encoding::Base64Decode(headers[kPayloadPropertyFileHash], 72 &payload.hash)) { 73 LOG(WARNING) << "Unable to decode base64 file hash: " 74 << headers[kPayloadPropertyFileHash]; 75 } 76 if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize], 77 &payload.metadata_size)) { 78 payload.metadata_size = 0; 79 } 80 // The |payload.type| is not used anymore since minor_version 3. 81 payload.type = InstallPayloadType::kUnknown; 82 //为payload赋值后放入install_plan_.payloads容器中 83 install_plan_.payloads.push_back(payload); 84 85 // The |public_key_rsa| key would override the public key stored on disk. 86 install_plan_.public_key_rsa = ""; 87 //是否强制性校验hash 88 install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild(); 89 //判断是否进行未完成的升级 90 install_plan_.is_resume = !payload_id.empty() && 91 DeltaPerformer::CanResumeUpdate(prefs_, payload_id); 92 if (!install_plan_.is_resume) { 93 if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) { 94 LOG(WARNING) << "Unable to reset the update progress."; 95 } 96 if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) { 97 LOG(WARNING) << "Unable to save the update check response hash."; 98 } 99 } 100 //当前正在运行的分区 101 install_plan_.source_slot = boot_control_->GetCurrentSlot(); 102 //需要升级的分区 103 install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0; 104 105 install_plan_.powerwash_required = 106 GetHeaderAsBool(headers[kPayloadPropertyPowerwash], false); 107 //选择那个分区进行重启 108 install_plan_.switch_slot_on_reboot = 109 GetHeaderAsBool(headers[kPayloadPropertySwitchSlotOnReboot], true); 110 111 install_plan_.run_post_install = true; 112 // Optionally skip post install if and only if: 113 // a) we're resuming 114 // b) post install has already succeeded before 115 // c) RUN_POST_INSTALL is set to 0. 116 if (install_plan_.is_resume && prefs_->Exists(kPrefsPostInstallSucceeded)) { 117 bool post_install_succeeded = false; 118 prefs_->GetBoolean(kPrefsPostInstallSucceeded, &post_install_succeeded); 119 if (post_install_succeeded) { 120 install_plan_.run_post_install = 121 GetHeaderAsBool(headers[kPayloadPropertyRunPostInstall], true); 122 } 123 } 124 125 NetworkId network_id = kDefaultNetworkId; 126 if (!headers[kPayloadPropertyNetworkId].empty()) { 127 if (!base::StringToUint64(headers[kPayloadPropertyNetworkId], 128 &network_id)) { 129 return LogAndSetError( 130 error, 131 FROM_HERE, 132 "Invalid network_id: " + headers[kPayloadPropertyNetworkId]); 133 } 134 if (!network_selector_->SetProcessNetwork(network_id)) { 135 return LogAndSetError( 136 error, 137 FROM_HERE, 138 "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]); 139 } 140 } 141 142 LOG(INFO) << "Using this install plan:"; 143 //一直到这里,参数终于设定完了,这个方法是install_plan.cc中的,相当于遍历输出了结构体中所有的内容 144 install_plan_.Dump(); 145 146 //4、创建升级的各种action 147 BuildUpdateActions(payload_url); 148 // Setup extra headers.设定了两个额外的参数 149 HttpFetcher* fetcher = download_action_->http_fetcher(); 150 if (!headers[kPayloadPropertyAuthorization].empty()) 151 fetcher->SetHeader("Authorization", headers[kPayloadPropertyAuthorization]); 152 if (!headers[kPayloadPropertyUserAgent].empty()) 153 fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]); 154 //5、回调给客户端当前升级状态为UPDATE_AVAILABLE 155 SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE); 156 //设定标志为正在更新 157 ongoing_update_ = true; 158 159 // Just in case we didn't update boot flags yet, make sure they're updated 160 // before any update processing starts. This will start the update process. 161 //6、更新启动分区的标识 162 UpdateBootFlags(); 163 164 UpdatePrefsOnUpdateStart(install_plan_.is_resume); 165 // TODO(xunchang) report the metrics for unresumable updates 166 167 return true; 168}
3、BuildUpdateActions(payload_url)方法
说明这个方法之前先讲解以下update_engine的Action机制和ActionProcessor类,大概了解Action之后之后的方法理解起来会容易一些
3.1 Action机制
是的,我是从网上直接copy的,因为我觉得概念总结的很全面,所以直接抄了
出处:https://blog.csdn.net/guyongqiangx/article/details/82226079
Action机制是整个Update Engine服务端进程运行的核心,不清楚Action机制,就无法了解整个Update Engine服务端是如何运作的。
Action机制主要有三个部分组成: Action, ActionProcessor和ActionPipe。
3.1.1 Action
基于Action机制,Update Engine里面的每一个任务都被封装为一个Action,例如下载任务被封装为DownloadAction, 文件系统验证的任务被封装为FilesystemVerifierAction,更新完成后所有收尾动作被封装为PostinstallRunnerAction。
当然,这个Action机制很灵活,你甚至可以根据需要定义自己特有的Action。例如,将数据解密的操作定义为DecryptAction,在DownloadAction下载完数据后需要先通过DecryptAction将数据解密,再将解密后的数据送往下一个操作。
总之,Action就是一个基本的任务单元。
Update Engine代码中,默认定义了4个Action,分别为:InstallPlanAction, DownloadAction, FilesystemVerifierAction, PostinstallRunnerAction。这些Action的名字都很直观,见名知意。
单个Action执行的时间不是固定的。例如,基于不同的网络状况,有的DownloadAction很快就可以完成,但有的DownloadAction可能需要很久。因此代码上,Action都是异步执行的,对Action调用PerformAction()使其开始工作,但这个函数返回只表明Action开始了,并不代表执行结束(有可能结束,也有可能刚开始)。
例如DownloadAction,调用PerformAction()对数据下载进行初始化设置,然后底层的数据传输开始工作,函数返回时数据传输并没有完成。在数据传输完成时底层会触发调用TransferComplete()进行通知。
3.1.2 Action Processor
既然Update Engine里定义了多个Action,那这些Action是如何组织运行的呢?此时就需要有一个Action的管理者,这就是ActionProcessor.
在ActionProcessor里面定义了一个Action的队列, 在Update Engine准备更新时,会根据当前传入的参数构造多个Action并放入ActionProcessor的Action队列。
除了Action队列,ActionProcessor中还有一个指针,用于指示当前正在运行的Action。
ActionProcessor通过StartProcessing()操作开始工作,先挑选队列中的第一个Action作为当前Action。然后当前Action调用PerformAction()开始工作,Action结束后会调用ActionProcessor的ActionComplete()接口通知当前Action已经完成。随后ActionProcessor通过StartNextActionOrFinish()挑选队列中的下一个Action进行操作。循环往复,直到队列中的所有Action都完成操作。
3.1.3 Action Pipe
类似于Unix系统的管道,Action机制中,也会通过管道ActionPipe将这些Action链接在一起。上一个Action的输出会作为下一个Action的输入。
因此在Update Engine中,所有的Action之间有一个先后关系。例如,只有DownloadAction完成操作了,才能开始FilesystemVerifierAction操作;也只有FilesystemVerifierAction结束了,才会开始PostinstallRunnerAction操作。
3.2 Action基类AbstractAction
本来是准备直接分析ActionProcessor,发现还是要从最基础的开始,相当于我们看了半天菜谱,没看食材,所以对AbstractAction做一个简单的分析,同时我们也看到了Action机制大概的概念
这里我们要注意的是,AbstractAction中定义的虚函数,每个具体的action都会重写该抽象类中的开始,停止,执行action等方法
1update_engine/common/action.h 2// 你看这注释的多详细 3// The structure of these classes (Action, ActionPipe, ActionProcessor, etc.) 4// is based on the KSAction* classes from the Google Update Engine code at 5// http://code.google.com/p/update-engine/ . The author of this file sends 6// a big thanks to that team for their high quality design, implementation, 7// and documentation. 8// 9// Readers may want to consult this wiki page from the Update Engine site: 10// http://code.google.com/p/update-engine/wiki/ActionProcessor 11// Although it's referring to the Objective-C KSAction* classes, much 12// applies here as well. 13// 14// How it works: 15// 16// First off, there is only one thread and all I/O should be asynchronous. 17// A message loop blocks whenever there is no work to be done. This happens 18// where there is no CPU work to be done and no I/O ready to transfer in or 19// out. Two kinds of events can wake up the message loop: timer alarm or file 20// descriptors. If either of these happens, the message loop finds out the owner 21// of what fired and calls the appropriate code to handle it. As such, all the 22// code in the Action* classes and the code that is calls is non-blocking. 23// 24// An ActionProcessor contains a queue of Actions to perform. When 25// ActionProcessor::StartProcessing() is called, it executes the first action. 26// Each action tells the processor when it has completed, which causes the 27// Processor to execute the next action. ActionProcessor may have a delegate 28// (an object of type ActionProcessorDelegate). If it does, the delegate 29// is called to be notified of events as they happen. 30// 31// ActionPipe classes 32// 33// See action_pipe.h 34// 35// ActionTraits 36// 37// We need to use an extra class ActionTraits. ActionTraits is a simple 38// templated class that contains only two typedefs: OutputObjectType and 39// InputObjectType. Each action class also has two typedefs of the same name 40// that are of the same type. So, to get the input/output types of, e.g., the 41// DownloadAction class, we look at the type of 42// DownloadAction::InputObjectType. 43// 44// Each concrete Action class derives from Action<T>. This means that during 45// template instantiation of Action<T>, T is declared but not defined, which 46// means that T::InputObjectType (and OutputObjectType) is not defined. 47// However, the traits class is constructed in such a way that it will be 48// template instantiated first, so Action<T> *can* find the types it needs by 49// consulting ActionTraits<T>::InputObjectType (and OutputObjectType). 50// This is why the ActionTraits classes are needed. 51 52namespace chromeos_update_engine { 53 54// It is handy to have a non-templated base class of all Actions. 55// 拥有所有Actions的非模板基类 56class AbstractAction { 57 public: 58 AbstractAction() : processor_(nullptr) {} 59 virtual ~AbstractAction() = default; 60 61 // Begin performing the action. Since this code is asynchronous, when this 62 // method returns, it means only that the action has started, not necessarily 63 // completed. However, it's acceptable for this method to perform the 64 // action synchronously; Action authors should understand the implications 65 // of synchronously performing, though, because this is a single-threaded 66 // app, the entire process will be blocked while the action performs. 67 // 68 // When the action is complete, it must call 69 // ActionProcessor::ActionComplete(this); to notify the processor that it's 70 // done. 71 // 开始执行操作。 由于此代码是异步的,因此当此方法返回时,仅意味着该动作已开始,不一定完成。 72 // 但是,此方法可以同步执行操作,这是可以接受的; 但是,动作作者应该了解同步执行的含义, 73 // 因为这是一个单线程应用程序,所以动作执行时会阻塞整个过程。 74 // 操作完成后,必须调用ActionProcessor::ActionComplete(this);通知处理器已完成。 75 virtual void PerformAction() = 0; 76 77 // Called on ActionProcess::ActionComplete() by ActionProcessor. 78 // 执行ActionProcessor的ActionProcess::ActionComplete()时调用该方法 79 virtual void ActionCompleted(ErrorCode code) {} 80 81 // Called by the ActionProcessor to tell this Action which processor 82 // it belongs to. 83 // 由ActionProcessor调用以说明这个Action属于那个processor 84 void SetProcessor(ActionProcessor* processor) { 85 if (processor) 86 CHECK(!processor_); 87 else 88 CHECK(processor_); 89 processor_ = processor; 90 } 91 92 // Returns true iff the action is the current action of its ActionProcessor. 93 // 返回true 如果这个action 是ActionProcessor的当前的action 94 bool IsRunning() const { 95 if (!processor_) 96 return false; 97 return processor_->current_action() == this; 98 } 99 100 // Called on asynchronous actions if canceled. Actions may implement if 101 // there's any cleanup to do. There is no need to call 102 // ActionProcessor::ActionComplete() because the processor knows this 103 // action is terminating. 104 // Only the ActionProcessor should call this. 105 // 只有ActionProcessor 可以调用该方法 106 virtual void TerminateProcessing() {} 107 108 // Called on asynchronous actions if the processing is suspended and resumed, 109 // respectively. These methods are called by the ActionProcessor and should 110 // not be explicitly called. 111 // The action may still call ActionCompleted() once the action is completed 112 // while the processing is suspended, for example if suspend/resume is not 113 // implemented for the given action. 114 virtual void SuspendAction() {} 115 virtual void ResumeAction() {} 116 117 // These methods are useful for debugging. TODO(adlr): consider using 118 // std::type_info for this? 119 // Type() returns a string of the Action type. I.e., for DownloadAction, 120 // Type() would return "DownloadAction". 121 virtual std::string Type() const = 0; 122 123 protected: 124 // A weak pointer to the processor that owns this Action. 125 ActionProcessor* processor_; 126}; 127 128// Forward declare a couple classes we use. 129template<typename T> 130class ActionPipe; 131template<typename T> 132class ActionTraits; 133 134//Action类继承了AbstractAction类 135//这里面涉及到Action pipe一些方法操作 136template<typename SubClass> 137class Action : public AbstractAction { 138 public: 139 ~Action() override {} 140 141 // Attaches an input pipe to this Action. This is optional; an Action 142 // doesn't need to have an input pipe. The input pipe must be of the type 143 // of object that this class expects. 144 // This is generally called by ActionPipe::Bond() 145 // 将输入管道附加到此动作。 这是可选的; 一种Action不需要输入管道。 输入管道必须为该类期望的对象。 146 // 通常由ActionPipe :: Bond()调用 147 void set_in_pipe( 148 // this type is a fancy way of saying: a shared_ptr to an 149 // ActionPipe<InputObjectType>. 150 const std::shared_ptr<ActionPipe< 151 typename ActionTraits<SubClass>::InputObjectType>>& in_pipe) { 152 in_pipe_ = in_pipe; 153 } 154 155 // Attaches an output pipe to this Action. This is optional; an Action 156 // doesn't need to have an output pipe. The output pipe must be of the type 157 // of object that this class expects. 158 // This is generally called by ActionPipe::Bond() 159 void set_out_pipe( 160 // this type is a fancy way of saying: a shared_ptr to an 161 // ActionPipe<OutputObjectType>. 162 const std::shared_ptr<ActionPipe< 163 typename ActionTraits<SubClass>::OutputObjectType>>& out_pipe) { 164 out_pipe_ = out_pipe; 165 } 166 167 // Returns true iff there is an associated input pipe. If there's an input 168 // pipe, there's an input object, but it may have been constructed with the 169 // default ctor if the previous action didn't call SetOutputObject(). 170 // 如果存在关联的输入管道,则返回true。 如果有输入管道中有一个输入对象, 171 // 但如果先前的action未调用SetOutputObject(),则可能已使用默认ctor构造了该对象。 172 bool HasInputObject() const { return in_pipe_.get(); } 173 174 // returns a const reference to the object in the input pipe. 175 // 返回对输入管道中对象的const引用。 176 const typename ActionTraits<SubClass>::InputObjectType& GetInputObject() 177 const { 178 CHECK(HasInputObject()); 179 return in_pipe_->contents(); 180 } 181 182 // Returns true iff there's an output pipe. 183 // 如果有输出管道,返回true 184 bool HasOutputPipe() const { 185 return out_pipe_.get(); 186 } 187 188 // Copies the object passed into the output pipe. It will be accessible to 189 // the next Action via that action's input pipe (which is the same as this 190 // Action's output pipe). 191 // 复制传递到输出管道中的对象,下一个动作可以通过该动作的输入管道(与该动作的输出管道相同)进行访问。 192 void SetOutputObject( 193 const typename ActionTraits<SubClass>::OutputObjectType& out_obj) { 194 CHECK(HasOutputPipe()); 195 out_pipe_->set_contents(out_obj); 196 } 197 198 // Returns a reference to the object sitting in the output pipe. 199 const typename ActionTraits<SubClass>::OutputObjectType& GetOutputObject() { 200 CHECK(HasOutputPipe()); 201 return out_pipe_->contents(); 202 } 203 204 protected: 205 // We use a shared_ptr to the pipe. shared_ptr objects destroy what they 206 // point to when the last such shared_ptr object dies. We consider the 207 // Actions on either end of a pipe to "own" the pipe. When the last Action 208 // of the two dies, the ActionPipe will die, too. 209 std::shared_ptr<ActionPipe<typename ActionTraits<SubClass>::InputObjectType>> 210 in_pipe_; 211 std::shared_ptr<ActionPipe<typename ActionTraits<SubClass>::OutputObjectType>> 212 out_pipe_; 213};
3.3 ActionProcessor类
看了这一大段概念后,很明显ActionProcessor是分析的重点
我们大概看下这个文件的代码和相关的方法定义
3.3.1 action_processor.h 分析
1update_engine/common/action_processor.h 2 3class ActionProcessor { 4 public: 5 ActionProcessor() = default; 6 7 virtual ~ActionProcessor(); 8 9 // Starts processing the first Action in the queue. If there's a delegate, 10 // when all processing is complete, ProcessingDone() will be called on the 11 // delegate. 12 // 开始处理队列中的第一个Action。 如果有代表, 13 // 当所有处理完成后,将在委托上调用ProcessingDone()。 14 // 定义开始方法 15 virtual void StartProcessing(); 16 17 // Aborts processing. If an Action is running, it will have 18 // TerminateProcessing() called on it. The Action that was running and all the 19 // remaining actions will be lost and must be re-enqueued if this Processor is 20 // to use it. 21 // 中止处理。 如果某个动作正在运行,它将具有调用TerminateProcessing()。 如果此处理器要使用它, 22 // 则正在运行的动作以及所有其他剩余动作将丢失,必须重新排队。 23 // 定义结束方法 24 void StopProcessing(); 25 26 // Suspend the processing. If an Action is running, it will have the 27 // SuspendProcessing() called on it, and it should suspend operations until 28 // ResumeProcessing() is called on this class to continue. While suspended, 29 // no new actions will be started. Calling SuspendProcessing while the 30 // processing is suspended or not running this method performs no action. 31 // 暂停处理。 如果某个Action正在运行,它将具有SuspendProcessing()对其进行了调用, 32 // 它应该挂起操作,直到对该类调用ResumeProcessing()继续。 33 // 在暂停期间,不会启动任何新动作,在处理暂停或不运行此方法时调用SuspendProcessing不会执行任何操作。 34 // 定义暂停方法 35 void SuspendProcessing(); 36 37 // Resume the suspended processing. If the ActionProcessor is not suspended 38 // or not running in the first place this method performs no action. 39 // 恢复暂停的处理。 如果ActionProcessor没有被挂起或没有首先运行,则此方法不执行任何操作。 40 // 定义恢复方法 41 void ResumeProcessing(); 42 43 // Returns true if the processing was started but not yet completed nor 44 // stopped. 45 // 定义一个判断条件,是不是正在运行或者是不是状态 46 bool IsRunning() const { return current_action_ != nullptr || suspended_; } 47 48 // Adds another Action to the end of the queue. 49 // 将Action方入队列 50 virtual void EnqueueAction(AbstractAction* action); 51 52 // Sets/gets the current delegate. Set to null to remove a delegate. 53 // 设置一个代理委托,注意,update_engine很多地方都用到了这个思路 54 ActionProcessorDelegate* delegate() const { return delegate_; } 55 void set_delegate(ActionProcessorDelegate *delegate) { 56 delegate_ = delegate; 57 } 58 59 // Returns a pointer to the current Action that's processing. 60 // 返回当前正在运行的Action 61 AbstractAction* current_action() const { 62 return current_action_; 63 } 64 65 // Called by an action to notify processor that it's done. Caller passes self. 66 // Action完成后通知ActionProcessor完成了 67 void ActionComplete(AbstractAction* actionptr, ErrorCode code); 68 69 private: 70 // Continue processing actions (if any) after the last action terminated with 71 // the passed error code. If there are no more actions to process, the 72 // processing will terminate. 73 // 在上一个操作以传递的错误代码终止后,继续处理操作(如果有)。 74 // 如果没有更多要处理的操作,则处理将终止。 75 // 定义继续下一个Action还是结束的方法 76 void StartNextActionOrFinish(ErrorCode code); 77 78 // Actions that have not yet begun processing, in the order in which 79 // they'll be processed. 80 // Action还没有开始处理,定义一个对接,放入 81 std::deque<AbstractAction*> actions_; 82 83 // A pointer to the currently processing Action, if any. 84 // 定义一个指针指向正在运行的Action 85 AbstractAction* current_action_{nullptr}; 86 87 // The ErrorCode reported by an action that was suspended but finished while 88 // being suspended. This error code is stored here to be reported back to the 89 // delegate once the processor is resumed. 90 // 由已暂停但在被暂停时完成的操作报告的ErrorCode。 91 // 此错误代码存储在此处,一旦处理器恢复,便会报告给委托人。 92 ErrorCode suspended_error_code_{ErrorCode::kSuccess}; 93 94 // Whether the action processor is or should be suspended. 95 // 定义一个标志位,判断时候暂停状态 96 bool suspended_{false}; 97 98 // A pointer to the delegate, or null if none. 99 // 定义委托的指针 100 ActionProcessorDelegate* delegate_{nullptr}; 101 102 DISALLOW_COPY_AND_ASSIGN(ActionProcessor); 103}; 104 105// A delegate object can be used to be notified of events that happen 106// in an ActionProcessor. An instance of this class can be passed to an 107// ActionProcessor to register itself. 108// 可以使用委托对象来通知发生的事件在ActionProcessor中。 此类的实例可以传递给ActionProcessor自行注册。 109// updateAttempter继承了ActionProcessorDelegate,所以会重写它的三个方法 110// 其实这个类的定义是我设置一个委托,在ActionProcessor中进行注册,这样用委托调用ActionProcessor的方法 111// 这样我可以调用到processtor的方法,也可以定义一些与外部类交互的方法,例如Action完成或者停止给客户端返回状态 112class ActionProcessorDelegate { 113 public: 114 virtual ~ActionProcessorDelegate() = default; 115 116 // Called when all processing in an ActionProcessor has completed. A pointer 117 // to the ActionProcessor is passed. |code| is set to the exit code of the 118 // last completed action. 119 // 当ActionProcessor中的所有处理完成时调用。 指向ActionProcessor的指针被传递。 120 // |代码| 设置为最后完成的操作的退出代码。 121 virtual void ProcessingDone(const ActionProcessor* processor, 122 ErrorCode code) {} 123 124 // Called when processing has stopped. Does not mean that all Actions have 125 // completed. If/when all Actions complete, ProcessingDone() will be called. 126 // 处理停止时调用。 并不意味着所有动作均已完成。 如果/当所有动作完成时,将调用ProcessingDone 127 virtual void ProcessingStopped(const ActionProcessor* processor) {} 128 129 // Called whenever an action has finished processing, either successfully 130 // or otherwise. 131 // 每当动作完成时调用,不管是成功或者其他 132 virtual void ActionCompleted(ActionProcessor* processor, 133 AbstractAction* action, 134 ErrorCode code) {} 135};
这里做一个简单的总结
定义ActionProcessor类 作为Action管理类,其中包含
Action放入队列
Action启动停止:StartProcessing StopProcessing
Action暂停恢复:SuspendProcessing ResumeProcessing
Action 完成和进行下一个:ActionComplete StartNextActionOrFinish
设置委托类:set_delegate
定义判定条件是否正在运行:IsRunning()
定义判断条件是否暂停状态:suspended_
定义ActionProcessorDelegate委托类
处理完成:ProcessingDone
处理停止:ProcessingStopped
Action完成:ActionCompleted
查看了大概的方法分类,我们去action_processor.cc文件中看下这些方法具体的实现
3.3.2 action_processor.cc文件分析
上面分析action_processor.h文件,下面.cc文件把大致的方法做了下讲解
1update_engine/common/action_processor.h 2 3ActionProcessor::~ActionProcessor() { 4 if (IsRunning()) 5 StopProcessing(); 6 for (auto action : actions_) 7 action->SetProcessor(nullptr); 8} 9 10//放入队列,actions_是存放adction的deque 11void ActionProcessor::EnqueueAction(AbstractAction* action) { 12 //将传入的action放入队列尾部 13 actions_.push_back(action); 14 //将现在的ActionProcessor 设置为action的ActionProcessor 15 action->SetProcessor(this); 16} 17 18//https://www.cnblogs.com/linuxAndMcu/p/10260124.html 关于C++ qedue的一些操作函数介绍 19//开始处理action 20void ActionProcessor::StartProcessing() { 21 //检查是不是当前没有运行 22 CHECK(!IsRunning()); 23 //判断action对列中时候有action 24 if (!actions_.empty()) { 25 //从对接中取出第一个作为当前的action 26 current_action_ = actions_.front(); 27 LOG(INFO) << "ActionProcessor: starting " << current_action_->Type(); 28 //删除队列中的第一个元素,因为已经取出来了,所以删除了 29 actions_.pop_front(); 30 //执行当前action 31 current_action_->PerformAction(); 32 } 33} 34//停止处理action 35void ActionProcessor::StopProcessing() { 36 //检查是不是正在运行 37 CHECK(IsRunning()); 38 //如果当前action存在 39 if (current_action_) { 40 //停止当前处理 41 current_action_->TerminateProcessing(); 42 //不再与当前ActionProcessor关联 43 current_action_->SetProcessor(nullptr); 44 } 45 LOG(INFO) << "ActionProcessor: aborted " 46 << (current_action_ ? current_action_->Type() : "") 47 << (suspended_ ? " while suspended" : ""); 48 //设置当前action为空,设置suspended标志位为false 49 current_action_ = nullptr; 50 suspended_ = false; 51 // Delete all the actions before calling the delegate. 52 // 清空action队列 53 for (auto action : actions_) 54 action->SetProcessor(nullptr); 55 actions_.clear(); 56 //如果委托对象存在,调用委托对象的ProcessingStopped方法 57 //实际这里调用的就是UpdateAttempterAndroid的ProcessingStopped方法 58 if (delegate_) 59 delegate_->ProcessingStopped(this); 60} 61//暂停处理action 62void ActionProcessor::SuspendProcessing() { 63 // No current_action_ when not suspended means that the action processor was 64 // never started or already finished. 65 // 没有current_action_存在,说明processor没有启动或者已经结束,调用暂停就没有意义了 66 // 如果suspended_标志位是true,说明已经是暂停状态,直接return 67 if (suspended_ || !current_action_) { 68 LOG(WARNING) << "Called SuspendProcessing while not processing."; 69 return; 70 } 71 //设定暂停标志位为true 72 suspended_ = true; 73 74 // If there's a current action we should notify it that it should suspend, but 75 // the action can ignore that and terminate at any point. 76 // 暂停当前action 77 LOG(INFO) << "ActionProcessor: suspending " << current_action_->Type(); 78 current_action_->SuspendAction(); 79} 80//恢复处理action 81void ActionProcessor::ResumeProcessing() { 82 //如果suspended_就为false,说明没有暂停过,所以无需执行恢复操作 83 if (!suspended_) { 84 LOG(WARNING) << "Called ResumeProcessing while not suspended."; 85 return; 86 } 87 //设定暂停标志位为false 88 suspended_ = false; 89 //如果存在当前action 90 if (current_action_) { 91 // The current_action_ did not call ActionComplete while suspended, so we 92 // should notify it of the resume operation. 93 LOG(INFO) << "ActionProcessor: resuming " << current_action_->Type(); 94 //执行恢复action操作 95 current_action_->ResumeAction(); 96 } else { 97 // The last action called ActionComplete while suspended, so there is 98 // already a log message with the type of the finished action. We simply 99 // state that we are resuming processing and the next function will log the 100 // start of the next action or processing completion. 101 LOG(INFO) << "ActionProcessor: resuming processing"; 102 //如果没有当前action,说明或者当前action处理完了,或者结束了 103 StartNextActionOrFinish(suspended_error_code_); 104 } 105} 106//action完成的操作 107void ActionProcessor::ActionComplete(AbstractAction* actionptr, 108 ErrorCode code) { 109 CHECK_EQ(actionptr, current_action_); 110 //如果委托对象存在 111 if (delegate_) 112 //执行委托对象的ActionCompleted,这里就是UpdateAttempterAndroid类的方法 113 delegate_->ActionCompleted(this, actionptr, code); 114 string old_type = current_action_->Type(); 115 //执行action的ActionCompleted 116 current_action_->ActionCompleted(code); 117 current_action_->SetProcessor(nullptr); 118 //设置当前action为空 119 current_action_ = nullptr; 120 LOG(INFO) << "ActionProcessor: finished " 121 << (actions_.empty() ? "last action " : "") << old_type 122 << (suspended_ ? " while suspended" : "") 123 << " with code " << utils::ErrorCodeToString(code); 124 //如果action_对列中还有action而且结果不是成功 125 if (!actions_.empty() && code != ErrorCode::kSuccess) { 126 LOG(INFO) << "ActionProcessor: Aborting processing due to failure."; 127 //清空action_对列 128 actions_.clear(); 129 } 130 //如果当前的已经执行完了,而且还是暂停状态,那就不用再执行下一个action,直接return 131 if (suspended_) { 132 // If an action finished while suspended we don't start the next action (or 133 // terminate the processing) until the processor is resumed. This condition 134 // will be flagged by a nullptr current_action_ while suspended_ is true. 135 suspended_error_code_ = code; 136 return; 137 } 138 //执行下一个action 139 StartNextActionOrFinish(code); 140} 141//执行下一个action或者结束 142void ActionProcessor::StartNextActionOrFinish(ErrorCode code) { 143 //如果action_为空 144 if (actions_.empty()) { 145 //执行delegate_也就是updateAttempterAndroid的方法ProcessingDone 146 if (delegate_) { 147 delegate_->ProcessingDone(this, code); 148 } 149 return; 150 } 151 //如果不为空,继续取出队列中的第一个作为当前的action 152 current_action_ = actions_.front(); 153 //删除队列中的第一个元素 154 actions_.pop_front(); 155 LOG(INFO) << "ActionProcessor: starting " << current_action_->Type(); 156 //执行具体的action业务 157 current_action_->PerformAction(); 158}
3.4 BuildUpdateAction方法分析
前面讲了一堆action相关的,再来看这个方法就比较好理解了
1//创建各类升级相关的action 2void UpdateAttempterAndroid::BuildUpdateActions(const string& url) { 3 //检查是不是没有执行action 4 CHECK(!processor_->IsRunning()); 5 //1、将自身设置为委托对象,updateAttempterAndroid继承了ActionProcessorDelegate 6 processor_->set_delegate(this); 7 8 // Actions: 9 // 2、构建install_plan_action 10 shared_ptr<InstallPlanAction> install_plan_action( 11 new InstallPlanAction(install_plan_)); 12 // 3、选择Http协议 13 HttpFetcher* download_fetcher = nullptr; 14 if (FileFetcher::SupportedUrl(url)) { 15 DLOG(INFO) << "Using FileFetcher for file URL."; 16 download_fetcher = new FileFetcher(); 17 } else { 18#ifdef _UE_SIDELOAD 19 LOG(FATAL) << "Unsupported sideload URI: " << url; 20#else 21 LibcurlHttpFetcher* libcurl_fetcher = 22 new LibcurlHttpFetcher(&proxy_resolver_, hardware_); 23 libcurl_fetcher->set_server_to_check(ServerToCheck::kDownload); 24 download_fetcher = libcurl_fetcher; 25#endif // _UE_SIDELOAD 26 } 27 // 4、构建download_action 28 shared_ptr<DownloadAction> download_action( 29 new DownloadAction(prefs_, 30 boot_control_, 31 hardware_, 32 nullptr, // system_state, not used. 33 download_fetcher, // passes ownership 34 true /* is_interactive */)); 35 // 5、构建filesystem_verifier_action 36 shared_ptr<FilesystemVerifierAction> filesystem_verifier_action( 37 new FilesystemVerifierAction()); 38 // 6、构建PostinstallRunnerAction 39 shared_ptr<PostinstallRunnerAction> postinstall_runner_action( 40 new PostinstallRunnerAction(boot_control_, hardware_)); 41 42 download_action->set_delegate(this); 43 download_action->set_base_offset(base_offset_); 44 download_action_ = download_action; 45 postinstall_runner_action->set_delegate(this); 46 47 // 7、放入action_队列 48 actions_.push_back(shared_ptr<AbstractAction>(install_plan_action)); 49 actions_.push_back(shared_ptr<AbstractAction>(download_action)); 50 actions_.push_back(shared_ptr<AbstractAction>(filesystem_verifier_action)); 51 actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action)); 52 53 // Bond them together. We have to use the leaf-types when calling 54 // BondActions(). 55 // 8、使用管道连接各个action 56 BondActions(install_plan_action.get(), download_action.get()); 57 BondActions(download_action.get(), filesystem_verifier_action.get()); 58 BondActions(filesystem_verifier_action.get(), 59 postinstall_runner_action.get()); 60 61 // Enqueue the actions 62 // 将action放入队列 63 for (const shared_ptr<AbstractAction>& action : actions_) 64 processor_->EnqueueAction(action.get()); 65}
4、UpdateBootFlags()方法
从这个方法的调用逻辑可以看出,在执行最后做了一个认为是安全保险的操作,将当前分区标记为成功启动分区,
然后开始了StartProcessing处理各种action
1//更新启动分区的标识 2void UpdateAttempterAndroid::UpdateBootFlags() { 3 //判断updated_boot_flags_不熬只为是否为true 4 if (updated_boot_flags_) { 5 LOG(INFO) << "Already updated boot flags. Skipping."; 6 //调用CompleteUpdateBootFlags 方法 7 CompleteUpdateBootFlags(true); 8 return; 9 } 10 // This is purely best effort. 11 LOG(INFO) << "Marking booted slot as good."; 12 // 如果updated_boot_flags_为false,调用boot_control_的MarkBootSuccessfulAsync方法 13 // 将当前启动分区标记为成功启动分区 14 if (!boot_control_->MarkBootSuccessfulAsync( 15 Bind(&UpdateAttempterAndroid::CompleteUpdateBootFlags, 16 base::Unretained(this)))) { 17 LOG(ERROR) << "Failed to mark current boot as successful."; 18 //调用CompleteUpdateBootFlags方法 19 CompleteUpdateBootFlags(false); 20 } 21} 22//更新标志位updated_boot_flags_,开始执行处理 23void UpdateAttempterAndroid::CompleteUpdateBootFlags(bool successful) { 24 updated_boot_flags_ = true; 25 ScheduleProcessingStart(); 26} 27//开始执行处理 28void UpdateAttempterAndroid::ScheduleProcessingStart() { 29 LOG(INFO) << "Scheduling an action processor start."; 30 //执行StartProcessing(),开启action处理 31 brillo::MessageLoop::current()->PostTask( 32 FROM_HERE, 33 Bind([](ActionProcessor* processor) { processor->StartProcessing(); }, 34 base::Unretained(processor_.get()))); 35}
上面的最主要核心的部分已经说明完了,下面我们按继承的父类区分,分别介绍重写的方法
5、重写父类ServiceDelegateAndroidInterface的方法
1//暂停升级 2bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) { 3 if (!ongoing_update_) 4 return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend."); 5 //调用ActionProcessor的暂停处理方法 6 processor_->SuspendProcessing(); 7 return true; 8} 9//继续升级 10bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) { 11 if (!ongoing_update_) 12 return LogAndSetError(error, FROM_HERE, "No ongoing update to resume."); 13 //调用ActionProcessor的恢复处理方法 14 processor_->ResumeProcessing(); 15 return true; 16} 17//取消升级 18bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) { 19 if (!ongoing_update_) 20 return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel."); 21 调用ActionProcessor的停止处理方法 22 processor_->StopProcessing(); 23 return true; 24} 25//重置状态,判断升级状态,重置为IDIE状态 26bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) { 27 LOG(INFO) << "Attempting to reset state from " 28 << UpdateStatusToString(status_) << " to UpdateStatus::IDLE"; 29 //根据status_的当前状态做相应的重置操作 30 switch (status_) { 31 //如果已经是IDIE状态,那么不用处理,直接return 32 case UpdateStatus::IDLE: 33 return true; 34 //如果是升级完成 需要重启的状态 35 case UpdateStatus::UPDATED_NEED_REBOOT: { 36 // Remove the reboot marker so that if the machine is rebooted 37 // after resetting to idle state, it doesn't go back to 38 // UpdateStatus::UPDATED_NEED_REBOOT state. 39 // 清除kPrefsUpdateCompletedOnBootId的标记 40 bool ret_value = prefs_->Delete(kPrefsUpdateCompletedOnBootId); 41 ClearMetricsPrefs(); 42 43 // Update the boot flags so the current slot has higher priority. 44 //更新boot标记,将当前分区设置为正常启动分区 45 if (!boot_control_->SetActiveBootSlot(boot_control_->GetCurrentSlot())) 46 ret_value = false; 47 48 // Mark the current slot as successful again, since marking it as active 49 // may reset the successful bit. We ignore the result of whether marking 50 // the current slot as successful worked. 51 //再次通过异步操作,将当前分区标记为正常启动分区 52 if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful){}))) 53 ret_value = false; 54 55 if (!ret_value) { 56 return LogAndSetError( 57 error, 58 FROM_HERE, 59 "Failed to reset the status to "); 60 } 61 //通知客户端重置成功,已经设置为了IDIE状态 62 SetStatusAndNotify(UpdateStatus::IDLE); 63 LOG(INFO) << "Reset status successful"; 64 return true; 65 } 66 //如果是其他状态,不允许重置的操作,需要先取消正在进行的升级 67 default: 68 return LogAndSetError( 69 error, 70 FROM_HERE, 71 "Reset not allowed in this state. Cancel the ongoing update first"); 72 } 73} 74 75bool UpdateAttempterAndroid::VerifyPayloadApplicable 76//TODO
可以看出这些方法其实就是调用了相应的ActionProcessor的对应方法进行处理
6、重写父类ActionProcessorDelegate的方法
1//该方法由ActionProcessor::StartNextActionOrFinish调用,执行子类重写的方法, 2//action队列为空的时候,那就是要么升级成功跑完了,要么报错了 3void UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor, 4 ErrorCode code) { 5 LOG(INFO) << "Processing Done."; 6 //根据传入的errorcode 判断 7 switch (code) { 8 //如果是升级成功,写入升级成功的标记 9 case ErrorCode::kSuccess: 10 // Update succeeded. 11 WriteUpdateCompletedMarker(); 12 prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0); 13 14 LOG(INFO) << "Update successfully applied, waiting to reboot."; 15 break; 16 //如果是升级失败了,那就重置升级 17 case ErrorCode::kFilesystemCopierError: 18 case ErrorCode::kNewRootfsVerificationError: 19 case ErrorCode::kNewKernelVerificationError: 20 case ErrorCode::kFilesystemVerifierError: 21 case ErrorCode::kDownloadStateInitializationError: 22 // Reset the ongoing update for these errors so it starts from the 23 // beginning next time. 24 DeltaPerformer::ResetUpdateProgress(prefs_, false); 25 LOG(INFO) << "Resetting update progress."; 26 break; 27 //如果是payload时间戳错误,写入错误并停止 28 case ErrorCode::kPayloadTimestampError: 29 // SafetyNet logging, b/36232423 30 android_errorWriteLog(0x534e4554, "36232423"); 31 break; 32 33 default: 34 // Ignore all other error codes. 35 break; 36 } 37 //终止升级并进行通知 38 TerminateUpdateAndNotify(code); 39} 40 41//由ActionProcessor::StopProcessing调用 42void UpdateAttempterAndroid::ProcessingStopped( 43 const ActionProcessor* processor) { 44 //终止升级并进行通知,使用的errorcode为用户取消 45 TerminateUpdateAndNotify(ErrorCode::kUserCanceled); 46} 47 48//由ActionProcessor::ActionComplete调用 49void UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor, 50 AbstractAction* action, 51 ErrorCode code) { 52 // Reset download progress regardless of whether or not the download 53 // action succeeded. 54 //重置download_progress为0 不管是否升级成功了 55 const string type = action->Type(); 56 if (type == DownloadAction::StaticType()) { 57 download_progress_ = 0; 58 } 59 if (type == PostinstallRunnerAction::StaticType()) { 60 bool succeeded = 61 code == ErrorCode::kSuccess || code == ErrorCode::kUpdatedButNotActive; 62 prefs_->SetBoolean(kPrefsPostInstallSucceeded, succeeded); 63 } 64 //如果不是成功状态,ActionProcessor会取消整个过程 65 if (code != ErrorCode::kSuccess) { 66 // If an action failed, the ActionProcessor will cancel the whole thing. 67 return; 68 } 69 //通知客户端升级状态 70 if (type == DownloadAction::StaticType()) { 71 SetStatusAndNotify(UpdateStatus::FINALIZING); 72 } 73}
这三个方法,是根据ActionProcessor的相关处理通知客户端和其他模块进行相应的状态更新
7、重写父类DownloadAction和PostinstallRunnerAction的方法
这部分我准备分析完action的时候再加上去,而且其实只有两个方法用到了,有两个是空方法
1void UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed, 2 uint64_t bytes_received, 3 uint64_t total) { 4 double progress = 0; 5 if (total) 6 progress = static_cast<double>(bytes_received) / static_cast<double>(total); 7 if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) { 8 download_progress_ = progress; 9 SetStatusAndNotify(UpdateStatus::DOWNLOADING); 10 } else { 11 ProgressUpdate(progress); 12 } 13 14 // Update the bytes downloaded in prefs. 15 int64_t current_bytes_downloaded = 16 metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_); 17 int64_t total_bytes_downloaded = 18 metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_); 19 prefs_->SetInt64(kPrefsCurrentBytesDownloaded, 20 current_bytes_downloaded + bytes_progressed); 21 prefs_->SetInt64(kPrefsTotalBytesDownloaded, 22 total_bytes_downloaded + bytes_progressed); 23} 24 25bool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) { 26 // TODO(deymo): Notify the DownloadAction that it should cancel the update 27 // download. 28 return false; 29} 30 31void UpdateAttempterAndroid::DownloadComplete() { 32 // Nothing needs to be done when the download completes. 33} 34 35void UpdateAttempterAndroid::ProgressUpdate(double progress) { 36 // Self throttle based on progress. Also send notifications if progress is 37 // too slow. 38 if (progress == 1.0 || 39 progress - download_progress_ >= kBroadcastThresholdProgress || 40 TimeTicks::Now() - last_notify_time_ >= 41 TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) { 42 download_progress_ = progress; 43 SetStatusAndNotify(status_); 44 } 45}
8、TerminateUpdateAndNotify方法
1//终止升级,并发送相关的通知 2void UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) { 3 //如果升级状态是空闲状态,那表明升级没进行,调用这个方法也没什么意义 4 if (status_ == UpdateStatus::IDLE) { 5 LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called."; 6 return; 7 } 8 //设置下载进度为0 9 download_progress_ = 0; 10 //清空action队列 11 actions_.clear(); 12 //根据升级的errorcode进行判断,如果成功,则使用状态UPDATED_NEED_REBOOT 13 UpdateStatus new_status = 14 (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT 15 : UpdateStatus::IDLE); 16 //发送通知给到客户段,目前的升级进度 17 SetStatusAndNotify(new_status); 18 // 设定正在升级标志位为false 19 ongoing_update_ = false; 20 21 // The network id is only applicable to one download attempt and once it's 22 // done the network id should not be re-used anymore. 23 // 该网络ID仅适用于一次下载尝试,一旦完成,该网络ID将不能再次使用 24 if (!network_selector_->SetProcessNetwork(kDefaultNetworkId)) { 25 LOG(WARNING) << "Unable to unbind network."; 26 } 27 //发送给客户端升级的结果 28 for (auto observer : daemon_state_->service_observers()) 29 observer->SendPayloadApplicationComplete(error_code); 30 31 CollectAndReportUpdateMetricsOnUpdateFinished(error_code); 32 ClearMetricsPrefs(); 33 if (error_code == ErrorCode::kSuccess) { 34 metrics_utils::SetSystemUpdatedMarker(clock_.get(), prefs_); 35 // Clear the total bytes downloaded if and only if the update succeeds. 36 prefs_->SetInt64(kPrefsTotalBytesDownloaded, 0); 37 } 38}
好了到目前为止基本上这个文件里所有的流程我们大概跑了一遍,其中有一些我们其实没有分析到,prefs_和boot_control_的方法,不过并不影响我们的主要升级流程的分析,这两个都是设置了分区相关的标志位,下一篇开始分析各种action的,别问,问就是重点