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
This commit is contained in:
Sen Jiang 2016-12-09 16:20:49 -08:00
parent d6a5005fcb
commit d530449e54
9 changed files with 102 additions and 17 deletions

View file

@ -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);

View file

@ -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<float>(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() {

View file

@ -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();

67
stub_ui.h Normal file
View file

@ -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

View file

@ -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*/) { }

3
ui.cpp
View file

@ -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) {

4
ui.h
View file

@ -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;

View file

@ -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)

View file

@ -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;