Loading adb/adb.cpp +51 −4 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #include <time.h> #include <chrono> #include <condition_variable> #include <mutex> #include <string> #include <thread> #include <vector> Loading @@ -48,6 +50,7 @@ #include "adb_io.h" #include "adb_listeners.h" #include "adb_utils.h" #include "sysdeps/chrono.h" #include "transport.h" #if !ADB_HOST Loading Loading @@ -313,19 +316,15 @@ void parse_banner(const std::string& banner, atransport* t) { if (type == "bootloader") { D("setting connection_state to kCsBootloader"); t->SetConnectionState(kCsBootloader); update_transports(); } else if (type == "device") { D("setting connection_state to kCsDevice"); t->SetConnectionState(kCsDevice); update_transports(); } else if (type == "recovery") { D("setting connection_state to kCsRecovery"); t->SetConnectionState(kCsRecovery); update_transports(); } else if (type == "sideload") { D("setting connection_state to kCsSideload"); t->SetConnectionState(kCsSideload); update_transports(); } else { D("setting connection_state to kCsHost"); t->SetConnectionState(kCsHost); Loading Loading @@ -353,6 +352,8 @@ static void handle_new_connection(atransport* t, apacket* p) { send_auth_request(t); } #endif update_transports(); } void handle_packet(apacket *p, atransport *t) Loading Loading @@ -1229,4 +1230,50 @@ int handle_host_request(const char* service, TransportType type, return ret - 1; return -1; } static auto& init_mutex = *new std::mutex(); static auto& init_cv = *new std::condition_variable(); static bool device_scan_complete = false; static bool transports_ready = false; void update_transport_status() { bool result = iterate_transports([](const atransport* t) { if (t->type == kTransportUsb && t->online != 1) { return false; } return true; }); D("update_transport_status: transports_ready = %s", result ? "true" : "false"); bool ready; { std::lock_guard<std::mutex> lock(init_mutex); transports_ready = result; ready = transports_ready && device_scan_complete; } if (ready) { D("update_transport_status: notifying"); init_cv.notify_all(); } } void adb_notify_device_scan_complete() { D("device scan complete"); { std::lock_guard<std::mutex> lock(init_mutex); device_scan_complete = true; } update_transport_status(); } void adb_wait_for_device_initialization() { std::unique_lock<std::mutex> lock(init_mutex); init_cv.wait_for(lock, 3s, []() { return device_scan_complete && transports_ready; }); } #endif // ADB_HOST adb/adb.h +14 −0 Original line number Diff line number Diff line Loading @@ -228,4 +228,18 @@ void SendConnectOnHost(atransport* t); void parse_banner(const std::string&, atransport* t); // On startup, the adb server needs to wait until all of the connected devices are ready. // To do this, we need to know when the scan has identified all of the potential new transports, and // when each transport becomes ready. // TODO: Do this for mDNS as well, instead of just USB? // We've found all of the transports we potentially care about. void adb_notify_device_scan_complete(); // One or more transports have changed status, check to see if we're ready. void update_transport_status(); // Wait until device scan has completed and every transport is ready, or a timeout elapses. void adb_wait_for_device_initialization(); #endif adb/adb_client.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -28,12 +28,15 @@ #include <sys/stat.h> #include <sys/types.h> #include <condition_variable> #include <mutex> #include <string> #include <thread> #include <vector> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/thread_annotations.h> #include <cutils/sockets.h> #include "adb_io.h" Loading Loading @@ -177,9 +180,8 @@ int adb_connect(const std::string& service, std::string* error) { } else { fprintf(stderr, "* daemon started successfully\n"); } // Give the server some time to start properly and detect devices. std::this_thread::sleep_for(3s); // fall through to _adb_connect // The server will wait until it detects all of its connected devices before acking. // Fall through to _adb_connect. } else { // If a server is already running, check its version matches. int version = ADB_SERVER_VERSION - 1; Loading adb/client/main.cpp +29 −24 Original line number Diff line number Diff line Loading @@ -156,7 +156,10 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply } #endif // Inform our parent that we are up and running. // Wait for the USB scan to complete before notifying the parent that we're up. // We need to perform this in a thread, because we would otherwise block the event loop. std::thread notify_thread([ack_reply_fd]() { adb_wait_for_device_initialization(); // Any error output written to stderr now goes to adb.log. We could // keep around a copy of the stderr fd and use that to write any errors Loading @@ -171,8 +174,8 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply android::base::SystemErrorCodeToString(GetLastError()).c_str()); } if (written != bytes_to_write) { fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes", bytes_to_write, written); fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes", bytes_to_write, written); } CloseHandle(ack_reply_handle); #else Loading @@ -183,6 +186,8 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply } unix_close(ack_reply_fd); #endif }); notify_thread.detach(); } D("Event loop starting"); Loading adb/client/usb_libusb.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,8 @@ static void poll_for_devices() { } libusb_free_device_list(list, 1); adb_notify_device_scan_complete(); std::this_thread::sleep_for(500ms); } } Loading Loading
adb/adb.cpp +51 −4 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #include <time.h> #include <chrono> #include <condition_variable> #include <mutex> #include <string> #include <thread> #include <vector> Loading @@ -48,6 +50,7 @@ #include "adb_io.h" #include "adb_listeners.h" #include "adb_utils.h" #include "sysdeps/chrono.h" #include "transport.h" #if !ADB_HOST Loading Loading @@ -313,19 +316,15 @@ void parse_banner(const std::string& banner, atransport* t) { if (type == "bootloader") { D("setting connection_state to kCsBootloader"); t->SetConnectionState(kCsBootloader); update_transports(); } else if (type == "device") { D("setting connection_state to kCsDevice"); t->SetConnectionState(kCsDevice); update_transports(); } else if (type == "recovery") { D("setting connection_state to kCsRecovery"); t->SetConnectionState(kCsRecovery); update_transports(); } else if (type == "sideload") { D("setting connection_state to kCsSideload"); t->SetConnectionState(kCsSideload); update_transports(); } else { D("setting connection_state to kCsHost"); t->SetConnectionState(kCsHost); Loading Loading @@ -353,6 +352,8 @@ static void handle_new_connection(atransport* t, apacket* p) { send_auth_request(t); } #endif update_transports(); } void handle_packet(apacket *p, atransport *t) Loading Loading @@ -1229,4 +1230,50 @@ int handle_host_request(const char* service, TransportType type, return ret - 1; return -1; } static auto& init_mutex = *new std::mutex(); static auto& init_cv = *new std::condition_variable(); static bool device_scan_complete = false; static bool transports_ready = false; void update_transport_status() { bool result = iterate_transports([](const atransport* t) { if (t->type == kTransportUsb && t->online != 1) { return false; } return true; }); D("update_transport_status: transports_ready = %s", result ? "true" : "false"); bool ready; { std::lock_guard<std::mutex> lock(init_mutex); transports_ready = result; ready = transports_ready && device_scan_complete; } if (ready) { D("update_transport_status: notifying"); init_cv.notify_all(); } } void adb_notify_device_scan_complete() { D("device scan complete"); { std::lock_guard<std::mutex> lock(init_mutex); device_scan_complete = true; } update_transport_status(); } void adb_wait_for_device_initialization() { std::unique_lock<std::mutex> lock(init_mutex); init_cv.wait_for(lock, 3s, []() { return device_scan_complete && transports_ready; }); } #endif // ADB_HOST
adb/adb.h +14 −0 Original line number Diff line number Diff line Loading @@ -228,4 +228,18 @@ void SendConnectOnHost(atransport* t); void parse_banner(const std::string&, atransport* t); // On startup, the adb server needs to wait until all of the connected devices are ready. // To do this, we need to know when the scan has identified all of the potential new transports, and // when each transport becomes ready. // TODO: Do this for mDNS as well, instead of just USB? // We've found all of the transports we potentially care about. void adb_notify_device_scan_complete(); // One or more transports have changed status, check to see if we're ready. void update_transport_status(); // Wait until device scan has completed and every transport is ready, or a timeout elapses. void adb_wait_for_device_initialization(); #endif
adb/adb_client.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -28,12 +28,15 @@ #include <sys/stat.h> #include <sys/types.h> #include <condition_variable> #include <mutex> #include <string> #include <thread> #include <vector> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/thread_annotations.h> #include <cutils/sockets.h> #include "adb_io.h" Loading Loading @@ -177,9 +180,8 @@ int adb_connect(const std::string& service, std::string* error) { } else { fprintf(stderr, "* daemon started successfully\n"); } // Give the server some time to start properly and detect devices. std::this_thread::sleep_for(3s); // fall through to _adb_connect // The server will wait until it detects all of its connected devices before acking. // Fall through to _adb_connect. } else { // If a server is already running, check its version matches. int version = ADB_SERVER_VERSION - 1; Loading
adb/client/main.cpp +29 −24 Original line number Diff line number Diff line Loading @@ -156,7 +156,10 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply } #endif // Inform our parent that we are up and running. // Wait for the USB scan to complete before notifying the parent that we're up. // We need to perform this in a thread, because we would otherwise block the event loop. std::thread notify_thread([ack_reply_fd]() { adb_wait_for_device_initialization(); // Any error output written to stderr now goes to adb.log. We could // keep around a copy of the stderr fd and use that to write any errors Loading @@ -171,8 +174,8 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply android::base::SystemErrorCodeToString(GetLastError()).c_str()); } if (written != bytes_to_write) { fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes", bytes_to_write, written); fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes", bytes_to_write, written); } CloseHandle(ack_reply_handle); #else Loading @@ -183,6 +186,8 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply } unix_close(ack_reply_fd); #endif }); notify_thread.detach(); } D("Event loop starting"); Loading
adb/client/usb_libusb.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,8 @@ static void poll_for_devices() { } libusb_free_device_list(list, 1); adb_notify_device_scan_complete(); std::this_thread::sleep_for(500ms); } } Loading