四、A/B 升级update_engine分析-服务端启动

update_engine简介 近期猛然发现公司的项目都已经换成了AB升级,AB升级之前一直有所了解,只是一直都没有去仔细查看过其具体升级流程,这两天捋了捋,简单整理下。 AB升级(谷歌官网叫法无缝更新)是自android7.0开始新增的一种android设备升级方式,只是这种方式对设备存储要求高,所以之前没有怎么被国内手机厂商采用。 简而言之:系统同时存在两套system分区,一套处于休眠状态不可使用,一套处于使用状态,两者通过slot的概念来做区分,在设备启动引导阶段通过特殊标记位确定启动哪个system,当有可用升级版本时候,客 阅读详情

    以下我们将分析AB升级的核心内容 update_engine服务端,我们还是一样,看下该模块的编译文件和依赖。

一、相关依赖

 1LOCAL_MODULE := update_engine
 2LOCAL_SRC_FILES := \
 3    main.cc
 4LOCAL_STATIC_LIBRARIES += \
 5    libupdate_engine_android \
 6    $(ue_libupdate_engine_android_exported_static_libraries:-host=)
 7LOCAL_SHARED_LIBRARIES += \
 8    $(ue_libupdate_engine_android_exported_shared_libraries:-host=)
 9endif  # local_use_omaha == 1
10
11LOCAL_INIT_RC := update_engine.rc
12include $(BUILD_EXECUTABLE)

 

 1# libupdate_engine_android (type: static_library)
 2# ========================================================
 3# The main daemon static_library used in Android (non-Brillo). This only has a
 4# loop to apply payloads provided by the upper layer via a Binder interface.
 5ue_libupdate_engine_android_exported_static_libraries := \
 6    libpayload_consumer \
 7    libfs_mgr \
 8    libbase \
 9    liblog \
10    $(ue_libpayload_consumer_exported_static_libraries) \
11    libupdate_engine_boot_control \
12    $(ue_libupdate_engine_boot_control_exported_static_libraries)
13ue_libupdate_engine_android_exported_shared_libraries := \
14    $(ue_libpayload_consumer_exported_shared_libraries) \
15    $(ue_libupdate_engine_boot_control_exported_shared_libraries) \
16    libandroid_net \
17    libbinder \
18    libbinderwrapper \
19    libbrillo-binder \
20    libcutils \
21    libcurl \
22    libmetricslogger \
23    libssl \
24    libutils
25
26include $(CLEAR_VARS)
27LOCAL_MODULE := libupdate_engine_android
28LOCAL_MODULE_CLASS := STATIC_LIBRARIES
29LOCAL_CPP_EXTENSION := .cc
30LOCAL_CFLAGS := $(ue_common_cflags)
31LOCAL_CPPFLAGS := $(ue_common_cppflags)
32LOCAL_LDFLAGS := $(ue_common_ldflags)
33LOCAL_C_INCLUDES := \
34    $(ue_common_c_includes) \
35    bootable/recovery
36#TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved
37# out of the DBus interface.
38LOCAL_C_INCLUDES += \
39    external/cros/system_api/dbus
40LOCAL_STATIC_LIBRARIES := \
41    $(ue_common_static_libraries) \
42    $(ue_libupdate_engine_android_exported_static_libraries:-host=)
43LOCAL_SHARED_LIBRARIES += \
44    $(ue_common_shared_libraries) \
45    $(ue_libupdate_engine_android_exported_shared_libraries:-host=)
46LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder_bindings
47LOCAL_SRC_FILES += \
48    binder_bindings/android/os/IUpdateEngine.aidl \
49    binder_bindings/android/os/IUpdateEngineCallback.aidl \
50    binder_service_android.cc \
51    certificate_checker.cc \
52    daemon.cc \
53    daemon_state_android.cc \
54    hardware_android.cc \
55    libcurl_http_fetcher.cc \
56    metrics_reporter_android.cc \
57    metrics_utils.cc \
58    network_selector_android.cc \
59    proxy_resolver.cc \
60    update_attempter_android.cc \
61    update_status_utils.cc \
62    utils_android.cc
63include $(BUILD_STATIC_LIBRARY)

可以看出update_engine模块编译了main.cc文件,而其他编译相关文件都在所依赖静态库libupdate_engine_android中,我们分析可执行程序也是从main函数开始,从main.cc开始入手吧,

