Merge "adb host: add device state in "adb wait-for-*""

am: 82509e7925

* commit '82509e79253309af7d78ebc833ca922b7f7b3c48':
  adb host: add device state in "adb wait-for-*"
This commit is contained in:
Elliott Hughes 2015-12-17 22:50:16 +00:00 committed by android-build-merger
commit ba7a198c29
2 changed files with 74 additions and 40 deletions

View File

@ -204,7 +204,10 @@ static void help() {
" adb version - show version num\n"
"\n"
"scripting:\n"
" adb wait-for-device - block until device is online\n"
" adb wait-for[-<transport>]-<state>\n"
" - wait for device to be in the given state:\n"
" device, recovery, sideload, or bootloader\n"
" Transport is: usb, local or any [default=any]\n"
" adb start-server - ensure that there is a server running\n"
" adb kill-server - kill the server if it is running\n"
" adb get-state - prints: offline | bootloader | device\n"
@ -1010,19 +1013,49 @@ static int ppp(int argc, const char** argv) {
#endif /* !defined(_WIN32) */
}
static bool check_wait_for_device_syntax(const char* service) {
// TODO: when we have libc++ for Windows, use a regular expression instead.
// wait-for-((any|local|usb)-)?(bootloader|device|recovery|sideload)
char type[20];
char state[20];
int length = 0;
if (sscanf(service, "wait-for-%20[a-z]-%20[a-z]%n", type, state, &length) < 2 ||
length != static_cast<int>(strlen(service))) {
fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service);
return false;
}
if (strcmp(type, "any") != 0 && strcmp(type, "local") != 0 && strcmp(type, "usb") != 0) {
fprintf(stderr, "adb: unknown type %s; expected 'any', 'local', or 'usb'\n", type);
return false;
}
if (strcmp(state, "bootloader") != 0 && strcmp(state, "device") != 0 &&
strcmp(state, "recovery") != 0 && strcmp(state, "sideload") != 0) {
fprintf(stderr, "adb: unknown state %s; "
"expected 'bootloader', 'device', 'recovery', or 'sideload'\n", state);
return false;
}
return true;
}
static bool wait_for_device(const char* service, TransportType t, const char* serial) {
// Was the caller vague about what they'd like us to wait for?
// If so, check they weren't more specific in their choice of transport type.
if (strcmp(service, "wait-for-device") == 0) {
if (t == kTransportUsb) {
service = "wait-for-usb";
service = "wait-for-usb-device";
} else if (t == kTransportLocal) {
service = "wait-for-local";
service = "wait-for-local-device";
} else {
service = "wait-for-any";
service = "wait-for-any-device";
}
}
if (!check_wait_for_device_syntax(service)) {
return false;
}
std::string cmd = format_host_command(service, t, serial);
return adb_command(cmd);
}

View File

@ -356,19 +356,19 @@ int service_to_fd(const char* name, const atransport* transport) {
#if ADB_HOST
struct state_info {
TransportType transport_type;
char* serial;
std::string serial;
ConnectionState state;
};
static void wait_for_state(int fd, void* cookie) {
state_info* sinfo = reinterpret_cast<state_info*>(cookie);
static void wait_for_state(int fd, void* data) {
std::unique_ptr<state_info> sinfo(reinterpret_cast<state_info*>(data));
D("wait_for_state %d", sinfo->state);
while (true) {
bool is_ambiguous = false;
std::string error = "unknown error";
atransport* t = acquire_one_transport(sinfo->transport_type, sinfo->serial,
atransport* t = acquire_one_transport(sinfo->transport_type, sinfo->serial.c_str(),
&is_ambiguous, &error);
if (t != nullptr && t->connection_state == sinfo->state) {
SendOkay(fd);
@ -382,10 +382,6 @@ static void wait_for_state(int fd, void* cookie) {
}
}
if (sinfo->serial) {
free(sinfo->serial);
}
free(sinfo);
adb_close(fd);
D("wait_for_state is done");
}
@ -491,38 +487,43 @@ static void connect_service(int fd, void* data) {
asocket* host_service_to_socket(const char* name, const char* serial) {
if (!strcmp(name,"track-devices")) {
return create_device_tracker();
} else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
auto sinfo = reinterpret_cast<state_info*>(malloc(sizeof(state_info)));
if (sinfo == nullptr) {
fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
return NULL;
}
if (serial)
sinfo->serial = strdup(serial);
else
sinfo->serial = NULL;
} else if (android::base::StartsWith(name, "wait-for-")) {
name += strlen("wait-for-");
if (!strncmp(name, "local", strlen("local"))) {
sinfo->transport_type = kTransportLocal;
sinfo->state = kCsDevice;
} else if (!strncmp(name, "usb", strlen("usb"))) {
sinfo->transport_type = kTransportUsb;
sinfo->state = kCsDevice;
} else if (!strncmp(name, "any", strlen("any"))) {
sinfo->transport_type = kTransportAny;
sinfo->state = kCsDevice;
} else {
if (sinfo->serial) {
free(sinfo->serial);
}
free(sinfo);
return NULL;
std::unique_ptr<state_info> sinfo(new state_info);
if (sinfo == nullptr) {
fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
return nullptr;
}
int fd = create_service_thread(wait_for_state, sinfo);
if (serial) sinfo->serial = serial;
if (android::base::StartsWith(name, "local")) {
name += strlen("local");
sinfo->transport_type = kTransportLocal;
} else if (android::base::StartsWith(name, "usb")) {
name += strlen("usb");
sinfo->transport_type = kTransportUsb;
} else if (android::base::StartsWith(name, "any")) {
name += strlen("any");
sinfo->transport_type = kTransportAny;
} else {
return nullptr;
}
if (!strcmp(name, "-device")) {
sinfo->state = kCsDevice;
} else if (!strcmp(name, "-recovery")) {
sinfo->state = kCsRecovery;
} else if (!strcmp(name, "-sideload")) {
sinfo->state = kCsSideload;
} else if (!strcmp(name, "-bootloader")) {
sinfo->state = kCsBootloader;
} else {
return nullptr;
}
int fd = create_service_thread(wait_for_state, sinfo.release());
return create_local_socket(fd);
} else if (!strncmp(name, "connect:", 8)) {
char* host = strdup(name + 8);