summaryrefslogtreecommitdiffstats
path: root/recovery_ui
diff options
context:
space:
mode:
Diffstat (limited to 'recovery_ui')
-rw-r--r--recovery_ui/Android.bp1
-rw-r--r--recovery_ui/device.cpp13
-rw-r--r--recovery_ui/include/recovery_ui/device.h12
-rw-r--r--recovery_ui/include/recovery_ui/screen_ui.h3
-rw-r--r--recovery_ui/include/recovery_ui/stub_ui.h6
-rw-r--r--recovery_ui/include/recovery_ui/ui.h21
-rw-r--r--recovery_ui/screen_ui.cpp46
-rw-r--r--recovery_ui/stub_ui.cpp36
-rw-r--r--recovery_ui/ui.cpp24
9 files changed, 121 insertions, 41 deletions
diff --git a/recovery_ui/Android.bp b/recovery_ui/Android.bp
index ee3149d5e..149ef8acc 100644
--- a/recovery_ui/Android.bp
+++ b/recovery_ui/Android.bp
@@ -23,6 +23,7 @@ cc_library {
srcs: [
"device.cpp",
"screen_ui.cpp",
+ "stub_ui.cpp",
"ui.cpp",
"vr_ui.cpp",
"wear_ui.cpp",
diff --git a/recovery_ui/device.cpp b/recovery_ui/device.cpp
index e7ae1a3e1..d46df92d3 100644
--- a/recovery_ui/device.cpp
+++ b/recovery_ui/device.cpp
@@ -23,6 +23,7 @@
#include <android-base/logging.h>
+#include "otautil/boot_state.h"
#include "recovery_ui/ui.h"
static std::vector<std::pair<std::string, Device::BuiltinAction>> g_menu_actions{
@@ -95,3 +96,15 @@ int Device::HandleMenuKey(int key, bool visible) {
return ui_->HasThreeButtons() ? kNoAction : kHighlightDown;
}
}
+
+void Device::SetBootState(const BootState* state) {
+ boot_state_ = state;
+}
+
+std::optional<std::string> Device::GetReason() const {
+ return boot_state_ ? std::make_optional(boot_state_->reason()) : std::nullopt;
+}
+
+std::optional<std::string> Device::GetStage() const {
+ return boot_state_ ? std::make_optional(boot_state_->stage()) : std::nullopt;
+}
diff --git a/recovery_ui/include/recovery_ui/device.h b/recovery_ui/include/recovery_ui/device.h
index 7c76cdb0a..f4f993638 100644
--- a/recovery_ui/include/recovery_ui/device.h
+++ b/recovery_ui/include/recovery_ui/device.h
@@ -20,12 +20,15 @@
#include <stddef.h>
#include <memory>
+#include <optional>
#include <string>
#include <vector>
// Forward declaration to avoid including "ui.h".
class RecoveryUI;
+class BootState;
+
class Device {
public:
static constexpr const int kNoAction = -1;
@@ -58,6 +61,8 @@ class Device {
REBOOT_FASTBOOT = 17,
REBOOT_RECOVERY = 18,
REBOOT_RESCUE = 19,
+ REBOOT_FROM_FASTBOOT = 20,
+ SHUTDOWN_FROM_FASTBOOT = 21,
};
explicit Device(RecoveryUI* ui);
@@ -124,9 +129,16 @@ class Device {
return true;
}
+ void SetBootState(const BootState* state);
+ // The getters for reason and stage may return std::nullopt until StartRecovery() is called. It's
+ // the caller's responsibility to perform the check and handle the exception.
+ std::optional<std::string> GetReason() const;
+ std::optional<std::string> GetStage() const;
+
private:
// The RecoveryUI object that should be used to display the user interface for this device.
std::unique_ptr<RecoveryUI> ui_;
+ const BootState* boot_state_{ nullptr };
};
// Disable name mangling, as this function will be loaded via dlsym(3).
diff --git a/recovery_ui/include/recovery_ui/screen_ui.h b/recovery_ui/include/recovery_ui/screen_ui.h
index 5cda2a2e5..92b3c2546 100644
--- a/recovery_ui/include/recovery_ui/screen_ui.h
+++ b/recovery_ui/include/recovery_ui/screen_ui.h
@@ -286,6 +286,9 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
// selected.
virtual int SelectMenu(int sel);
+ // Returns the help message displayed on top of the menu.
+ virtual std::vector<std::string> GetMenuHelpMessage() const;
+
virtual void draw_background_locked();
virtual void draw_foreground_locked();
virtual void draw_screen_locked();
diff --git a/recovery_ui/include/recovery_ui/stub_ui.h b/recovery_ui/include/recovery_ui/stub_ui.h
index fb1d8c7a6..511b1314a 100644
--- a/recovery_ui/include/recovery_ui/stub_ui.h
+++ b/recovery_ui/include/recovery_ui/stub_ui.h
@@ -62,11 +62,9 @@ class StubRecoveryUI : public RecoveryUI {
// menu display
size_t ShowMenu(const std::vector<std::string>& /* headers */,
- const std::vector<std::string>& /* items */, size_t initial_selection,
+ const std::vector<std::string>& /* items */, size_t /* initial_selection */,
bool /* menu_only */,
- const std::function<int(int, bool)>& /* key_handler */) override {
- return initial_selection;
- }
+ const std::function<int(int, bool)>& /* key_handler */) override;
size_t ShowPromptWipeDataMenu(const std::vector<std::string>& /* backup_headers */,
const std::vector<std::string>& /* backup_items */,
diff --git a/recovery_ui/include/recovery_ui/ui.h b/recovery_ui/include/recovery_ui/ui.h
index d55322cf0..08ec1d76a 100644
--- a/recovery_ui/include/recovery_ui/ui.h
+++ b/recovery_ui/include/recovery_ui/ui.h
@@ -27,6 +27,8 @@
#include <thread>
#include <vector>
+static constexpr const char* DEFAULT_LOCALE = "en-US";
+
// Abstract class for controlling the user interface during recovery.
class RecoveryUI {
public:
@@ -116,7 +118,7 @@ class RecoveryUI {
// Returns true if you have the volume up/down and power trio typical of phones and tablets, false
// otherwise.
- virtual bool HasThreeButtons();
+ virtual bool HasThreeButtons() const;
// Returns true if it has a power key.
virtual bool HasPowerKey() const;
@@ -228,20 +230,23 @@ class RecoveryUI {
bool InitScreensaver();
void SetScreensaverState(ScreensaverState state);
+
// Key event input queue
std::mutex key_queue_mutex;
std::condition_variable key_queue_cond;
bool key_interrupted_;
int key_queue[256], key_queue_len;
- char key_pressed[KEY_MAX + 1]; // under key_queue_mutex
- int key_last_down; // under key_queue_mutex
- bool key_long_press; // under key_queue_mutex
- int key_down_count; // under key_queue_mutex
- bool enable_reboot; // under key_queue_mutex
- int rel_sum;
+ // key press events
+ std::mutex key_press_mutex;
+ char key_pressed[KEY_MAX + 1];
+ int key_last_down;
+ bool key_long_press;
+ int key_down_count;
+ bool enable_reboot;
+
+ int rel_sum;
int consecutive_power_keys;
- int last_key;
bool has_power_key;
bool has_up_key;
diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp
index 870db621c..087fc0e84 100644
--- a/recovery_ui/screen_ui.cpp
+++ b/recovery_ui/screen_ui.cpp
@@ -673,6 +673,19 @@ void ScreenRecoveryUI::SetTitle(const std::vector<std::string>& lines) {
title_lines_ = lines;
}
+std::vector<std::string> ScreenRecoveryUI::GetMenuHelpMessage() const {
+ // clang-format off
+ static std::vector<std::string> REGULAR_HELP{
+ "Use volume up/down and power.",
+ };
+ static std::vector<std::string> LONG_PRESS_HELP{
+ "Any button cycles highlight.",
+ "Long-press activates.",
+ };
+ // clang-format on
+ return HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP;
+}
+
// Redraws everything on the screen. Does not flip pages. Should only be called with updateMutex
// locked.
void ScreenRecoveryUI::draw_screen_locked() {
@@ -685,16 +698,7 @@ void ScreenRecoveryUI::draw_screen_locked() {
gr_color(0, 0, 0, 255);
gr_clear();
- // clang-format off
- static std::vector<std::string> REGULAR_HELP{
- "Use volume up/down and power.",
- };
- static std::vector<std::string> LONG_PRESS_HELP{
- "Any button cycles highlight.",
- "Long-press activates.",
- };
- // clang-format on
- draw_menu_and_text_buffer_locked(HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP);
+ draw_menu_and_text_buffer_locked(GetMenuHelpMessage());
}
// Draws the menu and text buffer on the screen. Should only be called with updateMutex locked.
@@ -817,12 +821,22 @@ std::unique_ptr<GRSurface> ScreenRecoveryUI::LoadBitmap(const std::string& filen
std::unique_ptr<GRSurface> ScreenRecoveryUI::LoadLocalizedBitmap(const std::string& filename) {
GRSurface* surface;
- if (auto result = res_create_localized_alpha_surface(filename.c_str(), locale_.c_str(), &surface);
- result < 0) {
- LOG(ERROR) << "Failed to load bitmap " << filename << " (error " << result << ")";
- return nullptr;
+ auto result = res_create_localized_alpha_surface(filename.c_str(), locale_.c_str(), &surface);
+ if (result == 0) {
+ return std::unique_ptr<GRSurface>(surface);
}
- return std::unique_ptr<GRSurface>(surface);
+ // TODO(xunchang) create a error code enum to refine the retry condition.
+ LOG(WARNING) << "Failed to load bitmap " << filename << " for locale " << locale_ << " (error "
+ << result << "). Falling back to use default locale.";
+
+ result = res_create_localized_alpha_surface(filename.c_str(), DEFAULT_LOCALE, &surface);
+ if (result == 0) {
+ return std::unique_ptr<GRSurface>(surface);
+ }
+
+ LOG(ERROR) << "Failed to load bitmap " << filename << " for locale " << DEFAULT_LOCALE
+ << " (error " << result << ")";
+ return nullptr;
}
static char** Alloc2d(size_t rows, size_t cols) {
@@ -1253,7 +1267,7 @@ size_t ScreenRecoveryUI::ShowMenu(const std::vector<std::string>& headers,
return initial_selection;
}
- return ShowMenu(CreateMenu(headers, items, initial_selection), menu_only, key_handler);
+ return ShowMenu(std::move(menu), menu_only, key_handler);
}
size_t ScreenRecoveryUI::ShowPromptWipeDataMenu(const std::vector<std::string>& backup_headers,
diff --git a/recovery_ui/stub_ui.cpp b/recovery_ui/stub_ui.cpp
new file mode 100644
index 000000000..a56b3f725
--- /dev/null
+++ b/recovery_ui/stub_ui.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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 "recovery_ui/stub_ui.h"
+
+#include <android-base/logging.h>
+
+#include "recovery_ui/device.h"
+
+size_t StubRecoveryUI::ShowMenu(const std::vector<std::string>& /* headers */,
+ const std::vector<std::string>& /* items */,
+ size_t /* initial_selection */, bool /* menu_only */,
+ const std::function<int(int, bool)>& /*key_handler*/) {
+ while (true) {
+ int key = WaitKey();
+ // Exit the loop in the case of interruption or time out.
+ if (key == static_cast<int>(KeyError::INTERRUPTED) ||
+ key == static_cast<int>(KeyError::TIMED_OUT)) {
+ return static_cast<size_t>(key);
+ }
+ }
+ LOG(FATAL) << "Unreachable key selected in ShowMenu of stub UI";
+}
diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp
index b7107ff21..6f5cbbca6 100644
--- a/recovery_ui/ui.cpp
+++ b/recovery_ui/ui.cpp
@@ -70,7 +70,6 @@ RecoveryUI::RecoveryUI()
key_down_count(0),
enable_reboot(true),
consecutive_power_keys(0),
- last_key(-1),
has_power_key(false),
has_up_key(false),
has_down_key(false),
@@ -346,7 +345,7 @@ void RecoveryUI::ProcessKey(int key_code, int updown) {
bool long_press = false;
{
- std::lock_guard<std::mutex> lg(key_queue_mutex);
+ std::lock_guard<std::mutex> lg(key_press_mutex);
key_pressed[key_code] = updown;
if (updown) {
++key_down_count;
@@ -375,7 +374,7 @@ void RecoveryUI::ProcessKey(int key_code, int updown) {
case RecoveryUI::REBOOT:
if (reboot_enabled) {
- reboot("reboot,");
+ Reboot("userrequested,recovery,ui");
while (true) {
pause();
}
@@ -393,7 +392,7 @@ void RecoveryUI::TimeKey(int key_code, int count) {
std::this_thread::sleep_for(750ms); // 750 ms == "long"
bool long_press = false;
{
- std::lock_guard<std::mutex> lg(key_queue_mutex);
+ std::lock_guard<std::mutex> lg(key_press_mutex);
if (key_last_down == key_code && key_down_count == count) {
long_press = key_long_press = true;
}
@@ -419,7 +418,7 @@ void RecoveryUI::SetScreensaverState(ScreensaverState state) {
LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_
<< "%)";
} else {
- LOG(ERROR) << "Unable to set brightness to normal";
+ LOG(WARNING) << "Unable to set brightness to normal";
}
break;
case ScreensaverState::DIMMED:
@@ -429,7 +428,7 @@ void RecoveryUI::SetScreensaverState(ScreensaverState state) {
<< "%)";
screensaver_state_ = ScreensaverState::DIMMED;
} else {
- LOG(ERROR) << "Unable to set brightness to dim";
+ LOG(WARNING) << "Unable to set brightness to dim";
}
break;
case ScreensaverState::OFF:
@@ -437,7 +436,7 @@ void RecoveryUI::SetScreensaverState(ScreensaverState state) {
LOG(INFO) << "Brightness: 0 (off)";
screensaver_state_ = ScreensaverState::OFF;
} else {
- LOG(ERROR) << "Unable to set brightness to off";
+ LOG(WARNING) << "Unable to set brightness to off";
}
break;
default:
@@ -518,18 +517,18 @@ bool RecoveryUI::IsUsbConnected() {
}
bool RecoveryUI::IsKeyPressed(int key) {
- std::lock_guard<std::mutex> lg(key_queue_mutex);
+ std::lock_guard<std::mutex> lg(key_press_mutex);
int pressed = key_pressed[key];
return pressed;
}
bool RecoveryUI::IsLongPress() {
- std::lock_guard<std::mutex> lg(key_queue_mutex);
+ std::lock_guard<std::mutex> lg(key_press_mutex);
bool result = key_long_press;
return result;
}
-bool RecoveryUI::HasThreeButtons() {
+bool RecoveryUI::HasThreeButtons() const {
return has_power_key && has_up_key && has_down_key;
}
@@ -548,7 +547,7 @@ void RecoveryUI::FlushKeys() {
RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) {
{
- std::lock_guard<std::mutex> lg(key_queue_mutex);
+ std::lock_guard<std::mutex> lg(key_press_mutex);
key_long_press = false;
}
@@ -585,13 +584,12 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) {
consecutive_power_keys = 0;
}
- last_key = key;
return (IsTextVisible() || screensaver_state_ == ScreensaverState::OFF) ? ENQUEUE : IGNORE;
}
void RecoveryUI::KeyLongPress(int) {}
void RecoveryUI::SetEnableReboot(bool enabled) {
- std::lock_guard<std::mutex> lg(key_queue_mutex);
+ std::lock_guard<std::mutex> lg(key_press_mutex);
enable_reboot = enabled;
}