二、main函数分析

 1system/update_engine/main.cc
 2
 3int main(int argc, char** argv) {
 4  DEFINE_bool(logtofile, false, "Write logs to a file in log_dir.");
 5  DEFINE_bool(logtostderr, false,
 6              "Write logs to stderr instead of to a file in log_dir.");
 7  DEFINE_bool(foreground, false,
 8              "Don't daemon()ize; run in foreground.");
 9  //初始化Terminator
10  chromeos_update_engine::Terminator::Init();
11  //初始化传入的参数
12  brillo::FlagHelper::Init(argc, argv, "Chromium OS Update Engine");
13  
14  //重定向log位置
15  // We have two logging flags "--logtostderr" and "--logtofile"; and the logic
16  // to choose the logging destination is:
17  // 1. --logtostderr --logtofile -> logs to both
18  // 2. --logtostderr             -> logs to system debug
19  // 3. --logtofile or no flags   -> logs to file
20  bool log_to_system = FLAGS_logtostderr;
21  bool log_to_file = FLAGS_logtofile || !FLAGS_logtostderr;
22  chromeos_update_engine::SetupLogging(log_to_system, log_to_file);
23  if (!FLAGS_foreground)
24    PLOG_IF(FATAL, daemon(0, 0) == 1) << "daemon() failed";
25
26  LOG(INFO) << "Chrome OS Update Engine starting";
27
28  // xz-embedded requires to initialize its CRC-32 table once on startup.
29  xz_crc32_init();
30
31  // Ensure that all written files have safe permissions.
32  // This is a mask, so we _block_ all permissions for the group owner and other
33  // users but allow all permissions for the user owner. We allow execution
34  // for the owner so we can create directories.
35  // Done _after_ log file creation.
36  umask(S_IRWXG | S_IRWXO);
37  //创建UpdateEngineDaemon 对象
38  chromeos_update_engine::UpdateEngineDaemon update_engine_daemon;
39  //调用UpdateEngineDaemon 的Run方法
40  int exit_code = update_engine_daemon.Run();
41
42  LOG(INFO) << "Chrome OS Update Engine terminating with exit code "
43            << exit_code;
44  return exit_code;
45}

update_engine_daemon.Run();  UpdateEngineDaemon类

 1system/update_engine/daemon.h
 2
 3//命名空间chromeos_update_engine
 4namespace chromeos_update_engine {
 5//继承brillo::Daemon 与客户端继承的父类相同
 6class UpdateEngineDaemon : public brillo::Daemon {
 7 public:
 8  UpdateEngineDaemon() = default;
 9
10 protected:
11  int OnInit() override;
12  
13//没有这个宏定义,所以不用关注这里
14 private:
15#if USE_DBUS
16  // Run from the main loop when the |dbus_adaptor_| object is registered. At
17  // this point we can request ownership of the DBus service name and continue
18  // initialization.
19  void OnDBusRegistered(bool succeeded);
20
21  // Main D-Bus service adaptor.
22  std::unique_ptr<UpdateEngineAdaptor> dbus_adaptor_;
23#endif  // USE_DBUS
24
25  // The Subprocess singleton class requires a brillo::MessageLoop in the
26  // current thread, so we need to initialize it from this class instead of
27  // the main() function.
28  Subprocess subprocess_;
29
30#if USE_BINDER //定义binder_watcher_指针
31  brillo::BinderWatcher binder_watcher_;
32#endif  // USE_BINDER
33
34#if USE_BINDER
35#if USE_OMAHA
36  android::sp<BinderUpdateEngineBrilloService> binder_service_;
37#else  // !USE_OMAHA //定义binder_service_指针
38  android::sp<BinderUpdateEngineAndroidService> binder_service_;
39#endif  // USE_OMAHA
40#endif  // USE_BINDER
41
42  // The daemon state with all the required daemon classes for the configured
43  // platform.定义daemon_state_指针
44  std::unique_ptr<DaemonStateInterface> daemon_state_;
45
46  DISALLOW_COPY_AND_ASSIGN(UpdateEngineDaemon);
47};
48
49}  // namespace chromeos_update_engine
50
51#endif  // UPDATE_ENGINE_DAEMON_H_

由于子类没有定义Run方法,所以会调用父类的方法

 1external/libbrillo/brillo/daemons/daemon.cc
 2int Daemon::Run() {
 3  //执行onint方法,获得返回值exit_code
 4  int exit_code = OnInit();
 5  if (exit_code != EX_OK)
 6    return exit_code;
 7  //开启消息处理循环
 8  message_loop_.Run();
 9  //空方法,不用管
10  OnShutdown(&exit_code_);
11
12  // base::RunLoop::QuitClosure() causes the message loop to quit
13  // immediately, even if pending tasks are still queued.
14  // Run a secondary loop to make sure all those are processed.
15  // This becomes important when working with D-Bus since dbus::Bus does
16  // a bunch of clean-up tasks asynchronously when shutting down.
17  //base :: RunLoop :: QuitClosure()导致消息循环退出 即使待处理的任务仍在排队,也要立即运行。
18  //运行辅助循环以确保所有这些任务都得到处理。这在使用D-Bus时非常重要,
19  //因为dbus :: Bus在关闭时会异步执行大量清理任务。
20  //等待消息退出
21  while (message_loop_.RunOnce(false /* may_block */)) {}
22  //返回onint结果exit_code
23  return exit_code_;
24}

执行Oninit(),因为父类的OnInit定义为虚函数,所以会执行子类的方法,这里大致的流程如下:

