Skip to content

Commit 113a554

Browse files
tdmcyngnSteve Kondik
authored and
Steve Kondik
committed
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
1 parent d35a865 commit 113a554

27 files changed

+151
-17
lines changed

device.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ Device::BuiltinAction Device::InvokeMenuItem(int menu_position) {
141141
return entry->action.action;
142142
}
143143

144+
void Device::GoHome() {
145+
while (menu_stack.size() > 1) {
146+
menu_stack.pop();
147+
}
148+
}
149+
144150
int Device::HandleMenuKey(int key, int visible) {
145151
if (!visible) {
146152
return kNoAction;
@@ -166,15 +172,17 @@ int Device::HandleMenuKey(int key, int visible) {
166172
case KEY_ENTER:
167173
case KEY_POWER:
168174
case BTN_MOUSE:
169-
case KEY_HOME:
170-
case KEY_HOMEPAGE:
171175
case KEY_SEND:
172176
return kInvokeItem;
173177

174178
case KEY_BACKSPACE:
175179
case KEY_BACK:
176180
return kGoBack;
177181

182+
case KEY_HOME:
183+
case KEY_HOMEPAGE:
184+
return kGoHome;
185+
178186
default:
179187
// If you have all of the above buttons, any other buttons
180188
// are ignored. Otherwise, any button cycles the highlight.

device.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,15 @@ class Device : public VoldWatcher {
9393
// actually perform it here and return NO_ACTION.
9494
virtual BuiltinAction InvokeMenuItem(int menu_position);
9595

96+
virtual void GoHome();
97+
9698
static const int kNoAction = -1;
9799
static const int kHighlightUp = -2;
98100
static const int kHighlightDown = -3;
99101
static const int kInvokeItem = -4;
100102
static const int kGoBack = -5;
101-
static const int kRefresh = -6;
103+
static const int kGoHome = -6;
104+
static const int kRefresh = -7;
102105

103106
// Called before and after we do a wipe data/factory reset operation,
104107
// either via a reboot from the main system with the --wipe_data flag,

recovery.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,10 @@ get_menu_selection(const char* const * headers, const char* const * items,
774774
int selected = initial_selection;
775775
int chosen_item = -1;
776776

777-
while (chosen_item < 0 && chosen_item != Device::kGoBack && chosen_item != Device::kRefresh) {
777+
while (chosen_item < 0 &&
778+
chosen_item != Device::kGoBack &&
779+
chosen_item != Device::kGoHome &&
780+
chosen_item != Device::kRefresh) {
778781
int key = ui->WaitKey();
779782
int visible = ui->IsTextVisible();
780783

@@ -825,6 +828,9 @@ get_menu_selection(const char* const * headers, const char* const * items,
825828
case Device::kGoBack:
826829
chosen_item = Device::kGoBack;
827830
break;
831+
case Device::kGoHome:
832+
chosen_item = Device::kGoHome;
833+
break;
828834
case Device::kRefresh:
829835
chosen_item = Device::kRefresh;
830836
break;
@@ -835,6 +841,9 @@ get_menu_selection(const char* const * headers, const char* const * items,
835841
}
836842

837843
ui->EndMenu();
844+
if (chosen_item == Device::kGoHome) {
845+
device->GoHome();
846+
}
838847
return chosen_item;
839848
}
840849

@@ -908,6 +917,11 @@ static char* browse_directory(const char* path, Device* device) {
908917
int chosen_item = 0;
909918
while (true) {
910919
chosen_item = get_menu_selection(headers, zips, 1, chosen_item, device);
920+
if (chosen_item == Device::kGoHome) {
921+
// go up and stop browsing
922+
result = strdup("");
923+
break;
924+
}
911925
if (chosen_item == 0 || chosen_item == Device::kGoBack) {
912926
// go up but continue browsing (if the caller is update_directory)
913927
result = NULL;
@@ -1058,6 +1072,7 @@ static void choose_recovery_file(Device* device) {
10581072

10591073
while (true) {
10601074
int chosen_item = get_menu_selection(headers, entries, 1, 0, device);
1075+
if (chosen_item == Device::kGoHome) break;
10611076
if (chosen_item == Device::kGoBack) break;
10621077
if (chosen_item >= 0 && strcmp(entries[chosen_item], "Back") == 0) break;
10631078

@@ -1116,9 +1131,10 @@ static int apply_from_storage(Device* device, const std::string& id, bool* wipe_
11161131
VolumeInfo vi = vdc->getVolume(id);
11171132

11181133
char* path = browse_directory(vi.mInternalPath.c_str(), device);
1119-
if (path == NULL) {
1134+
if (path == NULL || *path == '\0') {
11201135
ui->Print("\n-- No package file selected.\n");
11211136
vdc->volumeUnmount(vi.mId);
1137+
free(path);
11221138
return INSTALL_NONE;
11231139
}
11241140

@@ -1221,6 +1237,9 @@ show_apply_update_menu(Device* device) {
12211237
if (chosen == Device::kRefresh) {
12221238
goto refresh;
12231239
}
1240+
if (chosen == Device::kGoHome) {
1241+
return INSTALL_NONE;
1242+
}
12241243
if (chosen == Device::kGoBack) {
12251244
return INSTALL_NONE;
12261245
}

res-hdpi/images/icon_sysbar_back.png

762 Bytes
Loading
2.61 KB
Loading

res-hdpi/images/icon_sysbar_home.png

860 Bytes
Loading
2.79 KB
Loading

res-mdpi/images/icon_sysbar_back.png

555 Bytes
Loading
1.46 KB
Loading

res-mdpi/images/icon_sysbar_home.png

576 Bytes
Loading
1.53 KB
Loading

res-xhdpi/images/icon_sysbar_back.png

946 Bytes
Loading
Loading

res-xhdpi/images/icon_sysbar_home.png

1.12 KB
Loading
Loading
1.42 KB
Loading
4.83 KB
Loading
1.72 KB
Loading
5.27 KB
Loading
1.22 KB
Loading
Loading
1.41 KB
Loading
Loading

screen_ui.cpp

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
7777
show_menu(false),
7878
menu_items(0),
7979
menu_sel(0),
80+
sysbar_state(0),
8081
file_viewer_text_(nullptr),
8182
intro_frames(0),
8283
loop_frames(0),
@@ -89,6 +90,10 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
8990
wrap_count(0) {
9091

9192
headerIcon = nullptr;
93+
sysbarBackIcon = nullptr;
94+
sysbarBackHighlightIcon = nullptr;
95+
sysbarHomeIcon = nullptr;
96+
sysbarHomeHighlightIcon = nullptr;
9297
}
9398

9499
GRSurface* ScreenRecoveryUI::GetCurrentFrame() {
@@ -306,6 +311,45 @@ void ScreenRecoveryUI::draw_menu_item(int textrow, const char *text, int selecte
306311
}
307312
}
308313

314+
void ScreenRecoveryUI::draw_sysbar()
315+
{
316+
GRSurface* surface;
317+
int sw = gr_fb_width();
318+
int sh = gr_fb_height();
319+
int iw;
320+
int ih;
321+
SetColor(TEXT_FILL);
322+
gr_fill(0, sh - sysbar_height_, sw, sh);
323+
324+
// Left third is back button
325+
if (!HasBackKey()) {
326+
if (sysbar_state & SYSBAR_BACK) {
327+
surface = sysbarBackHighlightIcon;
328+
}
329+
else {
330+
surface = sysbarBackIcon;
331+
}
332+
iw = gr_get_width(surface);
333+
ih = gr_get_height(surface);
334+
gr_blit(surface, 0, 0, iw, ih,
335+
1 * (sw / 6) - (iw / 2), sh - ih);
336+
}
337+
338+
// Middle third is home button
339+
if (!HasHomeKey()) {
340+
if (sysbar_state & SYSBAR_HOME) {
341+
surface = sysbarHomeHighlightIcon;
342+
}
343+
else {
344+
surface = sysbarHomeIcon;
345+
}
346+
iw = gr_get_width(surface);
347+
ih = gr_get_height(surface);
348+
gr_blit(surface, 0, 0, iw, ih,
349+
3 * (sw / 6) - (iw / 2), sh - ih);
350+
}
351+
}
352+
309353
// Redraw everything on the screen. Does not flip pages.
310354
// Should only be called with updateMutex locked.
311355
void ScreenRecoveryUI::draw_screen_locked() {
@@ -341,9 +385,9 @@ void ScreenRecoveryUI::draw_screen_locked() {
341385
}
342386

343387
if (show_menu) {
344-
int i;
388+
int i, y;
345389
draw_header_icon();
346-
int y;
390+
draw_sysbar();
347391

348392
// Divider
349393
y = text_first_row_ * char_height_;
@@ -495,25 +539,33 @@ void ScreenRecoveryUI::Init() {
495539
gr_font_size(&log_char_width_, &log_char_height_);
496540
gr_set_font("menu");
497541
gr_font_size(&char_width_, &char_height_);
498-
text_rows_ = gr_fb_height() / char_height_;
499-
text_cols_ = gr_fb_width() / char_width_;
500-
501-
log_text_rows_ = gr_fb_height() / log_char_height_;
502-
log_text_cols_ = gr_fb_width() / log_char_width_;
503-
504-
text_ = Alloc2d(log_text_rows_, log_text_cols_ + 1);
505-
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
506-
menu_ = Alloc2d(text_rows_, text_cols_ + 1);
507542

508543
text_col_ = text_row_ = 0;
509544
text_top_ = 1;
510545

511546
LoadBitmap("icon_error", &error_icon);
512547

513548
LoadBitmap("icon_header", &headerIcon);
549+
LoadBitmap("icon_sysbar_back", &sysbarBackIcon);
550+
LoadBitmap("icon_sysbar_back_highlight", &sysbarBackHighlightIcon);
551+
LoadBitmap("icon_sysbar_home", &sysbarHomeIcon);
552+
LoadBitmap("icon_sysbar_home_highlight", &sysbarHomeHighlightIcon);
553+
514554
header_height_ = gr_get_height(headerIcon);
515555
header_width_ = gr_get_width(headerIcon);
516556

557+
sysbar_height_ = gr_get_height(sysbarBackIcon);
558+
559+
text_rows_ = (gr_fb_height() - sysbar_height_) / char_height_;
560+
text_cols_ = gr_fb_width() / char_width_;
561+
562+
log_text_rows_ = (gr_fb_height() - sysbar_height_) / log_char_height_;
563+
log_text_cols_ = gr_fb_width() / log_char_width_;
564+
565+
text_ = Alloc2d(log_text_rows_, log_text_cols_ + 1);
566+
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
567+
menu_ = Alloc2d(text_rows_, text_cols_ + 1);
568+
517569
text_first_row_ = (header_height_ / char_height_) + 1;
518570
menu_item_start_ = text_first_row_ * char_height_;
519571
max_menu_rows_ = (text_rows_ - text_first_row_) / 3;

screen_ui.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include "ui.h"
2424
#include "minui/minui.h"
2525

26+
#define SYSBAR_BACK 0x01
27+
#define SYSBAR_HOME 0x02
28+
2629
// Implementation of RecoveryUI appropriate for devices with a screen
2730
// (shows an icon + a progress bar, text logging, menu, etc.)
2831
class ScreenRecoveryUI : public RecoveryUI {
@@ -53,6 +56,11 @@ class ScreenRecoveryUI : public RecoveryUI {
5356
void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3);
5457
void ShowFile(const char* filename);
5558

59+
// sysbar
60+
int GetSysbarHeight() { return gr_get_height(sysbarBackHighlightIcon); }
61+
int GetSysbarState() { return sysbar_state; }
62+
void SetSysbarState(int state) { sysbar_state = state; Redraw(); }
63+
5664
// menu display
5765
virtual int MenuItemStart() const { return menu_item_start_; }
5866
virtual int MenuItemHeight() const { return 3 * char_height_; }
@@ -93,6 +101,10 @@ class ScreenRecoveryUI : public RecoveryUI {
93101
GRSurface** loopFrames;
94102

95103
GRSurface* headerIcon;
104+
GRSurface* sysbarBackIcon;
105+
GRSurface* sysbarBackHighlightIcon;
106+
GRSurface* sysbarHomeIcon;
107+
GRSurface* sysbarHomeHighlightIcon;
96108
GRSurface* progressBarEmpty;
97109
GRSurface* progressBarFill;
98110
GRSurface* stageMarkerEmpty;
@@ -125,6 +137,8 @@ class ScreenRecoveryUI : public RecoveryUI {
125137
int menu_show_start_;
126138
int max_menu_rows_;
127139

140+
int sysbar_state;
141+
128142
// An alternate text screen, swapped with 'text_' when we're viewing a log file.
129143
char** file_viewer_text_;
130144

@@ -156,10 +170,12 @@ class ScreenRecoveryUI : public RecoveryUI {
156170
int char_height_, char_width_;
157171

158172
int header_height_, header_width_;
173+
int sysbar_height_;
159174
int text_first_row_;
160175

161176
int draw_header_icon();
162177
void draw_menu_item(int textrow, const char *text, int selected);
178+
void draw_sysbar();
163179
void draw_screen_locked();
164180
void update_screen_locked();
165181
void update_progress_locked();

ui.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ RecoveryUI::RecoveryUI()
5959
last_key(-1),
6060
has_power_key(false),
6161
has_up_key(false),
62-
has_down_key(false) {
62+
has_down_key(false),
63+
has_back_key(false),
64+
has_home_key(false) {
6365
pthread_mutex_init(&key_queue_mutex, nullptr);
6466
pthread_cond_init(&key_queue_cond, nullptr);
6567
memset(key_pressed, 0, sizeof(key_pressed));
@@ -72,6 +74,12 @@ void RecoveryUI::OnKeyDetected(int key_code) {
7274
has_down_key = true;
7375
} else if (key_code == KEY_UP || key_code == KEY_VOLUMEUP) {
7476
has_up_key = true;
77+
} else if (key_code == KEY_BACK) {
78+
has_back_key = true;
79+
LOGI("Detected back key, disabling virtual back button\n");
80+
} else if (key_code == KEY_HOMEPAGE) {
81+
has_home_key = true;
82+
LOGI("Detected home key, disabling virtual home button\n");
7583
}
7684
}
7785

@@ -475,6 +483,12 @@ void RecoveryUI::handle_press(input_device* dev) {
475483
dev->touch_start = dev->touch_track = dev->touch_pos;
476484
dev->in_touch = true;
477485
dev->in_swipe = false;
486+
if (dev->touch_pos.y >= gr_fb_height() - GetSysbarHeight()) {
487+
SetSysbarState(1 << (3 * dev->touch_pos.x / gr_fb_width()));
488+
}
489+
else {
490+
SetSysbarState(0);
491+
}
478492
}
479493

480494
void RecoveryUI::handle_release(input_device* dev) {
@@ -497,6 +511,19 @@ void RecoveryUI::handle_release(input_device* dev) {
497511
return;
498512
}
499513
}
514+
515+
int sysbar_state = GetSysbarState();
516+
SetSysbarState(0);
517+
if (sysbar_state == 0x01) {
518+
ProcessKey(dev, KEY_BACK, 1);
519+
ProcessKey(dev, KEY_BACK, 0);
520+
return;
521+
}
522+
if (sysbar_state == 0x02) {
523+
ProcessKey(dev, KEY_HOME, 1);
524+
ProcessKey(dev, KEY_HOME, 0);
525+
return;
526+
}
500527
}
501528

502529
if (DialogShowing()) {

ui.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ class RecoveryUI {
154154
// of phones and tablets, false otherwise.
155155
virtual bool HasThreeButtons();
156156

157+
virtual bool HasBackKey() const { return has_back_key; }
158+
virtual bool HasHomeKey() const { return has_home_key; }
159+
157160
// Erase any queued-up keys.
158161
virtual void FlushKeys();
159162

@@ -183,6 +186,10 @@ class RecoveryUI {
183186
virtual int MenuItemStart() const = 0;
184187
virtual int MenuItemHeight() const = 0;
185188

189+
virtual int GetSysbarHeight() = 0;
190+
virtual int GetSysbarState() = 0;
191+
virtual void SetSysbarState(int state) = 0;
192+
186193
// Display some header text followed by a menu of items, which appears
187194
// at the top of the screen (in place of any scrolling ui_print()
188195
// output, if necessary).
@@ -222,6 +229,8 @@ class RecoveryUI {
222229
bool has_power_key;
223230
bool has_up_key;
224231
bool has_down_key;
232+
bool has_back_key;
233+
bool has_home_key;
225234

226235
input_device input_devices[MAX_NR_INPUT_DEVICES];
227236

0 commit comments

Comments
 (0)