1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <linux/input.h> 18 #include <sys/stat.h> 19 #include <errno.h> 20 #include <string.h> 21 22 #include "recovery_ui.h" 23 #include "common.h" 24 25 char* MENU_HEADERS[] = { "Volume up/down to move highlight;", 26 "power button to select.", 27 "", 28 NULL }; 29 30 char* MENU_ITEMS[] = { "reboot system now", 31 "apply update from /sdcard", 32 "wipe data/factory reset", 33 "wipe cache partition", 34 NULL }; 35 36 int device_recovery_start() { 37 // recovery can get started before the kernel has created the EMMC 38 // devices, which will make the wipe_data operation fail (trying 39 // to open a device that doesn't exist). Hold up the start of 40 // recovery for up to 5 seconds waiting for the userdata partition 41 // block device to exist. 42 43 const char* fn = "/dev/block/platform/s3c-sdhci.0/by-name/userdata"; 44 45 int tries = 0; 46 int ret; 47 struct stat buf; 48 do { 49 ++tries; 50 ret = stat(fn, &buf); 51 if (ret) { 52 printf("try %d: %s\n", tries, strerror(errno)); 53 sleep(1); 54 } 55 } while (ret && tries < 5); 56 if (!ret) { 57 printf("stat() of %s succeeded on try %d\n", fn, tries); 58 } else { 59 printf("failed to stat %s\n", fn); 60 } 61 62 // We let recovery attempt to carry on even if the stat never 63 // succeeded. 64 65 return 0; 66 } 67 68 int device_toggle_display(volatile char* key_pressed, int key_code) { 69 // hold power and press volume-up 70 return key_pressed[KEY_POWER] && key_code == KEY_VOLUMEUP; 71 } 72 73 int device_reboot_now(volatile char* key_pressed, int key_code) { 74 // Reboot if the power key is pressed five times in a row, with 75 // no other keys in between. 76 static int presses = 0; 77 if (key_code == KEY_POWER) { // power button 78 ++presses; 79 return presses == 5; 80 } else { 81 presses = 0; 82 return 0; 83 } 84 } 85 86 int device_handle_key(int key_code, int visible) { 87 if (visible) { 88 switch (key_code) { 89 case KEY_DOWN: 90 case KEY_VOLUMEDOWN: 91 return HIGHLIGHT_DOWN; 92 93 case KEY_UP: 94 case KEY_VOLUMEUP: 95 return HIGHLIGHT_UP; 96 97 case KEY_ENTER: 98 case KEY_POWER: // crespo power 99 return SELECT_ITEM; 100 } 101 } 102 103 return NO_ACTION; 104 } 105 106 int device_perform_action(int which) { 107 return which; 108 } 109 110 int device_wipe_data() { 111 return 0; 112 } 113