Android P update_engine分析 -- update_engine_daemon的启动
Posted Give.Me.Five
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android P update_engine分析 -- update_engine_daemon的启动相关的知识,希望对你有一定的参考价值。
上篇我们在update_engine启动时,分析了update_engine日志logging的启动和log文件的操作。这篇我们继续来研究update_engine_daemon的启动过程。因为updateEngineDaemon是继承brillo::Daemon的。从Daemon.Run()可以看到会调用onInit()函数。
int UpdateEngineDaemon::OnInit() {
subprocess_.Init(this);
//父类初始化
int exit_code = Daemon::OnInit();
//Binder初始化
android::BinderWrapper::Create();
binder_watcher_.Init();
//DaemonStateAndroid的初始化
DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid();
daemon_state_.reset(daemon_state_android);
LOG_IF(ERROR, !daemon_state_android->Initialize())
<< "Failed to initialize system state.";
//初始化BinderUpdateEngineAndroidService
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());
//启动updater
daemon_state_->StartUpdater();
updateEngineDaemon的onInit()里大致做了三件事情:1. 初始化DaemonStateAndroid 2. 初始化BinderUpdateEngineAndroidService 3.启动startUpdater.
初始化DaemonStateAndroid
bool DaemonStateAndroid::Initialize() {
//初始化boot_control
boot_control_ = boot_control::CreateBootControl();
//创建硬件相关接口,主要以属性操作为主
hardware_ = hardware::CreateHardware();
//初始化存取key的存储接口
Prefs* prefs = new Prefs();
prefs_.reset(prefs);
if (!prefs->Init(non_volatile_path.Append(kPrefsSubDirectory))) {
LOG(ERROR) << "Failed to initialize preferences.";
return false;
}
//校验类的初始化
certificate_checker_.reset(
new CertificateChecker(prefs_.get(), &openssl_wrapper_));
certificate_checker_->Init();
//update_attempter的实始化
update_attempter_.reset(new UpdateAttempterAndroid(
this, prefs_.get(), boot_control_.get(), hardware_.get()));
DaemonStateAndroid的初始化主要做了如下事件
- boot_control的初始化,为后面的切换A/B slot做准备。后续专门写一篇来详细说明
- hardware的初始化,为了后续获取版本信息,OOB的状态,编译时间等信息
- prefs的初始化,主要为了从文件中读写key
- certificateChecker的初始化,主要为后面验证升级包
- updateAttempterAndroid的初始化, 基于前面获取的boot_control, perfs, hardware的实类初始化
初始化BinderUpdateEngineAndroidService
BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
ServiceDelegateAndroidInterface* service_delegate)
: service_delegate_(service_delegate) {
}
从上面代码看,初始化BinderUpdateEngineAndroidService时,会把DaemonStateAndroid 的实例指针传给BinderUpdateEngineAndroidService。然后DaemonStateAndroid 会调用 AddObserver,将这个加入到service_observers_的列表中,后续通过调用service_observers()来获取这个列表,从而获取这个函数指针来调用其函数。其函数列表里有:
// android::os::BnUpdateEngine overrides.
android::binder::Status applyPayload(
const android::String16& url,
int64_t payload_offset,
int64_t payload_size,
const std::vector<android::String16>& header_kv_pairs) override;
android::binder::Status bind(
const android::sp<android::os::IUpdateEngineCallback>& callback,
bool* return_value) override;
android::binder::Status unbind(
const android::sp<android::os::IUpdateEngineCallback>& callback,
bool* return_value) override;
android::binder::Status suspend() override;
android::binder::Status resume() override;
android::binder::Status cancel() override;
android::binder::Status resetStatus() override;
android::binder::Status verifyPayloadApplicable(
const android::String16& metadata_filename, bool* return_value) override;
启动startUpdater
bool DaemonStateAndroid::StartUpdater() {
update_attempter_->Init();
return true;
}
这个会调用 到UpdateAttempterAndroid的init()函数:
void UpdateAttempterAndroid::Init() {
// In case of update_engine restart without a reboot we need to restore the
// reboot needed state.
//检测升级状态
if (UpdateCompletedOnThisBoot()) {
//设置为需要重启,并通知回调给升级应用
SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
} else {
//设置为空间模式,同时更新配置
SetStatusAndNotify(UpdateStatus::IDLE);
UpdatePrefsAndReportUpdateMetricsOnReboot();
}
}
bool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() {
// In case of an update_engine restart without a reboot, we stored the boot_id
// when the update was completed by setting a pref, so we can check whether
// the last update was on this boot or a previous one.
string boot_id;
TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
string update_completed_on_boot_id;
//判断配置升级完成的bootid 与当前的bootId,是不是同一个???
return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) &&
prefs_->GetString(kPrefsUpdateCompletedOnBootId,
&update_completed_on_boot_id) &&
update_completed_on_boot_id == boot_id);
}
void UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) {
status_ = status;
size_t payload_size =
install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size;
UpdateEngineStatus status_to_send = {.status = status_,
.progress = download_progress_,
.new_size_bytes = payload_size};
//遍历所有监控者
for (auto observer : daemon_state_->service_observers()) {
//将当前状态通知监控者
observer->SendStatusUpdate(status_to_send);
}
last_notify_time_ = TimeTicks::Now();
}
上面注释与逻辑中可以看到,我们需要先去看当前的bootid 是否需要等待重启切换slot, 如果需要刚通知上面的调用方去上报状态。不需要重启,也需要上报空闲状态,同时更新perfs配置。下面来看如何更新配置:
void UpdateAttempterAndroid::UpdatePrefsAndReportUpdateMetricsOnReboot() {
string current_boot_id;
//获取当前slot
TEST_AND_RETURN(utils::GetBootId(¤t_boot_id));
// Example: [ro.build.version.incremental]: [4292972]
//获取当前版本
string current_version =
android::base::GetProperty("ro.build.version.incremental", "");
TEST_AND_RETURN(!current_version.empty());
// If there's no record of previous version (e.g. due to a data wipe), we
// save the info of current boot and skip the metrics report.
//如果没有之前版本的记录信息,刚更新保存当前版本信息和去掉一些升级信息
if (!prefs_->Exists(kPrefsPreviousVersion)) {
prefs_->SetString(kPrefsBootId, current_boot_id);
prefs_->SetString(kPrefsPreviousVersion, current_version);
ClearMetricsPrefs();
return;
}
string previous_version;
// 更新bootid 和 重启次数
if (prefs_->GetString(kPrefsPreviousVersion, &previous_version) &&
previous_version == current_version) {
string last_boot_id;
bool is_reboot = prefs_->Exists(kPrefsBootId) &&
(prefs_->GetString(kPrefsBootId, &last_boot_id) &&
last_boot_id != current_boot_id);
// Increment the reboot number if |kPrefsNumReboots| exists. That pref is
// set when we start a new update.
if (is_reboot && prefs_->Exists(kPrefsNumReboots)) {
prefs_->SetString(kPrefsBootId, current_boot_id);
int64_t reboot_count =
metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
metrics_utils::SetNumReboots(reboot_count + 1, prefs_);
}
return;
}
// 更新bootid
prefs_->SetString(kPrefsBootId, current_boot_id);
prefs_->SetString(kPrefsPreviousVersion, current_version);
bool previous_attempt_exists = prefs_->Exists(kPrefsPayloadAttemptNumber);
// |kPrefsPayloadAttemptNumber| should be cleared upon successful update.
if (previous_attempt_exists) {
metrics_reporter_->ReportAbnormallyTerminatedUpdateAttemptMetrics();
}
metrics_utils::LoadAndReportTimeToReboot(
metrics_reporter_.get(), prefs_, clock_.get());
ClearMetricsPrefs();
}
到这里update_engine_daemon的启动信息就升级完了
以上是关于Android P update_engine分析 -- update_engine_daemon的启动的主要内容,如果未能解决你的问题,请参考以下文章
Android P update_engine分析--升级核心DeltaPerformer的分析
Android P update_engine分析--升级核心DeltaPerformer的分析
Android P update_engine分析--升级核心DeltaPerformer的分析
Android P update_engine分析--升级核心DeltaPerformer的分析