A|B升级框架

A|B升级

A|B 升级主要包含了3个部分:

  1. boot_control 服务主要用于提供修改 A|B 系统分区状态的相关接口。
  2. UpdateEngine 服务 主要用于后台更新 A|B 系统,并通过通过boot_control去修改 当时的分区状态。
  3. java 层的 UpdateEngine 类,用于向apk 暴露接口

A|B 升级的大概流程为:

​ 当需要进行OTA 升级时, 在apk 进程中使用java层的UpdateEngine类 通知 底层的UpdateEngine服务触发升级,UpdateEngine 服务会根据java层传递的参数,去下载升级包,进行后台更新,并同时通过 boot_control 服务去设置A|B 系统分区的状态。

​ java 层的 UpdateEngine 类在初始化时会绑定底层的UpdateEngine 服务,使用Binder系统通知底层的UpdateEngine 服务进行系统升级。

​ 而底层的 UpdateEngine 服务通过 hidl 联系 boot_control 服务去设置A|B系统的分区状态。


boot_control服务

boot_control 服务是用于提供一些接口,达到让外部通过此服务 修改 A|B 系统状态的目的,boot_control 服务 是在开机时通过 rc 文件启动,并同时将自己添加到了halServiceManager里面,以便让外界进行访问,它大概可以 分为以下几个部分:。

  1. boot_control 服务的启动
  2. boot_control 服务的初始化
  3. boot_control 服务 添加到 halServiceManager 里面

boot_control 服务的启动

hardware/interfaces/boot/1.0/default/android.hardware.boot@1.0-service.rc
service boot-hal-1-0 /vendor/bin/hw/android.hardware.boot@1.0-service 
    class early_hal
    user root
    group root

rc 文件里面 直接启动 boot_control 服务 android.hardware.boot@1.0-service,此服务的用户为root之后会调用此服务入口的main方法,启动此服务:

hardware/interfaces/boot/1.0/default/service.cpp
int main (int /* argc */, char * /* argv */ []) {
    return defaultPassthroughServiceImplementation<IBootControl>();
}

在它的 main方法中,它只调用了defaultPassthroughServiceImplementation方法,实现将本身service 初始化,与添加到 halServiceManager中,此方法的展开为:

/system/libhidl/transport/include/hidl/LegacySupport.h
template<class Interface>
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1) {
    return defaultPassthroughServiceImplementation<Interface>("default", maxThreads);
}
template<class Interface>
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(std::string name,
                                            size_t maxThreads = 1) {
    configureRpcThreadpool(maxThreads, true);
    status_t result = registerPassthroughServiceImplementation<Interface>(name);
     joinRpcThreadpool();
    return 0;
}
设置用于hwbinder通信的线程数

configureRpcThreadpool用于设置 当前进程用于hwbinder通信的最大线程数:

system/libhidl/transport/HidlTransportSupport.cpp
void configureRpcThreadpool(size_t maxThreads, bool callerWillJoin) {
    configureBinderRpcThreadpool(maxThreads, callerWillJoin);        
}
system/libhidl/transport/HidlBinderSupport.cpp
void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) {                     ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin);
}

这里 google 是为了hidl 实现一套专用 ProcessStateIPCThreadStateBpHwBinder … 与原有的那套区别开来,它的具体实现,之后有空,在另行总结。

此处configureBinderRpcThreadpool方法内,一行代码共做了两个操作:

  1. ProcessState::self()类似 binder 框架里面的流程,在当前进程中初始化 hwbinder
  2. setThreadPoolConfiguration 设置当前进程用于hwBinder 通信的进程数
当前进程中hwbinder框架的初始化

hidlPrcessStateIPCThreadState… 的代码位置为:

 system/libhwbinder/ProcessState.cpp
 system/libhwbinder/IPCThreadState.cpp 
 ......

在self 方法里面创建 ProcessState对象

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {  //C++中的单例模式
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
}

ProcessState 的构造方法中会使用 open_driver 方法,去打开 /dev/hwbinder 节点,来在 kernel 里面初始化 此进程 相关hwbinder数据结构, 并将打开 hwbinder 节点的 fd 保存在mDriverFD 变量里面,之后通过此 fd来和 kernel 内部的驱动进行通信。

