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:
commit
ba7a198c29
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue