summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--device.cpp29
-rw-r--r--device.h69
-rw-r--r--recovery.cpp58
-rw-r--r--screen_ui.cpp47
-rw-r--r--screen_ui.h27
-rw-r--r--stub_ui.h8
-rw-r--r--tests/unit/screen_ui_test.cpp27
-rw-r--r--ui.h10
-rw-r--r--wear_ui.cpp6
-rw-r--r--wear_ui.h7
10 files changed, 147 insertions, 141 deletions
diff --git a/device.cpp b/device.cpp
index 3b0942c49..5cf9cc242 100644
--- a/device.cpp
+++ b/device.cpp
@@ -16,9 +16,13 @@
#include "device.h"
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+
#include "ui.h"
-static const char* MENU_ITEMS[] = {
+// clang-format off
+static constexpr const char* kItems[]{
"Reboot system now",
"Reboot to bootloader",
"Apply update from ADB",
@@ -32,10 +36,11 @@ static const char* MENU_ITEMS[] = {
"Run graphics test",
"Run locale test",
"Power off",
- nullptr,
};
+// clang-format on
-static const Device::BuiltinAction MENU_ACTIONS[] = {
+// clang-format off
+static constexpr Device::BuiltinAction kMenuActions[] {
Device::REBOOT,
Device::REBOOT_BOOTLOADER,
Device::APPLY_ADB_SIDELOAD,
@@ -50,18 +55,20 @@ static const Device::BuiltinAction MENU_ACTIONS[] = {
Device::RUN_LOCALE_TEST,
Device::SHUTDOWN,
};
+// clang-format on
+
+static_assert(arraysize(kItems) == arraysize(kMenuActions),
+ "kItems and kMenuActions should have the same length.");
-static_assert(sizeof(MENU_ITEMS) / sizeof(MENU_ITEMS[0]) ==
- sizeof(MENU_ACTIONS) / sizeof(MENU_ACTIONS[0]) + 1,
- "MENU_ITEMS and MENU_ACTIONS should have the same length, "
- "except for the extra NULL entry in MENU_ITEMS.");
+static const std::vector<std::string> kMenuItems(kItems, kItems + arraysize(kItems));
-const char* const* Device::GetMenuItems() {
- return MENU_ITEMS;
+const std::vector<std::string>& Device::GetMenuItems() {
+ return kMenuItems;
}
-Device::BuiltinAction Device::InvokeMenuItem(int menu_position) {
- return menu_position < 0 ? NO_ACTION : MENU_ACTIONS[menu_position];
+Device::BuiltinAction Device::InvokeMenuItem(size_t menu_position) {
+ // CHECK_LT(menu_position, );
+ return kMenuActions[menu_position];
}
int Device::HandleMenuKey(int key, bool visible) {
diff --git a/device.h b/device.h
index 4ea3159bd..8788b2d14 100644
--- a/device.h
+++ b/device.h
@@ -17,11 +17,37 @@
#ifndef _RECOVERY_DEVICE_H
#define _RECOVERY_DEVICE_H
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
// Forward declaration to avoid including "ui.h".
class RecoveryUI;
class Device {
public:
+ static constexpr const int kNoAction = -1;
+ static constexpr const int kHighlightUp = -2;
+ static constexpr const int kHighlightDown = -3;
+ static constexpr const int kInvokeItem = -4;
+
+ enum BuiltinAction {
+ NO_ACTION = 0,
+ REBOOT = 1,
+ APPLY_SDCARD = 2,
+ // APPLY_CACHE was 3.
+ APPLY_ADB_SIDELOAD = 4,
+ WIPE_DATA = 5,
+ WIPE_CACHE = 6,
+ REBOOT_BOOTLOADER = 7,
+ SHUTDOWN = 8,
+ VIEW_RECOVERY_LOGS = 9,
+ MOUNT_SYSTEM = 10,
+ RUN_GRAPHICS_TEST = 11,
+ RUN_LOCALE_TEST = 12,
+ };
+
explicit Device(RecoveryUI* ui) : ui_(ui) {}
virtual ~Device() {}
@@ -48,44 +74,23 @@ class Device {
//
// Returns one of the defined constants below in order to:
//
- // - move the menu highlight (kHighlight{Up,Down})
- // - invoke the highlighted item (kInvokeItem)
- // - do nothing (kNoAction)
- // - invoke a specific action (a menu position: any non-negative number)
+ // - move the menu highlight (kHighlight{Up,Down}: negative value)
+ // - invoke the highlighted item (kInvokeItem: negative value)
+ // - do nothing (kNoAction: negative value)
+ // - invoke a specific action (a menu position: non-negative value)
virtual int HandleMenuKey(int key, bool visible);
- enum BuiltinAction {
- NO_ACTION = 0,
- REBOOT = 1,
- APPLY_SDCARD = 2,
- // APPLY_CACHE was 3.
- APPLY_ADB_SIDELOAD = 4,
- WIPE_DATA = 5,
- WIPE_CACHE = 6,
- REBOOT_BOOTLOADER = 7,
- SHUTDOWN = 8,
- VIEW_RECOVERY_LOGS = 9,
- MOUNT_SYSTEM = 10,
- RUN_GRAPHICS_TEST = 11,
- RUN_LOCALE_TEST = 12,
- };
-
- // Return the list of menu items (an array of strings, NULL-terminated). The menu_position passed
- // to InvokeMenuItem will correspond to the indexes into this array.
- virtual const char* const* GetMenuItems();
+ // Returns the list of menu items (a vector of strings). The menu_position passed to
+ // InvokeMenuItem will correspond to the indexes into this array.
+ virtual const std::vector<std::string>& GetMenuItems();
- // Perform a recovery action selected from the menu. 'menu_position' will be the item number of
- // the selected menu item, or a non-negative number returned from HandleMenuKey(). The menu will
- // be hidden when this is called; implementations can call ui_print() to print information to the
+ // Performs a recovery action selected from the menu. 'menu_position' will be the index of the
+ // selected menu item, or a non-negative value returned from HandleMenuKey(). The menu will be
+ // hidden when this is called; implementations can call ui_print() to print information to the
// screen. If the menu position is one of the builtin actions, you can just return the
// corresponding enum value. If it is an action specific to your device, you actually perform it
// here and return NO_ACTION.
- virtual BuiltinAction InvokeMenuItem(int menu_position);
-
- static const int kNoAction = -1;
- static const int kHighlightUp = -2;
- static const int kHighlightDown = -3;
- static const int kInvokeItem = -4;
+ virtual BuiltinAction InvokeMenuItem(size_t menu_position);
// 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, or when the user boots into recovery image manually and
diff --git a/recovery.cpp b/recovery.cpp
index dc2cc085f..890f99c53 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -507,7 +507,7 @@ static std::string browse_directory(const std::string& path, Device* device) {
}
std::vector<std::string> dirs;
- std::vector<std::string> zips = { "../" }; // "../" is always the first entry.
+ std::vector<std::string> entries{ "../" }; // "../" is always the first entry.
dirent* de;
while ((de = readdir(d.get())) != nullptr) {
@@ -518,31 +518,25 @@ static std::string browse_directory(const std::string& path, Device* device) {
if (name == "." || name == "..") continue;
dirs.push_back(name + "/");
} else if (de->d_type == DT_REG && android::base::EndsWithIgnoreCase(name, ".zip")) {
- zips.push_back(name);
+ entries.push_back(name);
}
}
std::sort(dirs.begin(), dirs.end());
- std::sort(zips.begin(), zips.end());
+ std::sort(entries.begin(), entries.end());
- // Append dirs to the zips list.
- zips.insert(zips.end(), dirs.begin(), dirs.end());
+ // Append dirs to the entries list.
+ entries.insert(entries.end(), dirs.begin(), dirs.end());
- const char* entries[zips.size() + 1];
- entries[zips.size()] = nullptr;
- for (size_t i = 0; i < zips.size(); i++) {
- entries[i] = zips[i].c_str();
- }
-
- const char* headers[] = { "Choose a package to install:", path.c_str(), nullptr };
+ std::vector<std::string> headers{ "Choose a package to install:", path };
- int chosen_item = 0;
+ size_t chosen_item = 0;
while (true) {
chosen_item = ui->ShowMenu(
headers, entries, chosen_item, true,
std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
- const std::string& item = zips[chosen_item];
+ const std::string& item = entries[chosen_item];
if (chosen_item == 0) {
// Go up but continue browsing (if the caller is browse_directory).
return "";
@@ -564,10 +558,10 @@ static std::string browse_directory(const std::string& path, Device* device) {
}
static bool yes_no(Device* device, const char* question1, const char* question2) {
- const char* headers[] = { question1, question2, NULL };
- const char* items[] = { " No", " Yes", NULL };
+ std::vector<std::string> headers{ question1, question2 };
+ std::vector<std::string> items{ " No", " Yes" };
- int chosen_item = ui->ShowMenu(
+ size_t chosen_item = ui->ShowMenu(
headers, items, 0, true,
std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
return (chosen_item == 1);
@@ -601,20 +595,20 @@ static bool wipe_data(Device* device) {
static bool prompt_and_wipe_data(Device* device) {
// Use a single string and let ScreenRecoveryUI handles the wrapping.
- const char* const headers[] = {
+ std::vector<std::string> headers{
"Can't load Android system. Your data may be corrupt. "
"If you continue to get this message, you may need to "
"perform a factory data reset and erase all user data "
"stored on this device.",
- nullptr
};
- const char* const items[] = {
+ // clang-format off
+ std::vector<std::string> items {
"Try again",
"Factory data reset",
- NULL
};
+ // clang-format on
for (;;) {
- int chosen_item = ui->ShowMenu(
+ size_t chosen_item = ui->ShowMenu(
headers, items, 0, true,
std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
if (chosen_item != 1) {
@@ -806,17 +800,12 @@ static void choose_recovery_file(Device* device) {
entries.push_back("Back");
- std::vector<const char*> menu_entries(entries.size());
- std::transform(entries.cbegin(), entries.cend(), menu_entries.begin(),
- [](const std::string& entry) { return entry.c_str(); });
- menu_entries.push_back(nullptr);
+ std::vector<std::string> headers{ "Select file to view" };
- const char* headers[] = { "Select file to view", nullptr };
-
- int chosen_item = 0;
+ size_t chosen_item = 0;
while (true) {
chosen_item = ui->ShowMenu(
- headers, menu_entries.data(), chosen_item, true,
+ headers, entries, chosen_item, true,
std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
if (entries[chosen_item] == "Back") break;
@@ -963,14 +952,15 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
}
ui->SetProgressType(RecoveryUI::EMPTY);
- int chosen_item = ui->ShowMenu(
- nullptr, device->GetMenuItems(), 0, false,
+ size_t chosen_item = ui->ShowMenu(
+ {}, device->GetMenuItems(), 0, false,
std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
// Device-specific code may take some action here. It may return one of the core actions
// handled in the switch statement below.
- Device::BuiltinAction chosen_action =
- (chosen_item == -1) ? Device::REBOOT : device->InvokeMenuItem(chosen_item);
+ Device::BuiltinAction chosen_action = (chosen_item == static_cast<size_t>(-1))
+ ? Device::REBOOT
+ : device->InvokeMenuItem(chosen_item);
bool should_wipe_cache = false;
switch (chosen_action) {
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 56ca48ea8..7ae81e55f 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -31,6 +31,7 @@
#include <time.h>
#include <unistd.h>
+#include <algorithm>
#include <memory>
#include <string>
#include <unordered_map>
@@ -52,8 +53,9 @@ static double now() {
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
-Menu::Menu(bool scrollable, size_t max_items, size_t max_length, const char* const* headers,
- const char* const* items, int initial_selection)
+Menu::Menu(bool scrollable, size_t max_items, size_t max_length,
+ const std::vector<std::string>& headers, const std::vector<std::string>& items,
+ size_t initial_selection)
: scrollable_(scrollable),
max_display_items_(max_items),
max_item_length_(max_length),
@@ -63,15 +65,15 @@ Menu::Menu(bool scrollable, size_t max_items, size_t max_length, const char* con
CHECK_LE(max_items, static_cast<size_t>(std::numeric_limits<int>::max()));
// It's fine to have more entries than text_rows_ if scrollable menu is supported.
- size_t max_items_count = scrollable_ ? std::numeric_limits<int>::max() : max_display_items_;
- for (size_t i = 0; i < max_items_count && items[i] != nullptr; ++i) {
- text_items_.emplace_back(items[i], strnlen(items[i], max_item_length_));
+ size_t items_count = scrollable_ ? items.size() : std::min(items.size(), max_display_items_);
+ for (size_t i = 0; i < items_count; ++i) {
+ text_items_.emplace_back(items[i].substr(0, max_item_length_));
}
CHECK(!text_items_.empty());
}
-const char* const* Menu::text_headers() const {
+const std::vector<std::string>& Menu::text_headers() const {
return text_headers_;
}
@@ -99,7 +101,7 @@ bool Menu::ItemsOverflow(std::string* cur_selection_str) const {
}
*cur_selection_str =
- android::base::StringPrintf("Current item: %d/%zu", selection_ + 1, ItemsCount());
+ android::base::StringPrintf("Current item: %zu/%zu", selection_ + 1, ItemsCount());
return true;
}
@@ -503,10 +505,10 @@ void ScreenRecoveryUI::draw_screen_locked() {
gr_clear();
// clang-format off
- static std::vector<std::string> REGULAR_HELP = {
+ static std::vector<std::string> REGULAR_HELP{
"Use volume up/down and power.",
};
- static std::vector<std::string> LONG_PRESS_HELP = {
+ static std::vector<std::string> LONG_PRESS_HELP{
"Any button cycles highlight.",
"Long-press activates.",
};
@@ -532,22 +534,12 @@ void ScreenRecoveryUI::draw_menu_and_text_buffer_locked(
y += DrawTextLines(x, y, help_message);
- auto convert_to_vector = [](const char* const* items) -> std::vector<std::string> {
- if (items == nullptr) return {};
-
- std::vector<std::string> result;
- for (size_t i = 0; items[i] != nullptr; ++i) {
- result.emplace_back(items[i]);
- }
- return result;
- };
-
// Draw menu header.
SetColor(HEADER);
if (!menu_->scrollable()) {
- y += DrawWrappedTextLines(x, y, convert_to_vector(menu_->text_headers()));
+ y += DrawWrappedTextLines(x, y, menu_->text_headers());
} else {
- y += DrawTextLines(x, y, convert_to_vector(menu_->text_headers()));
+ y += DrawTextLines(x, y, menu_->text_headers());
// Show the current menu item number in relation to total number if items don't fit on the
// screen.
std::string cur_selection_str;
@@ -979,8 +971,8 @@ void ScreenRecoveryUI::ShowFile(const std::string& filename) {
text_row_ = old_text_row;
}
-void ScreenRecoveryUI::StartMenu(const char* const* headers, const char* const* items,
- int initial_selection) {
+void ScreenRecoveryUI::StartMenu(const std::vector<std::string>& headers,
+ const std::vector<std::string>& items, size_t initial_selection) {
pthread_mutex_lock(&updateMutex);
if (text_rows_ > 0 && text_cols_ > 1) {
menu_ = std::make_unique<Menu>(scrollable_menu_, text_rows_, text_cols_ - 1, headers, items,
@@ -1013,9 +1005,10 @@ void ScreenRecoveryUI::EndMenu() {
pthread_mutex_unlock(&updateMutex);
}
-int ScreenRecoveryUI::ShowMenu(const char* const* headers, const char* const* items,
- int initial_selection, bool menu_only,
- const std::function<int(int, bool)>& key_handler) {
+size_t ScreenRecoveryUI::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) {
// Throw away keys pressed previously, so user doesn't accidentally trigger menu items.
FlushKeys();
@@ -1031,7 +1024,7 @@ int ScreenRecoveryUI::ShowMenu(const char* const* headers, const char* const* it
} else {
LOG(INFO) << "Timed out waiting for key input; rebooting.";
EndMenu();
- return -1;
+ return static_cast<size_t>(-1);
}
}
diff --git a/screen_ui.h b/screen_ui.h
index 3b309fb13..fb811ce70 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -35,14 +35,15 @@ class Menu {
public:
// Constructs a Menu instance with the given |headers|, |items| and properties. Sets the initial
// selection to |initial_selection|.
- Menu(bool scrollable, size_t max_items, size_t max_length, const char* const* headers,
- const char* const* items, int initial_selection);
+ Menu(bool scrollable, size_t max_items, size_t max_length,
+ const std::vector<std::string>& headers, const std::vector<std::string>& items,
+ size_t initial_selection);
bool scrollable() const {
return scrollable_;
}
- int selection() const {
+ size_t selection() const {
return selection_;
}
@@ -66,7 +67,7 @@ class Menu {
// /cache/recovery/last_log.1
// /cache/recovery/last_log.2
// ...
- const char* const* text_headers() const;
+ const std::vector<std::string>& text_headers() const;
std::string TextItem(size_t index) const;
// Checks if the menu items fit vertically on the screen. Returns true and set the
@@ -84,15 +85,14 @@ class Menu {
const size_t max_display_items_;
// The length of each item to fit horizontally on a screen.
const size_t max_item_length_;
-
- // Internal storage for the menu headers and items in text.
- const char* const* text_headers_;
+ // The menu headers.
+ std::vector<std::string> text_headers_;
+ // The actual menu items trimmed to fit the given properties.
std::vector<std::string> text_items_;
-
// The first item to display on the screen.
size_t menu_start_;
// Current menu selection.
- int selection_;
+ size_t selection_;
};
// Implementation of RecoveryUI appropriate for devices with a screen
@@ -137,8 +137,9 @@ class ScreenRecoveryUI : public RecoveryUI {
void ShowFile(const std::string& filename) override;
// menu display
- int ShowMenu(const char* const* headers, const char* const* items, int initial_selection,
- bool menu_only, const std::function<int(int, bool)>& key_handler) override;
+ size_t 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) override;
void KeyLongPress(int) override;
@@ -166,8 +167,8 @@ class ScreenRecoveryUI : public RecoveryUI {
// Displays 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).
- virtual void StartMenu(const char* const* headers, const char* const* items,
- int initial_selection);
+ virtual void StartMenu(const std::vector<std::string>& headers,
+ const std::vector<std::string>& items, size_t initial_selection);
// Sets the menu highlight to the given index, wrapping if necessary. Returns the actual item
// selected.
diff --git a/stub_ui.h b/stub_ui.h
index 362aab443..2ccd49115 100644
--- a/stub_ui.h
+++ b/stub_ui.h
@@ -19,6 +19,7 @@
#include <functional>
#include <string>
+#include <vector>
#include "ui.h"
@@ -57,9 +58,10 @@ class StubRecoveryUI : public RecoveryUI {
void ShowFile(const std::string& /* filename */) override {}
// menu display
- int ShowMenu(const char* const* /* headers */, const char* const* /* items */,
- int initial_selection, bool /* menu_only */,
- const std::function<int(int, bool)>& /* key_handler */) override {
+ size_t 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 */) override {
return initial_selection;
}
};
diff --git a/tests/unit/screen_ui_test.cpp b/tests/unit/screen_ui_test.cpp
index 9c123e863..e47d7054b 100644
--- a/tests/unit/screen_ui_test.cpp
+++ b/tests/unit/screen_ui_test.cpp
@@ -14,19 +14,22 @@
* limitations under the License.
*/
-#include "screen_ui.h"
+#include <stddef.h>
#include <string>
+#include <vector>
#include <gtest/gtest.h>
-constexpr const char* HEADER[] = { "header", nullptr };
-constexpr const char* ITEMS[] = { "items1", "items2", "items3", "items4", "1234567890", nullptr };
+#include "screen_ui.h"
+
+static const std::vector<std::string> HEADERS{ "header" };
+static const std::vector<std::string> ITEMS{ "item1", "item2", "item3", "item4", "1234567890" };
TEST(ScreenUITest, StartPhoneMenuSmoke) {
- Menu menu(false, 10, 20, HEADER, ITEMS, 0);
+ Menu menu(false, 10, 20, HEADERS, ITEMS, 0);
ASSERT_FALSE(menu.scrollable());
- ASSERT_EQ(HEADER[0], menu.text_headers()[0]);
+ ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
ASSERT_EQ(5u, menu.ItemsCount());
std::string message;
@@ -39,9 +42,9 @@ TEST(ScreenUITest, StartPhoneMenuSmoke) {
}
TEST(ScreenUITest, StartWearMenuSmoke) {
- Menu menu(true, 10, 8, HEADER, ITEMS, 1);
+ Menu menu(true, 10, 8, HEADERS, ITEMS, 1);
ASSERT_TRUE(menu.scrollable());
- ASSERT_EQ(HEADER[0], menu.text_headers()[0]);
+ ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
ASSERT_EQ(5u, menu.ItemsCount());
std::string message;
@@ -55,7 +58,7 @@ TEST(ScreenUITest, StartWearMenuSmoke) {
}
TEST(ScreenUITest, StartPhoneMenuItemsOverflow) {
- Menu menu(false, 1, 20, HEADER, ITEMS, 0);
+ Menu menu(false, 1, 20, HEADERS, ITEMS, 0);
ASSERT_FALSE(menu.scrollable());
ASSERT_EQ(1u, menu.ItemsCount());
@@ -70,7 +73,7 @@ TEST(ScreenUITest, StartPhoneMenuItemsOverflow) {
}
TEST(ScreenUITest, StartWearMenuItemsOverflow) {
- Menu menu(true, 1, 20, HEADER, ITEMS, 0);
+ Menu menu(true, 1, 20, HEADERS, ITEMS, 0);
ASSERT_TRUE(menu.scrollable());
ASSERT_EQ(5u, menu.ItemsCount());
@@ -88,7 +91,7 @@ TEST(ScreenUITest, StartWearMenuItemsOverflow) {
TEST(ScreenUITest, PhoneMenuSelectSmoke) {
int sel = 0;
- Menu menu(false, 10, 20, HEADER, ITEMS, sel);
+ Menu menu(false, 10, 20, HEADERS, ITEMS, sel);
// Mimic down button 10 times (2 * items size)
for (int i = 0; i < 10; i++) {
sel = menu.Select(++sel);
@@ -117,7 +120,7 @@ TEST(ScreenUITest, PhoneMenuSelectSmoke) {
TEST(ScreenUITest, WearMenuSelectSmoke) {
int sel = 0;
- Menu menu(true, 10, 20, HEADER, ITEMS, sel);
+ Menu menu(true, 10, 20, HEADERS, ITEMS, sel);
// Mimic pressing down button 10 times (2 * items size)
for (int i = 0; i < 10; i++) {
sel = menu.Select(++sel);
@@ -146,7 +149,7 @@ TEST(ScreenUITest, WearMenuSelectSmoke) {
TEST(ScreenUITest, WearMenuSelectItemsOverflow) {
int sel = 1;
- Menu menu(true, 3, 20, HEADER, ITEMS, sel);
+ Menu menu(true, 3, 20, HEADERS, ITEMS, sel);
ASSERT_EQ(5u, menu.ItemsCount());
// Scroll the menu to the end, and check the start & end of menu.
diff --git a/ui.h b/ui.h
index c4689923a..35cc36e70 100644
--- a/ui.h
+++ b/ui.h
@@ -23,6 +23,7 @@
#include <functional>
#include <string>
+#include <vector>
// Abstract class for controlling the user interface during recovery.
class RecoveryUI {
@@ -139,10 +140,11 @@ class RecoveryUI {
// key_handler, which may be beyond the range of menu items. This could be used to trigger a
// device-specific action, even without that being listed in the menu. Caller needs to handle
// such a case accordingly (e.g. by calling Device::InvokeMenuItem() to process the action).
- // Returns a non-negative value (the chosen item number or device-specific action code), or -1 if
- // timed out waiting for input.
- virtual int ShowMenu(const char* const* headers, const char* const* items, int initial_selection,
- bool menu_only, const std::function<int(int, bool)>& key_handler) = 0;
+ // Returns a non-negative value (the chosen item number or device-specific action code), or
+ // static_cast<size_t>(-1) if timed out waiting for input.
+ virtual size_t 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) = 0;
protected:
void EnqueueKey(int key_code);
diff --git a/wear_ui.cpp b/wear_ui.cpp
index d21f83542..f157d3ca3 100644
--- a/wear_ui.cpp
+++ b/wear_ui.cpp
@@ -20,6 +20,7 @@
#include <string.h>
#include <string>
+#include <vector>
#include <android-base/properties.h>
#include <android-base/strings.h>
@@ -88,13 +89,12 @@ void WearRecoveryUI::update_progress_locked() {
void WearRecoveryUI::SetStage(int /* current */, int /* max */) {}
-void WearRecoveryUI::StartMenu(const char* const* headers, const char* const* items,
- int initial_selection) {
+void WearRecoveryUI::StartMenu(const std::vector<std::string>& headers,
+ const std::vector<std::string>& items, size_t initial_selection) {
pthread_mutex_lock(&updateMutex);
if (text_rows_ > 0 && text_cols_ > 0) {
menu_ = std::make_unique<Menu>(scrollable_menu_, text_rows_ - kMenuUnusableRows - 1,
text_cols_ - 1, headers, items, initial_selection);
-
update_screen_locked();
}
pthread_mutex_unlock(&updateMutex);
diff --git a/wear_ui.h b/wear_ui.h
index fcbbee289..c9a9f0e13 100644
--- a/wear_ui.h
+++ b/wear_ui.h
@@ -17,6 +17,9 @@
#ifndef RECOVERY_WEAR_UI_H
#define RECOVERY_WEAR_UI_H
+#include <string>
+#include <vector>
+
#include "screen_ui.h"
class WearRecoveryUI : public ScreenRecoveryUI {
@@ -33,8 +36,8 @@ class WearRecoveryUI : public ScreenRecoveryUI {
// Recovery, build id and etc) and the bottom lines that may otherwise go out of the screen.
const int kMenuUnusableRows;
- void StartMenu(const char* const* headers, const char* const* items,
- int initial_selection) override;
+ void StartMenu(const std::vector<std::string>& headers, const std::vector<std::string>& items,
+ size_t initial_selection) override;
int GetProgressBaseline() const override;