ProcessState::ProcessState()
    : mDriverFD(open_driver())
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    ......
{
    if (mDriverFD >= 0) {
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    }
}

open_driver 会直接区打开 /dev/hwbinder 节点, 此方法会通知hwbinder驱动,在kernel中初始化 此进程中 hwBinder相关的数据结构。

static int open_driver()
{
    int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        int vers = 0;
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
         size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
    }
    return fd;
}

BINDER_VERSION

将此进程中的binder版本,通过ioctl 方法告诉kernel,与kernel的版本进行对比

BINDER_SET_MAX_THREADS

设置此进程给用于hwbinder 通信的线程数,为BINDER_SET_MAX_THREADS

ps:在此处设置完之后,又通过setThreadPoolConfiguration,对通信线程数进行了修改。

rc启动boot_control 服务后,在servicemain方法中,通过defaultPassthroughServiceImplementation展开为为两个步骤去处理:

  1. configureRpcThreadpool 初始化当前进程内的hwbinder体系
  2. registerPassthroughServiceImplementation 初始化boot_control服务,并添加到halServiceManager里面。

boot_control 服务的初始化

registerPassthroughServiceImplementation<Interface>(name)这个方法其实也作了两个操作:

  1. boot_control 服务的初始化
  2. boot_control 服务添加到 halServiceManager

    此处 InterfaceIBootControlnamedefault ,此方法展开为:

template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(                            
        std::string name = "default") {
    sp<Interface> service = Interface::getService(name, true /* getStub */);
    status_t status = service->registerAsService(name);
    return status;
}
调用模板代码来初始化 boot_control 服务

Interface::getService(name, true)

​ 是调用hidl自动生成的一些类,来初始化boot_control 服务,系统在编译时,会自动生成 hidl 相关的代码,此模块对应生成的相关代码位置为:

out/soong/.intermediates/hardware/interfaces/boot/1.0/android.hardware.boot@1.0_genc++_headers/gen/android/hardware/boot/1.0

它的实现可以参考:

https://source.android.com/devices/architecture/configstore/service

Interface::getService 通过调用 hidl生成的模板代码,此代码默认会调用HIDL_FETCH_IBootControl方法,对boot_control 服务进行初始化,大概流程为:

hardware/interfaces/boot/1.0/default/BootControl.cpp
IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) {
    int ret = 0;
    boot_control_module_t* module = NULL;
    hw_module_t **hwm = reinterpret_cast<hw_module_t**>(&module);
    ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast<const hw_module_t**>(hwm));
    module->init(module);
    return new BootControl(module);
}
BootControl::BootControl(boot_control_module_t *module) : mModule(module){
}

getService调用模板代码,会自动调用到*HIDL_FETCH_IBootControl 方法去进行初始化操作, 此操作默认会做以下操作:

  • 通过hw_get_module 方法获取系统的 bootctrl 模块

  • 调用moduleinit 方法,初始化模块内部记录的分区状态标识

  • 创建并返回 BootControl 对象

BootControl 通过hw_get_modulebootctrl 模块 建立了联系,然后调用 它的init 方法,从misc 分区中读取 A|B系统分区的状况,并以此初始化bootctrl模块数据。

​ 之后BootControl 服务就可以通过 其内部的 bootctrl 模块对象,对A|B系统分区状态进行修改。

bootctrl 模块的实现有 多种方案:见文档 *AB升级.pdf*

boot_control服务添加到 halServiceManager

service->registerAsService(name)

这个也是通过调用hidl生成的 模板代码将 boot_control 服务 添加到halServiceManager里面:

out/soong/.intermediates/hardware/interfaces/boot/1.0/android.hardware.boot@1.0_genc++_headers/gen/android/hardware/boot/1.0/BootControlAll.cpp
::android::status_t IBootControl::registerAsService(const std::string &serviceName) {
    ::android::hardware::details::onRegistration("android.hardware.boot@1.0", "IBootControl", serviceName);

  const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
            = ::android::hardware::defaultServiceManager();

    ::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);

  return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
}

