From d530449e54bd327e9c26209ffa0490c6508afe6c Mon Sep 17 00:00:00 2001 From: Sen Jiang Date: Fri, 9 Dec 2016 16:20:49 -0800 Subject: Add a stub recovery UI. This allows recovery to work on devices without screen. The stub recovery UI does nothing except print to stdout. Test: write 'recovery\n--wipe_data\n--reason=wipe_data_from_ota\n' to misc and boot to recovery on a device without screen. Bug: 33175036 Change-Id: Icde698aa2e2e29f4b3d0532dfd3c6a939ac2bc63 --- recovery.cpp | 6 +++- screen_ui.cpp | 15 ++++++--- screen_ui.h | 4 +-- stub_ui.h | 67 +++++++++++++++++++++++++++++++++++++++ tests/component/verifier_test.cpp | 2 +- ui.cpp | 3 +- ui.h | 4 +-- wear_ui.cpp | 14 +++++--- wear_ui.h | 4 +-- 9 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 stub_ui.h diff --git a/recovery.cpp b/recovery.cpp index e777c46cd..9152bb128 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -68,6 +68,7 @@ #include "roots.h" #include "rotate_logs.h" #include "screen_ui.h" +#include "stub_ui.h" #include "ui.h" static const struct option OPTIONS[] = { @@ -1495,8 +1496,11 @@ int main(int argc, char **argv) { Device* device = make_device(); ui = device->GetUI(); + if (!ui->Init()) { + printf("Failed to initialize UI, use stub UI instead."); + ui = new StubRecoveryUI(); + } ui->SetLocale(locale.c_str()); - ui->Init(); // Set background string to "installing security update" for security update, // otherwise set it to "installing system update". ui->SetSystemUpdateText(security_update); diff --git a/screen_ui.cpp b/screen_ui.cpp index a7b03c50d..5b9e5a5a9 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -448,17 +448,22 @@ void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) { Redraw(); } -void ScreenRecoveryUI::InitTextParams() { - gr_init(); +bool ScreenRecoveryUI::InitTextParams() { + if (gr_init() < 0) { + return false; + } gr_font_size(gr_sys_font(), &char_width_, &char_height_); text_rows_ = gr_fb_height() / char_height_; text_cols_ = gr_fb_width() / char_width_; + return true; } -void ScreenRecoveryUI::Init() { +bool ScreenRecoveryUI::Init() { RecoveryUI::Init(); - InitTextParams(); + if (!InitTextParams()) { + return false; + } density_ = static_cast(android::base::GetIntProperty("ro.sf.lcd_density", 160)) / 160.f; @@ -493,6 +498,8 @@ void ScreenRecoveryUI::Init() { LoadAnimation(); pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this); + + return true; } void ScreenRecoveryUI::LoadAnimation() { diff --git a/screen_ui.h b/screen_ui.h index de7b6442e..38e2f0723 100644 --- a/screen_ui.h +++ b/screen_ui.h @@ -29,7 +29,7 @@ class ScreenRecoveryUI : public RecoveryUI { public: ScreenRecoveryUI(); - void Init(); + bool Init() override; void SetLocale(const char* locale); // overall recovery state ("background image") @@ -137,7 +137,7 @@ class ScreenRecoveryUI : public RecoveryUI { pthread_mutex_t updateMutex; bool rtl_locale; - virtual void InitTextParams(); + virtual bool InitTextParams(); virtual void draw_background_locked(); virtual void draw_foreground_locked(); diff --git a/stub_ui.h b/stub_ui.h new file mode 100644 index 000000000..1219b284c --- /dev/null +++ b/stub_ui.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 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 RECOVERY_STUB_UI_H +#define RECOVERY_STUB_UI_H + +#include "ui.h" + +// Stub implementation of RecoveryUI for devices without screen. +class StubRecoveryUI : public RecoveryUI { + public: + StubRecoveryUI() = default; + + void SetLocale(const char* locale) override {} + + void SetBackground(Icon icon) override {} + void SetSystemUpdateText(bool security_update) override {} + + // progress indicator + void SetProgressType(ProgressType type) override {} + void ShowProgress(float portion, float seconds) override {} + void SetProgress(float fraction) override {} + + void SetStage(int current, int max) override {} + + // text log + void ShowText(bool visible) override {} + bool IsTextVisible() override { + return false; + } + bool WasTextEverVisible() override { + return false; + } + + // printing messages + void Print(const char* fmt, ...) override { + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + } + void PrintOnScreenOnly(const char* fmt, ...) override {} + void ShowFile(const char* filename) override {} + + // menu display + void StartMenu(const char* const* headers, const char* const* items, + int initial_selection) override {} + int SelectMenu(int sel) override { + return sel; + } + void EndMenu() override {} +}; + +#endif // RECOVERY_STUB_UI_H diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp index 60a78f5c3..33aadb3fb 100644 --- a/tests/component/verifier_test.cpp +++ b/tests/component/verifier_test.cpp @@ -40,7 +40,7 @@ RecoveryUI* ui = NULL; class MockUI : public RecoveryUI { - void Init() { } + bool Init() { return true; } void SetStage(int, int) { } void SetLocale(const char*) { } void SetBackground(Icon /*icon*/) { } diff --git a/ui.cpp b/ui.cpp index 78b6e4f1b..2d80c382f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -80,12 +80,13 @@ static void* InputThreadLoop(void*) { return nullptr; } -void RecoveryUI::Init() { +bool RecoveryUI::Init() { ev_init(InputCallback, this); ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1)); pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr); + return true; } int RecoveryUI::OnInputEvent(int fd, uint32_t epevents) { diff --git a/ui.h b/ui.h index 82d95a346..be95a4e23 100644 --- a/ui.h +++ b/ui.h @@ -28,8 +28,8 @@ class RecoveryUI { virtual ~RecoveryUI() { } - // Initialize the object; called before anything else. - virtual void Init(); + // Initialize the object; called before anything else. Returns true on success. + virtual bool Init(); // Show a stage indicator. Call immediately after Init(). virtual void SetStage(int current, int max) = 0; diff --git a/wear_ui.cpp b/wear_ui.cpp index 0918ac457..11e5a7168 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -190,8 +190,10 @@ void WearRecoveryUI::update_progress_locked() { gr_flip(); } -void WearRecoveryUI::InitTextParams() { - ScreenRecoveryUI::InitTextParams(); +bool WearRecoveryUI::InitTextParams() { + if (!ScreenRecoveryUI::InitTextParams()) { + return false; + } text_cols_ = (gr_fb_width() - (outer_width * 2)) / char_width_; @@ -199,15 +201,19 @@ void WearRecoveryUI::InitTextParams() { if (text_cols_ > kMaxCols) text_cols_ = kMaxCols; visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height_; + return true; } -void WearRecoveryUI::Init() { - ScreenRecoveryUI::Init(); +bool WearRecoveryUI::Init() { + if (!ScreenRecoveryUI::Init()) { + return false; + } LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; LoadBitmap("icon_error", &backgroundIcon[ERROR]); backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; + return true; } void WearRecoveryUI::SetStage(int current, int max) diff --git a/wear_ui.h b/wear_ui.h index 9351d4166..5ac6f49dd 100644 --- a/wear_ui.h +++ b/wear_ui.h @@ -23,7 +23,7 @@ class WearRecoveryUI : public ScreenRecoveryUI { public: WearRecoveryUI(); - void Init() override; + bool Init() override; void SetStage(int current, int max) override; @@ -52,7 +52,7 @@ class WearRecoveryUI : public ScreenRecoveryUI { int GetProgressBaseline() override; - void InitTextParams() override; + bool InitTextParams() override; void update_progress_locked() override; -- cgit v1.2.3