adb: add reconnect command.

Add reconnect command for debugging. `reconnect` kicks a transport
from the host side, `reconnect device` kicks a transport from
the device side. They can be used to produce transport errors.

Bug: 25935458

Change-Id: I47daa338796b561941e7aba44a51a6dd117d1e98
This commit is contained in:
Yabin Cui 2016-04-05 13:50:44 -07:00
parent fbdbf100cb
commit 1f4ec19e49
5 changed files with 39 additions and 5 deletions

View file

@ -1134,6 +1134,13 @@ int handle_host_request(const char* service, TransportType type,
/* we don't even need to send a reply */
return 0;
}
if (!strcmp(service, "reconnect")) {
if (s->transport != nullptr) {
kick_transport(s->transport);
}
return SendOkay(reply_fd, "done");
}
#endif // ADB_HOST
int ret = handle_forward_request(service, type, serial, reply_fd);

View file

@ -158,7 +158,8 @@ int _adb_connect(const std::string& service, std::string* error) {
}
}
if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
switch_socket_transport(fd, error)) {
return -1;
}
@ -168,9 +169,11 @@ int _adb_connect(const std::string& service, std::string* error) {
return -1;
}
if (!adb_status(fd, error)) {
adb_close(fd);
return -1;
if (service != "reconnect") {
if (!adb_status(fd, error)) {
adb_close(fd);
return -1;
}
}
D("_adb_connect: return fd %d", fd);

View file

@ -239,6 +239,9 @@ static void help() {
" - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
" is updated.\n"
"\n"
"internal debugging:\n"
" adb reconnect Kick current connection from host side and make it reconnect.\n"
" adb reconnect device Kick current connection from device side and make it reconnect.\n"
"environment variables:\n"
" ADB_TRACE - Print debug information. A comma separated list of the following values\n"
" 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
@ -1905,6 +1908,14 @@ int adb_commandline(int argc, const char **argv) {
}
}
return 0;
} else if (!strcmp(argv[0], "reconnect")) {
if (argc == 1) {
return adb_query_command("host:reconnect");
} else if (argc == 2 && !strcmp(argv[1], "device")) {
std::string err;
adb_connect("reconnect", &err);
return 0;
}
}
usage();

View file

@ -184,6 +184,13 @@ void reboot_service(int fd, void* arg)
adb_close(fd);
}
static void reconnect_service(int fd, void* arg) {
WriteFdExactly(fd, "done");
adb_close(fd);
atransport* t = static_cast<atransport*>(arg);
kick_transport(t);
}
int reverse_service(const char* command) {
int s[2];
if (adb_socketpair(s)) {
@ -345,6 +352,8 @@ int service_to_fd(const char* name, const atransport* transport) {
ret = create_service_thread(set_verity_enabled_state_service, (void*)0);
} else if(!strncmp(name, "enable-verity:", 15)) {
ret = create_service_thread(set_verity_enabled_state_service, (void*)1);
} else if (!strcmp(name, "reconnect")) {
ret = create_service_thread(reconnect_service, const_cast<atransport*>(transport));
#endif
}
if (ret >= 0) {

View file

@ -305,7 +305,11 @@ static void kick_transport_locked(atransport* t) {
void kick_transport(atransport* t) {
adb_mutex_lock(&transport_lock);
kick_transport_locked(t);
// As kick_transport() can be called from threads without guarantee that t is valid,
// check if the transport is in transport_list first.
if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) {
kick_transport_locked(t);
}
adb_mutex_unlock(&transport_lock);
}