/* * 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 "device.h" #define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) // *** Main menu *** static const menu_type_t MAIN_MENU_TYPE = MT_GRID; static const MenuItem MAIN_MENU_ITEMS[] = { MenuItem("Reboot", "ic_reboot", "ic_reboot_sel"), MenuItem("Apply update", "ic_system_update", "ic_system_update_sel"), MenuItem("Factory reset", "ic_factory_reset", "ic_factory_reset_sel"), MenuItem("Advanced", "ic_options_advanced", "ic_options_advanced_sel"), }; static const MenuItemVector main_menu_items_ = MenuItemVector(MAIN_MENU_ITEMS, MAIN_MENU_ITEMS + ARRAY_SIZE(MAIN_MENU_ITEMS)); static const Device::BuiltinAction MAIN_MENU_ACTIONS[] = { Device::REBOOT, Device::APPLY_UPDATE, Device::WIPE_MENU, Device::ADVANCED_MENU, }; static const Device::MenuActionVector main_menu_actions_ = Device::MenuActionVector(MAIN_MENU_ACTIONS, MAIN_MENU_ACTIONS + ARRAY_SIZE(MAIN_MENU_ACTIONS)); static_assert(ARRAY_SIZE(MAIN_MENU_ITEMS) == ARRAY_SIZE(MAIN_MENU_ACTIONS), "MAIN_MENU_ITEMS and MAIN_MENU_ACTIONS should have the same length."); // *** Wipe menu *** static const menu_type_t WIPE_MENU_TYPE = MT_LIST; static const MenuItem WIPE_MENU_ITEMS[] = { MenuItem("Wipe data / factory reset"), #ifndef AB_OTA_UPDATER MenuItem("Wipe cache"), #endif MenuItem("Wipe system"), }; static const MenuItemVector wipe_menu_items_ = MenuItemVector(WIPE_MENU_ITEMS, WIPE_MENU_ITEMS + ARRAY_SIZE(WIPE_MENU_ITEMS)); static const Device::BuiltinAction WIPE_MENU_ACTIONS[] = { Device::WIPE_DATA, #ifndef AB_OTA_UPDATER Device::WIPE_CACHE, #endif Device::WIPE_SYSTEM, }; static const Device::MenuActionVector wipe_menu_actions_ = Device::MenuActionVector(WIPE_MENU_ACTIONS, WIPE_MENU_ACTIONS + ARRAY_SIZE(WIPE_MENU_ACTIONS)); static_assert(ARRAY_SIZE(WIPE_MENU_ITEMS) == ARRAY_SIZE(WIPE_MENU_ACTIONS), "WIPE_MENU_ITEMS and WIPE_MENU_ACTIONS should have the same length."); // *** Advanced menu static const menu_type_t ADVANCED_MENU_TYPE = MT_LIST; static const MenuItem ADVANCED_MENU_ITEMS[] = { #ifdef DOWNLOAD_MODE MenuItem("Reboot to download mode"), #else MenuItem("Reboot to bootloader"), #endif MenuItem("Reboot to recovery"), MenuItem("Mount system"), MenuItem("View logs"), #ifdef SHOW_TESTS MenuItem("Run graphics test"), MenuItem("Run locale test"), #endif MenuItem("Power off"), }; static const MenuItemVector advanced_menu_items_ = MenuItemVector(ADVANCED_MENU_ITEMS, ADVANCED_MENU_ITEMS + ARRAY_SIZE(ADVANCED_MENU_ITEMS)); static const Device::BuiltinAction ADVANCED_MENU_ACTIONS[] = { Device::REBOOT_BOOTLOADER, Device::REBOOT_RECOVERY, Device::MOUNT_SYSTEM, Device::VIEW_RECOVERY_LOGS, #ifdef SHOW_TESTS Device::RUN_GRAPHICS_TEST, Device::RUN_LOCALE_TEST, #endif Device::SHUTDOWN, }; static const Device::MenuActionVector advanced_menu_actions_ = Device::MenuActionVector( ADVANCED_MENU_ACTIONS, ADVANCED_MENU_ACTIONS + ARRAY_SIZE(ADVANCED_MENU_ACTIONS)); static_assert(ARRAY_SIZE(ADVANCED_MENU_ITEMS) == ARRAY_SIZE(ADVANCED_MENU_ACTIONS), "ADVANCED_MENU_ITEMS and ADVANCED_MENU_ACTIONS should have the same length."); Device::Device(RecoveryUI* ui) : ui_(ui) { GoHome(); } Device::BuiltinAction Device::InvokeMenuItem(int menu_position) { if (menu_position < 0) { if (menu_position == Device::kGoBack || menu_position == Device::kGoHome) { // Assume only two menu levels, so back is equivalent to home. GoHome(); } return NO_ACTION; } BuiltinAction action = menu_actions_.at(menu_position); switch (action) { case WIPE_MENU: menu_is_main_ = false; menu_type_ = WIPE_MENU_TYPE; menu_items_ = wipe_menu_items_; menu_actions_ = wipe_menu_actions_; break; case ADVANCED_MENU: menu_is_main_ = false; menu_type_ = ADVANCED_MENU_TYPE; menu_items_ = advanced_menu_items_; menu_actions_ = advanced_menu_actions_; break; default: break; // Fall through } return action; } void Device::GoHome() { menu_is_main_ = true; menu_type_ = MAIN_MENU_TYPE; menu_items_ = main_menu_items_; menu_actions_ = main_menu_actions_; } 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_LEFTSHIFT: 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; 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; } }