Merge "metricsd: Add Android.mk."
diff --git a/adb/adb.cpp b/adb/adb.cpp
index dd6c555..821b785 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -630,7 +630,7 @@
     ZeroMemory( &startup, sizeof(startup) );
     startup.cb = sizeof(startup);
     startup.hStdInput  = nul_read;
-    startup.hStdOutput = pipe_write;
+    startup.hStdOutput = nul_write;
     startup.hStdError  = nul_write;
     startup.dwFlags    = STARTF_USESTDHANDLES;
 
@@ -645,9 +645,23 @@
                 SystemErrorCodeToString(GetLastError()).c_str());
         return -1;
     }
+
+    // Verify that the pipe_write handle value can be passed on the command line
+    // as %d and that the rest of adb code can pass it around in an int.
+    const int pipe_write_as_int = cast_handle_to_int(pipe_write);
+    if (cast_int_to_handle(pipe_write_as_int) != pipe_write) {
+        // If this fires, either handle values are larger than 32-bits or else
+        // there is a bug in our casting.
+        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
+        fprintf(stderr, "CreatePipe handle value too large: 0x%p\n",
+                pipe_write);
+        return -1;
+    }
+
     WCHAR args[64];
     snwprintf(args, arraysize(args),
-              L"adb -P %d fork-server server", server_port);
+              L"adb -P %d fork-server server --reply-fd %d", server_port,
+              pipe_write_as_int);
     ret = CreateProcessW(
             program_path,                              /* program path  */
             args,
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index af3a6a1..73acbb0 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -160,16 +160,24 @@
     // Inform our parent that we are up and running.
     if (is_daemon) {
 #if defined(_WIN32)
-        // Change stdout mode to binary so \n => \r\n translation does not
-        // occur. In a moment stdout will be reopened to the daemon log file
-        // anyway.
-        _setmode(ack_reply_fd, _O_BINARY);
-#endif
+        const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
+        const CHAR ack[] = "OK\n";
+        const DWORD bytes_to_write = arraysize(ack) - 1;
+        DWORD written = 0;
+        if (!WriteFile(ack_reply_handle, ack, bytes_to_write, &written, NULL)) {
+            fatal("adb: cannot write ACK to handle 0x%p: %s", ack_reply_handle,
+                  SystemErrorCodeToString(GetLastError()).c_str());
+        }
+        if (written != bytes_to_write) {
+            fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes",
+                  bytes_to_write, written);
+        }
+        CloseHandle(ack_reply_handle);
+#else
         // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not
         // "OKAY".
         android::base::WriteStringToFd("OK\n", ack_reply_fd);
-#if !defined(_WIN32)
-        adb_close(ack_reply_fd);
+        unix_close(ack_reply_fd);
 #endif
         close_stdin();
         setup_daemon_logging();
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 2e182e8..1e1690e 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -953,14 +953,7 @@
     int is_server = 0;
     int r;
     TransportType transport_type = kTransportAny;
-
-#if defined(_WIN32)
-    // TODO(compareandswap): Windows should use a separate reply fd too.
-    int ack_reply_fd = STDOUT_FILENO;
-#else
     int ack_reply_fd = -1;
-#endif
-
 
     // If defined, this should be an absolute path to
     // the directory containing all of the various system images
@@ -1003,7 +996,14 @@
             argc--;
             argv++;
             ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
+#ifdef _WIN32
+            const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
+            if ((GetStdHandle(STD_INPUT_HANDLE) == ack_reply_handle) ||
+                (GetStdHandle(STD_OUTPUT_HANDLE) == ack_reply_handle) ||
+                (GetStdHandle(STD_ERROR_HANDLE) == ack_reply_handle)) {
+#else
             if (ack_reply_fd <= 2) { // Disallow stdin, stdout, and stderr.
+#endif
                 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
                 return usage();
             }
@@ -1084,7 +1084,7 @@
 
     if (is_server) {
         if (no_daemon || is_daemon) {
-            if (ack_reply_fd == -1) {
+            if (is_daemon && (ack_reply_fd == -1)) {
                 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
                 return usage();
             }
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 9189955..6f3c443 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -338,6 +338,23 @@
     char** narrow_args;
 };
 
+// Windows HANDLE values only use 32-bits of the type, even on 64-bit machines,
+// so they can fit in an int. To convert back, we just need to sign-extend.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
+// Note that this does not make a HANDLE value work with APIs like open(), nor
+// does this make a value from open() passable to APIs taking a HANDLE. This
+// just lets you take a HANDLE, pass it around as an int, and then use it again
+// as a HANDLE.
+inline int cast_handle_to_int(const HANDLE h) {
+    // truncate
+    return static_cast<int>(reinterpret_cast<INT_PTR>(h));
+}
+
+inline HANDLE cast_int_to_handle(const int fd) {
+    // sign-extend
+    return reinterpret_cast<HANDLE>(static_cast<INT_PTR>(fd));
+}
+
 #else /* !_WIN32 a.k.a. Unix */
 
 #include "fdevent.h"
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index b964a36..5d7b151 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -189,25 +189,16 @@
     return load_fd(fd, _sz);
 }
 
-int match_fastboot_with_serial(usb_ifc_info *info, const char *local_serial)
-{
-    if(!(vendor_id && (info->dev_vendor == vendor_id)) &&
-       (info->dev_vendor != 0x18d1) &&  // Google
-       (info->dev_vendor != 0x8087) &&  // Intel
-       (info->dev_vendor != 0x0451) &&
-       (info->dev_vendor != 0x0502) &&
-       (info->dev_vendor != 0x0fce) &&  // Sony Ericsson
-       (info->dev_vendor != 0x05c6) &&  // Qualcomm
-       (info->dev_vendor != 0x22b8) &&  // Motorola
-       (info->dev_vendor != 0x0955) &&  // Nvidia
-       (info->dev_vendor != 0x413c) &&  // DELL
-       (info->dev_vendor != 0x2314) &&  // INQ Mobile
-       (info->dev_vendor != 0x0b05) &&  // Asus
-       (info->dev_vendor != 0x0bb4))    // HTC
-            return -1;
-    if(info->ifc_class != 0xff) return -1;
-    if(info->ifc_subclass != 0x42) return -1;
-    if(info->ifc_protocol != 0x03) return -1;
+int match_fastboot_with_serial(usb_ifc_info* info, const char* local_serial) {
+    // Require a matching vendor id if the user specified one with -i.
+    if (vendor_id != 0  && info->dev_vendor != vendor_id) {
+        return -1;
+    }
+
+    if (info->ifc_class != 0xff || info->ifc_subclass != 0x42 || info->ifc_protocol != 0x03) {
+        return -1;
+    }
+
     // require matching serial number or device path if requested
     // at the command line with the -s option.
     if (local_serial && (strcmp(local_serial, info->serial_number) != 0 &&
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index aa92af7..ae880c3 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -56,7 +56,6 @@
     stop \
     top \
     uptime \
-    watchprops \
 
 ALL_TOOLS = $(BSD_TOOLS) $(OUR_TOOLS)
 
diff --git a/toolbox/watchprops.c b/toolbox/watchprops.c
deleted file mode 100644
index cd62922..0000000
--- a/toolbox/watchprops.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include <cutils/properties.h>
-#include <cutils/hashmap.h>
-
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-
-static int str_hash(void *key)
-{
-    return hashmapHash(key, strlen(key));
-}
-
-static bool str_equals(void *keyA, void *keyB)
-{
-    return strcmp(keyA, keyB) == 0;
-}
-
-static void announce(char *name, char *value)
-{
-    unsigned char *x;
-    
-    for(x = (unsigned char *)value; *x; x++) {
-        if((*x < 32) || (*x > 127)) *x = '.';
-    }
-
-    fprintf(stderr,"%10d %s = '%s'\n", (int) time(0), name, value);
-}
-
-static void add_to_watchlist(Hashmap *watchlist, const char *name,
-        const prop_info *pi)
-{
-    char *key = strdup(name);
-    unsigned *value = malloc(sizeof(unsigned));
-    if (!key || !value)
-        exit(1);
-
-    *value = __system_property_serial(pi);
-    hashmapPut(watchlist, key, value);
-}
-
-static void populate_watchlist(const prop_info *pi, void *cookie)
-{
-    Hashmap *watchlist = cookie;
-    char name[PROP_NAME_MAX];
-    char value_unused[PROP_VALUE_MAX];
-
-    __system_property_read(pi, name, value_unused);
-    add_to_watchlist(watchlist, name, pi);
-}
-
-static void update_watchlist(const prop_info *pi, void *cookie)
-{
-    Hashmap *watchlist = cookie;
-    char name[PROP_NAME_MAX];
-    char value[PROP_VALUE_MAX];
-    unsigned *serial;
-
-    __system_property_read(pi, name, value);
-    serial = hashmapGet(watchlist, name);
-    if (!serial) {
-        add_to_watchlist(watchlist, name, pi);
-        announce(name, value);
-    } else {
-        unsigned tmp = __system_property_serial(pi);
-        if (*serial != tmp) {
-            *serial = tmp;
-            announce(name, value);
-        }
-    }
-}
-
-int watchprops_main(int argc, char *argv[])
-{
-    unsigned serial;
-    
-    Hashmap *watchlist = hashmapCreate(1024, str_hash, str_equals);
-    if (!watchlist)
-        exit(1);
-
-    __system_property_foreach(populate_watchlist, watchlist);
-
-    for(serial = 0;;) {
-        serial = __system_property_wait_any(serial);
-        __system_property_foreach(update_watchlist, watchlist);
-    }
-    return 0;
-}