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

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

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

    上一篇我们讲到了服务端启动的流程,本篇主要讲解主要升级流程,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、更新启动分区的标

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值