summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--minzip/DirUtil.c58
-rw-r--r--minzip/DirUtil.h8
-rw-r--r--ui.cpp48
-rw-r--r--ui.h6
-rw-r--r--updater/install.c87
6 files changed, 52 insertions, 156 deletions
diff --git a/Android.mk b/Android.mk
index 075fa2cfe..645a83534 100644
--- a/Android.mk
+++ b/Android.mk
@@ -82,6 +82,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := verifier_test
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS += -DNO_RECOVERY_MOUNT
LOCAL_SRC_FILES := \
verifier_test.cpp \
verifier.cpp \
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.c
index 8dd5da1da..fe2c880ac 100644
--- a/minzip/DirUtil.c
+++ b/minzip/DirUtil.c
@@ -234,61 +234,3 @@ dirUnlinkHierarchy(const char *path)
/* delete target directory */
return rmdir(path);
}
-
-int
-dirSetHierarchyPermissions(const char *path,
- int uid, int gid, int dirMode, int fileMode)
-{
- struct stat st;
- if (lstat(path, &st)) {
- return -1;
- }
-
- /* ignore symlinks */
- if (S_ISLNK(st.st_mode)) {
- return 0;
- }
-
- /* directories and files get different permissions */
- if (chown(path, uid, gid) ||
- chmod(path, S_ISDIR(st.st_mode) ? dirMode : fileMode)) {
- return -1;
- }
-
- /* recurse over directory components */
- if (S_ISDIR(st.st_mode)) {
- DIR *dir = opendir(path);
- if (dir == NULL) {
- return -1;
- }
-
- errno = 0;
- const struct dirent *de;
- while (errno == 0 && (de = readdir(dir)) != NULL) {
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
- continue;
- }
-
- char dn[PATH_MAX];
- snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
- if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode)) {
- errno = 0;
- } else if (errno == 0) {
- errno = -1;
- }
- }
-
- if (errno != 0) {
- int save = errno;
- closedir(dir);
- errno = save;
- return -1;
- }
-
- if (closedir(dir)) {
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/minzip/DirUtil.h b/minzip/DirUtil.h
index a5cfa761b..85a00128b 100644
--- a/minzip/DirUtil.h
+++ b/minzip/DirUtil.h
@@ -48,14 +48,6 @@ int dirCreateHierarchy(const char *path, int mode,
*/
int dirUnlinkHierarchy(const char *path);
-/* chown -R <uid>:<gid> <path>
- * chmod -R <mode> <path>
- *
- * Sets directories to <dirMode> and files to <fileMode>. Skips symlinks.
- */
-int dirSetHierarchyPermissions(const char *path,
- int uid, int gid, int dirMode, int fileMode);
-
#ifdef __cplusplus
}
#endif
diff --git a/ui.cpp b/ui.cpp
index cece02d31..5043ee528 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -31,6 +31,7 @@
#include <cutils/android_reboot.h>
#include "common.h"
+#include "roots.h"
#include "device.h"
#include "minui/minui.h"
#include "screen_ui.h"
@@ -47,7 +48,10 @@ RecoveryUI::RecoveryUI() :
key_queue_len(0),
key_last_down(-1),
key_long_press(false),
- key_down_count(0) {
+ key_down_count(0),
+ consecutive_power_keys(0),
+ consecutive_alternate_keys(0),
+ last_key(-1) {
pthread_mutex_init(&key_queue_mutex, NULL);
pthread_cond_init(&key_queue_cond, NULL);
self = this;
@@ -152,6 +156,13 @@ void RecoveryUI::process_key(int key_code, int updown) {
case RecoveryUI::ENQUEUE:
EnqueueKey(key_code);
break;
+
+ case RecoveryUI::MOUNT_SYSTEM:
+#ifndef NO_RECOVERY_MOUNT
+ ensure_path_mounted("/system");
+ Print("Mounted /system.");
+#endif
+ break;
}
}
}
@@ -258,8 +269,41 @@ void RecoveryUI::FlushKeys() {
pthread_mutex_unlock(&key_queue_mutex);
}
+// The default CheckKey implementation assumes the device has power,
+// volume up, and volume down keys.
+//
+// - Hold power and press vol-up to toggle display.
+// - Press power seven times in a row to reboot.
+// - Alternate vol-up and vol-down seven times to mount /system.
RecoveryUI::KeyAction RecoveryUI::CheckKey(int key) {
- return RecoveryUI::ENQUEUE;
+ if (IsKeyPressed(KEY_POWER) && key == KEY_VOLUMEUP) {
+ return TOGGLE;
+ }
+
+ if (key == KEY_POWER) {
+ ++consecutive_power_keys;
+ if (consecutive_power_keys >= 7) {
+ return REBOOT;
+ }
+ } else {
+ consecutive_power_keys = 0;
+ }
+
+ if ((key == KEY_VOLUMEUP &&
+ (last_key == KEY_VOLUMEDOWN || last_key == -1)) ||
+ (key == KEY_VOLUMEDOWN &&
+ (last_key == KEY_VOLUMEUP || last_key == -1))) {
+ ++consecutive_alternate_keys;
+ if (consecutive_alternate_keys >= 7) {
+ consecutive_alternate_keys = 0;
+ return MOUNT_SYSTEM;
+ }
+ } else {
+ consecutive_alternate_keys = 0;
+ }
+ last_key = key;
+
+ return ENQUEUE;
}
void RecoveryUI::NextCheckKeyIsLong(bool is_long_press) {
diff --git a/ui.h b/ui.h
index 6c8987a33..d85fc659b 100644
--- a/ui.h
+++ b/ui.h
@@ -77,7 +77,7 @@ class RecoveryUI {
// Return value indicates whether an immediate operation should be
// triggered (toggling the display, rebooting the device), or if
// the key should be enqueued for use by the main thread.
- enum KeyAction { ENQUEUE, TOGGLE, REBOOT, IGNORE };
+ enum KeyAction { ENQUEUE, TOGGLE, REBOOT, IGNORE, MOUNT_SYSTEM };
virtual KeyAction CheckKey(int key);
// Called immediately before each call to CheckKey(), tell you if
@@ -121,6 +121,10 @@ private:
int key_down_count; // under key_queue_mutex
int rel_sum;
+ int consecutive_power_keys;
+ int consecutive_alternate_keys;
+ int last_key;
+
typedef struct {
RecoveryUI* ui;
int key_code;
diff --git a/updater/install.c b/updater/install.c
index 0a859452a..061aa7b5b 100644
--- a/updater/install.c
+++ b/updater/install.c
@@ -524,88 +524,6 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
return StringValue(strdup(""));
}
-
-Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
- char* result = NULL;
- bool recursive = (strcmp(name, "set_perm_recursive") == 0);
-
- int min_args = 4 + (recursive ? 1 : 0);
- if (argc < min_args) {
- return ErrorAbort(state, "%s() expects %d+ args, got %d",
- name, min_args, argc);
- }
-
- char** args = ReadVarArgs(state, argc, argv);
- if (args == NULL) return NULL;
-
- char* end;
- int i;
- int bad = 0;
-
- int uid = strtoul(args[0], &end, 0);
- if (*end != '\0' || args[0][0] == 0) {
- ErrorAbort(state, "%s: \"%s\" not a valid uid", name, args[0]);
- goto done;
- }
-
- int gid = strtoul(args[1], &end, 0);
- if (*end != '\0' || args[1][0] == 0) {
- ErrorAbort(state, "%s: \"%s\" not a valid gid", name, args[1]);
- goto done;
- }
-
- if (recursive) {
- int dir_mode = strtoul(args[2], &end, 0);
- if (*end != '\0' || args[2][0] == 0) {
- ErrorAbort(state, "%s: \"%s\" not a valid dirmode", name, args[2]);
- goto done;
- }
-
- int file_mode = strtoul(args[3], &end, 0);
- if (*end != '\0' || args[3][0] == 0) {
- ErrorAbort(state, "%s: \"%s\" not a valid filemode",
- name, args[3]);
- goto done;
- }
-
- for (i = 4; i < argc; ++i) {
- dirSetHierarchyPermissions(args[i], uid, gid, dir_mode, file_mode);
- }
- } else {
- int mode = strtoul(args[2], &end, 0);
- if (*end != '\0' || args[2][0] == 0) {
- ErrorAbort(state, "%s: \"%s\" not a valid mode", name, args[2]);
- goto done;
- }
-
- for (i = 3; i < argc; ++i) {
- if (chown(args[i], uid, gid) < 0) {
- printf("%s: chown of %s to %d %d failed: %s\n",
- name, args[i], uid, gid, strerror(errno));
- ++bad;
- }
- if (chmod(args[i], mode) < 0) {
- printf("%s: chmod of %s to %o failed: %s\n",
- name, args[i], mode, strerror(errno));
- ++bad;
- }
- }
- }
- result = strdup("");
-
-done:
- for (i = 0; i < argc; ++i) {
- free(args[i]);
- }
- free(args);
-
- if (bad) {
- free(result);
- return ErrorAbort(state, "%s: some changes failed", name);
- }
- return StringValue(result);
-}
-
struct perm_parsed_args {
bool has_uid;
uid_t uid;
@@ -1398,11 +1316,6 @@ void RegisterInstallFunctions() {
RegisterFunction("package_extract_file", PackageExtractFileFn);
RegisterFunction("symlink", SymlinkFn);
- // Maybe, at some future point, we can delete these functions? They have been
- // replaced by perm_set and perm_set_recursive.
- RegisterFunction("set_perm", SetPermFn);
- RegisterFunction("set_perm_recursive", SetPermFn);
-
// Usage:
// set_metadata("filename", "key1", "value1", "key2", "value2", ...)
// Example: