Merge "adb: Add ability to specify device path" into ics-aah

This commit is contained in:
Scott Anderson 2012-05-01 19:31:55 -07:00 committed by Android (Google) Code Review
commit 9526a788a6
10 changed files with 112 additions and 30 deletions

View file

@ -17,8 +17,10 @@ host:kill
upgrade. upgrade.
host:devices host:devices
host:devices-l
Ask to return the list of available Android devices and their Ask to return the list of available Android devices and their
state. After the OKAY, this is followed by a 4-byte hex len, state. devices-l includes the device paths in the state.
After the OKAY, this is followed by a 4-byte hex len,
and a string that will be dumped as-is by the client, then and a string that will be dumped as-is by the client, then
the connection is closed the connection is closed
@ -88,6 +90,9 @@ host:<request>
Returns the serial number of the corresponding device/emulator. Returns the serial number of the corresponding device/emulator.
Note that emulator serial numbers are of the form "emulator-5554" Note that emulator serial numbers are of the form "emulator-5554"
<host-prefix>:get-devpath
Returns the device path of the corresponding device/emulator.
<host-prefix>:get-state <host-prefix>:get-state
Returns the state of a given device as a string. Returns the state of a given device as a string.

View file

@ -1132,16 +1132,19 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
} }
// return a list of all connected devices // return a list of all connected devices
if (!strcmp(service, "devices")) { if (!strncmp(service, "devices", 7)) {
char buffer[4096]; char buffer[4096];
memset(buf, 0, sizeof(buf)); int use_long = !strcmp(service+7, "-l");
memset(buffer, 0, sizeof(buffer)); if (use_long || service[7] == 0) {
D("Getting device list \n"); memset(buf, 0, sizeof(buf));
list_transports(buffer, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); D("Getting device list \n");
D("Wrote device list \n"); list_transports(buffer, sizeof(buffer), use_long);
writex(reply_fd, buf, strlen(buf)); snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
return 0; D("Wrote device list \n");
writex(reply_fd, buf, strlen(buf));
return 0;
}
} }
// add a new TCP transport, device or emulator // add a new TCP transport, device or emulator
@ -1207,6 +1210,16 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
writex(reply_fd, buf, strlen(buf)); writex(reply_fd, buf, strlen(buf));
return 0; return 0;
} }
if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
char *out = "unknown";
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
if (transport && transport->devpath) {
out = transport->devpath;
}
snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
writex(reply_fd, buf, strlen(buf));
return 0;
}
// indicates a new emulator instance has started // indicates a new emulator instance has started
if (!strncmp(service,"emulator:",9)) { if (!strncmp(service,"emulator:",9)) {
int port = atoi(service+9); int port = atoi(service+9);

View file

@ -185,6 +185,7 @@ struct atransport
/* used to identify transports for clients */ /* used to identify transports for clients */
char *serial; char *serial;
char *product; char *product;
char *devpath;
int adb_port; // Use for emulators (local transport) int adb_port; // Use for emulators (local transport)
/* a list of adisconnect callbacks called when the transport is kicked */ /* a list of adisconnect callbacks called when the transport is kicked */
@ -248,7 +249,7 @@ int adb_main(int is_daemon, int server_port);
** get_device_transport does an acquire on your behalf before returning ** get_device_transport does an acquire on your behalf before returning
*/ */
void init_transport_registration(void); void init_transport_registration(void);
int list_transports(char *buf, size_t bufsize); int list_transports(char *buf, size_t bufsize, int show_devpath);
void update_transports(void); void update_transports(void);
asocket* create_device_tracker(void); asocket* create_device_tracker(void);
@ -281,7 +282,7 @@ void register_socket_transport(int s, const char *serial, int port, int local);
void unregister_transport(atransport *t); void unregister_transport(atransport *t);
void unregister_all_tcp_transports(); void unregister_all_tcp_transports();
void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable); void register_usb_transport(usb_handle *h, const char *serial, const char *devpath, unsigned writeable);
/* this should only be used for transports with connection_state == CS_NOPERM */ /* this should only be used for transports with connection_state == CS_NOPERM */
void unregister_usb_transport(usb_handle *usb); void unregister_usb_transport(usb_handle *usb);

View file

@ -84,8 +84,8 @@ void help()
" returns an error if more than one USB device is present.\n" " returns an error if more than one USB device is present.\n"
" -e - directs command to the only running emulator.\n" " -e - directs command to the only running emulator.\n"
" returns an error if more than one emulator is running.\n" " returns an error if more than one emulator is running.\n"
" -s <serial number> - directs command to the USB device or emulator with\n" " -s <specific device> - directs command to the device or emulator with the given\n"
" the given serial number. Overrides ANDROID_SERIAL\n" " serial number or device path. Overrides ANDROID_SERIAL\n"
" environment variable.\n" " environment variable.\n"
" -p <product name or path> - simple product name like 'sooner', or\n" " -p <product name or path> - simple product name like 'sooner', or\n"
" a relative/absolute path to a product\n" " a relative/absolute path to a product\n"
@ -93,7 +93,8 @@ void help()
" If -p is not specified, the ANDROID_PRODUCT_OUT\n" " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
" environment variable is used, which must\n" " environment variable is used, which must\n"
" be an absolute path.\n" " be an absolute path.\n"
" devices - list all connected devices\n" " devices [-l] - list all connected devices\n"
" ('-l' means list device paths)\n"
" connect <host>[:<port>] - connect to a device via TCP/IP\n" " connect <host>[:<port>] - connect to a device via TCP/IP\n"
" Port 5555 is used by default if no port number is specified.\n" " Port 5555 is used by default if no port number is specified.\n"
" disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n" " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
@ -157,6 +158,7 @@ void help()
" adb kill-server - kill the server if it is running\n" " adb kill-server - kill the server if it is running\n"
" adb get-state - prints: offline | bootloader | device\n" " adb get-state - prints: offline | bootloader | device\n"
" adb get-serialno - prints: <serial-number>\n" " adb get-serialno - prints: <serial-number>\n"
" adb get-devpath - prints: <device-path>\n"
" adb status-window - continuously print device status for a specified device\n" " adb status-window - continuously print device status for a specified device\n"
" adb remount - remounts the /system partition on the device read-write\n" " adb remount - remounts the /system partition on the device read-write\n"
" adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n" " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
@ -931,7 +933,16 @@ top:
if(!strcmp(argv[0], "devices")) { if(!strcmp(argv[0], "devices")) {
char *tmp; char *tmp;
snprintf(buf, sizeof buf, "host:%s", argv[0]); char *listopt;
if (argc < 2)
listopt = "";
else if (argc == 2 && !strcmp(argv[1], "-l"))
listopt = argv[1];
else {
fprintf(stderr, "Usage: adb devices [-l]\n");
return 1;
}
snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
tmp = adb_query(buf); tmp = adb_query(buf);
if(tmp) { if(tmp) {
printf("List of devices attached \n"); printf("List of devices attached \n");
@ -1204,7 +1215,8 @@ top:
/* passthrough commands */ /* passthrough commands */
if(!strcmp(argv[0],"get-state") || if(!strcmp(argv[0],"get-state") ||
!strcmp(argv[0],"get-serialno")) !strcmp(argv[0],"get-serialno") ||
!strcmp(argv[0],"get-devpath"))
{ {
char *tmp; char *tmp;

View file

@ -370,7 +370,7 @@ static int list_transports_msg(char* buffer, size_t bufferlen)
char head[5]; char head[5];
int len; int len;
len = list_transports(buffer+4, bufferlen-4); len = list_transports(buffer+4, bufferlen-4, 0);
snprintf(head, sizeof(head), "%04x", len); snprintf(head, sizeof(head), "%04x", len);
memcpy(buffer, head, 4); memcpy(buffer, head, 4);
len += 4; len += 4;
@ -601,6 +601,8 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
free(t->product); free(t->product);
if (t->serial) if (t->serial)
free(t->serial); free(t->serial);
if (t->devpath)
free(t->devpath);
memset(t,0xee,sizeof(atransport)); memset(t,0xee,sizeof(atransport));
free(t); free(t);
@ -762,6 +764,10 @@ retry:
result = t; result = t;
break; break;
} }
if (t->devpath && !strcmp(serial, t->devpath)) {
result = t;
break;
}
} else { } else {
if (ttype == kTransportUsb && t->type == kTransportUsb) { if (ttype == kTransportUsb && t->type == kTransportUsb) {
if (result) { if (result) {
@ -836,7 +842,7 @@ static const char *statename(atransport *t)
} }
} }
int list_transports(char *buf, size_t bufsize) int list_transports(char *buf, size_t bufsize, int show_devpath)
{ {
char* p = buf; char* p = buf;
char* end = buf + bufsize; char* end = buf + bufsize;
@ -849,7 +855,13 @@ int list_transports(char *buf, size_t bufsize)
const char* serial = t->serial; const char* serial = t->serial;
if (!serial || !serial[0]) if (!serial || !serial[0])
serial = "????????????"; serial = "????????????";
len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); 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));
if (p + len >= end) { if (p + len >= end) {
/* discard last line if buffer is too short */ /* discard last line if buffer is too short */
@ -910,6 +922,9 @@ atransport *find_transport(const char *serial)
if (t->serial && !strcmp(serial, t->serial)) { if (t->serial && !strcmp(serial, t->serial)) {
break; break;
} }
if (t->devpath && !strcmp(serial, t->devpath)) {
break;
}
} }
adb_mutex_unlock(&transport_lock); adb_mutex_unlock(&transport_lock);
@ -955,7 +970,7 @@ void unregister_all_tcp_transports()
#endif #endif
void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable) void register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable)
{ {
atransport *t = calloc(1, sizeof(atransport)); atransport *t = calloc(1, sizeof(atransport));
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
@ -964,6 +979,9 @@ void register_usb_transport(usb_handle *usb, const char *serial, unsigned writea
if(serial) { if(serial) {
t->serial = strdup(serial); t->serial = strdup(serial);
} }
if(devpath) {
t->devpath = strdup(devpath);
}
register_transport(t); register_transport(t);
} }

View file

@ -347,7 +347,7 @@ register_device(struct usb_handle *uh, const char *serial)
adb_mutex_unlock(&usb_lock); adb_mutex_unlock(&usb_lock);
register_usb_transport(usb, serial, 1); register_usb_transport(usb, serial, NULL, 1);
return (1); return (1);
} }

View file

@ -116,7 +116,8 @@ static void kick_disconnected_devices()
} }
static void register_device(const char *dev_name, unsigned char ep_in, unsigned char ep_out, static void register_device(const char *dev_name, const char *devpath,
unsigned char ep_in, unsigned char ep_out,
int ifc, int serial_index, unsigned zero_mask); int ifc, int serial_index, unsigned zero_mask);
static inline int badname(const char *name) static inline int badname(const char *name)
@ -129,7 +130,7 @@ static inline int badname(const char *name)
static void find_usb_device(const char *base, static void find_usb_device(const char *base,
void (*register_device_callback) void (*register_device_callback)
(const char *, unsigned char, unsigned char, int, int, unsigned)) (const char *, const char *, unsigned char, unsigned char, int, int, unsigned))
{ {
char busname[32], devname[32]; char busname[32], devname[32];
unsigned char local_ep_in, local_ep_out; unsigned char local_ep_in, local_ep_out;
@ -227,6 +228,11 @@ static void find_usb_device(const char *base,
is_adb_interface(vid, pid, interface->bInterfaceClass, is_adb_interface(vid, pid, interface->bInterfaceClass,
interface->bInterfaceSubClass, interface->bInterfaceProtocol)) { interface->bInterfaceSubClass, interface->bInterfaceProtocol)) {
struct stat st;
char pathbuf[128];
char link[256];
char *devpath = NULL;
DBGX("looking for bulk endpoints\n"); DBGX("looking for bulk endpoints\n");
// looks like ADB... // looks like ADB...
ep1 = (struct usb_endpoint_descriptor *)bufptr; ep1 = (struct usb_endpoint_descriptor *)bufptr;
@ -263,7 +269,26 @@ static void find_usb_device(const char *base,
local_ep_out = ep1->bEndpointAddress; local_ep_out = ep1->bEndpointAddress;
} }
register_device_callback(devname, local_ep_in, local_ep_out, // Determine the device path
if (!fstat(fd, &st) && S_ISCHR(st.st_mode)) {
char *slash;
ssize_t link_len;
snprintf(pathbuf, sizeof(pathbuf), "/sys/dev/char/%d:%d",
major(st.st_rdev), minor(st.st_rdev));
link_len = readlink(pathbuf, link, sizeof(link) - 1);
if (link_len > 0) {
link[link_len] = '\0';
slash = strrchr(link, '/');
if (slash) {
snprintf(pathbuf, sizeof(pathbuf),
"usb:%s", slash + 1);
devpath = pathbuf;
}
}
}
register_device_callback(devname, devpath,
local_ep_in, local_ep_out,
interface->bInterfaceNumber, device->iSerialNumber, zero_mask); interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
break; break;
} }
@ -532,7 +557,7 @@ int usb_close(usb_handle *h)
return 0; return 0;
} }
static void register_device(const char *dev_name, static void register_device(const char *dev_name, const char *devpath,
unsigned char ep_in, unsigned char ep_out, unsigned char ep_in, unsigned char ep_out,
int interface, int serial_index, unsigned zero_mask) int interface, int serial_index, unsigned zero_mask)
{ {
@ -644,7 +669,7 @@ static void register_device(const char *dev_name,
usb->next->prev = usb; usb->next->prev = usb;
adb_mutex_unlock(&usb_lock); adb_mutex_unlock(&usb_lock);
register_usb_transport(usb, serial, usb->writeable); register_usb_transport(usb, serial, devpath, usb->writeable);
return; return;
fail: fail:

View file

@ -72,7 +72,7 @@ static void *usb_open_thread(void *x)
usb->fd = fd; usb->fd = fd;
D("[ usb_thread - registering device ]\n"); D("[ usb_thread - registering device ]\n");
register_usb_transport(usb, 0, 1); register_usb_transport(usb, 0, 0, 1);
} }
// never gets here // never gets here

View file

@ -125,10 +125,13 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
IOUSBDeviceInterface197 **dev = NULL; IOUSBDeviceInterface197 **dev = NULL;
HRESULT result; HRESULT result;
SInt32 score; SInt32 score;
UInt32 locationId;
UInt16 vendor; UInt16 vendor;
UInt16 product; UInt16 product;
UInt8 serialIndex; UInt8 serialIndex;
char serial[256]; char serial[256];
char devpathBuf[64];
char *devpath = NULL;
while ((usbInterface = IOIteratorNext(iterator))) { while ((usbInterface = IOIteratorNext(iterator))) {
//* Create an intermediate interface plugin //* Create an intermediate interface plugin
@ -192,6 +195,11 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceVendor(dev, &vendor);
kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->GetDeviceProduct(dev, &product);
kr = (*dev)->GetLocationID(dev, &locationId);
if (kr == 0) {
snprintf(devpathBuf, sizeof(devpathBuf), "usb:%lX", locationId);
devpath = devpathBuf;
}
kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
if (serialIndex > 0) { if (serialIndex > 0) {
@ -256,7 +264,7 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
} }
DBG("AndroidDeviceAdded calling register_usb_transport\n"); DBG("AndroidDeviceAdded calling register_usb_transport\n");
register_usb_transport(handle, (serial[0] ? serial : NULL), 1); register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1);
// Register for an interest notification of this device being removed. // Register for an interest notification of this device being removed.
// Pass the reference to our private data as the refCon for the // Pass the reference to our private data as the refCon for the

View file

@ -490,7 +490,7 @@ void find_devices() {
true)) { true)) {
// Lets make sure that we don't duplicate this device // Lets make sure that we don't duplicate this device
if (register_new_device(handle)) { if (register_new_device(handle)) {
register_usb_transport(handle, serial_number, 1); register_usb_transport(handle, serial_number, NULL, 1);
} else { } else {
D("register_new_device failed for %s\n", interf_name); D("register_new_device failed for %s\n", interf_name);
usb_cleanup_handle(handle); usb_cleanup_handle(handle);