diff options
author | Scott Anderson <saa@android.com> | 2012-05-30 18:11:27 -0700 |
---|---|---|
committer | Scott Anderson <saa@android.com> | 2012-06-05 11:13:40 -0700 |
commit | 2ca3e6b35f79136418ebc32fef57580698dbd045 (patch) | |
tree | e691312df3690d47d2066cd107449ee96a23ac5e /adb/transport.c | |
parent | e82c2db05cae70a0490a1f84b7211ef42c329671 (diff) | |
download | system_core-2ca3e6b35f79136418ebc32fef57580698dbd045.zip system_core-2ca3e6b35f79136418ebc32fef57580698dbd045.tar.gz system_core-2ca3e6b35f79136418ebc32fef57580698dbd045.tar.bz2 |
adb: Generalizing -s to take qualifiers.
Prior to this change, -s could take either a serial number or a
device path (e.g. "-s 01498B1F02015015" or "-s usb:1-4.2"). This
change extends -s to also allow product, model or device names
(e.g. "-s product:mysid"). These new qualifiers will only be
available on devices that are running an adb daemon that provides
properties in the connect message per Change-Id:
I09200decde4facb8fc9b4056fdae910155f2bcb9
The product, model and device are derived from the
ro.product.name, ro.product.model and ro.product.device
properties respectively. They are prefixed with "product:",
"model:" or "device:" as appropriate. In addition, any
non-alphanumerics in the model are changed to underscores.
If the -s parameter matches multiple devices, the result will be
the same as when multiple devices are connected but no -d, -e or
-s option is specified. In general, this means the user will get
"error: more than one device". However for get-state,
get-devpath and get-serialno, they will get "unknown".
The format of "devices -l" was changed to list all of the
qualifiers that are available. The following example output
(with the last digits of the serial numbers replaced with X's) is
with a Galaxy Prime with an older adb daemon and another Galaxy
Prime and Galaxy S both with the enhanced adb daemons:
List of devices attached
016B75D60A0060XX device usb:2-5 product:mysid model:Galaxy_Nexus device:toro
3731B535FAC200XX device usb:1-4.2 product:soju model:Nexus_S device:crespo
01498B1F020150XX device usb:1-4.1
Note that the serial number and state are now column oriented
instead of tab delimited. After the serial number and state, all
qualifiers are listed with each preceded by a space. The output
of the original devices command (without -l) is unchanged.
Change-Id: Iceeb2789874effc25a630d514a375d6f1889dc56
Signed-off-by: Scott Anderson <saa@android.com>
Diffstat (limited to 'adb/transport.c')
-rw-r--r-- | adb/transport.c | 122 |
1 files changed, 104 insertions, 18 deletions
diff --git a/adb/transport.c b/adb/transport.c index 359b0d6..c88b90f 100644 --- a/adb/transport.c +++ b/adb/transport.c @@ -743,6 +743,45 @@ void remove_transport_disconnect(atransport* t, adisconnect* dis) dis->next = dis->prev = dis; } +static int qual_char_is_invalid(char ch) +{ + if ('A' <= ch && ch <= 'Z') + return 0; + if ('a' <= ch && ch <= 'z') + return 0; + if ('0' <= ch && ch <= '9') + return 0; + return 1; +} + +static int qual_match(const char *to_test, + const char *prefix, const char *qual, int sanitize_qual) +{ + if (!to_test || !*to_test) + /* Return true if both the qual and to_test are null strings. */ + return !qual || !*qual; + + if (!qual) + return 0; + + if (prefix) { + while (*prefix) { + if (*prefix++ != *to_test++) + return 0; + } + } + + while (*qual) { + char ch = *qual++; + if (sanitize_qual && qual_char_is_invalid(ch)) + ch = '_'; + if (ch != *to_test++) + return 0; + } + + /* Everything matched so far. Return true if *to_test is a NUL. */ + return !*to_test; +} atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) { @@ -764,13 +803,19 @@ retry: /* check for matching serial number */ if (serial) { - if (t->serial && !strcmp(serial, t->serial)) { - result = t; - break; - } - if (t->devpath && !strcmp(serial, t->devpath)) { + if ((t->serial && !strcmp(serial, t->serial)) || + (t->devpath && !strcmp(serial, t->devpath)) || + qual_match(serial, "product:", t->product, 0) || + qual_match(serial, "model:", t->model, 1) || + qual_match(serial, "device:", t->device, 0)) { + if (result) { + if (error_out) + *error_out = "more than one device"; + ambiguous = 1; + result = NULL; + break; + } result = t; - break; } } else { if (ttype == kTransportUsb && t->type == kTransportUsb) { @@ -846,7 +891,58 @@ static const char *statename(atransport *t) } } -int list_transports(char *buf, size_t bufsize, int show_devpath) +static void add_qual(char **buf, size_t *buf_size, + const char *prefix, const char *qual, int sanitize_qual) +{ + size_t len; + int prefix_len; + + if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual) + return; + + len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual); + + if (sanitize_qual) { + char *cp; + for (cp = *buf + prefix_len; cp < *buf + len; cp++) { + if (qual_char_is_invalid(*cp)) + *cp = '_'; + } + } + + *buf_size -= len; + *buf += len; +} + +static size_t format_transport(atransport *t, char *buf, size_t bufsize, + int long_listing) +{ + const char* serial = t->serial; + if (!serial || !serial[0]) + serial = "????????????"; + + if (!long_listing) { + return snprintf(buf, bufsize, "%s\t%s\n", serial, statename(t)); + } else { + size_t len, remaining = bufsize; + + len = snprintf(buf, remaining, "%-22s %s", serial, statename(t)); + remaining -= len; + buf += len; + + add_qual(&buf, &remaining, " ", t->devpath, 0); + add_qual(&buf, &remaining, " product:", t->product, 0); + add_qual(&buf, &remaining, " model:", t->model, 1); + add_qual(&buf, &remaining, " device:", t->device, 0); + + len = snprintf(buf, remaining, "\n"); + remaining -= len; + + return bufsize - remaining; + } +} + +int list_transports(char *buf, size_t bufsize, int long_listing) { char* p = buf; char* end = buf + bufsize; @@ -856,17 +952,7 @@ int list_transports(char *buf, size_t bufsize, int show_devpath) /* XXX OVERRUN PROBLEMS XXX */ adb_mutex_lock(&transport_lock); for(t = transport_list.next; t != &transport_list; t = t->next) { - const char* serial = t->serial; - if (!serial || !serial[0]) - serial = "????????????"; - if (show_devpath) { - const char* devpath = t->devpath; - if (!devpath || !devpath[0]) - devpath = "????????????"; - len = snprintf(p, end - p, "%s\t%s\t%s\n", serial, devpath, statename(t)); - } else - len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); - + len = format_transport(t, p, end - p, long_listing); if (p + len >= end) { /* discard last line if buffer is too short */ break; |