Fix adb -d/-e error reporting.

If -d/-e fail, get-serialno and friends will now report an error
and return a failure status code on exit.

Also fix the behavior of -d/-e with $ANDROID_SERIAL --- -d/-e
should override $ANDROID_SERIAL, not the other way round.

I'm deleting my own comment here about always returning "unknown"
for scripts. I can't find any evidence that there are scripts
relying on that, so I think my comment meant "I fear that there
are scripts doing so".

Bug: http://b/24403699
Change-Id: Ie13a751f1137abcfe0cc6c46a0630ba5e02db676
diff --git a/services.cpp b/services.cpp
index e832b1e..e24b470 100644
--- a/services.cpp
+++ b/services.cpp
@@ -363,23 +363,31 @@
     ConnectionState state;
 };
 
-static void wait_for_state(int fd, void* cookie)
-{
+static void wait_for_state(int fd, void* cookie) {
     state_info* sinfo = reinterpret_cast<state_info*>(cookie);
 
     D("wait_for_state %d", sinfo->state);
 
-    std::string error_msg = "unknown error";
-    atransport* t = acquire_one_transport(sinfo->state, sinfo->transport_type, sinfo->serial,
-                                          &error_msg);
-    if (t != nullptr) {
-        SendOkay(fd);
-    } else {
-        SendFail(fd, error_msg);
+    while (true) {
+        bool is_ambiguous = false;
+        std::string error = "unknown error";
+        atransport* t = acquire_one_transport(sinfo->transport_type, sinfo->serial,
+                                              &is_ambiguous, &error);
+        if (t != nullptr && t->connection_state == sinfo->state) {
+            SendOkay(fd);
+            break;
+        } else if (!is_ambiguous) {
+            adb_sleep_ms(1000);
+            // Try again...
+        } else {
+            SendFail(fd, error);
+            break;
+        }
     }
 
-    if (sinfo->serial)
+    if (sinfo->serial) {
         free(sinfo->serial);
+    }
     free(sinfo);
     adb_close(fd);
     D("wait_for_state is done");