Merge "Move menu headers/items to std::vector<std::string>." am: fb86bb2a07

am: 0d9ed29541

Change-Id: I7428f86e9bc3e46c5bcf0afeb3cf5608be31e470
This commit is contained in:
Tao Bao 2018-05-03 16:27:28 -07:00 committed by android-build-merger
commit 3777c4b859
10 changed files with 147 additions and 141 deletions

View file

@ -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(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_assert(arraysize(kItems) == arraysize(kMenuActions),
"kItems and kMenuActions should have the same length.");
const char* const* Device::GetMenuItems() {
return MENU_ITEMS;
static const std::vector<std::string> kMenuItems(kItems, kItems + arraysize(kItems));
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) {

View file

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

View file

@ -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();
}
std::vector<std::string> headers{ "Choose a package to install:", path };
const char* headers[] = { "Choose a package to install:", path.c_str(), nullptr };
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) {

View file

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

View file

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

View file

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

View file

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

10
ui.h
View file

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

View file

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

View file

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