system/update_engine/main.cc   update_engine_daemon.Run()

-->> external/libbrillo/brillo/daemons/daemon.cc int Daemon::Run()

-->> external/libbrillo/brillo/daemons/daemon.cc int Daemon::OnInit()

-->> system/update_engine/daemon.h int OnInit() override;

-->> system/update_engine/daemon.cc init OnInit()

所以我们需要关注的是UpdateEngineDaemon 实现类 daemon.cc的代码

 1int UpdateEngineDaemon::OnInit() {
 2  // Register the |subprocess_| singleton with this Daemon as the signal
 3  // handler.注册| subprocess_ | 以该守护程序作为信号的单例handler。
 4  subprocess_.Init(this);
 5  //调用父类Daemon::OnInit()方法注册 信号SIGINT 和 信号SIGHUP
 6  int exit_code = Daemon::OnInit();
 7  if (exit_code != EX_OK)
 8    return exit_code;
 9
10#if USE_BINDER //binder_watcher_初始化
11  android::BinderWrapper::Create();
12  binder_watcher_.Init();
13#endif  // USE_BINDER
14
15#if USE_OMAHA
16  // Initialize update engine global state but continue if something fails.
17  // TODO(deymo): Move the daemon_state_ initialization to a factory method
18  // avoiding the explicit re-usage of the |bus| instance, shared between
19  // D-Bus service and D-Bus client calls.
20  RealSystemState* real_system_state = new RealSystemState();
21  daemon_state_.reset(real_system_state);
22  LOG_IF(ERROR, !real_system_state->Initialize())
23      << "Failed to initialize system state.";
24#else  // !USE_OMAHA
25  //local_use_omaha = 0 执行else中的内容
26  //初始化类DaemonStateAndroid 的指针对象
27  DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid();
28  //将指针daemon_state_android设置为daemon_state_的成员
29  daemon_state_.reset(daemon_state_android);
30  //daemon_state_android执行初始化
31  LOG_IF(ERROR, !daemon_state_android->Initialize())
32      << "Failed to initialize system state.";
33#endif  // USE_OMAHA
34
35#if USE_BINDER
36  // Create the Binder Service.
37#if USE_OMAHA
38  binder_service_ = new BinderUpdateEngineBrilloService{real_system_state};
39#else  // !USE_OMAHA
40  //创建binder服务对象,
41  binder_service_ = new BinderUpdateEngineAndroidService{
42      daemon_state_android->service_delegate()};
43#endif  // USE_OMAHA
44  //注册binder服务 服务名为android.os.UpdateEngineService
45  auto binder_wrapper = android::BinderWrapper::Get();
46  if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),
47                                       binder_service_)) {
48    LOG(ERROR) << "Failed to register binder service.";
49  }
50  
51  daemon_state_->AddObserver(binder_service_.get());
52#endif  // USE_BINDER
53
54  // Create the DBus service.
55  dbus_adaptor_.reset(new UpdateEngineAdaptor(real_system_state));
56  daemon_state_->AddObserver(dbus_adaptor_.get());
57
58  dbus_adaptor_->RegisterAsync(base::Bind(&UpdateEngineDaemon::OnDBusRegistered,
59                                          base::Unretained(this)));
60  LOG(INFO) << "Waiting for DBus object to be registered.";
61#else  // !USE_DBUS //执行startupdater 
62  daemon_state_->StartUpdater();
63#endif  // USE_DBUS
64  return EX_OK;
65}

 

三、主要流程解析

由于对c++代码研究不深,来来回回看了好几遍这里的代码,我们先对代码中主要方法按顺序进行分析

1、执行oninit注册sign信号

2、初始化binder_watcher_

3、初始化指针daemon_state_

4、daemon_state_android执行初始化

5、创建binder_service对象

6、注册binder服务

7、执行daemon_state_->StartUpdater()

 

这里面比较重要的是345,我个人理解这里的代码,打比方相当于一次相亲,UpdateEngineDaemon相当于大家相约一个饭馆,DaemonStateAndroid相当于媒婆,女方是binder_service ,男方是update_attempter_,媒婆DaemonStateAndroid带着update_attempter_到女方binder_service_面前,一阵简单吹捧后,男方觉得女方很不错,之后两人在一起了,binder_service_说买房 买车,update_attempter_也就二话不说就去了,

3、初始化指针daemon_state_

1  //local_use_omaha = 0 执行else中的内容
2  //初始化类DaemonStateAndroid 的指针对象
3  DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid();
4  //将指针daemon_state_android设置为daemon_state_的成员
5  daemon_state_.reset(daemon_state_android);

由system/update_engine/daemon.h的 

// platform.定义daemon_state_指针

 std::unique_ptr<DaemonStateInterface> daemon_state_;

