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