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

* commit '9526a788a6bd528e14622404e8750bdcc147d15a':
  adb: Add ability to specify device path
This commit is contained in:
Scott Anderson 2012-05-01 19:33:41 -07:00 committed by Android Git Automerger
commit 76e47e0ec8
10 changed files with 112 additions and 30 deletions

View File

@ -17,8 +17,10 @@ host:kill
upgrade.
host:devices
host:devices-l
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
the connection is closed
@ -88,6 +90,9 @@ host:<request>
Returns the serial number of the corresponding device/emulator.
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
Returns the state of a given device as a string.

View File

@ -1201,16 +1201,19 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
}
// return a list of all connected devices
if (!strcmp(service, "devices")) {
if (!strncmp(service, "devices", 7)) {
char buffer[4096];
memset(buf, 0, sizeof(buf));
memset(buffer, 0, sizeof(buffer));
D("Getting device list \n");
list_transports(buffer, sizeof(buffer));
snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
D("Wrote device list \n");
writex(reply_fd, buf, strlen(buf));
return 0;
int use_long = !strcmp(service+7, "-l");
if (use_long || service[7] == 0) {
memset(buf, 0, sizeof(buf));
memset(buffer, 0, sizeof(buffer));
D("Getting device list \n");
list_transports(buffer, sizeof(buffer), use_long);
snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
D("Wrote device list \n");
writex(reply_fd, buf, strlen(buf));
return 0;
}
}
// add a new TCP transport, device or emulator
@ -1276,6 +1279,16 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
writex(reply_fd, buf, strlen(buf));
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
if (!strncmp(service,"emulator:",9)) {
int port = atoi(service+9);

View File

@ -190,6 +190,7 @@ struct atransport
/* used to identify transports for clients */
char *serial;
char *product;
char *devpath;
int adb_port; // Use for emulators (local transport)
/* a list of adisconnect callbacks called when the transport is kicked */
@ -253,7 +254,7 @@ int adb_main(int is_daemon, int server_port);
** get_device_transport does an acquire on your behalf before returning
*/
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);
asocket* create_device_tracker(void);
@ -286,7 +287,7 @@ void register_socket_transport(int s, const char *serial, int port, int local);
void unregister_transport(atransport *t);
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 */
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"
" -e - directs command to the only running emulator.\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"
" the given serial number. Overrides ANDROID_SERIAL\n"
" -s <specific device> - directs command to the device or emulator with the given\n"
" serial number or device path. Overrides ANDROID_SERIAL\n"
" environment variable.\n"
" -p <product name or path> - simple product name like 'sooner', or\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"
" environment variable is used, which must\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"
" Port 5555 is used by default if no port number is specified.\n"
" disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
@ -159,6 +160,7 @@ void help()
" adb kill-server - kill the server if it is running\n"
" adb get-state - prints: offline | bootloader | device\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 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"
@ -1016,7 +1018,16 @@ top:
if(!strcmp(argv[0], "devices")) {
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);
if(tmp) {
printf("List of devices attached \n");
@ -1298,7 +1309,8 @@ top:
/* passthrough commands */
if(!strcmp(argv[0],"get-state") ||
!strcmp(argv[0],"get-serialno"))
!strcmp(argv[0],"get-serialno") ||
!strcmp(argv[0],"get-devpath"))
{
char *tmp;

View File

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

View File

@ -347,7 +347,7 @@ register_device(struct usb_handle *uh, const char *serial)
adb_mutex_unlock(&usb_lock);
register_usb_transport(usb, serial, 1);
register_usb_transport(usb, serial, NULL, 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);
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,
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];
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,
interface->bInterfaceSubClass, interface->bInterfaceProtocol)) {
struct stat st;
char pathbuf[128];
char link[256];
char *devpath = NULL;
DBGX("looking for bulk endpoints\n");
// looks like ADB...
ep1 = (struct usb_endpoint_descriptor *)bufptr;
@ -263,7 +269,26 @@ static void find_usb_device(const char *base,
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);
break;
}
@ -532,7 +557,7 @@ int usb_close(usb_handle *h)
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,
int interface, int serial_index, unsigned zero_mask)
{
@ -644,7 +669,7 @@ static void register_device(const char *dev_name,
usb->next->prev = usb;
adb_mutex_unlock(&usb_lock);
register_usb_transport(usb, serial, usb->writeable);
register_usb_transport(usb, serial, devpath, usb->writeable);
return;
fail:

View File

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

View File

@ -125,10 +125,13 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
IOUSBDeviceInterface197 **dev = NULL;
HRESULT result;
SInt32 score;
UInt32 locationId;
UInt16 vendor;
UInt16 product;
UInt8 serialIndex;
char serial[256];
char devpathBuf[64];
char *devpath = NULL;
while ((usbInterface = IOIteratorNext(iterator))) {
//* Create an intermediate interface plugin
@ -192,6 +195,11 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
kr = (*dev)->GetDeviceVendor(dev, &vendor);
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);
if (serialIndex > 0) {
@ -256,7 +264,7 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
}
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.
// Pass the reference to our private data as the refCon for the

View File

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