/* * Copyright (C) 2015 The Android Open Source Project * Copyright (C) 2019 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "recovery_ui/device.h" #include #include #include #include #include #include "recovery_ui/ui.h" typedef std::pair menu_action_t; static std::vector g_main_header{}; static std::vector g_main_actions{ { "Reboot system now", Device::REBOOT }, { "Apply update", Device::APPLY_UPDATE }, { "Factory reset", Device::MENU_WIPE }, { "Advanced", Device::MENU_ADVANCED }, }; static std::vector g_advanced_header{ "Advanced options" }; static std::vector g_advanced_actions{ { "Enter fastboot", Device::ENTER_FASTBOOT }, { "Reboot to bootloader", Device::REBOOT_BOOTLOADER }, { "Reboot to recovery", Device::REBOOT_RECOVERY }, { "Mount /system", Device::MOUNT_SYSTEM }, { "View recovery logs", Device::VIEW_RECOVERY_LOGS }, { "Enable ADB", Device::ENABLE_ADB }, { "Run graphics test", Device::RUN_GRAPHICS_TEST }, { "Run locale test", Device::RUN_LOCALE_TEST }, { "Enter rescue", Device::ENTER_RESCUE }, { "Power off", Device::SHUTDOWN }, }; static std::vector g_wipe_header{ "Factory reset" }; static std::vector g_wipe_actions{ { "Format data/factory reset", Device::WIPE_DATA }, { "Format cache partition", Device::WIPE_CACHE }, { "Format system partition", Device::WIPE_SYSTEM }, }; static std::vector* current_menu_ = &g_main_actions; static std::vector g_menu_items; static void PopulateMenuItems() { g_menu_items.clear(); std::transform(current_menu_->cbegin(), current_menu_->cend(), std::back_inserter(g_menu_items), [](const auto& entry) { return entry.first; }); } Device::Device(RecoveryUI* ui) : ui_(ui) { PopulateMenuItems(); } void Device::GoHome() { current_menu_ = &g_main_actions; PopulateMenuItems(); } static void RemoveMenuItemForAction(std::vector& menu, Device::BuiltinAction action) { menu.erase( std::remove_if(menu.begin(), menu.end(), [action](const auto& entry) { return entry.second == action; }), menu.end()); CHECK(!menu.empty()); } void Device::RemoveMenuItemForAction(Device::BuiltinAction action) { ::RemoveMenuItemForAction(g_wipe_actions, action); ::RemoveMenuItemForAction(g_advanced_actions, action); } const std::vector& Device::GetMenuItems() { return g_menu_items; } const std::vector& Device::GetMenuHeaders() { if (current_menu_ == &g_wipe_actions) return g_wipe_header; if (current_menu_ == &g_advanced_actions) return g_advanced_header; return g_main_header; } Device::BuiltinAction Device::InvokeMenuItem(size_t menu_position) { Device::BuiltinAction action = (*current_menu_)[menu_position].second; if (action > MENU_BASE) { switch (action) { case Device::BuiltinAction::MENU_WIPE: current_menu_ = &g_wipe_actions; break; case Device::BuiltinAction::MENU_ADVANCED: current_menu_ = &g_advanced_actions; break; default: break; } PopulateMenuItems(); } return action; } int Device::HandleMenuKey(int key, bool visible) { if (!visible) { return kNoAction; } switch (key) { case KEY_RIGHTSHIFT: case KEY_DOWN: case KEY_VOLUMEDOWN: case KEY_MENU: return kHighlightDown; case KEY_UP: case KEY_VOLUMEUP: case KEY_SEARCH: return kHighlightUp; case KEY_SCROLLUP: return kScrollUp; case KEY_SCROLLDOWN: return kScrollDown; case KEY_ENTER: case KEY_POWER: case BTN_MOUSE: case KEY_SEND: return kInvokeItem; case KEY_HOME: case KEY_HOMEPAGE: return kGoHome; case KEY_BACKSPACE: case KEY_BACK: return kGoBack; case KEY_REFRESH: return kRefresh; case KEY_AGAIN: return kDoSideload; default: // If you have all of the above buttons, any other buttons // are ignored. Otherwise, any button cycles the highlight. return ui_->HasThreeButtons() ? kNoAction : kHighlightDown; } }