diff options
Diffstat (limited to 'adb')
-rw-r--r-- | adb/adb.cpp | 2 | ||||
-rw-r--r-- | adb/adb.h | 5 | ||||
-rw-r--r-- | adb/adb_main.cpp | 10 | ||||
-rw-r--r-- | adb/commandline.cpp | 51 | ||||
-rw-r--r-- | adb/services.cpp | 57 | ||||
-rw-r--r-- | adb/transport.cpp | 6 | ||||
-rw-r--r-- | adb/usb_linux_client.cpp | 59 |
7 files changed, 133 insertions, 57 deletions
diff --git a/adb/adb.cpp b/adb/adb.cpp index f64b19f..c09aee3 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -919,7 +919,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if(!strncmp(service,"get-state",strlen("get-state"))) { transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); SendOkay(reply_fd); - SendProtocolString(reply_fd, transport->connection_state_name()); + SendProtocolString(reply_fd, transport ? transport->connection_state_name() : "unknown"); return 0; } #endif // ADB_HOST @@ -339,6 +339,8 @@ int adb_commandline(int argc, const char **argv); int connection_state(atransport *t); +extern int recovery_mode; + #define CS_ANY -1 #define CS_OFFLINE 0 #define CS_BOOTLOADER 1 @@ -350,6 +352,9 @@ int connection_state(atransport *t); #define CS_UNAUTHORIZED 7 extern const char *adb_device_banner; + +#define CS_ONLINE 10 /* recovery or device */ + extern int HOST; extern int SHELL_EXIT_NOTIFY_FD; diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp index 45a2158..4025fbe 100644 --- a/adb/adb_main.cpp +++ b/adb/adb_main.cpp @@ -239,7 +239,9 @@ int adb_main(int is_daemon, int server_port) // descriptor will always be open. adbd_cloexec_auth_socket(); - if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) { + // Override auth in factory test mode + if ((ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) || + (property_get_bool("ro.boot.ftm", 0) == 1)) { auth_required = false; } @@ -359,6 +361,10 @@ void close_stdin() { } #endif +#if !ADB_HOST +int recovery_mode = 0; +#endif + // TODO(danalbert): Split this file up into adb_main.cpp and adbd_main.cpp. int main(int argc, char **argv) { #if ADB_HOST @@ -397,6 +403,8 @@ int main(int argc, char **argv) { } } + recovery_mode = (strcmp(adb_device_banner, "recovery") == 0); + close_stdin(); adb_trace_init(); diff --git a/adb/commandline.cpp b/adb/commandline.cpp index fd9953c..26eea2f 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -497,6 +497,8 @@ static int adb_download_buffer(const char *service, const char *fn, const void* #define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE) +#define MB (1024*1024) + /* * The sideload-host protocol serves the data in a file (given on the * command line) to the client, using a simple protocol: @@ -517,10 +519,13 @@ static int adb_download_buffer(const char *service, const char *fn, const void* * we hang up. */ static int adb_sideload_host(const char* fn) { + static const char spinner[] = "/-\\|"; + static const int spinlen = sizeof(spinner)-1; + size_t last_xfer = 0; + int spin_index = 0; unsigned sz; size_t xfer = 0; int status; - int last_percent = -1; int opt = SIDELOAD_HOST_BLOCK_SIZE; printf("loading: '%s'", fn); @@ -531,6 +536,11 @@ static int adb_sideload_host(const char* fn) { fprintf(stderr, "* cannot read '%s' *\n", fn); return -1; } + if (sz == 0) { + printf("\n"); + fprintf(stderr, "* '%s' is empty *\n", fn); + return -1; + } std::string service = android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE); @@ -547,6 +557,24 @@ static int adb_sideload_host(const char* fn) { opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt)); while (true) { + fd_set fds; + struct timeval tv; + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = 1; + tv.tv_usec = 0; + int rc = select(fd+1, &fds, NULL, NULL, &tv); + size_t diff = xfer - last_xfer; + if (rc == 0 || diff >= (1*MB)) { + spin_index = (spin_index+1) % spinlen; + printf("\rserving: '%s' %4umb %.2fx %c", fn, + (unsigned)xfer/(1*MB), (double)xfer/sz, spinner[spin_index]); + fflush(stdout); + last_xfer = xfer; + } + if (rc == 0) { + continue; + } char buf[9]; if (!ReadFdExactly(fd, buf, 8)) { fprintf(stderr, "* failed to read command: %s\n", strerror(errno)); @@ -582,22 +610,9 @@ static int adb_sideload_host(const char* fn) { goto done; } xfer += to_write; - - // For normal OTA packages, we expect to transfer every byte - // twice, plus a bit of overhead (one read during - // verification, one read of each byte for installation, plus - // extra access to things like the zip central directory). - // This estimate of the completion becomes 100% when we've - // transferred ~2.13 (=100/47) times the package size. - int percent = (int)(xfer * 47LL / (sz ? sz : 1)); - if (percent != last_percent) { - printf("\rserving: '%s' (~%d%%) ", fn, percent); - fflush(stdout); - last_percent = percent; - } } - printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, ""); + printf("\ntotal xfer: %4umb %.2fx\n", (unsigned)xfer/(1*MB), (double)xfer/sz); done: if (fd >= 0) adb_close(fd); @@ -741,8 +756,10 @@ static int logcat(transport_type transport, const char* serial, int argc, const static int mkdirs(const char *path) { + std::string holder(path); + int ret; - char *x = (char *)path + 1; + char *x = &holder[1]; for(;;) { x = adb_dirstart(x); @@ -759,7 +776,7 @@ static int mkdirs(const char *path) } static int backup(int argc, const char** argv) { - const char* filename = "./backup.ab"; + const char* filename = "backup.ab"; /* find, extract, and use any -f argument */ for (int i = 1; i < argc; i++) { diff --git a/adb/services.cpp b/adb/services.cpp index 1847447..ef2fa56 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -76,6 +76,18 @@ void restart_root_service(int fd, void *cookie) { return; } + char build_type[PROPERTY_VALUE_MAX]; + char cm_version[PROPERTY_VALUE_MAX]; + property_get("persist.sys.root_access", value, "0"); + property_get("ro.build.type", build_type, ""); + property_get("ro.cm.version", cm_version, ""); + + if (strlen(cm_version) > 0 && strcmp(build_type, "eng") != 0 && (atoi(value) & 2) != 2) { + WriteFdExactly(fd, "root access is disabled by system setting - enable in settings -> development options\n"); + adb_close(fd); + return; + } + property_set("service.adb.root", "1"); WriteFdExactly(fd, "restarting adbd as root\n"); adb_close(fd); @@ -342,8 +354,10 @@ static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg #if ADB_HOST #define SHELL_COMMAND "/bin/sh" +#define ALTERNATE_SHELL_COMMAND "" #else #define SHELL_COMMAND "/system/bin/sh" +#define ALTERNATE_SHELL_COMMAND "/sbin/sh" #endif #if !ADB_HOST @@ -384,6 +398,9 @@ static int create_subproc_thread(const char *name, const subproc_mode mode) int ret_fd; pid_t pid = -1; + const char* shell_command; + struct stat st; + const char *arg0, *arg1; if (name == 0 || *name == 0) { arg0 = "-"; arg1 = 0; @@ -391,12 +408,24 @@ static int create_subproc_thread(const char *name, const subproc_mode mode) arg0 = "-c"; arg1 = name; } + char value[PROPERTY_VALUE_MAX]; + property_get("persist.sys.adb.shell", value, ""); + if (value[0] != '\0' && stat(value, &st) == 0) { + shell_command = value; + } + else if (stat(ALTERNATE_SHELL_COMMAND, &st) == 0) { + shell_command = ALTERNATE_SHELL_COMMAND; + } + else { + shell_command = SHELL_COMMAND; + } + switch (mode) { case SUBPROC_PTY: - ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid); + ret_fd = create_subproc_pty(shell_command, arg0, arg1, &pid); break; case SUBPROC_RAW: - ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid); + ret_fd = create_subproc_raw(shell_command, arg0, arg1, &pid); break; default: fprintf(stderr, "invalid subproc_mode %d\n", mode); @@ -422,6 +451,13 @@ static int create_subproc_thread(const char *name, const subproc_mode mode) } #endif +#if !ADB_HOST +static const char* bu_path() +{ + return (recovery_mode ? "/sbin/bu" : "/system/bin/bu"); +} +#endif + int service_to_fd(const char *name) { int ret = -1; @@ -478,10 +514,14 @@ int service_to_fd(const char *name) } else if(!strncmp(name, "unroot:", 7)) { ret = create_service_thread(restart_unroot_service, NULL); } else if(!strncmp(name, "backup:", 7)) { - ret = create_subproc_thread(android::base::StringPrintf("/system/bin/bu backup %s", + ret = create_subproc_thread(android::base::StringPrintf("%s backup %s", bu_path(), (name + 7)).c_str(), SUBPROC_RAW); } else if(!strncmp(name, "restore:", 8)) { - ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW); + char* cmd; + if (asprintf(&cmd, "%s restore", bu_path()) != -1) { + ret = create_subproc_thread(cmd, SUBPROC_RAW); + free(cmd); + } } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) != 1) { @@ -672,6 +712,15 @@ asocket* host_service_to_socket(const char* name, const char *serial) } else if (!strncmp(name, "any", strlen("any"))) { sinfo->transport = kTransportAny; sinfo->state = CS_DEVICE; + } else if (!strncmp(name, "sideload", strlen("sideload"))) { + sinfo->transport = kTransportAny; + sinfo->state = CS_SIDELOAD; + } else if (!strncmp(name, "recovery", strlen("recovery"))) { + sinfo->transport = kTransportAny; + sinfo->state = CS_RECOVERY; + } else if (!strncmp(name, "online", strlen("online"))) { + sinfo->transport = kTransportAny; + sinfo->state = CS_ONLINE; } else { free(sinfo); return NULL; diff --git a/adb/transport.cpp b/adb/transport.cpp index 2cd6ac2..5ae49d3 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -821,8 +821,10 @@ retry: result = NULL; } - /* check for required connection state */ - if (result && state != CS_ANY && result->connection_state != state) { + /* check for required connection state */ + if (result && state != CS_ANY && ((state != CS_ONLINE && result->connection_state != state) + || (state == CS_ONLINE && !(result->connection_state == CS_DEVICE + || result->connection_state == CS_RECOVERY)))) { if (error_out) *error_out = "invalid device state"; result = NULL; } diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp index f3db346..44df695 100644 --- a/adb/usb_linux_client.cpp +++ b/adb/usb_linux_client.cpp @@ -333,37 +333,35 @@ static void init_functionfs(struct usb_handle *h) v2_descriptor.hs_descs = hs_descriptors; v2_descriptor.ss_descs = ss_descriptors; - if (h->control < 0) { // might have already done this before - D("OPENING %s\n", USB_FFS_ADB_EP0); - h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR); - if (h->control < 0) { - D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno); - goto err; - } - - ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor)); - if (ret < 0) { - v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC); - v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor)); - v1_descriptor.header.fs_count = 3; - v1_descriptor.header.hs_count = 3; - v1_descriptor.fs_descs = fs_descriptors; - v1_descriptor.hs_descs = hs_descriptors; - D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno); - ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor)); - if (ret < 0) { - D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno); - goto err; - } - } + D("OPENING %s\n", USB_FFS_ADB_EP0); + h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR); + if (h->control < 0) { + D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno); + goto err; + } - ret = adb_write(h->control, &strings, sizeof(strings)); + ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor)); + if (ret < 0) { + v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC); + v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor)); + v1_descriptor.header.fs_count = 3; + v1_descriptor.header.hs_count = 3; + v1_descriptor.fs_descs = fs_descriptors; + v1_descriptor.hs_descs = hs_descriptors; + D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno); + ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor)); if (ret < 0) { - D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno); + D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno); goto err; } } + ret = adb_write(h->control, &strings, sizeof(strings)); + if (ret < 0) { + D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno); + goto err; + } + h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR); if (h->bulk_out < 0) { D("[ %s: cannot open bulk-out ep: errno=%d ]\n", USB_FFS_ADB_OUT, errno); @@ -401,14 +399,14 @@ static void *usb_ffs_open_thread(void *x) while (true) { // wait until the USB device needs opening adb_mutex_lock(&usb->lock); - while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1) + while (usb->control != -1) adb_cond_wait(&usb->notify, &usb->lock); adb_mutex_unlock(&usb->lock); while (true) { init_functionfs(usb); - if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0) + if (usb->control >= 0) break; adb_sleep_ms(1000); @@ -500,13 +498,10 @@ static void usb_ffs_kick(usb_handle *h) D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno); adb_mutex_lock(&h->lock); - - // don't close ep0 here, since we may not need to reinitialize it with - // the same descriptors again. if however ep1/ep2 fail to re-open in - // init_functionfs, only then would we close and open ep0 again. + adb_close(h->control); adb_close(h->bulk_out); adb_close(h->bulk_in); - h->bulk_out = h->bulk_in = -1; + h->control = h->bulk_out = h->bulk_in = -1; // notify usb_ffs_open_thread that we are disconnected adb_cond_signal(&h->notify); |