74b0f7cce0
The TargetFile class parses a target-file and provides functions to read its contents. And the BuildInfo tries to simulate the device with files on host. Some work it does includes parsing the build properties, and extracting the image files for partitions specified in the fstab. Bug: 131911365 Test: unit tests pass, run simulator with cuttlefish, wear devices and from extracted TF. Change-Id: Iefe4a96d619d2e4b3d038e31480f11a0f9a70afa
126 lines
4.4 KiB
C++
126 lines
4.4 KiB
C++
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "updater/build_info.h"
|
|
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
#include <android-base/logging.h>
|
|
#include <android-base/stringprintf.h>
|
|
#include <android-base/strings.h>
|
|
|
|
#include "updater/target_files.h"
|
|
|
|
bool BuildInfo::ParseTargetFile(const std::string_view target_file_path, bool extracted_input) {
|
|
TargetFile target_file(std::string(target_file_path), extracted_input);
|
|
if (!target_file.Open()) {
|
|
return false;
|
|
}
|
|
|
|
if (!target_file.GetBuildProps(&build_props_)) {
|
|
return false;
|
|
}
|
|
|
|
std::vector<FstabInfo> fstab_info_list;
|
|
if (!target_file.ParseFstabInfo(&fstab_info_list)) {
|
|
return false;
|
|
}
|
|
|
|
for (const auto& fstab_info : fstab_info_list) {
|
|
for (const auto& directory : { "IMAGES", "RADIO" }) {
|
|
std::string entry_name = directory + fstab_info.mount_point + ".img";
|
|
if (!target_file.EntryExists(entry_name)) {
|
|
LOG(WARNING) << "Failed to find the image entry in the target file: " << entry_name;
|
|
continue;
|
|
}
|
|
|
|
temp_files_.emplace_back(work_dir_);
|
|
auto& image_file = temp_files_.back();
|
|
if (!target_file.ExtractImage(entry_name, fstab_info, work_dir_, &image_file)) {
|
|
LOG(ERROR) << "Failed to set up source image files.";
|
|
return false;
|
|
}
|
|
|
|
LOG(INFO) << "Mounted " << fstab_info.mount_point << "\nMapping: " << fstab_info.blockdev_name
|
|
<< " to " << image_file.path;
|
|
|
|
blockdev_map_.emplace(
|
|
fstab_info.blockdev_name,
|
|
FakeBlockDevice(fstab_info.blockdev_name, fstab_info.mount_point, image_file.path));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::string BuildInfo::GetProperty(const std::string_view key,
|
|
const std::string_view default_value) const {
|
|
// The logic to parse the ro.product properties should be in line with the generation script.
|
|
// More details in common.py BuildInfo.GetBuildProp.
|
|
// TODO(xunchang) handle the oem property and the source order defined in
|
|
// ro.product.property_source_order
|
|
const std::set<std::string, std::less<>> ro_product_props = {
|
|
"ro.product.brand", "ro.product.device", "ro.product.manufacturer", "ro.product.model",
|
|
"ro.product.name"
|
|
};
|
|
const std::vector<std::string> source_order = {
|
|
"product", "product_services", "odm", "vendor", "system",
|
|
};
|
|
if (ro_product_props.find(key) != ro_product_props.end()) {
|
|
std::string_view key_suffix(key);
|
|
CHECK(android::base::ConsumePrefix(&key_suffix, "ro.product"));
|
|
for (const auto& source : source_order) {
|
|
std::string resolved_key = "ro.product." + source + std::string(key_suffix);
|
|
if (auto entry = build_props_.find(resolved_key); entry != build_props_.end()) {
|
|
return entry->second;
|
|
}
|
|
}
|
|
LOG(WARNING) << "Failed to find property: " << key;
|
|
return std::string(default_value);
|
|
} else if (key == "ro.build.fingerprint") {
|
|
// clang-format off
|
|
return android::base::StringPrintf("%s/%s/%s:%s/%s/%s:%s/%s",
|
|
GetProperty("ro.product.brand", "").c_str(),
|
|
GetProperty("ro.product.name", "").c_str(),
|
|
GetProperty("ro.product.device", "").c_str(),
|
|
GetProperty("ro.build.version.release", "").c_str(),
|
|
GetProperty("ro.build.id", "").c_str(),
|
|
GetProperty("ro.build.version.incremental", "").c_str(),
|
|
GetProperty("ro.build.type", "").c_str(),
|
|
GetProperty("ro.build.tags", "").c_str());
|
|
// clang-format on
|
|
}
|
|
|
|
auto entry = build_props_.find(key);
|
|
if (entry == build_props_.end()) {
|
|
LOG(WARNING) << "Failed to find property: " << key;
|
|
return std::string(default_value);
|
|
}
|
|
|
|
return entry->second;
|
|
}
|
|
|
|
std::string BuildInfo::FindBlockDeviceName(const std::string_view name) const {
|
|
auto entry = blockdev_map_.find(name);
|
|
if (entry == blockdev_map_.end()) {
|
|
LOG(WARNING) << "Failed to find path to block device " << name;
|
|
return "";
|
|
}
|
|
|
|
return entry->second.mounted_file_path;
|
|
}
|