这里它的这套流程 也是hwbinder 模拟 binder来实现:

  1. 通过defaultServiceManager获取hwServiceManagerclient端口(类似binder系统,此处使用0 构建了一个hwServiceManagerclient端口)
  2. sm->add(serviceName.c_str(), this) 将当前 boot_control 服务添加进入hwServiceManager

defaultServiceManager 的实现为:

/system/libhidl/transport/ServiceManagement.cpp
sp<IServiceManager> defaultServiceManager() {
    {
        AutoMutex _l(details::gDefaultServiceManagerLock);
        if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
            return nullptr;
        }
        waitForHwServiceManager();
        while (details::gDefaultServiceManager == NULL) {
            details::gDefaultServiceManager =
                    fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>(
                        ProcessState::self()->getContextObject(NULL));
        }
    }
    return details::gDefaultServiceManager;
}
static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready";
void waitForHwServiceManager() {
    using std::literals::chrono_literals::operator""s;
    while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) {
    }
}

获取HwServiceManager的流程为:

access("/dev/hwbinder", F_OK|R_OK|W_OK)

​ 判断当前系统是否支持 hwbinder

waitForHwServiceManager()

​ 等待hwServiceManager ok,判断依据为 property项:hwservicemanager.ready 是否设置

ProcessState::self()->getContextObject(NULL)

​ 在ProcessStategetContextObject方法内,以0 构建一个hwServiceManagerclient

​ 然后sm->add(serviceName.c_str(), this) 将当前 boot_control 添加到hwServiceManager里面。

boot_control 服务对外提供的接口见: AB升级.pdf

到此boot_control 初始化完成,等待后续处理:

joinRpcThreadpool

boot_control初始化ok,通过joinRpcThreadpool开始等待 客户端的链接,进行处理。此方法的实现也是基于 binder框架移植过来的。


update_engine服务

update_engine服务也是 在开机时 通过rc启动的,它可以分为一下几个部分:

  1. update_engine 服务的启动
  2. update_engine 服务的初始化与通过hidlboot_control 建立联系
  3. update_engine 服务添加到 ServiceManager

update_engine 服务的启动

update_engine 服务也是在开机时,通过它的 rc文件启动的

system/update_engine/update_engine.rc
service update_engine /system/bin/update_engine --logtostderr --foreground 
    class late_start
    user root
    group root system wakelock inet cache
    writepid /dev/cpuset/system-background/tasks

通过rc文件,进入update_engine 的入口方法

system/update_engine/main.cc 
int main(int argc, char** argv) {
  chromeos_update_engine::UpdateEngineDaemon update_engine_daemon;
  int exit_code = update_engine_daemon.Run();   
  return exit_code;
}

​ 在update_engine 的入口main 方法中,会创建 UpdateEngineDaemon 对象,并调用他的run方法去初始化,展开Update_Engine框架。

UpdateEngineDaemon对象的初始化

UpdateEngineDaemon 继承自 daemon.h

system/update_engine/daemon.h
class UpdateEngineDaemon : public brillo::Daemon {
... 
}

因为UpdateEngineDaemon继承自brillodamon 类,执行的也为daemonrun方法:

初始化展开Update_Engine框架

通过daemon的run方法,进入初始化 update_engine服务的流程

external/libbrillo/brillo/daemons/daemon.cc
int exit_code = update_engine_daemon.Run();
int Daemon::Run() {
  int exit_code = OnInit();  //OnInit 回调用到UpdateEngineDaemon 的OnInit 方法,将native服务田间到halServiceManager
  if (exit_code != EX_OK)
    return exit_code;
  message_loop_.Run();
  OnShutdown(&exit_code_);
  while (message_loop_.RunOnce(false /* may_block */)) {}  //开始消息循环
  return exit_code_;
}

​ 因为是通过UpdateEngineDaemon 调用的 daemonrun方法,所以在此处是调用的UpdateEngineDaemonOnInit方法。

类似继承,onInit方法会调用brillodaemon 的继承类实现

