Merge "adb: win32: fix adb emu command"
diff --git a/adb/Android.mk b/adb/Android.mk
index 7d6238c..1aed2cb 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -96,6 +96,9 @@
 
 ifeq ($(HOST_OS),windows)
     LOCAL_C_INCLUDES += development/host/windows/usb/api/
+    # Windows.h defines an awful ERROR macro that collides with base/logging.h.
+    # Suppress it with NOGDI.
+    LOCAL_CFLAGS += -DNOGDI
 endif
 
 include $(BUILD_HOST_STATIC_LIBRARY)
@@ -152,18 +155,21 @@
 include $(CLEAR_VARS)
 
 ifeq ($(HOST_OS),linux)
-  LOCAL_LDLIBS += -lrt -ldl -lpthread
-  LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
+    LOCAL_LDLIBS += -lrt -ldl -lpthread
+    LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
 endif
 
 ifeq ($(HOST_OS),darwin)
-  LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
-  LOCAL_CFLAGS += -Wno-sizeof-pointer-memaccess -Wno-unused-parameter
+    LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
+    LOCAL_CFLAGS += -Wno-sizeof-pointer-memaccess -Wno-unused-parameter
 endif
 
 ifeq ($(HOST_OS),windows)
-  LOCAL_LDLIBS += -lws2_32 -lgdi32
-  EXTRA_STATIC_LIBS := AdbWinApi
+    # Windows.h defines an awful ERROR macro that collides with base/logging.h.
+    # Suppress it with NOGDI.
+    LOCAL_CFLAGS += -DNOGDI
+    LOCAL_LDLIBS += -lws2_32 -lgdi32
+    EXTRA_STATIC_LIBS := AdbWinApi
 endif
 
 LOCAL_CLANG := $(adb_host_clang)
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 510dcc2..e4658f5 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -16,6 +16,11 @@
 
 #define TRACE_TAG TRACE_AUTH
 
+#ifdef _WIN32
+// This blocks some definitions we need on Windows.
+#undef NOGDI
+#endif
+
 #include "sysdeps.h"
 #include "adb_auth.h"
 
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 18e14de..532af45 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -80,36 +80,6 @@
     __adb_server_name = hostname;
 }
 
