summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/recovery_l10n/res/values-en-rXC/strings.xml9
-rw-r--r--ui.cpp20
-rw-r--r--ui.h1
-rw-r--r--update_verifier/update_verifier.cpp82
4 files changed, 81 insertions, 31 deletions
diff --git a/tools/recovery_l10n/res/values-en-rXC/strings.xml b/tools/recovery_l10n/res/values-en-rXC/strings.xml
new file mode 100644
index 000000000..2d528b3fb
--- /dev/null
+++ b/tools/recovery_l10n/res/values-en-rXC/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recovery_installing" msgid="2013591905463558223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎Installing system update‎‏‎‎‏‎"</string>
+ <string name="recovery_erasing" msgid="7334826894904037088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎Erasing‎‏‎‎‏‎"</string>
+ <string name="recovery_no_command" msgid="4465476568623024327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎No command‎‏‎‎‏‎"</string>
+ <string name="recovery_error" msgid="5748178989622716736">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎Error!‎‏‎‎‏‎"</string>
+ <string name="recovery_installing_security" msgid="9184031299717114342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎Installing security update‎‏‎‎‏‎"</string>
+</resources>
diff --git a/ui.cpp b/ui.cpp
index eadcdd433..e80d7ed04 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -69,6 +69,7 @@ RecoveryUI::RecoveryUI()
has_down_key(false),
has_touch_screen(false),
touch_slot_(0),
+ is_bootreason_recovery_ui_(false),
screensaver_state_(ScreensaverState::DISABLED) {
pthread_mutex_init(&key_queue_mutex, nullptr);
pthread_cond_init(&key_queue_cond, nullptr);
@@ -142,6 +143,19 @@ bool RecoveryUI::Init(const std::string& locale) {
if (touch_screen_allowed_) {
ev_iterate_touch_inputs(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
+
+ // Parse /proc/cmdline to determine if it's booting into recovery with a bootreason of
+ // "recovery_ui". This specific reason is set by some (wear) bootloaders, to allow an easier way
+ // to turn on text mode. It will only be set if the recovery boot is triggered from fastboot, or
+ // with 'adb reboot recovery'. Note that this applies to all build variants. Otherwise the text
+ // mode will be turned on automatically on debuggable builds, even without a swipe.
+ std::string cmdline;
+ if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
+ is_bootreason_recovery_ui_ = cmdline.find("bootreason=recovery_ui") != std::string::npos;
+ } else {
+ // Non-fatal, and won't affect Init() result.
+ PLOG(WARNING) << "Failed to read /proc/cmdline";
+ }
}
if (!InitScreensaver()) {
@@ -168,6 +182,12 @@ void RecoveryUI::OnTouchDetected(int dx, int dy) {
return;
}
+ // Allow turning on text mode with any swipe, if bootloader has set a bootreason of recovery_ui.
+ if (is_bootreason_recovery_ui_ && !IsTextVisible()) {
+ ShowText(true);
+ return;
+ }
+
LOG(DEBUG) << "Swipe direction=" << direction;
switch (direction) {
case SwipeDirection::UP:
diff --git a/ui.h b/ui.h
index 5cda7af0f..3d9afece0 100644
--- a/ui.h
+++ b/ui.h
@@ -170,6 +170,7 @@ class RecoveryUI {
int touch_start_Y_;
bool touch_finger_down_;
bool touch_swiping_;
+ bool is_bootreason_recovery_ui_;
struct key_timer_t {
RecoveryUI* ui;
diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp
index b49011a12..ceb3ec948 100644
--- a/update_verifier/update_verifier.cpp
+++ b/update_verifier/update_verifier.cpp
@@ -45,6 +45,7 @@
#include <unistd.h>
#include <algorithm>
+#include <future>
#include <string>
#include <vector>
@@ -123,11 +124,6 @@ static bool read_blocks(const std::string& partition, const std::string& range_s
LOG(ERROR) << "Failed to find dm block device for " << partition;
return false;
}
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(dm_block_device.c_str(), O_RDONLY)));
- if (fd.get() == -1) {
- PLOG(ERROR) << "Error reading " << dm_block_device << " for partition " << partition;
- return false;
- }
// For block range string, first integer 'count' equals 2 * total number of valid ranges,
// followed by 'count' number comma separated integers. Every two integers reprensent a
@@ -142,37 +138,61 @@ static bool read_blocks(const std::string& partition, const std::string& range_s
return false;
}
- size_t blk_count = 0;
- for (size_t i = 1; i < ranges.size(); i += 2) {
- unsigned int range_start, range_end;
- bool parse_status = android::base::ParseUint(ranges[i], &range_start);
- parse_status = parse_status && android::base::ParseUint(ranges[i + 1], &range_end);
- if (!parse_status || range_start >= range_end) {
- LOG(ERROR) << "Invalid range pair " << ranges[i] << ", " << ranges[i + 1];
- return false;
- }
-
- static constexpr size_t BLOCKSIZE = 4096;
- if (lseek64(fd.get(), static_cast<off64_t>(range_start) * BLOCKSIZE, SEEK_SET) == -1) {
- PLOG(ERROR) << "lseek to " << range_start << " failed";
- return false;
- }
+ std::vector<std::future<bool>> threads;
+ size_t thread_num = std::thread::hardware_concurrency() ?: 4;
+ thread_num = std::min(thread_num, range_count / 2);
+ size_t group_range_count = range_count / thread_num;
- size_t remain = (range_end - range_start) * BLOCKSIZE;
- while (remain > 0) {
- size_t to_read = std::min(remain, 1024 * BLOCKSIZE);
- std::vector<uint8_t> buf(to_read);
- if (!android::base::ReadFully(fd.get(), buf.data(), to_read)) {
- PLOG(ERROR) << "Failed to read blocks " << range_start << " to " << range_end;
+ for (size_t t = 0; t < thread_num; t++) {
+ auto thread_func = [t, group_range_count, &dm_block_device, &ranges, &partition]() {
+ size_t blk_count = 0;
+ static constexpr size_t kBlockSize = 4096;
+ std::vector<uint8_t> buf(1024 * kBlockSize);
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(dm_block_device.c_str(), O_RDONLY)));
+ if (fd.get() == -1) {
+ PLOG(ERROR) << "Error reading " << dm_block_device << " for partition " << partition;
return false;
}
- remain -= to_read;
- }
- blk_count += (range_end - range_start);
+
+ for (size_t i = 1 + group_range_count * t; i < group_range_count * (t + 1) + 1; i += 2) {
+ unsigned int range_start, range_end;
+ bool parse_status = android::base::ParseUint(ranges[i], &range_start);
+ parse_status = parse_status && android::base::ParseUint(ranges[i + 1], &range_end);
+ if (!parse_status || range_start >= range_end) {
+ LOG(ERROR) << "Invalid range pair " << ranges[i] << ", " << ranges[i + 1];
+ return false;
+ }
+
+ if (lseek64(fd.get(), static_cast<off64_t>(range_start) * kBlockSize, SEEK_SET) == -1) {
+ PLOG(ERROR) << "lseek to " << range_start << " failed";
+ return false;
+ }
+
+ size_t remain = (range_end - range_start) * kBlockSize;
+ while (remain > 0) {
+ size_t to_read = std::min(remain, 1024 * kBlockSize);
+ if (!android::base::ReadFully(fd.get(), buf.data(), to_read)) {
+ PLOG(ERROR) << "Failed to read blocks " << range_start << " to " << range_end;
+ return false;
+ }
+ remain -= to_read;
+ }
+ blk_count += (range_end - range_start);
+ }
+ LOG(INFO) << "Finished reading " << blk_count << " blocks on " << dm_block_device;
+ return true;
+ };
+
+ threads.emplace_back(std::async(std::launch::async, thread_func));
}
- LOG(INFO) << "Finished reading " << blk_count << " blocks on " << dm_block_device;
- return true;
+ bool ret = true;
+ for (auto& t : threads) {
+ ret = t.get() && ret;
+ }
+ LOG(INFO) << "Finished reading blocks on " << dm_block_device << " with " << thread_num
+ << " threads.";
+ return ret;
}
// Returns true to indicate a passing verification (or the error should be ignored); Otherwise