diff options
-rw-r--r-- | device.cpp | 29 | ||||
-rw-r--r-- | device.h | 69 | ||||
-rw-r--r-- | recovery.cpp | 58 | ||||
-rw-r--r-- | screen_ui.cpp | 47 | ||||
-rw-r--r-- | screen_ui.h | 27 | ||||
-rw-r--r-- | stub_ui.h | 8 | ||||
-rw-r--r-- | tests/unit/screen_ui_test.cpp | 27 | ||||
-rw-r--r-- | ui.h | 10 | ||||
-rw-r--r-- | wear_ui.cpp | 6 | ||||
-rw-r--r-- | wear_ui.h | 7 |
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) { @@ -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. @@ -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. @@ -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); @@ -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; |