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