summaryrefslogtreecommitdiffstats
path: root/adb/services.cpp
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2015-03-29 11:22:34 -0700
committerTao Bao <tbao@google.com>2015-03-31 00:19:52 +0000
commit175b7bbfb4d935e1867a1d6df14e6ef94f2db2f4 (patch)
tree7559dc5d9a5104c1584a782392ca3784d49e92be /adb/services.cpp
parent934102baf8fca57abf63df7f134e977e696722db (diff)
downloadcore-175b7bbfb4d935e1867a1d6df14e6ef94f2db2f4.tar.gz
core-175b7bbfb4d935e1867a1d6df14e6ef94f2db2f4.tar.bz2
core-175b7bbfb4d935e1867a1d6df14e6ef94f2db2f4.zip
adb: Add option to reboot into sideload mode in recovery
Currently it requires manual key press to enter the sideload mode. This CL adds 'adb reboot sideload' to reboot the device into sideload mode directly with text display on. With 'adb reboot sideload-auto-reboot', it will reboot after the sideload regardless of the installation result, unless interrupted by user. Since it needs to write to /cache/recovery/command file, 'adb root' is required before calling 'adb reboot sideload' and the one with '-auto-reboot'. Also it requires the matching CL in bootable/recovery. Change-Id: Ib7bd4e216a1efc01e64460659c97c6005bbaec1b
Diffstat (limited to 'adb/services.cpp')
-rw-r--r--adb/services.cpp70
1 files changed, 56 insertions, 14 deletions
diff --git a/adb/services.cpp b/adb/services.cpp
index abf8ea572..12eb406ff 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -32,6 +32,7 @@
#endif
#if !ADB_HOST
+#include "base/file.h"
#include "cutils/android_reboot.h"
#include "cutils/properties.h"
#endif
@@ -132,31 +133,72 @@ void restart_usb_service(int fd, void *cookie)
adb_close(fd);
}
-void reboot_service(int fd, void *arg)
-{
+static bool reboot_service_impl(int fd, const char* arg) {
+ const char* reboot_arg = arg;
+ bool auto_reboot = false;
+
+ if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) {
+ auto_reboot = true;
+ reboot_arg = "sideload";
+ }
+
char buf[100];
- char property_val[PROPERTY_VALUE_MAX];
- int ret;
+ // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
+ // in the command file.
+ if (strcmp(reboot_arg, "sideload") == 0) {
+ if (getuid() != 0) {
+ snprintf(buf, sizeof(buf), "'adb root' is required for 'adb reboot sideload'.\n");
+ WriteStringFully(fd, buf);
+ return false;
+ }
+
+ const char* const recovery_dir = "/cache/recovery";
+ const char* const command_file = "/cache/recovery/command";
+ // Ensure /cache/recovery exists.
+ if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) {
+ D("Failed to create directory '%s': %s\n", recovery_dir, strerror(errno));
+ return false;
+ }
+
+ bool write_status = android::base::WriteStringToFile(
+ auto_reboot ? "--sideload_auto_reboot" : "--sideload", command_file);
+ if (!write_status) {
+ return false;
+ }
+
+ reboot_arg = "recovery";
+ }
sync();
- ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg);
- if (ret >= (int) sizeof(property_val)) {
+ char property_val[PROPERTY_VALUE_MAX];
+ int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
+ if (ret >= static_cast<int>(sizeof(property_val))) {
snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
- WriteFdExactly(fd, buf, strlen(buf));
- goto cleanup;
+ WriteStringFully(fd, buf);
+ return false;
}
ret = property_set(ANDROID_RB_PROPERTY, property_val);
if (ret < 0) {
snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
- WriteFdExactly(fd, buf, strlen(buf));
- goto cleanup;
+ WriteStringFully(fd, buf);
+ return false;
}
- // Don't return early. Give the reboot command time to take effect
- // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
- while(1) { pause(); }
-cleanup:
+
+ return true;
+}
+
+void reboot_service(int fd, void* arg)
+{
+ if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
+ // Don't return early. Give the reboot command time to take effect
+ // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
+ while (1) {
+ pause();
+ }
+ }
+
free(arg);
adb_close(fd);
}