summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
Diffstat (limited to 'adb')
-rw-r--r--adb/adb.cpp2
-rw-r--r--adb/adb.h5
-rw-r--r--adb/adb_main.cpp10
-rw-r--r--adb/commandline.cpp51
-rw-r--r--adb/services.cpp57
-rw-r--r--adb/transport.cpp6
-rw-r--r--adb/usb_linux_client.cpp59
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
diff --git a/adb/adb.h b/adb/adb.h
index fd9d0e6..1155cd3 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -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);