五、A/B 升级update_engine分析-UpdateAttempterAndroid

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
NOTE: > Executing update_desktop_database intercept ... NOTE: > Executing update_gtk_immodules_cache intercept ... NOTE: Exit code 1. Output: /home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/intercept_scripts-b51052418cd1de15aa19deeae9844eade47e1e2e32985d114ac9c6c1afe994aa/update_gtk_immodules_cache: line 15: /home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/rootfs/usr/lib64/gtk-3.0/3.0.0/immodules.cache: No such file or directory chown: cannot access '/home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/rootfs/usr/lib64/gtk-3.0/3.0.0/immodules.cache': No such file or directory ERROR: The postinstall intercept hook 'update_gtk_immodules_cache' failed, details in /home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/temp/log.do_rootfs NOTE: > Executing update_desktop_database intercept ... NOTE: > Executing update_gtk_immodules_cache intercept ... NOTE: Exit code 1. Output: /home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/intercept_scripts-b51052418cd1de15aa19deeae9844eade47e1e2e32985d114ac9c6c1afe994aa/update_gtk_immodules_cache: line 15: /home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/rootfs/usr/lib64/gtk-3.0/3.0.0/immodules.cache: No such file or directory chown: cannot access '/home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/rootfs/usr/lib64/gtk-3.0/3.0.0/immodules.cache': No such file or directory ERROR: The postinstall intercept hook 'update_gtk_immodules_cache' failed, details in /home/wu/g2l/build-niicl-nom-r001l/tmp/work/nom_r001l-niic-linux/core-image-weston/1.0-r0/temp/log.do_rootfs DEBUG: Python function do_rootfs finished如何解决
07-20

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值