1system/update_engine/daemon_state_android.h
2namespace chromeos_update_engine {
3
4class DaemonStateAndroid : public DaemonStateInterface {
5 public:
6  DaemonStateAndroid() = default;
7  ~DaemonStateAndroid() override = default;

可以看出daemon_state_其实是DaemonStateInterface父类的对象,这里指向了子类DaemonStateAndroid

4、daemon_state_android执行初始化

 1system/update_engine/daemon_state_android.cc
 2
 3bool DaemonStateAndroid::Initialize() {
 4  //初始化boot_control
 5  boot_control_ = boot_control::CreateBootControl();
 6  if (!boot_control_) {
 7    LOG(WARNING) << "Unable to create BootControl instance, using stub "
 8                 << "instead. All update attempts will fail.";
 9    boot_control_.reset(new BootControlStub());
10  }
11  //初始化hardware
12  hardware_ = hardware::CreateHardware();
13  if (!hardware_) {
14    LOG(ERROR) << "Error intializing the HardwareInterface.";
15    return false;
16  }
17  //判断hardware_ 的bootmode 和 officialbuild
18  LOG_IF(INFO, !hardware_->IsNormalBootMode()) << "Booted in dev mode.";
19  LOG_IF(INFO, !hardware_->IsOfficialBuild()) << "Booted non-official build.";
20
21  // Initialize prefs.初始化prefs
22  base::FilePath non_volatile_path;
23  // TODO(deymo): Fall back to in-memory prefs if there's no physical directory
24  // available.
25  if (!hardware_->GetNonVolatileDirectory(&non_volatile_path)) {
26    LOG(ERROR) << "Failed to get a non-volatile directory.";
27    return false;
28  }
29  Prefs* prefs = new Prefs();
30  prefs_.reset(prefs);
31  if (!prefs->Init(non_volatile_path.Append(kPrefsSubDirectory))) {
32    LOG(ERROR) << "Failed to initialize preferences.";
33    return false;
34  }
35
36  // The CertificateChecker singleton is used by the update attempter.
37  //初始化certificate_checker_
38  certificate_checker_.reset(
39      new CertificateChecker(prefs_.get(), &openssl_wrapper_));
40  certificate_checker_->Init();
41
42  // Initialize the UpdateAttempter before the UpdateManager.
43  //初始化update_attempter_
44  update_attempter_.reset(new UpdateAttempterAndroid(
45      this, prefs_.get(), boot_control_.get(), hardware_.get()));
46
47  return true;
48}

这里面比较重要的是update_attempter_的初始化,可以看出所有的参数 其实是为了给到他使用的,

这里相当于媒婆给男方一些非常重要的信息,我们暂且不看信息的内容,后面会分析到

5、创建binder_service对象

sysem/update_engine/daemon.cc:

  binder_service_ = new BinderUpdateEngineAndroidService{

     daemon_state_android->service_delegate()};

 

这里面涉及到两个类

首先daemon_state_android->service_delegate() 调用DaemonStateAndroid 对象daemon_state_android的service_delegate方法

 

system/update_engine/daemon_state_android.h:

ServiceDelegateAndroidInterface* DaemonStateAndroid::service_delegate() {

 return update_attempter_.get();

}

可以看到这里返回的是update_attempter_

 

1system/update_engine/binder_service_android.cc
2
3BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
4    ServiceDelegateAndroidInterface* service_delegate)
5    : service_delegate_(service_delegate) {
6}

 

BinderUpdateEngineAndroidService类对象的创建包含了成员变量service_delegate,而这里其实就是update_attempter_,也就是真正的执行者,目前相亲还算顺利,男方女方见面聊的可以大概看下BinderUpdateEngineAndroidService,执行具体升级方法的是service_delegate_对象,也就是现在的update_attempter_

 

6、注册binder服务

 1system/update_engine/daemon.cc
 2
 3  auto binder_wrapper = android::BinderWrapper::Get();
 4  //使用binder_wrapper的 RegisterService方法注册时名称
 5  //为"android.os.UpdateEngineService"的服务
 6  if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),
 7                                       binder_service_)) {
 8    LOG(ERROR) << "Failed to register binder service.";
 9  }
10  
11  daemon_state_->AddObserver(binder_service_.get());

我们看看AddObserver是做什么用的

 protected: 这里service_observers_是一个集合

 std::set<ServiceObserverInterface*> service_observers_;

 

void DaemonStateAndroid::AddObserver(ServiceObserverInterface* observer) {

 service_observers_.insert(observer);

}

调用AddObserver方法将observer 也就是binder_service_放入service_observers_集合

 

7、执行daemon_state_->StartUpdater()

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  // Android中的DaemonState是一个被动守护程序。 只会开始申请
5  //根据公开的活页夹API的指示进行更新。
6  update_attempter_->Init();
7  return true;
8}

StartUpdater() 方法中只是执行了update_attempter_的init方法,毕竟他是主要后面干活的,所以我准备放到单独进行讲解

 

四、BinderUpdateEngineAndroidService主要代码分析

接下来再看以下我们主要分析的BinderUpdateEngineAndroidService大概有什么方法

