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

    以下我们将分析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_);执行回调操作。

### SQL语法错误1064分析 SQL语法错误`1064`通常表示MySQL无法解析查询中的某些部分。具体到此问题,错误提示为 `near '// ----------------------------' at line 18`,这表明在第18行附近存在未被识别的语句或结构。 #### 错误原因分析 1. **单行注释符使用不当** 在MySQL中,单行注释应以双短横线 (`--`) 开头,并紧跟一个空格[^1]。如果直接使用两个斜杠 (`//`) 或者缺少后续空格,则可能导致语法错误。 2. **版本兼容性问题** 不同版本的MySQL可能对特定语法的支持程度不同。例如,较新的MySQL版本支持更多扩展功能,而旧版则可能存在限制[^2]。Navicat Premium作为数据库管理工具,在导出脚本时可能会生成针对高版本MySQL优化的内容,这些内容未必能完全适配低版本MySQL服务器。 3. **字符编码冲突** 如果源文件保存时使用的编码格式与目标数据库设置不符(比如UTF-8 vs GBK),也可能引发隐性的语法异常[^3]。 --- ### 解决方案 以下是几种可行的方法来修正该类问题: #### 方法一:调整单行注释形式 将所有形似`// 注释文字`的部分替换为标准写法即`-- 注释文字`并确保每条记录前都有至少一个空白间隔。例如: ```sql -- ---------------------------- -- Table structure for example_table -- ---------------------------- DROP TABLE IF EXISTS `example_table`; CREATE TABLE `example_table` ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(50), PRIMARY KEY (id) ); ``` #### 方法二:升级/降级MySQL服务端程序 确认当前运行环境所依赖的具体MySQL发行号之后再决定是否有必要更新至最新稳定发布或者回退到先前已知良好状态下的构建实例[^4]。可以通过执行命令`SELECT VERSION();`获取现有部署的信息。 #### 方法三:修改Navicat配置选项 当利用Navicat创建迁移任务之前,请仔细核查其高级属性面板里关于目标平台设定项是否存在偏差之处。特别是“Compatibility Mode”字段应当依据实际需求选择恰当的目标数据库引擎类型及其对应的主要特性集合[^5]。 #### 方法:手动清理多余元数据标记 有时为了便于阅读理解复杂DDL定义文档,开发者习惯于加入大量辅助说明性质的小节划分标签。然而这部分额外附加物往往并非严格意义上的有效SQL组成部分,因此建议移除它们后再尝试重新加载整个批次指令集。 --- ### 示例代码片段展示如何规范化处理后的SQL脚本样式 下面给出一段经过整理后更加贴近常规操作习惯的标准模板供参考: ```sql /* * File Name: schema_definition.sql */ SET FOREIGN_KEY_CHECKS=0; -- Drop existing table if it exists to prevent errors on creation. DROP TABLE IF EXISTS `users`; -- Create new users table with defined columns and constraints. CREATE TABLE `users` ( user_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique identifier', username CHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'Login account name.', password_hash BINARY(60) NOT NULL COMMENT 'Hashed value of the entered passcode.', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Record insertion timestamp.', UNIQUE INDEX idx_username(username ASC), -- Enforce uniqueness per login ID field entry level. PRIMARY KEY pk_user(user_id ASC USING BTREE) ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC AVG_ROW_LENGTH=768 MAX_ROWS=9223372036854775807; ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值