system/update_engine/daemon.cc
int exit_code = OnInit();
int UpdateEngineDaemon::OnInit() {
  subprocess_.Init(this);  //在common/subprocess.cc 中注册信号处理器
  int exit_code = Daemon::OnInit();  //调用到external/libbrillo/brillo/daemons/daemon.cc里面,对信号处理器进行初始化

#if USE_BINDER
  android::BinderWrapper::Create(); //在 system/core/libbinderwrapper/binder_wrapper.cc 里面创建一个 RealBinderWrapper 对象
  binder_watcher_.Init(); //external/libbrillo/brillo/binder_watcher.cc 当前进程binder 的初始化
#endif  // USE_BINDER

#if USE_OMAHA
  RealSystemState* real_system_state = new RealSystemState();
  daemon_state_.reset(real_system_state);
#else  // !USE_OMAHA
  DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid();
  daemon_state_.reset(daemon_state_android);
#endif  // USE_OMAHA

#if USE_BINDER
    #if USE_OMAHA  // Create the Binder Service. 
        binder_service_ = new BinderUpdateEngineBrilloService{real_system_state};
    #else  // !USE_OMAHA 
        binder_service_ = new BinderUpdateEngineAndroidService{
            daemon_state_android->service_delegate()
        };
    #endif  // USE_OMAHA

        //获取android::BinderWrapper::Create()里面创建的 real_binder_wrapper 对象
        auto binder_wrapper = android::BinderWrapper::Get();  
        //使用real_binder_wrapper 对象将自己注册到 servicemanager 里面
        if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),                                                                        binder_service_)) {
                LOG(ERROR) << "Failed to register binder service.";
        }
        daemon_state_->AddObserver(binder_service_.get());
#endif  // USE_BINDER

#if USE_DBUS
  // Create the DBus service.
  dbus_adaptor_.reset(new UpdateEngineAdaptor(real_system_state));
  daemon_state_->AddObserver(dbus_adaptor_.get());
  dbus_adaptor_->RegisterAsync(base::Bind(&UpdateEngineDaemon::OnDBusRegistered,
                                          base::Unretained(this)));
#else  // !USE_DBUS
  daemon_state_->StartUpdater();
#endif  // USE_DBUS
  return EX_OK;
}

update_engine服务的关键操作,全部集中在这个方法中。这个OnInit方法较长,它大体可以分为以下几个部分:

  • 异常信号处理
  • update_enginebinder 系统的构建
  • 初始化Update_Engine 并通过hidlboot_control 建立联系
  • update_engine 服务添加到 ServiceManager

其中异常信号的处理不是重点,仅仅在代码里面标注了一下

Update_Engine服务的初始化

update_engine 服务的初始化是在上面OnInit方法中实现的,它包含了上面写的两个部分:

  • 用于和ServiceManager通信的BinderWrapper对象的构建
  • update_enginebinder 系统的构建
  • 初始化Update_Engine 并通过hidlboot_control 建立联系
BinderWrapper对象的构建

BinderWarpper是用来和ServiceManager进行通信的一个对象,它在update_engine中的作用就是将当前服务添加注册到ServiceManager中。

OnInit方法中BinderWrapper的初始化创建:

system/core/libbinderwrapper/binder_wrapper.cc
android::BinderWrapper::Create();
void BinderWrapper::Create() {
  instance_ = new RealBinderWrapper();//创建一个RealBinderWrapper对象,用于之后向 service_manager 注册RegisterService服务
}
Binder系统的构建初始化

OnInit方法中使用binder_watcher_初始化进程中的binder系统

external/libbrillo/brillo/binder_watcher.cc
binder_watcher_.Init();
bool BinderWatcher::Init() {
  message_loop_ = MessageLoop::current();
  int binder_fd = -1;
  //初始化当前进程的的binder系统
  ProcessState::self()->setThreadPoolMaxThreadCount(0);
  IPCThreadState::self()->disableBackgroundScheduling(true);
  int err = IPCThreadState::self()->setupPolling(&binder_fd);

  task_id_ = message_loop_->WatchFileDescriptor(
      FROM_HERE,
      binder_fd,
      MessageLoop::kWatchRead,
      true /* persistent */,
      base::Bind(&OnBinderReadReady));
  if (task_id_ == MessageLoop::kTaskIdNull) {
    return false;
  }
  return true;
}

之后会在ProcessState里面,进行binder的初始化操作,与进行binder通信线程数 的设置:

frameworks/native/libs/binder/ProcessState.cpp
ProcessState::self()->setThreadPoolMaxThreadCount(0);
//ProcessState::self()  在ProcessState中初始化binder系统
//setThreadPoolMaxThreadCount(0)  设置当前进程用于binder通信的线程数为1
ProcessState中初始化binder系统:
sp<ProcessState> ProcessState::self()           
{
    //加锁,单例实现
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");//创建ProcessState对象
    return gProcess;
}

ProcesState的初始化方法中,会去打开binder驱动,在kernel中初始化本进程的相关数据结构:

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))  //打开binder(/dev/binder)节点, 初始化当前进程中的binder框架, 并将打开节点的fd 赋值给 mDriverFD 变量
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
{
    if (mDriverFD >= 0) {
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        ......
    }
}

open_driver会去打开binder节点,并与binder驱动进行通信,进行 binder版本对比,与 设置默认通信线程数:

static int open_driver(const char *driver)
{
    int fd = open(driver, O_RDWR | O_CLOEXEC); //打开/dev/binder节点,在binder驱动里面会初始化出,此进程对应binder数据结构
    if (fd >= 0) {      
        int vers = 0;   
        status_t result = ioctl(fd, BINDER_VERSION, &vers); // 使用ioctl 获取当前的binder 的版本
        .........
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;//15
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); //告诉binder驱动 当前binder进程 最大线程数,此处默认为16个 binder线程
    }}
    return fd;
}
设置用于binder通信的线程数目:

​ 在ProcessState初始化时,已经在open_driver方法中,将用于binder 通信的进程数设置为了默认值15。但之后会另行设置一次:

ProcessState::self()->setThreadPoolMaxThreadCount(0);
//self 初始化binder系统
//setThreadPoolMaxThreadCount(0) 是通过ProcessState 告诉binder驱动,但前进程,用于进行binder通信的线程数为1
初始化Update_Engine服务

UpdateEngine服务的构建,也是在 UpdateEngineDaemon::OnInit 里面开始的,服务在构建初始化时,会关联 绑定,底层的boot_control服务。

UpdateEngine 服务的实现在 代码里面有两个

BinderUpdateEngineAndroidServiceBinderUpdateEngineBrilloService在此 以BinderUpdateEngineAndroidService进行梳理:

DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid();
daemon_state_.reset(daemon_state_android);

binder_service_ = new BinderUpdateEngineAndroidService{
    daemon_state_android->service_delegate()
};
 auto binder_wrapper = android::BinderWrapper::Get();  
 if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),                                                                       binder_service_)) {
    LOG(ERROR) << "Failed to register binder service.";
 }
 daemon_state_->AddObserver(binder_service_.get()); 

以上代码为创建UpdateEngine服务的代码,它的流程为:*

  • 初始化DaemonStateAndroid对象,并将对象通过set方法赋值给daemon_state_
  • 使用daemon_state_android 创建BinderUpdateEngineAndroidService 服务对象
DaemonStateAndroid对象初始化
system/update_engine/daemon_state_android.cc
bool DaemonStateAndroid::Initialize() {
  boot_control_ = boot_control::CreateBootControl();

  hardware_ = hardware::CreateHardware();

  base::FilePath non_volatile_path;
  if (!hardware_->GetNonVolatileDirectory(&non_volatile_path)) {
    return false;
  }
  Prefs* prefs = new Prefs();
  prefs_.reset(prefs);
  if (!prefs->Init(non_volatile_path.Append(kPrefsSubDirectory))) {
    return false;
  }
  update_attempter_.reset(new UpdateAttempterAndroid(
      this, prefs_.get(), boot_control_.get(), hardware_.get()));

  return true;
}                                                                                 

​ 在DaemonStateAndroid对象初始化创建时 ,会自动调用DaemonStateAndroidInitialize 方法,在此方法中做的操作有:

  1. 初始化 update_engine 内部的 boot_control对象
  2. 创建update_engine 内部的 hardware 对象
  3. 初始化更新的具体实现类 UpdateAttempterAndroid 赋值给update_attempter_
关联并初始化boot_control对象

通过hidl 获取boot_contrlclient对象,通过此对象和 boot_contrl 服务进行通信, 对A|B 系统的分区状态进行管理