1、BinderUpdateEngineAndroidService类

 1system/update_engine/binder_service_android.h
 2
 3class BinderUpdateEngineAndroidService : public android::os::BnUpdateEngine,
 4                                         public ServiceObserverInterface {
 5 public: //定义成员变量service_delegate
 6  explicit BinderUpdateEngineAndroidService(
 7      ServiceDelegateAndroidInterface* service_delegate);
 8  ~BinderUpdateEngineAndroidService() override = default;
 9 //定义服务名称Servicename
10  const char* ServiceName() const {
11    return "android.os.UpdateEngineService";
12  }
13  
14  // ServiceObserverInterface overrides.
15  // ServiceObserverInterface 接口的相关方法
16  void SendStatusUpdate(
17      const update_engine::UpdateEngineStatus& update_engine_status) override;
18  void SendPayloadApplicationComplete(ErrorCode error_code) override;
19
20  // android::os::BnUpdateEngine overrides.
21  // BnUpdateEngine接口的方法IUpdateEngine.aidl接口的方法
22  android::binder::Status applyPayload(
23      const android::String16& url,
24      int64_t payload_offset,
25      int64_t payload_size,
26      const std::vector<android::String16>& header_kv_pairs) override;
27  android::binder::Status bind(
28      const android::sp<android::os::IUpdateEngineCallback>& callback,
29      bool* return_value) override;
30  android::binder::Status unbind(
31      const android::sp<android::os::IUpdateEngineCallback>& callback,
32      bool* return_value) override;
33  android::binder::Status suspend() override;
34  android::binder::Status resume() override;
35  android::binder::Status cancel() override;
36  android::binder::Status resetStatus() override;
37  android::binder::Status verifyPayloadApplicable(
38      const android::String16& metadata_filename, bool* return_value) override;
39
40 private:
41  // Remove the passed |callback| from the list of registered callbacks. Called
42  // on unbind() or whenever the callback object is destroyed.
43  // Returns true on success.
44  //删除传递的| callback | 从已注册的回调列表中。 在unbind()或回调对象被销毁时调用。
45  //成功则返回true。
46  bool UnbindCallback(const IBinder* callback);
47
48  // List of currently bound callbacks.当前绑定的回调列表。
49  std::vector<android::sp<android::os::IUpdateEngineCallback>> callbacks_;
50
51  // Cached copy of the last status update sent. Used to send an initial
52  // notification when bind() is called from the client.
53  int last_status_{-1};
54  double last_progress_{0.0};
55  //定义service_delegate_
56  ServiceDelegateAndroidInterface* service_delegate_;
57};
58
59}  // namespace chromeos_update_engine

 

  1system/update_engine/binder_service_android.cc
  2
  3namespace chromeos_update_engine {
  4
  5BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
  6    ServiceDelegateAndroidInterface* service_delegate)
  7    : service_delegate_(service_delegate) {
  8}
  9//执行callbackonStatusUpdate方法
 10void BinderUpdateEngineAndroidService::SendStatusUpdate(
 11    const UpdateEngineStatus& update_engine_status) {
 12  last_status_ = static_cast<int>(update_engine_status.status);
 13  last_progress_ = update_engine_status.progress;
 14  for (auto& callback : callbacks_) {
 15    callback->onStatusUpdate(last_status_, last_progress_);
 16  }
 17}
 18//执行onPayloadApplicationComplete方法
 19void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
 20    ErrorCode error_code) {
 21  for (auto& callback : callbacks_) {
 22    callback->onPayloadApplicationComplete(static_cast<int>(error_code));
 23  }
 24}
 25
 26//调用bind绑定服务 并传入callback
 27Status BinderUpdateEngineAndroidService::bind(
 28    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
 29  //将callback放入callback_容器中
 30  callbacks_.emplace_back(callback);
 31
 32  const android::sp<IBinder>& callback_binder =
 33      IUpdateEngineCallback::asBinder(callback);
 34  auto binder_wrapper = android::BinderWrapper::Get();
 35  binder_wrapper->RegisterForDeathNotifications(
 36      callback_binder,
 37      base::Bind(
 38          base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
 39          base::Unretained(this),
 40          base::Unretained(callback_binder.get())));
 41
 42  // Send an status update on connection (except when no update sent so far),
 43  // since the status update is oneway and we don't need to wait for the
 44  // response.
 45  if (last_status_ != -1)
 46    callback->onStatusUpdate(last_status_, last_progress_);
 47
 48  *return_value = true;
 49  return Status::ok();
 50}
 51//解除绑定
 52Status BinderUpdateEngineAndroidService::unbind(
 53    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
 54  const android::sp<IBinder>& callback_binder =
 55      IUpdateEngineCallback::asBinder(callback);
 56  auto binder_wrapper = android::BinderWrapper::Get();
 57  binder_wrapper->UnregisterForDeathNotifications(callback_binder);
 58  //调用UnbindCallback方法
 59  *return_value = UnbindCallback(callback_binder.get());
 60  return Status::ok();
 61}
 62//执行客户端applyPayload 调用service_delegate_->ApplyPayload方法
 63Status BinderUpdateEngineAndroidService::applyPayload(
 64    const android::String16& url,
 65    int64_t payload_offset,
 66    int64_t payload_size,
 67    const std::vector<android::String16>& header_kv_pairs) {
 68  const std::string payload_url{android::String8{url}.string()};
 69  std::vector<std::string> str_headers;
 70  str_headers.reserve(header_kv_pairs.size());
 71  for (const auto& header : header_kv_pairs) {
 72    str_headers.emplace_back(android::String8{header}.string());
 73  }
 74
 75  brillo::ErrorPtr error;
 76  if (!service_delegate_->ApplyPayload(
 77          payload_url, payload_offset, payload_size, str_headers, &error)) {
 78    return ErrorPtrToStatus(error);
 79  }
 80  return Status::ok();
 81}
 82//执行客户端suspend,调用service_delegate_->SuspendUpdate
 83Status BinderUpdateEngineAndroidService::suspend() {
 84  brillo::ErrorPtr error;
 85  if (!service_delegate_->SuspendUpdate(&error))
 86    return ErrorPtrToStatus(error);
 87  return Status::ok();
 88}
 89//执行客户端resume,调用service_delegate_->resume
 90Status BinderUpdateEngineAndroidService::resume() {
 91  brillo::ErrorPtr error;
 92  if (!service_delegate_->ResumeUpdate(&error))
 93    return ErrorPtrToStatus(error);
 94  return Status::ok();
 95}
 96//执行客户端cancel,调用service_delegate_->cancel
 97Status BinderUpdateEngineAndroidService::cancel() {
 98  brillo::ErrorPtr error;
 99  if (!service_delegate_->CancelUpdate(&error))
100    return ErrorPtrToStatus(error);
101  return Status::ok();
102}
103//执行客户端resetStatus,调用service_delegate_->resetStatus
104Status BinderUpdateEngineAndroidService::resetStatus() {
105  brillo::ErrorPtr error;
106  if (!service_delegate_->ResetStatus(&error))
107    return ErrorPtrToStatus(error);
108  return Status::ok();
109}
110//执行客户端verifyPayloadApplicable,调用service_delegate_->verifyPayloadApplicable
111Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
112    const android::String16& metadata_filename, bool* return_value) {
113  const std::string payload_metadata{
114      android::String8{metadata_filename}.string()};
115  LOG(INFO) << "Received a request of verifying payload metadata in "
116            << payload_metadata << ".";
117  brillo::ErrorPtr error;
118  *return_value =
119      service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
120  if (error != nullptr)
121    return ErrorPtrToStatus(error);
122  return Status::ok();
123}
124//解除callback绑定时执行
125bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
126  auto it = std::find_if(
127      callbacks_.begin(),
128      callbacks_.end(),
129      [&callback](const android::sp<IUpdateEngineCallback>& elem) {
130        return IUpdateEngineCallback::asBinder(elem).get() == callback;
131      });
132  if (it == callbacks_.end()) {
133    LOG(ERROR) << "Unable to unbind unknown callback.";
134    return false;
135  }
136  callbacks_.erase(it);
137  return true;
138}

