java调用hidl_A|B升级框架

A|B升级

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

boot_control 服务主要用于提供修改 A|B 系统分区状态的相关接口。

UpdateEngine 服务 主要用于后台更新 A|B 系统,并通过通过boot_control去修改 当时的分区状态。

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里面,以便让外界进行访问,它大概可以 分为以下几个部分:。

boot_control 服务的启动

boot_control 服务的初始化

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();

}

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

/system/libhidl/transport/include/hidl/LegacySupport.h

template

__attribute__((warn_unused_result))

status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1) {

return defaultPassthroughServiceImplementation("default", maxThreads);

}

template

__attribute__((warn_unused_result))

status_t defaultPassthroughServiceImplementation(std::string name,

size_t maxThreads = 1) {

configureRpcThreadpool(maxThreads, true);

status_t result = registerPassthroughServiceImplementation(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 实现一套专用 ProcessState、IPCThreadState、BpHwBinder … 与原有的那套区别开来,它的具体实现,之后有空,在另行总结。

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

ProcessState::self()类似 binder 框架里面的流程,在当前进程中初始化 hwbinder

setThreadPoolConfiguration 设置当前进程用于hwBinder 通信的进程数

当前进程中hwbinder框架的初始化

​ hidl 的 PrcessState、IPCThreadState… 的代码位置为:

system/libhwbinder/ProcessState.cpp

system/libhwbinder/IPCThreadState.cpp

......

​ 在self 方法里面创建 ProcessState对象

sp 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 服务后,在service的main方法中,通过defaultPassthroughServiceImplementation展开为为两个步骤去处理:

configureRpcThreadpool 初始化当前进程内的hwbinder体系

registerPassthroughServiceImplementation 初始化boot_control服务,并添加到halServiceManager里面。

boot_control 服务的初始化

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

boot_control 服务的初始化

boot_control 服务添加到 halServiceManager

此处 Interface 为 IBootControl ,name 为 default ,此方法展开为:

template

__attribute__((warn_unused_result))

status_t registerPassthroughServiceImplementation(

std::string name = "default") {

sp 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

它的实现可以参考:

​ 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(&module);

ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast(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 模块

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

创建并返回 BootControl 对象

​ BootControl 通过hw_get_module 与 bootctrl 模块 建立了联系,然后调用 它的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 ret = sm->add(serviceName.c_str(), this);

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

}

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

通过defaultServiceManager获取hwServiceManager的client端口(类似binder系统,此处使用0 构建了一个hwServiceManager 的 client端口)

sm->add(serviceName.c_str(), this) 将当前 boot_control 服务添加进入hwServiceManager

defaultServiceManager 的实现为:

/system/libhidl/transport/ServiceManagement.cpp

sp 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(

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)

​ 在ProcessState的 getContextObject方法内,以0 构建一个hwServiceManager的client端

​ 然后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启动的,它可以分为一下几个部分:

update_engine 服务的启动

update_engine 服务的初始化与通过hidl 与boot_control 建立联系

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继承自brillo的damon 类,执行的也为daemon的run方法:

初始化展开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 调用的 daemon的run方法,所以在此处是调用的UpdateEngineDaemon的OnInit方法。

类似继承,onInit方法会调用brillo中 daemon 的继承类实现

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_engine中 binder 系统的构建

初始化Update_Engine 并通过hidl 与boot_control 建立联系

update_engine 服务添加到 ServiceManager中

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

Update_Engine服务的初始化

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

用于和ServiceManager通信的BinderWrapper对象的构建

update_engine中 binder 系统的构建

初始化Update_Engine 并通过hidl 与boot_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::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 服务的实现在 代码里面有两个

BinderUpdateEngineAndroidService、BinderUpdateEngineBrilloService在此 以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对象初始化创建时 ,会自动调用DaemonStateAndroid 的Initialize 方法,在此方法中做的操作有:

初始化 update_engine 内部的 boot_control对象

创建update_engine 内部的 hardware 对象

初始化更新的具体实现类 UpdateAttempterAndroid 赋值给update_attempter_

关联并初始化boot_control对象

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

boot_control_ = boot_control::CreateBootControl();

//此方法的实现位于:

system/update_engine/boot_control_android.cc

namespace boot_control {

std::unique_ptr CreateBootControl() {

std::unique_ptr boot_control(new BootControlAndroid());

if (!boot_control->Init()) {

return nullptr;

}

return std::move(boot_control);

}

}

​ 创建一个 BootControlAndroid 对象 并 赋值给 boot_control , 然后调用BootControlAndroid 的 Init方法,使用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::getService(const std::string &serviceName, const bool getStub) {

sp iface = nullptr;

const sp<::android::hidl::manager::v1_0::iservicemanager> sm = defaultServiceManager();

Return> ret =

sm->get(IBootControl::descriptor, serviceName);

Return> castRet = IBootControl::castFrom(base, true );

return iface;

}

​ 从此getService 方法可以看到,它类似 binder系统,也是通过defaultServiceManager()方法,使用0构建一个halServiceManager的client端,然后从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& binder) {

sp service_manager = defaultServiceManager();

status_t status = defaultServiceManager()->addService(

String16(service_name.c_str()), binder);

return true;

}

​ 当前进程通过defaultServiceManager 方法来获取IServiceManager的 client 端口

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

native/libs/binder/IServiceManager.cpp

sp defaultServiceManager()

{

if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

{

AutoMutex _l(gDefaultServiceManagerLock);

while (gDefaultServiceManager == NULL) {

gDefaultServiceManager = interface_cast(

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

if (gDefaultServiceManager == NULL)

sleep(1);

}

}

return gDefaultServiceManager;

}

​ 取到IServiceManager 的client后,调用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();

}

bind 与unbind

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

applyPayload

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

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

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

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

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

java层UpdateEngine的使用

​ 在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& 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<: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& 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();

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值