boot_control_ = boot_control::CreateBootControl();
//此方法的实现位于:
system/update_engine/boot_control_android.cc
namespace boot_control {
    std::unique_ptr<BootControlInterface> CreateBootControl() {
        std::unique_ptr<BootControlAndroid> boot_control(new BootControlAndroid());
        if (!boot_control->Init()) {
            return nullptr;
        }
        return std::move(boot_control);
    }
}

​ 创建一个 BootControlAndroid 对象 并 赋值给 boot_control , 然后调用BootControlAndroidInit方法,使用Vender Interface,关联到了底层的 boot_control 服务。

bool BootControlAndroid::Init() {                         
  module_ = IBootControl::getService();
  if (module_ == nullptr) {
    LOG(ERROR) << "Error getting bootctrl HIDL module.";
    return false;
  }
  return true;
}

IBootControl::getService也是调用hidl 生成的代码来获取boot_contrl 的client 端的,此getService方法的实现为:

out/soong/.intermediates/hardware/interfaces/boot/1.0/android.hardware.boot@1.0_genc++/gen/android/hardware/boot/1.0/BootControlAll.cpp
 ::android::sp<IBootControl> IBootControl::getService(const std::string &serviceName, const bool getStub) {
     sp<IBootControl> iface = nullptr;
     const sp<::android::hidl::manager::V1_0::IServiceManager> sm = defaultServiceManager();
     Return<sp<::android::hidl::base::V1_0::IBase>> ret = 
                 sm->get(IBootControl::descriptor, serviceName);
     Return<sp<IBootControl>> castRet = IBootControl::castFrom(base, true );
     return iface;
  }

​ 从此getService 方法可以看到,它类似 binder系统,也是通过defaultServiceManager()方法,使用0构建一个halServiceManagerclient端,然后从halServiceManager中获取boot_control服务的client端口,并将对象返回,由此Update_Engine 服务就与 boot_control 服务建立了联系

update_engine 服务添加到 ServiceManager

update_engine 服务添加到ServiceManager ,也是从 UpdateEngineDaemon::OnInit 里面开始的:

 auto binder_wrapper = android::BinderWrapper::Get();  
 if (!binder_wrapper->RegisterService(binder_service_->ServiceName(), binder_service_)) {
 }

android::BinderWrapper::get() 获取到的是之前创建的RealBinderWrapper对象

那么BinderUpdateEngineAndroidService的服务的注册流程为:

system/core/libbinderwrapper/real_binder_wrapper.cc
bool RealBinderWrapper::RegisterService(const std::string& service_name,
                                        const sp<IBinder>& binder) {
  sp<IServiceManager> service_manager = defaultServiceManager();
  status_t status = defaultServiceManager()->addService(
      String16(service_name.c_str()), binder);
  return true;
}

当前进程通过defaultServiceManager 方法来获取IServiceManagerclient 端口

IServiceManager 的fd指定为 0,所以可以通过defaultServiceManager 方法以0 构建一个client端口

native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

​ 取到IServiceManagerclient后,调用addService将当前服务BinderUpdateEngineAndroidService注册到了 ServiceManager里面了, 之后java层就可以直接通过ServiceManager来获取服务的client端*

update_engine 对外提供的接口为:

package android.os;
import android.os.IUpdateEngineCallback;
/** @hide */
interface IUpdateEngine {
  /** @hide */
  void applyPayload(String url,
                    in long payload_offset,
                    in long payload_size,
                    in String[] headerKeyValuePairs);
  /** @hide */
  boolean bind(IUpdateEngineCallback callback);
  /** @hide */
  boolean unbind(IUpdateEngineCallback callback);
  /** @hide */
  void suspend();
  /** @hide */
  void resume();
  /** @hide */
  void cancel();
  /** @hide */
  void resetStatus();
}

bindunbind

java层 绑定 update_engine 服务,并将 callback传递给update_engine,实时接受更新时的状态。

applyPayload

url: 升级数据的url 可以是网上也可以是本地的

payload_offset:因为 升级数据里面可以存在一些额外的数据,所以此值指定的是 有效数据在 升级包中的偏移值

payload_size:这个指的是升级包中,有效数据的大小

headerKeyValuePairs: 升级包的元数据??? (不确定)

ps:从此处可以看出binderhwbinder 的流程非常相识, binderhwbinder的具体流程,将来在理理