这里面我需要知道

1、bind会传入callback

2、客户端相应的升级操作 其实是service_delegate_来完成的,但是我们之前在daemon.cc中将具体的业务实现,但是我们有媒婆在中间,现在是update_attempter_,这样就连接起了服务端和客户端

3、SendStatusUpdate 和 SendPayloadApplicationComplete 其实就是对应callback的回调函数,也就是给客户端返回对应的升级状态和升级结果

 

这就是大致的main流程,可以看出我们下一步主要分析的是update_attempter_,执行相应的升级动作,其实我们还有两个问题没有处理,后续分析后进行补充

1、什么地方,什么时间调用到回调函数的,

2、当然也有一个方法没有看到具体使用的地方,AddObserver到底有什么作用

把binder_service_放入到service_observers_这个set集合中

带着这个问题继续往后的分析,我个人推测是方法在update_attempter_中的,只有执行了具体的升级逻辑,才能拿到相应的升级参数。

 

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

2019年10月15日关于最后预留更新

我们最后留了两个疑问,因为daemon.cc 最后执行的是 update_attempter_的init方法,在这个方法中看到了我们疑问的地方

 

 1system/update_engine/update_attempter_android.cc
 2
 3UpdateAttempterAndroid::UpdateAttempterAndroid(
 4    DaemonStateInterface* daemon_state,
 5    PrefsInterface* prefs,
 6    BootControlInterface* boot_control,
 7    HardwareInterface* hardware)
 8    : daemon_state_(daemon_state),
 9      prefs_(prefs),
