Loading adb/commandline.cpp +37 −4 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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); } Loading adb/services.cpp +29 −28 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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"); } Loading Loading @@ -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))); } else if (android::base::StartsWith(name, "wait-for-")) { name += strlen("wait-for-"); std::unique_ptr<state_info> sinfo(new state_info); if (sinfo == nullptr) { fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno)); return NULL; return nullptr; } if (serial) sinfo->serial = strdup(serial); else sinfo->serial = NULL; name += strlen("wait-for-"); if (serial) sinfo->serial = serial; if (!strncmp(name, "local", strlen("local"))) { if (android::base::StartsWith(name, "local")) { name += strlen("local"); sinfo->transport_type = kTransportLocal; sinfo->state = kCsDevice; } else if (!strncmp(name, "usb", strlen("usb"))) { } else if (android::base::StartsWith(name, "usb")) { name += strlen("usb"); sinfo->transport_type = kTransportUsb; sinfo->state = kCsDevice; } else if (!strncmp(name, "any", strlen("any"))) { } else if (android::base::StartsWith(name, "any")) { name += strlen("any"); sinfo->transport_type = kTransportAny; sinfo->state = kCsDevice; } else { if (sinfo->serial) { free(sinfo->serial); return nullptr; } free(sinfo); return NULL; 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); 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 Loading
adb/commandline.cpp +37 −4 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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); } Loading
adb/services.cpp +29 −28 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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"); } Loading Loading @@ -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))); } else if (android::base::StartsWith(name, "wait-for-")) { name += strlen("wait-for-"); std::unique_ptr<state_info> sinfo(new state_info); if (sinfo == nullptr) { fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno)); return NULL; return nullptr; } if (serial) sinfo->serial = strdup(serial); else sinfo->serial = NULL; name += strlen("wait-for-"); if (serial) sinfo->serial = serial; if (!strncmp(name, "local", strlen("local"))) { if (android::base::StartsWith(name, "local")) { name += strlen("local"); sinfo->transport_type = kTransportLocal; sinfo->state = kCsDevice; } else if (!strncmp(name, "usb", strlen("usb"))) { } else if (android::base::StartsWith(name, "usb")) { name += strlen("usb"); sinfo->transport_type = kTransportUsb; sinfo->state = kCsDevice; } else if (!strncmp(name, "any", strlen("any"))) { } else if (android::base::StartsWith(name, "any")) { name += strlen("any"); sinfo->transport_type = kTransportAny; sinfo->state = kCsDevice; } else { if (sinfo->serial) { free(sinfo->serial); return nullptr; } free(sinfo); return NULL; 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); 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