javaUpdateEngine的使用

​ 在java层 通过 UpdateEngine类,访问底层的Update_Engine服务,Update_Engine服务,则在后台实现更新,并通过 boot_control 更新系统分区的状态,它的调用大概为:

UpdateEngine engine = new UpdateEngine();
engine.bind(new UpdateEngineCallback(){
    @Override
    public void onStatusUpdate(int status, float percent){
    }
    @Override
    public void onPayloadApplicationComplete(int errorCode){
    }
});
engine.applyPayload(......);

这段代码有一下作用:

  • UpdateEngine 在初始化时, 获取 Update_Engine 服务的client
  • client端 使用bind 方法将 Callback 对象, 传递给Update_Engine服务 以便获取更新的状态
  • engine.applyPayload通知 UPdate_Engine 服务,去更新系统

UpdateEngine初始化

UpdateEngine 在初始化时,会从 ServiceManager中获取Update_Engine 服务的client端:

 @SystemApi
 public UpdateEngine() {
     mUpdateEngine = IUpdateEngine.Stub.asInterface(
             ServiceManager.getService(UPDATE_ENGINE_SERVICE));
 }

这种从ServiceManager中获取服务的方式,在java中常见,不另行展开了。

Update_Engine服务注册CallBack对象

 engine.bind(new UpdateEngineCallback(){
        @Override
        public void onStatusUpdate(int status, float percent){
        }
        @Override
        public void onPayloadApplicationComplete(int errorCode){
        }
    });

Update_Engine服务的实现,从上面可知是位于:

system/update_engine/binder_service_android.cc

bind方法的具体实现为:

Status BinderUpdateEngineAndroidService::bind(
    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {                   
  callbacks_.emplace_back(callback);
  ...
  return Status::ok();
}

Update_Engine 服务中会将 callback 对象存储于callbacks_ 集合中,之后状态更新时,对callback进行回调。

applyPayload 进行系统更新

 engine.applyPayload(......);

它的实现也是位于:

system/update_engine/binder_service_android.cc
Status BinderUpdateEngineAndroidService::applyPayload(
    const android::String16& url, int64_t payload_offset, int64_t payload_size,
    const std::vector<android::String16>& header_kv_pairs) {

  if (!service_delegate_->ApplyPayload(                                               
          payload_url, payload_offset, payload_size, str_headers, &error)) {
    return ErrorPtrToStatus(error);
  }
  return Status::ok();
}

​ 在Update_Engine 服务内,会在去调用service_delegate_ApplyPayload方法,而service_delegate_对象为 update_attempter_android.cc的实现。(可以跟踪 DaemonStateAndroid对象初始化 的流程,去看 service_delegate_的初始化流程)

system/update_engine/update_attempter_android.cc
bool UpdateAttempterAndroid::ApplyPayload( const string& payload_url,
    int64_t payload_offset, int64_t payload_size,
    const vector<string>& key_value_pair_headers, brillo::ErrorPtr* error) {

  install_plan_ = InstallPlan();

  install_plan_.download_url = payload_url;
  install_plan_.version = "";
  base_offset_ = payload_offset;
  InstallPlan::Payload payload;
  payload.size = payload_size;

  if (!brillo::data_encoding::Base64Decode(headers[kPayloadPropertyFileHash],
                                           &payload.hash)) {
  }

  payload.type = InstallPayloadType::kUnknown;
  install_plan_.payloads.push_back(payload);

  install_plan_.source_slot = boot_control_->GetCurrentSlot();
  install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0;

  int data_wipe = 0;
  install_plan_.powerwash_required =
      base::StringToInt(headers[kPayloadPropertyPowerwash], &data_wipe) &&
      data_wipe != 0;
  NetworkId network_id = kDefaultNetworkId;
  BuildUpdateActions(payload_url);
  SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
  ongoing_update_ = true;
  UpdateBootFlags();
  return true;
} 

这块后台更新的代码还没有梳理清楚,但大概做的操作为:

  • 校验升级包
  • 下载升级数据包
  • 回调callback,通知状态发生改变 SetStatusAndNotify
  • 更新 boot_control 中对分区的标记UpdateBootFlags();
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值