10      boot_control_(boot_control),
11      hardware_(hardware),
12      processor_(new ActionProcessor()),
13      clock_(new Clock()) {
14  metrics_reporter_ = metrics::CreateMetricsReporter();
15  network_selector_ = network::CreateNetworkSelector();
16}
17
18void UpdateAttempterAndroid::Init() {
19  // In case of update_engine restart without a reboot we need to restore the
20  // reboot needed state.
21  //调用SetStatusAndNotify方法
22  if (UpdateCompletedOnThisBoot()) {
23    SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
24  } else {
25    SetStatusAndNotify(UpdateStatus::IDLE);
26    UpdatePrefsAndReportUpdateMetricsOnReboot();
27  }
28}
29
30void UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) {
31  status_ = status;
32  size_t payload_size =
33      install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size;
34  UpdateEngineStatus status_to_send = {.status = status_,
35                                       .progress = download_progress_,
36                                       .new_size_bytes = payload_size};
37  
38  //编译
39  for (auto observer : daemon_state_->service_observers()) {
40    observer->SendStatusUpdate(status_to_send);
41  }
42  last_notify_time_ = TimeTicks::Now();
43}

首先UpdateAttempterAndroid 的成员变量包含了daemon_state_,所以可以调用其中的方法service_observers(),返回set集合service_observers_

observer是ServiceObserverInterface的子类BinderUpdateEngineAndroidService的对象binder_service_,所以执行BinderUpdateEngineAndroidService的SendStatusUpdate方法,进而调用回调方法callback->onStatusUpdate(last_status_, last_progress_);执行回调操作。

二、A/B 升级update_engine分析-整体模块 调试通了AB后确实想好好整理下这部分,其实与传统ota对比,我个人这样划分1、bootloder部分 2、kernel部分 3、framwork部分 4、update_engine核心 5、升级包的制作,而其中的大部分工作都来源于核心update_engine,在这里卡了很久,决定先从这里入手,按照framwork---->(binder机制)update_engine流程(设定对应... 阅读详情

相关推荐

update_engine模块移植到linux平台

update_engine是google提供的一个升级模块,对于linux的平台,我们可以移植到我们的嵌入式平台,通过update_engine模块对系统升级,最近由于工作需要,在linux平台上面移植一下,其中遇到了很多问题,在不停的寻找答案中,问题都一一解决了,现在分享一下移植的过程,提供给有同样需求的童鞋。

csdn66_2016的博客 2908

Android UpdateEngine 模块分析(三)升级触发以及Action机制介绍

前面分析了 UpdateEngine 模块的编译和启动流程,对于 UpdateEngine 模块已经有了初步的了解,接下来我们从升级的功能出发,分析 UpdateEngine 的升级过程,升级过程的内容非常的多,准备从 UpdateEngine 的 Action 机制开始分析,UpdateEngine 的升级过程有很多步骤,每一个步骤由一个 Action 去控制。因此,我们先说明 UpdateEngine 模块的 Action 机制,并从升级的触发方式以及实现流程展开描述。

Yang_Mao_Shan的博客 8386

android动态分区AB升级,Android A/B System OTA分析(四)系统的启动和升级

Android从7.0开始引入新的OTA升级方式,A/B System Updates,这里将其叫做A/B系统,涉及的内容较多,分多篇对A/B系统的各个方面进行分析。本文为第四篇,系统的启动和升级。本文基于AOSP 7.1.1_r23 (NMF27D)代码进行分析。1. 系统的启动1.1 bootloader检查slot metadata系统复位后,bootloader会去读取boot_contr...

weixin_42299560的博客 3462

Android UpdateEngine 模块分析(二)UpdateEngine 服务启动

updateengine 可执行文件是 UpdateEngine 服务模块的入口文件,既然是分析 UpdateEngine 模块功能,我们先从 udpateengine 文件的定义入手,进而详细分析~],

Yang_Mao_Shan的博客 5237

Android A/B system - update_engine(一)

Android A/B System的升级过程是怎样的?理解这一过程就需要理解update_engine的逻辑。 首先来看main.cc,main.cc主要做了这些事: log相关 初始化crc-32 table 调用update_engine_daemon.Run() /system/update_engine/main.cc int main(int argc, char** argv) ...

Dufre 2895

Android P update_engine分析(四) --update_engine_client的工作

当AB系统升级时,有两种方式来调用updateengine,来实现升级,一种方法是直接执行shell命令,调用 update_engine_client,带参数来实现升级,另一种方式是应用层直接调用UpdateEngine的applyPayload方法来升级。 update_engine_client 带参升级 shell命令调用update_engine_client带参数去升级,具体如下: update_engine_client --payload=file:///sdcard/payload.bin

tovey2008的专栏 6636

三、A/B 升级update_engine分析-客户端

本编将从两个方面分析客户端,原生测试模块update_engine_client和framwork层接口 一、update_engine_client Android原生编译出了测试模块update_engine_client,在system/bin/下,我个人理解是与framekwork 层binder机制连接update_engine服务端是类似的,不过该模块增加了命令行测试的部分...

李标标的博客 5636

