上一篇我们讲到了服务端启动的流程,本篇主要讲解主要升级流程,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.youkuaiyun.com/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的,别问,问就是重点

本文深入解析了UpdateAttempterAndroid类在Android系统中的升级流程,包括服务启动、主要升级流程、Action机制及各Action的创建与执行,强调了ActionProcessor在升级过程中的核心作用。
3985





