diff options
Diffstat (limited to 'otautil')
-rw-r--r-- | otautil/Android.bp | 37 | ||||
-rw-r--r-- | otautil/dirutil.cpp (renamed from otautil/DirUtil.cpp) | 2 | ||||
-rw-r--r-- | otautil/include/otautil/cache_location.h | 69 | ||||
-rw-r--r-- | otautil/include/otautil/dirutil.h (renamed from otautil/include/otautil/DirUtil.h) | 0 | ||||
-rw-r--r-- | otautil/include/otautil/error_code.h | 2 | ||||
-rw-r--r-- | otautil/include/otautil/mounts.h | 25 | ||||
-rw-r--r-- | otautil/include/otautil/parse_install_logs.h | 33 | ||||
-rw-r--r-- | otautil/include/otautil/paths.h | 118 | ||||
-rw-r--r-- | otautil/include/otautil/sysutil.h (renamed from otautil/include/otautil/SysUtil.h) | 9 | ||||
-rw-r--r-- | otautil/include/otautil/thermalutil.h (renamed from otautil/include/otautil/ThermalUtil.h) | 0 | ||||
-rw-r--r-- | otautil/mounts.cpp | 82 | ||||
-rw-r--r-- | otautil/parse_install_logs.cpp | 114 | ||||
-rw-r--r-- | otautil/paths.cpp (renamed from otautil/cache_location.cpp) | 24 | ||||
-rw-r--r-- | otautil/rangeset.cpp | 38 | ||||
-rw-r--r-- | otautil/sysutil.cpp (renamed from otautil/SysUtil.cpp) | 21 | ||||
-rw-r--r-- | otautil/thermalutil.cpp (renamed from otautil/ThermalUtil.cpp) | 2 |
16 files changed, 464 insertions, 112 deletions
diff --git a/otautil/Android.bp b/otautil/Android.bp index 75cf69148..41018dd2f 100644 --- a/otautil/Android.bp +++ b/otautil/Android.bp @@ -16,27 +16,40 @@ cc_library_static { name: "libotautil", host_supported: true, + recovery_available: true, + defaults: [ + "recovery_defaults", + ], + + // Minimal set of files to support host build. srcs: [ - "SysUtil.cpp", - "DirUtil.cpp", - "ThermalUtil.cpp", - "cache_location.cpp", + "paths.cpp", "rangeset.cpp", ], - static_libs: [ - "libselinux", + shared_libs: [ "libbase", ], - cflags: [ - "-D_FILE_OFFSET_BITS=64", - "-Werror", - "-Wall", - ], - export_include_dirs: [ "include", ], + + target: { + android: { + srcs: [ + "dirutil.cpp", + "mounts.cpp", + "parse_install_logs.cpp", + "sysutil.cpp", + "thermalutil.cpp", + ], + + shared_libs: [ + "libcutils", + "libselinux", + ], + }, + }, } diff --git a/otautil/DirUtil.cpp b/otautil/dirutil.cpp index 61c832813..ae1cd5c28 100644 --- a/otautil/DirUtil.cpp +++ b/otautil/dirutil.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "otautil/DirUtil.h" +#include "otautil/dirutil.h" #include <dirent.h> #include <errno.h> diff --git a/otautil/include/otautil/cache_location.h b/otautil/include/otautil/cache_location.h deleted file mode 100644 index f2f663816..000000000 --- a/otautil/include/otautil/cache_location.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef _OTAUTIL_OTAUTIL_CACHE_LOCATION_H_ -#define _OTAUTIL_OTAUTIL_CACHE_LOCATION_H_ - -#include <string> - -#include "android-base/macros.h" - -// A singleton class to maintain the update related locations. The locations should be only set -// once at the start of the program. -class CacheLocation { - public: - static CacheLocation& location(); - - // getter and setter functions. - std::string cache_temp_source() const { - return cache_temp_source_; - } - void set_cache_temp_source(const std::string& temp_source) { - cache_temp_source_ = temp_source; - } - - std::string last_command_file() const { - return last_command_file_; - } - void set_last_command_file(const std::string& last_command) { - last_command_file_ = last_command; - } - - std::string stash_directory_base() const { - return stash_directory_base_; - } - void set_stash_directory_base(const std::string& base) { - stash_directory_base_ = base; - } - - private: - CacheLocation(); - DISALLOW_COPY_AND_ASSIGN(CacheLocation); - - // When there isn't enough room on the target filesystem to hold the patched version of the file, - // we copy the original here and delete it to free up space. If the expected source file doesn't - // exist, or is corrupted, we look to see if the cached file contains the bits we want and use it - // as the source instead. The default location for the cached source is "/cache/saved.file". - std::string cache_temp_source_; - - // Location to save the last command that stashes blocks. - std::string last_command_file_; - - // The base directory to write stashes during update. - std::string stash_directory_base_; -}; - -#endif // _OTAUTIL_OTAUTIL_CACHE_LOCATION_H_ diff --git a/otautil/include/otautil/DirUtil.h b/otautil/include/otautil/dirutil.h index 85d6c16d1..85d6c16d1 100644 --- a/otautil/include/otautil/DirUtil.h +++ b/otautil/include/otautil/dirutil.h diff --git a/otautil/include/otautil/error_code.h b/otautil/include/otautil/error_code.h index b0ff42d8d..2b73c1353 100644 --- a/otautil/include/otautil/error_code.h +++ b/otautil/include/otautil/error_code.h @@ -48,6 +48,8 @@ enum CauseCode : int { kRebootFailure, kPackageExtractFileFailure, kPatchApplicationFailure, + kHashTreeComputationFailure, + kEioFailure, kVendorFailure = 200 }; diff --git a/otautil/include/otautil/mounts.h b/otautil/include/otautil/mounts.h new file mode 100644 index 000000000..6786c8d2e --- /dev/null +++ b/otautil/include/otautil/mounts.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007 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. + */ + +#pragma once + +struct MountedVolume; + +bool scan_mounted_volumes(); + +MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point); + +int unmount_mounted_volume(MountedVolume* volume); diff --git a/otautil/include/otautil/parse_install_logs.h b/otautil/include/otautil/parse_install_logs.h new file mode 100644 index 000000000..135d29ccf --- /dev/null +++ b/otautil/include/otautil/parse_install_logs.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 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. + */ + +#pragma once + +#include <stdint.h> + +#include <map> +#include <string> +#include <vector> + +constexpr const char* LAST_INSTALL_FILE = "/data/misc/recovery/last_install"; +constexpr const char* LAST_INSTALL_FILE_IN_CACHE = "/cache/recovery/last_install"; + +// Parses the metrics of update applied under recovery mode in |lines|, and returns a map with +// "name: value". +std::map<std::string, int64_t> ParseRecoveryUpdateMetrics(const std::vector<std::string>& lines); +// Parses the sideload history and update metrics in the last_install file. Returns a map with +// entries as "metrics_name: value". If no such file exists, returns an empty map. +std::map<std::string, int64_t> ParseLastInstall(const std::string& file_name); diff --git a/otautil/include/otautil/paths.h b/otautil/include/otautil/paths.h new file mode 100644 index 000000000..f95741a24 --- /dev/null +++ b/otautil/include/otautil/paths.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2018 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. + */ + +#ifndef _OTAUTIL_PATHS_H_ +#define _OTAUTIL_PATHS_H_ + +#include <string> + +#include <android-base/macros.h> + +// A singleton class to maintain the update related paths. The paths should be only set once at the +// start of the program. +class Paths { + public: + static Paths& Get(); + + std::string cache_log_directory() const { + return cache_log_directory_; + } + void set_cache_log_directory(const std::string& log_dir) { + cache_log_directory_ = log_dir; + } + + std::string cache_temp_source() const { + return cache_temp_source_; + } + void set_cache_temp_source(const std::string& temp_source) { + cache_temp_source_ = temp_source; + } + + std::string last_command_file() const { + return last_command_file_; + } + void set_last_command_file(const std::string& last_command_file) { + last_command_file_ = last_command_file; + } + + std::string resource_dir() const { + return resource_dir_; + } + void set_resource_dir(const std::string& resource_dir) { + resource_dir_ = resource_dir; + } + + std::string stash_directory_base() const { + return stash_directory_base_; + } + void set_stash_directory_base(const std::string& base) { + stash_directory_base_ = base; + } + + std::string temporary_install_file() const { + return temporary_install_file_; + } + void set_temporary_install_file(const std::string& install_file) { + temporary_install_file_ = install_file; + } + + std::string temporary_log_file() const { + return temporary_log_file_; + } + void set_temporary_log_file(const std::string& log_file) { + temporary_log_file_ = log_file; + } + + std::string temporary_update_binary() const { + return temporary_update_binary_; + } + void set_temporary_update_binary(const std::string& update_binary) { + temporary_update_binary_ = update_binary; + } + + private: + Paths(); + DISALLOW_COPY_AND_ASSIGN(Paths); + + // Path to the directory that contains last_log and last_kmsg log files. + std::string cache_log_directory_; + + // Path to the temporary source file on /cache. When there isn't enough room on the target + // filesystem to hold the patched version of the file, we copy the original here and delete it to + // free up space. If the expected source file doesn't exist, or is corrupted, we look to see if + // the cached file contains the bits we want and use it as the source instead. + std::string cache_temp_source_; + + // Path to the last command file. + std::string last_command_file_; + + // Path to the resource dir; + std::string resource_dir_; + + // Path to the base directory to write stashes during update. + std::string stash_directory_base_; + + // Path to the temporary file that contains the install result. + std::string temporary_install_file_; + + // Path to the temporary log file while under recovery. + std::string temporary_log_file_; + + // Path to the temporary update binary while installing a non-A/B package. + std::string temporary_update_binary_; +}; + +#endif // _OTAUTIL_PATHS_H_ diff --git a/otautil/include/otautil/SysUtil.h b/otautil/include/otautil/sysutil.h index 52f6d20a7..2eeb7c302 100644 --- a/otautil/include/otautil/SysUtil.h +++ b/otautil/include/otautil/sysutil.h @@ -50,4 +50,13 @@ class MemMapping { std::vector<MappedRange> ranges_; }; +// Wrapper function to trigger a reboot, by additionally handling quiescent reboot mode. The +// command should start with "reboot," (e.g. "reboot,bootloader" or "reboot,"). +bool reboot(const std::string& command); + +// Returns a null-terminated char* array, where the elements point to the C-strings in the given +// vector, plus an additional nullptr at the end. This is a helper function that facilitates +// calling C functions (such as getopt(3)) that expect an array of C-strings. +std::vector<char*> StringVectorToNullTerminatedArray(const std::vector<std::string>& args); + #endif // _OTAUTIL_SYSUTIL diff --git a/otautil/include/otautil/ThermalUtil.h b/otautil/include/otautil/thermalutil.h index 43ab55940..43ab55940 100644 --- a/otautil/include/otautil/ThermalUtil.h +++ b/otautil/include/otautil/thermalutil.h diff --git a/otautil/mounts.cpp b/otautil/mounts.cpp new file mode 100644 index 000000000..951311bf3 --- /dev/null +++ b/otautil/mounts.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2007 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 "otautil/mounts.h" + +#include <errno.h> +#include <fcntl.h> +#include <mntent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mount.h> + +#include <string> +#include <vector> + +#include <android-base/logging.h> + +struct MountedVolume { + std::string device; + std::string mount_point; + std::string filesystem; + std::string flags; +}; + +static std::vector<MountedVolume*> g_mounts_state; + +bool scan_mounted_volumes() { + for (size_t i = 0; i < g_mounts_state.size(); ++i) { + delete g_mounts_state[i]; + } + g_mounts_state.clear(); + + // Open and read mount table entries. + FILE* fp = setmntent("/proc/mounts", "re"); + if (fp == NULL) { + return false; + } + mntent* e; + while ((e = getmntent(fp)) != NULL) { + MountedVolume* v = new MountedVolume; + v->device = e->mnt_fsname; + v->mount_point = e->mnt_dir; + v->filesystem = e->mnt_type; + v->flags = e->mnt_opts; + g_mounts_state.push_back(v); + } + endmntent(fp); + return true; +} + +MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point) { + for (size_t i = 0; i < g_mounts_state.size(); ++i) { + if (g_mounts_state[i]->mount_point == mount_point) return g_mounts_state[i]; + } + return nullptr; +} + +int unmount_mounted_volume(MountedVolume* volume) { + // Intentionally pass the empty string to umount if the caller tries to unmount a volume they + // already unmounted using this function. + std::string mount_point = volume->mount_point; + volume->mount_point.clear(); + int result = umount(mount_point.c_str()); + if (result == -1) { + PLOG(WARNING) << "Failed to umount " << mount_point; + } + return result; +} diff --git a/otautil/parse_install_logs.cpp b/otautil/parse_install_logs.cpp new file mode 100644 index 000000000..13a729921 --- /dev/null +++ b/otautil/parse_install_logs.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2018 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 "otautil/parse_install_logs.h" + +#include <unistd.h> + +#include <optional> + +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/parseint.h> +#include <android-base/properties.h> +#include <android-base/strings.h> + +constexpr const char* OTA_SIDELOAD_METRICS = "ota_sideload"; + +// Here is an example of lines in last_install: +// ... +// time_total: 101 +// bytes_written_vendor: 51074 +// bytes_stashed_vendor: 200 +std::map<std::string, int64_t> ParseRecoveryUpdateMetrics(const std::vector<std::string>& lines) { + constexpr unsigned int kMiB = 1024 * 1024; + std::optional<int64_t> bytes_written_in_mib; + std::optional<int64_t> bytes_stashed_in_mib; + std::map<std::string, int64_t> metrics; + for (const auto& line : lines) { + size_t num_index = line.find(':'); + if (num_index == std::string::npos) { + LOG(WARNING) << "Skip parsing " << line; + continue; + } + + std::string num_string = android::base::Trim(line.substr(num_index + 1)); + int64_t parsed_num; + if (!android::base::ParseInt(num_string, &parsed_num)) { + LOG(ERROR) << "Failed to parse numbers in " << line; + continue; + } + + if (android::base::StartsWith(line, "bytes_written")) { + bytes_written_in_mib = bytes_written_in_mib.value_or(0) + parsed_num / kMiB; + } else if (android::base::StartsWith(line, "bytes_stashed")) { + bytes_stashed_in_mib = bytes_stashed_in_mib.value_or(0) + parsed_num / kMiB; + } else if (android::base::StartsWith(line, "time")) { + metrics.emplace("ota_time_total", parsed_num); + } else if (android::base::StartsWith(line, "uncrypt_time")) { + metrics.emplace("ota_uncrypt_time", parsed_num); + } else if (android::base::StartsWith(line, "source_build")) { + metrics.emplace("ota_source_version", parsed_num); + } else if (android::base::StartsWith(line, "temperature_start")) { + metrics.emplace("ota_temperature_start", parsed_num); + } else if (android::base::StartsWith(line, "temperature_end")) { + metrics.emplace("ota_temperature_end", parsed_num); + } else if (android::base::StartsWith(line, "temperature_max")) { + metrics.emplace("ota_temperature_max", parsed_num); + } else if (android::base::StartsWith(line, "error")) { + metrics.emplace("ota_non_ab_error_code", parsed_num); + } else if (android::base::StartsWith(line, "cause")) { + metrics.emplace("ota_non_ab_cause_code", parsed_num); + } + } + + if (bytes_written_in_mib) { + metrics.emplace("ota_written_in_MiBs", bytes_written_in_mib.value()); + } + if (bytes_stashed_in_mib) { + metrics.emplace("ota_stashed_in_MiBs", bytes_stashed_in_mib.value()); + } + + return metrics; +} + +std::map<std::string, int64_t> ParseLastInstall(const std::string& file_name) { + if (access(file_name.c_str(), F_OK) != 0) { + return {}; + } + + std::string content; + if (!android::base::ReadFileToString(file_name, &content)) { + PLOG(ERROR) << "Failed to read " << file_name; + return {}; + } + + if (content.empty()) { + LOG(INFO) << "Empty last_install file"; + return {}; + } + + std::vector<std::string> lines = android::base::Split(content, "\n"); + auto metrics = ParseRecoveryUpdateMetrics(lines); + + // LAST_INSTALL starts with "/sideload/package.zip" after a sideload. + if (android::base::Trim(lines[0]) == "/sideload/package.zip") { + int type = (android::base::GetProperty("ro.build.type", "") == "user") ? 1 : 0; + metrics.emplace(OTA_SIDELOAD_METRICS, type); + } + + return metrics; +} diff --git a/otautil/cache_location.cpp b/otautil/paths.cpp index 8ddefec5e..33ab4a5d4 100644 --- a/otautil/cache_location.cpp +++ b/otautil/paths.cpp @@ -14,18 +14,28 @@ * limitations under the License. */ -#include "otautil/cache_location.h" +#include "otautil/paths.h" +constexpr const char kDefaultCacheLogDirectory[] = "/cache/recovery"; constexpr const char kDefaultCacheTempSource[] = "/cache/saved.file"; constexpr const char kDefaultLastCommandFile[] = "/cache/recovery/last_command"; +constexpr const char kDefaultResourceDirectory[] = "/res/images"; constexpr const char kDefaultStashDirectoryBase[] = "/cache/recovery"; +constexpr const char kDefaultTemporaryInstallFile[] = "/tmp/last_install"; +constexpr const char kDefaultTemporaryLogFile[] = "/tmp/recovery.log"; +constexpr const char kDefaultTemporaryUpdateBinary[] = "/tmp/update-binary"; -CacheLocation& CacheLocation::location() { - static CacheLocation cache_location; - return cache_location; +Paths& Paths::Get() { + static Paths paths; + return paths; } -CacheLocation::CacheLocation() - : cache_temp_source_(kDefaultCacheTempSource), +Paths::Paths() + : cache_log_directory_(kDefaultCacheLogDirectory), + cache_temp_source_(kDefaultCacheTempSource), last_command_file_(kDefaultLastCommandFile), - stash_directory_base_(kDefaultStashDirectoryBase) {} + resource_dir_(kDefaultResourceDirectory), + stash_directory_base_(kDefaultStashDirectoryBase), + temporary_install_file_(kDefaultTemporaryInstallFile), + temporary_log_file_(kDefaultTemporaryLogFile), + temporary_update_binary_(kDefaultTemporaryUpdateBinary) {} diff --git a/otautil/rangeset.cpp b/otautil/rangeset.cpp index 96955b9d0..5ab8e08fe 100644 --- a/otautil/rangeset.cpp +++ b/otautil/rangeset.cpp @@ -148,8 +148,8 @@ std::string RangeSet::ToString() const { return ""; } std::string result = std::to_string(ranges_.size() * 2); - for (const auto& r : ranges_) { - result += android::base::StringPrintf(",%zu,%zu", r.first, r.second); + for (const auto& [begin, end] : ranges_) { + result += android::base::StringPrintf(",%zu,%zu", begin, end); } return result; @@ -159,11 +159,11 @@ std::string RangeSet::ToString() const { size_t RangeSet::GetBlockNumber(size_t idx) const { CHECK_LT(idx, blocks_) << "Out of bound index " << idx << " (total blocks: " << blocks_ << ")"; - for (const auto& range : ranges_) { - if (idx < range.second - range.first) { - return range.first + idx; + for (const auto& [begin, end] : ranges_) { + if (idx < end - begin) { + return begin + idx; } - idx -= (range.second - range.first); + idx -= (end - begin); } CHECK(false) << "Failed to find block number for index " << idx; @@ -173,14 +173,10 @@ size_t RangeSet::GetBlockNumber(size_t idx) const { // RangeSet has half-closed half-open bounds. For example, "3,5" contains blocks 3 and 4. So "3,5" // and "5,7" are not overlapped. bool RangeSet::Overlaps(const RangeSet& other) const { - for (const auto& range : ranges_) { - size_t start = range.first; - size_t end = range.second; - for (const auto& other_range : other.ranges_) { - size_t other_start = other_range.first; - size_t other_end = other_range.second; - // [start, end) vs [other_start, other_end) - if (!(other_start >= end || start >= other_end)) { + for (const auto& [begin, end] : ranges_) { + for (const auto& [other_begin, other_end] : other.ranges_) { + // [begin, end) vs [other_begin, other_end) + if (!(other_begin >= end || begin >= other_end)) { return true; } } @@ -248,20 +244,20 @@ bool SortedRangeSet::Overlaps(size_t start, size_t len) const { size_t SortedRangeSet::GetOffsetInRangeSet(size_t old_offset) const { size_t old_block_start = old_offset / kBlockSize; size_t new_block_start = 0; - for (const auto& range : ranges_) { + for (const auto& [start, end] : ranges_) { // Find the index of old_block_start. - if (old_block_start >= range.second) { - new_block_start += (range.second - range.first); - } else if (old_block_start >= range.first) { - new_block_start += (old_block_start - range.first); + if (old_block_start >= end) { + new_block_start += (end - start); + } else if (old_block_start >= start) { + new_block_start += (old_block_start - start); return (new_block_start * kBlockSize + old_offset % kBlockSize); } else { CHECK(false) << "block_start " << old_block_start - << " is missing between two ranges: " << this->ToString(); + << " is missing between two ranges: " << ToString(); return 0; } } CHECK(false) << "block_start " << old_block_start - << " exceeds the limit of current RangeSet: " << this->ToString(); + << " exceeds the limit of current RangeSet: " << ToString(); return 0; } diff --git a/otautil/SysUtil.cpp b/otautil/sysutil.cpp index 48336ad07..d8969a0bb 100644 --- a/otautil/SysUtil.cpp +++ b/otautil/sysutil.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "otautil/SysUtil.h" +#include "otautil/sysutil.h" #include <errno.h> // TEMP_FAILURE_RETRY #include <fcntl.h> @@ -23,13 +23,16 @@ #include <sys/stat.h> #include <sys/types.h> +#include <algorithm> #include <string> #include <vector> #include <android-base/file.h> #include <android-base/logging.h> +#include <android-base/properties.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> +#include <cutils/android_reboot.h> bool MemMapping::MapFD(int fd) { struct stat sb; @@ -201,3 +204,19 @@ MemMapping::~MemMapping() { }; ranges_.clear(); } + +bool reboot(const std::string& command) { + std::string cmd = command; + if (android::base::GetBoolProperty("ro.boot.quiescent", false)) { + cmd += ",quiescent"; + } + return android::base::SetProperty(ANDROID_RB_PROPERTY, cmd); +} + +std::vector<char*> StringVectorToNullTerminatedArray(const std::vector<std::string>& args) { + std::vector<char*> result(args.size()); + std::transform(args.cbegin(), args.cend(), result.begin(), + [](const std::string& arg) { return const_cast<char*>(arg.c_str()); }); + result.push_back(nullptr); + return result; +} diff --git a/otautil/ThermalUtil.cpp b/otautil/thermalutil.cpp index 5d9bd45c0..4660e057e 100644 --- a/otautil/ThermalUtil.cpp +++ b/otautil/thermalutil.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "otautil/ThermalUtil.h" +#include "otautil/thermalutil.h" #include <dirent.h> #include <stdio.h> |