Android A/B升级实战:从update_engine模块拆解到避坑指南

本文深入拆解了Android A/B升级的核心模块update_engine,详细剖析了libpayload_consumer、libupdate_engine_android等静态库的功能与依赖关系,并提供了从编译配置到实战调试的完整避坑指南,帮助开发者高效解决升级过程中的常见问题。

weixin_28365523的博客 170

Android A/B System OTA分析(四)系统的启动和升级

Android从7.0开始引入新的OTA升级方式,`A/B System Updates`,这里将其叫做`A/B`系统,涉及的内容较多,分多篇对`A/B`系统的各个方面进行分析。本文为第四篇,系统的启动和升级。 本文为洛奇看世界(guyongqiangx)原创,转载请注明出处。 文章链接:https://blog.youkuaiyun.com/guyongqiangx/article/details/72604355

洛奇看世界 3万+

Android A/B System OTA分析(五)客户端参数

AB OTA

qq_42135379的博客 1602

Android Update Engine分析(七) DownloadAction之FileWriter

Android Update Engine分析(七) DownloadAction之FileWriter 本系列到现在为止的共有六篇,分别分析分析了Makefile,Update Engine的客户端、服务端及Action机制的细节: Android Update Engine分析(一)Makefile Android Update Engine分析(二)Protobuf和AIDL文件 Andr......

洛奇看世界 9432

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

上一篇我们讲到了服务端启动的流程,本篇主要讲解主要升级流程,UpdateAttempterAndroid类包含的内容较多,所以单独讲解,这个文件看了很长时间,大概方法都已经了解,但是想了很久从哪儿开始梳理这个流程,不仅仅是我能看懂,而且能讲出来的很清晰,这是我想做到的,别问,问就是重点 一、update_attempter_android.h 简要分析 1、继承和构造函数 ...

李标标的博客 3558

Android Update Engine 分析(十五) FullUpdateGenerator 策略

生成 payload 时,会选择不同的策略去遍历每一个分区的每一个 block 生成相应的 Operation 数据: 1. 差分升级的情况下,如果 version.minor = 1, 则使用 InplaceGenerator 策略 2. 差分升级的情况下,其它情况使用 ABGenerator 策略 3. 全量升级情况, 使用 FullUpdateGenerator 策略 本篇分析最简单的 FullUpdateGenerator 策略

洛奇看世界 2982

Android OTA 升级专栏文章导读

从 2017 年起,我陆续写了一些 Android OTA 升级相关的文章,主要介绍从 Android 7.1 开始引入的 A/B 升级系统,包括从早前的 A/B 系统,到后来的动态分区,再到最近的虚拟 A/B 分区,以及最新的一些 Android OTA 话题。毫不夸张的说,这是目前全网关于 Android OTA 升级最系统,最全面的专栏,没有之一。

洛奇看世界 1万+

Android Update Engine 分析(二十五)升级状态 prefs 是如何保存的?

本系列到现在为止一共二十四篇,前面十七篇基本上就是阅读 update engine 的核心代码和函数,第十七篇以后开始按照话题进行分析。在前面十七篇中,把核心功能代码过了一遍,但仍然有不少功能代码还没分析过。例如,Update Engine 的升级状态数据时如何保存的?系统到底定义了哪些 prefs 数据?本文就管理 Update Engine 状态的 Prefs 类进行详细分析。

洛奇看世界 1848

Android Update Engine分析(四)服务端进程

Android Update Engine分析(四)服务端进程 前面三篇分别分析了Makefile,Protobuf和AIDL相关文件以及Update Engine的客户端进程update_engine_client, Android Update Engine分析(一)Makefile Android Update Engine分析(二)Protobuf和AIDL文件 Android Up...

洛奇看世界 8339

Android Update Engine 分析(三十)有了A/B系统,为什么还要 Recovery?

本文先单独分析 A/B 系统和 Recovery 系统各自的功能,然后对比功能差异来找到 A/B 系统并不能完全替代 Recovery 系统的原因。如果 Recovery 系统所有的功能 A/B 系统都能满足,那自然的结果就是有了 A/B 系统,就可以不需要 Recovery 系统了。如果 A/B 系统并不能实现所有的 Recovery 所具有的功能,那就无法完全替换。同时,也解释了 Recovery 系统存在的意义。

洛奇看世界 784

Android Update Engine分析(十四) 生成 payload 数据

生成 payload 数据是 `delta_generator` 工具最主要的功能,当我准备重新更新这一些列文章时,一开始就想写这个的,不过因为太久没看,不记得 payload 细节了,更无从从细节上分析。所以就先写一些简单的操作,等熟悉了再开始写。经过前面篇的分析了解 payload 结构,现在是时候来解决这个问题了。

洛奇看世界 3914
上一篇: 三、A/B 升级update_engine分析-客户端
下一篇: 五、A/B 升级update_engine分析-UpdateAttempterAndroid
李标标
博客等级 码龄11年 124粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值