adb: don't try to reconnect emulators.

Bug: http://b/113533872
Test: ./test_adb.py
Change-Id: Id591f43b487cc3928390e30f11645990e34a51bf
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 332e0f8..239403a 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -220,25 +220,34 @@
         }
         D("attempting to reconnect %s", attempt.transport->serial.c_str());
 
-        if (!attempt.transport->Reconnect()) {
-            D("attempting to reconnect %s failed.", attempt.transport->serial.c_str());
-            if (attempt.attempts_left == 0) {
-                D("transport %s exceeded the number of retry attempts. giving up on it.",
-                  attempt.transport->serial.c_str());
-                remove_transport(attempt.transport);
+        switch (attempt.transport->Reconnect()) {
+            case ReconnectResult::Retry: {
+                D("attempting to reconnect %s failed.", attempt.transport->serial.c_str());
+                if (attempt.attempts_left == 0) {
+                    D("transport %s exceeded the number of retry attempts. giving up on it.",
+                      attempt.transport->serial.c_str());
+                    remove_transport(attempt.transport);
+                    continue;
+                }
+
+                std::lock_guard<std::mutex> lock(reconnect_mutex_);
+                reconnect_queue_.emplace(ReconnectAttempt{
+                        attempt.transport,
+                        std::chrono::steady_clock::now() + ReconnectHandler::kDefaultTimeout,
+                        attempt.attempts_left - 1});
                 continue;
             }
 
-            std::lock_guard<std::mutex> lock(reconnect_mutex_);
-            reconnect_queue_.emplace(ReconnectAttempt{
-                    attempt.transport,
-                    std::chrono::steady_clock::now() + ReconnectHandler::kDefaultTimeout,
-                    attempt.attempts_left - 1});
-            continue;
-        }
+            case ReconnectResult::Success:
+                D("reconnection to %s succeeded.", attempt.transport->serial.c_str());
+                register_transport(attempt.transport);
+                continue;
 
-        D("reconnection to %s succeeded.", attempt.transport->serial.c_str());
-        register_transport(attempt.transport);
+            case ReconnectResult::Abort:
+                D("cancelling reconnection attempt to %s.", attempt.transport->serial.c_str());
+                remove_transport(attempt.transport);
+                continue;
+        }
     }
 }
 
@@ -1128,7 +1137,7 @@
     connection_waitable_->SetConnectionEstablished(success);
 }
 
-bool atransport::Reconnect() {
+ReconnectResult atransport::Reconnect() {
     return reconnect_(this);
 }
 
diff --git a/adb/transport.h b/adb/transport.h
index f362f24..f854ce5 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -193,6 +193,12 @@
     DISALLOW_COPY_AND_ASSIGN(ConnectionWaitable);
 };
 
+enum class ReconnectResult {
+    Retry,
+    Success,
+    Abort,
+};
+
 class atransport {
   public:
     // TODO(danalbert): We expose waaaaaaay too much stuff because this was
@@ -200,7 +206,7 @@
     // class in one go is a very large change. Given how bad our testing is,
     // it's better to do this piece by piece.
 
-    using ReconnectCallback = std::function<bool(atransport*)>;
+    using ReconnectCallback = std::function<ReconnectResult(atransport*)>;
 
     atransport(ReconnectCallback reconnect, ConnectionState state)
         : id(NextTransportId()),
@@ -215,7 +221,7 @@
         max_payload = MAX_PAYLOAD;
     }
     atransport(ConnectionState state = kCsOffline)
-        : atransport([](atransport*) { return false; }, state) {}
+        : atransport([](atransport*) { return ReconnectResult::Abort; }, state) {}
     virtual ~atransport();
 
     int Write(apacket* p);
@@ -295,9 +301,8 @@
     // Gets a shared reference to the ConnectionWaitable.
     std::shared_ptr<ConnectionWaitable> connection_waitable() { return connection_waitable_; }
 
-    // Attempts to reconnect with the underlying Connection. Returns true if the
-    // reconnection attempt succeeded.
-    bool Reconnect();
+    // Attempts to reconnect with the underlying Connection.
+    ReconnectResult Reconnect();
 
   private:
     std::atomic<bool> kicked_;
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 8b8fd51..4fd483b 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -117,14 +117,15 @@
         std::tie(fd, port, serial) = tcp_connect(address, &response);
         if (fd == -1) {
             D("reconnect failed: %s", response.c_str());
-            return false;
+            return ReconnectResult::Retry;
         }
 
         // This invokes the part of register_socket_transport() that needs to be
         // invoked if the atransport* has already been setup. This eventually
         // calls atransport->SetConnection() with a newly created Connection*
         // that will in turn send the CNXN packet.
-        return init_socket_transport(t, std::move(fd), port, 0) >= 0;
+        return init_socket_transport(t, std::move(fd), port, 0) >= 0 ? ReconnectResult::Success
+                                                                     : ReconnectResult::Retry;
     };
 
     int error;
@@ -166,7 +167,7 @@
         disable_tcp_nagle(fd.get());
         std::string serial = getEmulatorSerialString(console_port);
         if (register_socket_transport(std::move(fd), std::move(serial), adb_port, 1,
-                                      [](atransport*) { return false; })) {
+                                      [](atransport*) { return ReconnectResult::Abort; })) {
             return 0;
         }
     }
@@ -269,7 +270,7 @@
             disable_tcp_nagle(fd.get());
             std::string serial = android::base::StringPrintf("host-%d", fd.get());
             register_socket_transport(std::move(fd), std::move(serial), port, 1,
-                                      [](atransport*) { return false; });
+                                      [](atransport*) { return ReconnectResult::Abort; });
         }
     }
     D("transport: server_socket_thread() exiting");
@@ -366,7 +367,7 @@
                 std::string serial = android::base::StringPrintf("host-%d", fd.get());
                 WriteFdExactly(fd.get(), _start_req, strlen(_start_req));
                 register_socket_transport(std::move(fd), std::move(serial), port, 1,
-                                          [](atransport*) { return false; });
+                                          [](atransport*) { return ReconnectResult::Abort; });
             }
 
             /* Prepare for accepting of the next ADB host connection. */