aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Marshall <tdm@cyngn.com>2016-02-15 15:36:06 -0800
committerTom Marshall <tdm@cyngn.com>2016-03-07 15:16:25 -0800
commit6c20b00105e405823aa3ec12479e52cc30c0df9c (patch)
tree607a9223c74ea58e8d62bce4874ebc281846c134
parentd66f66eb72fc72c17d1a292cfbeaf2ec08721327 (diff)
downloadbootable_recovery-6c20b00105e405823aa3ec12479e52cc30c0df9c.zip
bootable_recovery-6c20b00105e405823aa3ec12479e52cc30c0df9c.tar.gz
bootable_recovery-6c20b00105e405823aa3ec12479e52cc30c0df9c.tar.bz2
recovery: Implement sysbar
Add a system bar (navigation bar) similar to the main Android system with back and home buttons. This makes it easier for users to figure out how to go back on devices that lack hardware buttons, and also provides a quick way to get back to the main menu. Note only buttons that do not have a hardware equivalent are shown, in order to prevent redundancy and confusion. Change-Id: I7538749978837571a8c250c3c8e54ac127b39d84
-rw-r--r--device.cpp12
-rw-r--r--device.h5
-rw-r--r--recovery.cpp23
-rw-r--r--res-hdpi/images/icon_sysbar_back.pngbin0 -> 762 bytes
-rw-r--r--res-hdpi/images/icon_sysbar_back_highlight.pngbin0 -> 2674 bytes
-rw-r--r--res-hdpi/images/icon_sysbar_home.pngbin0 -> 860 bytes
-rw-r--r--res-hdpi/images/icon_sysbar_home_highlight.pngbin0 -> 2852 bytes
-rw-r--r--res-mdpi/images/icon_sysbar_back.pngbin0 -> 555 bytes
-rw-r--r--res-mdpi/images/icon_sysbar_back_highlight.pngbin0 -> 1491 bytes
-rw-r--r--res-mdpi/images/icon_sysbar_home.pngbin0 -> 576 bytes
-rw-r--r--res-mdpi/images/icon_sysbar_home_highlight.pngbin0 -> 1567 bytes
-rw-r--r--res-xhdpi/images/icon_sysbar_back.pngbin0 -> 946 bytes
-rw-r--r--res-xhdpi/images/icon_sysbar_back_highlight.pngbin0 -> 3481 bytes
-rw-r--r--res-xhdpi/images/icon_sysbar_home.pngbin0 -> 1150 bytes
-rw-r--r--res-xhdpi/images/icon_sysbar_home_highlight.pngbin0 -> 3788 bytes
-rw-r--r--res-xxhdpi/images/icon_sysbar_back.pngbin0 -> 1450 bytes
-rw-r--r--res-xxhdpi/images/icon_sysbar_back_highlight.pngbin0 -> 4942 bytes
-rw-r--r--res-xxhdpi/images/icon_sysbar_home.pngbin0 -> 1759 bytes
-rw-r--r--res-xxhdpi/images/icon_sysbar_home_highlight.pngbin0 -> 5398 bytes
-rw-r--r--res-xxxhdpi/images/icon_sysbar_back.pngbin0 -> 1245 bytes
-rw-r--r--res-xxxhdpi/images/icon_sysbar_back_highlight.pngbin0 -> 8323 bytes
-rw-r--r--res-xxxhdpi/images/icon_sysbar_home.pngbin0 -> 1445 bytes
-rw-r--r--res-xxxhdpi/images/icon_sysbar_home_highlight.pngbin0 -> 8905 bytes
-rw-r--r--screen_ui.cpp75
-rw-r--r--screen_ui.h16
-rw-r--r--ui.cpp29
-rw-r--r--ui.h9
-rw-r--r--verifier_test.cpp4
28 files changed, 156 insertions, 17 deletions
diff --git a/device.cpp b/device.cpp
index 7f579cf..95608d6 100644
--- a/device.cpp
+++ b/device.cpp
@@ -139,6 +139,12 @@ Device::BuiltinAction Device::InvokeMenuItem(int menu_position) {
return entry->action.action;
}
+void Device::GoHome() {
+ while (menu_stack.size() > 1) {
+ menu_stack.pop();
+ }
+}
+
int Device::HandleMenuKey(int key, int visible) {
if (!visible) {
return kNoAction;
@@ -164,8 +170,6 @@ int Device::HandleMenuKey(int key, int visible) {
case KEY_ENTER:
case KEY_POWER:
case BTN_MOUSE:
- case KEY_HOME:
- case KEY_HOMEPAGE:
case KEY_SEND:
return kInvokeItem;
@@ -173,6 +177,10 @@ int Device::HandleMenuKey(int key, int visible) {
case KEY_BACK:
return kGoBack;
+ case KEY_HOME:
+ case KEY_HOMEPAGE:
+ return kGoHome;
+
default:
// If you have all of the above buttons, any other buttons
// are ignored. Otherwise, any button cycles the highlight.
diff --git a/device.h b/device.h
index dba4ac1..98427a2 100644
--- a/device.h
+++ b/device.h
@@ -92,12 +92,15 @@ class Device : public VoldWatcher {
// actually perform it here and return NO_ACTION.
virtual BuiltinAction InvokeMenuItem(int menu_position);
+ virtual void GoHome();
+
static const int kNoAction = -1;
static const int kHighlightUp = -2;
static const int kHighlightDown = -3;
static const int kInvokeItem = -4;
static const int kGoBack = -5;
- static const int kRefresh = -6;
+ static const int kGoHome = -6;
+ static const int kRefresh = -7;
// Called before and after we do a wipe data/factory reset operation,
// either via a reboot from the main system with the --wipe_data flag,
diff --git a/recovery.cpp b/recovery.cpp
index 35c6830..c13a689 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -662,7 +662,10 @@ get_menu_selection(const char* const * headers, const char* const * items,
int selected = initial_selection;
int chosen_item = -1;
- while (chosen_item < 0 && chosen_item != Device::kGoBack && chosen_item != Device::kRefresh) {
+ while (chosen_item < 0 &&
+ chosen_item != Device::kGoBack &&
+ chosen_item != Device::kGoHome &&
+ chosen_item != Device::kRefresh) {
int key = ui->WaitKey();
int visible = ui->IsTextVisible();
@@ -713,6 +716,9 @@ get_menu_selection(const char* const * headers, const char* const * items,
case Device::kGoBack:
chosen_item = Device::kGoBack;
break;
+ case Device::kGoHome:
+ chosen_item = Device::kGoHome;
+ break;
case Device::kRefresh:
chosen_item = Device::kRefresh;
break;
@@ -723,6 +729,9 @@ get_menu_selection(const char* const * headers, const char* const * items,
}
ui->EndMenu();
+ if (chosen_item == Device::kGoHome) {
+ device->GoHome();
+ }
return chosen_item;
}
@@ -796,6 +805,11 @@ static char* browse_directory(const char* path, Device* device) {
int chosen_item = 0;
while (true) {
chosen_item = get_menu_selection(headers, zips, 1, chosen_item, device);
+ if (chosen_item == Device::kGoHome) {
+ // go up and stop browsing
+ result = strdup("");
+ break;
+ }
if (chosen_item == 0 || chosen_item == Device::kGoBack) {
// go up but continue browsing (if the caller is update_directory)
result = NULL;
@@ -936,6 +950,7 @@ static void choose_recovery_file(Device* device) {
while (true) {
int chosen_item = get_menu_selection(headers, entries, 1, 0, device);
+ if (chosen_item == Device::kGoHome) break;
if (chosen_item == Device::kGoBack) break;
if (chosen_item >= 0 && strcmp(entries[chosen_item], "Back") == 0) break;
@@ -959,9 +974,10 @@ static int apply_from_storage(Device* device, const std::string& id, bool* wipe_
VolumeInfo vi = vdc->getVolume(id);
char* path = browse_directory(vi.mInternalPath.c_str(), device);
- if (path == NULL) {
+ if (path == NULL || *path == '\0') {
ui->Print("\n-- No package file selected.\n");
vdc->volumeUnmount(vi.mId);
+ free(path);
return INSTALL_NONE;
}
@@ -1013,6 +1029,9 @@ refresh:
if (chosen == Device::kRefresh) {
goto refresh;
}
+ if (chosen == Device::kGoHome) {
+ return INSTALL_NONE;
+ }
if (chosen == Device::kGoBack) {
return INSTALL_NONE;
}
diff --git a/res-hdpi/images/icon_sysbar_back.png b/res-hdpi/images/icon_sysbar_back.png
new file mode 100644
index 0000000..5aa8e62
--- /dev/null
+++ b/res-hdpi/images/icon_sysbar_back.png
Binary files differ
diff --git a/res-hdpi/images/icon_sysbar_back_highlight.png b/res-hdpi/images/icon_sysbar_back_highlight.png
new file mode 100644
index 0000000..5836504
--- /dev/null
+++ b/res-hdpi/images/icon_sysbar_back_highlight.png
Binary files differ
diff --git a/res-hdpi/images/icon_sysbar_home.png b/res-hdpi/images/icon_sysbar_home.png
new file mode 100644
index 0000000..b37422d
--- /dev/null
+++ b/res-hdpi/images/icon_sysbar_home.png
Binary files differ
diff --git a/res-hdpi/images/icon_sysbar_home_highlight.png b/res-hdpi/images/icon_sysbar_home_highlight.png
new file mode 100644
index 0000000..ed0ccfa
--- /dev/null
+++ b/res-hdpi/images/icon_sysbar_home_highlight.png
Binary files differ
diff --git a/res-mdpi/images/icon_sysbar_back.png b/res-mdpi/images/icon_sysbar_back.png
new file mode 100644
index 0000000..81e4637
--- /dev/null
+++ b/res-mdpi/images/icon_sysbar_back.png
Binary files differ
diff --git a/res-mdpi/images/icon_sysbar_back_highlight.png b/res-mdpi/images/icon_sysbar_back_highlight.png
new file mode 100644
index 0000000..d173042
--- /dev/null
+++ b/res-mdpi/images/icon_sysbar_back_highlight.png
Binary files differ
diff --git a/res-mdpi/images/icon_sysbar_home.png b/res-mdpi/images/icon_sysbar_home.png
new file mode 100644
index 0000000..d9e3a43
--- /dev/null
+++ b/res-mdpi/images/icon_sysbar_home.png
Binary files differ
diff --git a/res-mdpi/images/icon_sysbar_home_highlight.png b/res-mdpi/images/icon_sysbar_home_highlight.png
new file mode 100644
index 0000000..ef65d61
--- /dev/null
+++ b/res-mdpi/images/icon_sysbar_home_highlight.png
Binary files differ
diff --git a/res-xhdpi/images/icon_sysbar_back.png b/res-xhdpi/images/icon_sysbar_back.png
new file mode 100644
index 0000000..415715e
--- /dev/null
+++ b/res-xhdpi/images/icon_sysbar_back.png
Binary files differ
diff --git a/res-xhdpi/images/icon_sysbar_back_highlight.png b/res-xhdpi/images/icon_sysbar_back_highlight.png
new file mode 100644
index 0000000..237af6a
--- /dev/null
+++ b/res-xhdpi/images/icon_sysbar_back_highlight.png
Binary files differ
diff --git a/res-xhdpi/images/icon_sysbar_home.png b/res-xhdpi/images/icon_sysbar_home.png
new file mode 100644
index 0000000..425c0dc
--- /dev/null
+++ b/res-xhdpi/images/icon_sysbar_home.png
Binary files differ
diff --git a/res-xhdpi/images/icon_sysbar_home_highlight.png b/res-xhdpi/images/icon_sysbar_home_highlight.png
new file mode 100644
index 0000000..f7b6ce3
--- /dev/null
+++ b/res-xhdpi/images/icon_sysbar_home_highlight.png
Binary files differ
diff --git a/res-xxhdpi/images/icon_sysbar_back.png b/res-xxhdpi/images/icon_sysbar_back.png
new file mode 100644
index 0000000..0b2e866
--- /dev/null
+++ b/res-xxhdpi/images/icon_sysbar_back.png
Binary files differ
diff --git a/res-xxhdpi/images/icon_sysbar_back_highlight.png b/res-xxhdpi/images/icon_sysbar_back_highlight.png
new file mode 100644
index 0000000..03cb8a1
--- /dev/null
+++ b/res-xxhdpi/images/icon_sysbar_back_highlight.png
Binary files differ
diff --git a/res-xxhdpi/images/icon_sysbar_home.png b/res-xxhdpi/images/icon_sysbar_home.png
new file mode 100644
index 0000000..7348841
--- /dev/null
+++ b/res-xxhdpi/images/icon_sysbar_home.png
Binary files differ
diff --git a/res-xxhdpi/images/icon_sysbar_home_highlight.png b/res-xxhdpi/images/icon_sysbar_home_highlight.png
new file mode 100644
index 0000000..a981495
--- /dev/null
+++ b/res-xxhdpi/images/icon_sysbar_home_highlight.png
Binary files differ
diff --git a/res-xxxhdpi/images/icon_sysbar_back.png b/res-xxxhdpi/images/icon_sysbar_back.png
new file mode 100644
index 0000000..f630553
--- /dev/null
+++ b/res-xxxhdpi/images/icon_sysbar_back.png
Binary files differ
diff --git a/res-xxxhdpi/images/icon_sysbar_back_highlight.png b/res-xxxhdpi/images/icon_sysbar_back_highlight.png
new file mode 100644
index 0000000..9211093
--- /dev/null
+++ b/res-xxxhdpi/images/icon_sysbar_back_highlight.png
Binary files differ
diff --git a/res-xxxhdpi/images/icon_sysbar_home.png b/res-xxxhdpi/images/icon_sysbar_home.png
new file mode 100644
index 0000000..9ee96ce
--- /dev/null
+++ b/res-xxxhdpi/images/icon_sysbar_home.png
Binary files differ
diff --git a/res-xxxhdpi/images/icon_sysbar_home_highlight.png b/res-xxxhdpi/images/icon_sysbar_home_highlight.png
new file mode 100644
index 0000000..d63ecb0
--- /dev/null
+++ b/res-xxxhdpi/images/icon_sysbar_home_highlight.png
Binary files differ
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 8e6c733..849f6d1 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -77,6 +77,7 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
show_menu(false),
menu_items(0),
menu_sel(0),
+ sysbar_state(0),
file_viewer_text_(nullptr),
animation_fps(20),
installing_frames(-1),
@@ -86,6 +87,10 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
wrap_count(0) {
headerIcon = nullptr;
+ sysbarBackIcon = nullptr;
+ sysbarBackHighlightIcon = nullptr;
+ sysbarHomeIcon = nullptr;
+ sysbarHomeHighlightIcon = nullptr;
for (int i = 0; i < NR_ICONS; i++) {
backgroundIcon[i] = nullptr;
}
@@ -281,6 +286,45 @@ void ScreenRecoveryUI::draw_menu_item(int textrow, const char *text, int selecte
}
}
+void ScreenRecoveryUI::draw_sysbar()
+{
+ GRSurface* surface;
+ int sw = gr_fb_width();
+ int sh = gr_fb_height();
+ int iw;
+ int ih;
+ SetColor(TEXT_FILL);
+ gr_fill(0, sh - sysbar_height_, sw, sh);
+
+ // Left third is back button
+ if (!HasBackKey()) {
+ if (sysbar_state & SYSBAR_BACK) {
+ surface = sysbarBackHighlightIcon;
+ }
+ else {
+ surface = sysbarBackIcon;
+ }
+ iw = gr_get_width(surface);
+ ih = gr_get_height(surface);
+ gr_blit(surface, 0, 0, iw, ih,
+ 1 * (sw / 6) - (iw / 2), sh - ih);
+ }
+
+ // Middle third is home button
+ if (!HasHomeKey()) {
+ if (sysbar_state & SYSBAR_HOME) {
+ surface = sysbarHomeHighlightIcon;
+ }
+ else {
+ surface = sysbarHomeIcon;
+ }
+ iw = gr_get_width(surface);
+ ih = gr_get_height(surface);
+ gr_blit(surface, 0, 0, iw, ih,
+ 3 * (sw / 6) - (iw / 2), sh - ih);
+ }
+}
+
void ScreenRecoveryUI::draw_dialog()
{
int x, y, w, h;
@@ -289,6 +333,7 @@ void ScreenRecoveryUI::draw_dialog()
return;
}
draw_header_icon();
+ draw_sysbar();
int iconHeight = gr_get_height(backgroundIcon[dialog_icon]);
@@ -374,9 +419,9 @@ void ScreenRecoveryUI::draw_screen_locked() {
}
if (show_menu) {
- int i;
+ int i, y;
draw_header_icon();
- int y;
+ draw_sysbar();
// Divider
y = text_first_row_ * char_height_;
@@ -519,23 +564,31 @@ void ScreenRecoveryUI::Init() {
gr_font_size(&log_char_width_, &log_char_height_);
gr_set_font("menu");
gr_font_size(&char_width_, &char_height_);
- text_rows_ = gr_fb_height() / char_height_;
- text_cols_ = gr_fb_width() / char_width_;
-
- log_text_rows_ = gr_fb_height() / log_char_height_;
- log_text_cols_ = gr_fb_width() / log_char_width_;
-
- text_ = Alloc2d(log_text_rows_, log_text_cols_ + 1);
- file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
- menu_ = Alloc2d(text_rows_, text_cols_ + 1);
text_col_ = text_row_ = 0;
text_top_ = 1;
LoadBitmap("icon_header", &headerIcon);
+ LoadBitmap("icon_sysbar_back", &sysbarBackIcon);
+ LoadBitmap("icon_sysbar_back_highlight", &sysbarBackHighlightIcon);
+ LoadBitmap("icon_sysbar_home", &sysbarHomeIcon);
+ LoadBitmap("icon_sysbar_home_highlight", &sysbarHomeHighlightIcon);
+
header_height_ = gr_get_height(headerIcon);
header_width_ = gr_get_width(headerIcon);
+ sysbar_height_ = gr_get_height(sysbarBackIcon);
+
+ text_rows_ = (gr_fb_height() - sysbar_height_) / char_height_;
+ text_cols_ = gr_fb_width() / char_width_;
+
+ log_text_rows_ = (gr_fb_height() - sysbar_height_) / log_char_height_;
+ log_text_cols_ = gr_fb_width() / log_char_width_;
+
+ text_ = Alloc2d(log_text_rows_, log_text_cols_ + 1);
+ file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
+ menu_ = Alloc2d(text_rows_, text_cols_ + 1);
+
text_first_row_ = (header_height_ / char_height_) + 1;
menu_item_start_ = text_first_row_ * char_height_;
max_menu_rows_ = (text_rows_ - text_first_row_) / 3;
diff --git a/screen_ui.h b/screen_ui.h
index 93d06bc..9d7b263 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -23,6 +23,9 @@
#include "ui.h"
#include "minui/minui.h"
+#define SYSBAR_BACK 0x01
+#define SYSBAR_HOME 0x02
+
// Implementation of RecoveryUI appropriate for devices with a screen
// (shows an icon + a progress bar, text logging, menu, etc.)
class ScreenRecoveryUI : public RecoveryUI {
@@ -60,6 +63,11 @@ class ScreenRecoveryUI : public RecoveryUI {
void DialogDismiss();
void SetHeadlessMode();
+ // sysbar
+ int GetSysbarHeight() { return gr_get_height(sysbarBackHighlightIcon); }
+ int GetSysbarState() { return sysbar_state; }
+ void SetSysbarState(int state) { sysbar_state = state; Redraw(); }
+
// menu display
virtual int MenuItemStart() const { return menu_item_start_; }
virtual int MenuItemHeight() const { return 3 * char_height_; }
@@ -87,6 +95,10 @@ class ScreenRecoveryUI : public RecoveryUI {
pthread_cond_t progressCondition;
GRSurface* headerIcon;
+ GRSurface* sysbarBackIcon;
+ GRSurface* sysbarBackHighlightIcon;
+ GRSurface* sysbarHomeIcon;
+ GRSurface* sysbarHomeHighlightIcon;
GRSurface* backgroundIcon[NR_ICONS];
GRSurface* backgroundText[NR_ICONS];
GRSurface** installation;
@@ -126,6 +138,8 @@ class ScreenRecoveryUI : public RecoveryUI {
int menu_show_start_;
int max_menu_rows_;
+ int sysbar_state;
+
// An alternate text screen, swapped with 'text_' when we're viewing a log file.
char** file_viewer_text_;
@@ -147,6 +161,7 @@ class ScreenRecoveryUI : public RecoveryUI {
int char_height_, char_width_;
int header_height_, header_width_;
+ int sysbar_height_;
int text_first_row_;
bool update_waiting;
@@ -155,6 +170,7 @@ class ScreenRecoveryUI : public RecoveryUI {
void draw_progress_locked();
int draw_header_icon();
void draw_menu_item(int textrow, const char *text, int selected);
+ void draw_sysbar();
void draw_dialog();
void draw_screen_locked();
void update_screen_locked();
diff --git a/ui.cpp b/ui.cpp
index 1594580..14f92b4 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -144,7 +144,9 @@ RecoveryUI::RecoveryUI()
last_key(-1),
has_power_key(false),
has_up_key(false),
- has_down_key(false) {
+ has_down_key(false),
+ has_back_key(false),
+ has_home_key(false) {
pthread_mutex_init(&key_queue_mutex, nullptr);
pthread_cond_init(&key_queue_cond, nullptr);
memset(key_pressed, 0, sizeof(key_pressed));
@@ -157,6 +159,12 @@ void RecoveryUI::OnKeyDetected(int key_code) {
has_down_key = true;
} else if (key_code == KEY_UP || key_code == KEY_VOLUMEUP) {
has_up_key = true;
+ } else if (key_code == KEY_BACK) {
+ has_back_key = true;
+ LOGI("Detected back key, disabling virtual back button\n");
+ } else if (key_code == KEY_HOMEPAGE) {
+ has_home_key = true;
+ LOGI("Detected home key, disabling virtual home button\n");
}
}
@@ -566,6 +574,12 @@ void RecoveryUI::handle_press(input_device* dev) {
dev->touch_start = dev->touch_track = dev->touch_pos;
dev->in_touch = true;
dev->in_swipe = false;
+ if (dev->touch_pos.y >= gr_fb_height() - GetSysbarHeight()) {
+ SetSysbarState(1 << (3 * dev->touch_pos.x / gr_fb_width()));
+ }
+ else {
+ SetSysbarState(0);
+ }
}
void RecoveryUI::handle_release(input_device* dev) {
@@ -588,6 +602,19 @@ void RecoveryUI::handle_release(input_device* dev) {
return;
}
}
+
+ int sysbar_state = GetSysbarState();
+ SetSysbarState(0);
+ if (sysbar_state == 0x01) {
+ ProcessKey(dev, KEY_BACK, 1);
+ ProcessKey(dev, KEY_BACK, 0);
+ return;
+ }
+ if (sysbar_state == 0x02) {
+ ProcessKey(dev, KEY_HOME, 1);
+ ProcessKey(dev, KEY_HOME, 0);
+ return;
+ }
}
if (DialogShowing()) {
diff --git a/ui.h b/ui.h
index abe4bca..e71dbe2 100644
--- a/ui.h
+++ b/ui.h
@@ -162,6 +162,9 @@ class RecoveryUI {
// of phones and tablets, false otherwise.
virtual bool HasThreeButtons();
+ virtual bool HasBackKey() const { return has_back_key; }
+ virtual bool HasHomeKey() const { return has_home_key; }
+
// Erase any queued-up keys.
virtual void FlushKeys();
@@ -191,6 +194,10 @@ class RecoveryUI {
virtual int MenuItemStart() const = 0;
virtual int MenuItemHeight() const = 0;
+ virtual int GetSysbarHeight() = 0;
+ virtual int GetSysbarState() = 0;
+ virtual void SetSysbarState(int state) = 0;
+
// Display some header text followed by a menu of items, which appears
// at the top of the screen (in place of any scrolling ui_print()
// output, if necessary).
@@ -230,6 +237,8 @@ private:
bool has_power_key;
bool has_up_key;
bool has_down_key;
+ bool has_back_key;
+ bool has_home_key;
input_device input_devices[MAX_NR_INPUT_DEVICES];
diff --git a/verifier_test.cpp b/verifier_test.cpp
index 623ae64..a9d42c0 100644
--- a/verifier_test.cpp
+++ b/verifier_test.cpp
@@ -165,6 +165,10 @@ class FakeUI : public RecoveryUI {
virtual int MenuItemStart() const { return 0; }
virtual int MenuItemHeight() const { return 0; }
+
+ virtual int GetSysbarHeight() { return 0; }
+ virtual int GetSysbarState() { return 0; }
+ virtual void SetSysbarState(int state) {}
};
void