-int adb_get_emulator_console_port() {
-    if (__adb_serial) {
-        // The user specified a serial number; is it an emulator?
-        int port;
-        return (sscanf(__adb_serial, "emulator-%d", &port) == 1) ? port : -1;
-    }
-
-    // No specific device was given, so get the list of connected
-    // devices and search for emulators. If there's one, we'll
-    // take it. If there are more than one, that's an error.
-    std::string devices;
-    std::string error;
-    if (!adb_query("host:devices", &devices, &error)) {
-        printf("no emulator connected: %s\n", error.c_str());
-        return -1;
-    }
-
-    int port;
-    size_t emulator_count = 0;
-    for (auto& device : android::base::Split(devices, "\n")) {
-        if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
-            if (++emulator_count > 1) {
-                return -2;
-            }
-        }
-    }
-    if (emulator_count == 0) return -1;
-    return port;
-}
-
 static int switch_socket_transport(int fd, std::string* error) {
     std::string service;
     if (__adb_serial) {
diff --git a/adb/adb_client.h b/adb/adb_client.h
index de5c2db..9895c49 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #ifndef _ADB_CLIENT_H_
 #define _ADB_CLIENT_H_
 
@@ -5,16 +21,13 @@
 
 #include <string>
 
-/* connect to adb, connect to the named service, and return
-** a valid fd for interacting with that service upon success
-** or a negative number on failure
-*/
+// Connect to adb, connect to the named service, and return a valid fd for
+// interacting with that service upon success or a negative number on failure.
 int adb_connect(const std::string& service, std::string* error);
 int _adb_connect(const std::string& service, std::string* error);
 
-/* connect to adb, connect to the named service, return 0 if
-** the connection succeeded AND the service returned OKAY
-*/
+// Connect to adb, connect to the named service, return 0 if the connection
+// succeeded AND the service returned OKAY.
 int adb_command(const std::string& service, std::string* error);
 
 // Connects to the named adb service and fills 'result' with the response.
@@ -24,29 +37,19 @@
 // Set the preferred transport to connect to.
 void adb_set_transport(TransportType type, const char* serial);
 
-/* Set TCP specifics of the transport to use
-*/
+// Set TCP specifics of the transport to use.
 void adb_set_tcp_specifics(int server_port);
 
-/* Set TCP Hostname of the transport to use
-*/
+// Set TCP Hostname of the transport to use.
 void adb_set_tcp_name(const char* hostname);
 
-/* Return the console port of the currently connected emulator (if any)
- * of -1 if there is no emulator, and -2 if there is more than one.
- * assumes adb_set_transport() was alled previously...
- */
-int  adb_get_emulator_console_port(void);
+// Send commands to the current emulator instance. Will fail if there is not
+// exactly one emulator connected (or if you use -s <serial> with a <serial>
+// that does not designate an emulator).
+int adb_send_emulator_command(int argc, const char** argv, const char* serial);
 
-/* send commands to the current emulator instance. will fail if there
- * is zero, or more than one emulator connected (or if you use -s <serial>
- * with a <serial> that does not designate an emulator)
- */
-int  adb_send_emulator_command(int  argc, const char**  argv);
-
-// Reads a standard adb status response (OKAY|FAIL) and
-// returns true in the event of OKAY, false in the event of FAIL
-// or protocol error.
+// Reads a standard adb status response (OKAY|FAIL) and returns true in the
+// event of OKAY, false in the event of FAIL or protocol error.
 bool adb_status(int fd, std::string* error);
 
 #endif
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 76eb8c0..27ab7b4 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1136,7 +1136,7 @@
         return adb_query_command(query);
     }
     else if (!strcmp(argv[0], "emu")) {
-        return adb_send_emulator_command(argc, argv);
+        return adb_send_emulator_command(argc, argv, serial);
     }
     else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
         char h = (argv[0][0] == 'h');
diff --git a/adb/console.cpp b/adb/console.cpp
index 452ee41..0707960 100644
--- a/adb/console.cpp
+++ b/adb/console.cpp
@@ -1,44 +1,115 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #include "sysdeps.h"
-#include "adb.h"
-#include "adb_client.h"
+
 #include <stdio.h>
 
-static int  connect_to_console(void)
-{
-    int  fd, port;
+#include "base/file.h"
+#include "base/logging.h"
+#include "base/strings.h"
 
-    port = adb_get_emulator_console_port();
-    if (port < 0) {
-        if (port == -2)
-            fprintf(stderr, "error: more than one emulator detected. use -s option\n");
-        else
-            fprintf(stderr, "error: no emulator detected\n");
+#include "adb.h"
+#include "adb_client.h"
+
+// Return the console port of the currently connected emulator (if any) or -1 if
+// there is no emulator, and -2 if there is more than one.
+static int adb_get_emulator_console_port(const char* serial) {
+    if (serial) {
+        // The user specified a serial number; is it an emulator?
+        int port;
+        return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1;
+    }
+
+    // No specific device was given, so get the list of connected devices and
+    // search for emulators. If there's one, we'll take it. If there are more
+    // than one, that's an error.
+    std::string devices;
+    std::string error;
+    if (!adb_query("host:devices", &devices, &error)) {
+        fprintf(stderr, "error: no emulator connected: %s\n", error.c_str());
         return -1;
     }
-    fd = socket_loopback_client( port, SOCK_STREAM );
-    if (fd < 0) {
+
+    int port;
+    size_t emulator_count = 0;
+    for (const auto& device : android::base::Split(devices, "\n")) {
+        if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
+            if (++emulator_count > 1) {
+                fprintf(
+                    stderr, "error: more than one emulator detected; use -s\n");
+                return -1;
+            }
+        }
+    }
+
+    if (emulator_count == 0) {
+        fprintf(stderr, "error: no emulator detected\n");
+        return -1;
+    }
+
+    return port;
+}
+
+static int connect_to_console(const char* serial) {
+    int port = adb_get_emulator_console_port(serial);
+    if (port == -1) {
+        return -1;
+    }
+
+    int fd = socket_loopback_client(port, SOCK_STREAM);
+    if (fd == -1) {
         fprintf(stderr, "error: could not connect to TCP port %d\n", port);
         return -1;
     }
-    return  fd;
+    return fd;
 }
 
-
-int  adb_send_emulator_command(int  argc, const char**  argv)
-{
-    int   fd, nn;
-
-    fd = connect_to_console();
-    if (fd < 0)
+int adb_send_emulator_command(int argc, const char** argv, const char* serial) {
+    int fd = connect_to_console(serial);
+    if (fd == -1) {
         return 1;
-
-#define  QUIT  "quit\n"
-
-    for (nn = 1; nn < argc; nn++) {
-        adb_write( fd, argv[nn], strlen(argv[nn]) );
-        adb_write( fd, (nn == argc-1) ? "\n" : " ", 1 );
     }
-    adb_write( fd, QUIT, sizeof(QUIT)-1 );
+
+    for (int i = 1; i < argc; i++) {
+        adb_write(fd, argv[i], strlen(argv[i]));
+        adb_write(fd, i == argc - 1 ? "\n" : " ", 1);
+    }
+
+    const char disconnect_command[] = "quit\n";
+    if (adb_write(fd, disconnect_command, sizeof(disconnect_command) - 1) == -1) {
+        LOG(FATAL) << "Could not finalize emulator command";
+    }
+
+    // Drain output that the emulator console has sent us to prevent a problem
+    // on Windows where if adb closes the socket without reading all the data,
+    // the emulator's next call to recv() will have an ECONNABORTED error,
+    // preventing the emulator from reading the command that adb has sent.
+    // https://code.google.com/p/android/issues/detail?id=21021
+    int result;
+    do {
+        char buf[BUFSIZ];
+        result = adb_read(fd, buf, sizeof(buf));
+        // Keep reading until zero bytes (EOF) or an error. If 'adb emu kill'
+        // is executed, the emulator calls exit() which causes adb to get
+        // ECONNRESET. Any other emu command is followed by the quit command
+        // that we sent above, and that causes the emulator to close the socket
+        // which should cause zero bytes (EOF) to be returned.
+    } while (result > 0);
+
     adb_close(fd);
 
     return 0;
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index a21272f..b7962b9 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -16,6 +16,9 @@
 
 #define TRACE_TAG TRACE_SYSDEPS
 
+// For whatever reason this blocks the definition of ToAscii...
+#undef NOGDI
+
 #include "sysdeps.h"
 
 #include <winsock2.h> /* winsock.h *must* be included before windows.h. */
diff --git a/base/include/base/logging.h b/base/include/base/logging.h
index 84ec538..4a15f43 100644
--- a/base/include/base/logging.h
+++ b/base/include/base/logging.h
@@ -23,8 +23,10 @@
 #endif
 
 #ifdef _WIN32
+#ifndef NOGDI
 #define NOGDI // Suppress the evil ERROR macro.
 #endif
+#endif
 
 #include <functional>
 #include <memory>