adb: wait for devices to come up instead of sleeping for 3s.
Replace a hard-coded 3 second sleep with logic to wait until we've
scanned USB devices once and they've all come online.
Before:
adb shell true 0.00s user 0.00s system 0% cpu 3.047 total
After:
adb shell true 0.00s user 0.00s system 9% cpu 0.041 total
Bug: http://b/37869663
Test: `time adb shell true` after adb kill-server
Change-Id: I251d42afb885908ed9d03167287594ea16650d3f
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 39e71e5..0181daa 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -31,6 +31,8 @@
#include <time.h>
#include <chrono>
+#include <condition_variable>
+#include <mutex>
#include <string>
#include <thread>
#include <vector>
@@ -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
@@ -313,19 +316,15 @@
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);
@@ -353,6 +352,8 @@
send_auth_request(t);
}
#endif
+
+ update_transports();
}
void handle_packet(apacket *p, atransport *t)
@@ -1229,4 +1230,50 @@
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