Merge "Remove a declaration for an unimplemented function."
diff --git a/adb/Android.mk b/adb/Android.mk
index 2ea89e9..d120f0a 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -5,7 +5,11 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ADB_CLANG := true
+ifeq ($(HOST_OS),windows)
+  adb_host_clang := false  # libc++ for mingw not ready yet.
+else
+  adb_host_clang := true
+endif
 
 # libadb
 # =========================================================
@@ -27,6 +31,11 @@
     transport_local.cpp \
     transport_usb.cpp \
 
+LIBADB_TEST_SRCS := \
+    adb_io_test.cpp \
+    adb_utils_test.cpp \
+    transport_test.cpp \
+
 LIBADB_CFLAGS := \
     -Wall -Werror \
     -Wno-unused-parameter \
@@ -63,7 +72,7 @@
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
 LOCAL_MODULE := libadb
 LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=1
 LOCAL_SRC_FILES := \
@@ -81,13 +90,8 @@
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
-LIBADB_TEST_SRCS := \
-    adb_io_test.cpp \
-    adb_utils_test.cpp \
-    transport_test.cpp \
-
 include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := true
 LOCAL_MODULE := adbd_test
 LOCAL_CFLAGS := -DADB_HOST=0 $(LIBADB_CFLAGS)
 LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS)
@@ -96,7 +100,7 @@
 include $(BUILD_NATIVE_TEST)
 
 include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
 LOCAL_MODULE := adb_test
 LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
 LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS) services.cpp
@@ -131,15 +135,11 @@
 endif
 
 ifeq ($(HOST_OS),windows)
+  LOCAL_LDLIBS += -lws2_32 -lgdi32
   EXTRA_STATIC_LIBS := AdbWinApi
-  ifneq ($(strip $(USE_MINGW)),)
-    # MinGW under Linux case
-    LOCAL_LDLIBS += -lws2_32 -lgdi32
-    USE_SYSDEPS_WIN32 := 1
-  endif
 endif
 
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
 
 LOCAL_SRC_FILES := \
     adb_main.cpp \
@@ -162,12 +162,19 @@
     libadb \
     libbase \
     libcrypto_static \
+    libcutils \
     $(EXTRA_STATIC_LIBS) \
 
-ifeq ($(USE_SYSDEPS_WIN32),)
-    LOCAL_STATIC_LIBRARIES += libcutils
+# libc++ not available on windows yet
+ifneq ($(HOST_OS),windows)
+    LOCAL_CXX_STL := libc++_static
 endif
 
+# Don't add anything here, we don't want additional shared dependencies
+# on the host adb tool, and shared libraries that link against libc++
+# will violate ODR
+LOCAL_SHARED_LIBRARIES :=
+
 include $(BUILD_HOST_EXECUTABLE)
 
 $(call dist-for-goals,dist_files sdk,$(LOCAL_BUILT_MODULE))
@@ -184,7 +191,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := true
 
 LOCAL_SRC_FILES := \
     adb_main.cpp \
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index b515f59..710ef3c 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -21,6 +21,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "sysdeps.h"
+
 bool getcwd(std::string* s) {
   char* cwd = getcwd(nullptr, 0);
   if (cwd != nullptr) *s = cwd;
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 2d41050..f193d2f 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1735,7 +1735,11 @@
         return 1;
     }
 
+#if defined(_WIN32) // Remove when we're using clang for Win32.
+    std::string cmd = android::base::StringPrintf("exec:pm install-create -S %u", (unsigned) total_size);
+#else
     std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
+#endif
     for (i = 1; i < first_apk; i++) {
         cmd += " " + escape_arg(argv[i]);
     }
@@ -1775,9 +1779,15 @@
             goto finalize_session;
         }
 
+#if defined(_WIN32) // Remove when we're using clang for Win32.
+        std::string cmd = android::base::StringPrintf(
+                "exec:pm install-write -S %u %d %d_%s -",
+                (unsigned) sb.st_size, session_id, i, get_basename(file));
+#else
         std::string cmd = android::base::StringPrintf(
                 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
                 static_cast<uint64_t>(sb.st_size), session_id, i, get_basename(file));
+#endif
 
         int localFd = adb_open(file, O_RDONLY);
         if (localFd < 0) {
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index b9e957f..7b2975b 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -74,6 +74,16 @@
 LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host
 endif
 
+# libc++ not available on windows yet
+ifneq ($(HOST_OS),windows)
+    LOCAL_CXX_STL := libc++_static
+endif
+
+# Don't add anything here, we don't want additional shared dependencies
+# on the host fastboot tool, and shared libraries that link against libc++
+# will violate ODR
+LOCAL_SHARED_LIBRARIES :=
+
 include $(BUILD_HOST_EXECUTABLE)
 
 my_dist_files := $(LOCAL_BUILT_MODULE)
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 57c46a3..8582344 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -1131,7 +1131,22 @@
     return kIoError;
   }
 
-  int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+  int result = 0;
+#if defined(__linux__)
+  // Make sure we have enough space on the volume to extract the compressed
+  // entry. Note that the call to ftruncate below will change the file size but
+  // will not allocate space on disk.
+  if (declared_length > 0) {
+    result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
+    if (result == -1) {
+      ALOGW("Zip: unable to allocate space for file to %" PRId64 ": %s",
+            static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+      return kIoError;
+    }
+  }
+#endif  // defined(__linux__)
+
+  result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
   if (result == -1) {
     ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
           static_cast<int64_t>(declared_length + current_offset), strerror(errno));
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index a0436ef..1859461 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -226,6 +226,68 @@
     return it;
 }
 
+// Define a temporary mechanism to report the last LogBufferElement pointer
+// for the specified uid, pid and tid. Used below to help merge-sort when
+// pruning for worst UID.
+class LogBufferElementKey {
+    const union {
+        struct {
+            uint16_t uid;
+            uint16_t pid;
+            uint16_t tid;
+            uint16_t padding;
+        } __packed;
+        uint64_t value;
+    } __packed;
+
+public:
+    LogBufferElementKey(uid_t u, pid_t p, pid_t t):uid(u),pid(p),tid(t),padding(0) { }
+    LogBufferElementKey(uint64_t k):value(k) { }
+
+    uint64_t getKey() { return value; }
+};
+
+struct LogBufferElementEntry {
+    const uint64_t key;
+    LogBufferElement *last;
+
+public:
+    LogBufferElementEntry(const uint64_t &k, LogBufferElement *e):key(k),last(e) { }
+
+    const uint64_t&getKey() const { return key; }
+
+    LogBufferElement *getLast() { return last; }
+};
+
+struct LogBufferElementLast : public android::BasicHashtable<uint64_t, LogBufferElementEntry> {
+
+    bool merge(LogBufferElement *e, unsigned short dropped) {
+        LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
+        android::hash_t hash = android::hash_type(key.getKey());
+        ssize_t index = find(-1, hash, key.getKey());
+        if (index != -1) {
+            LogBufferElementEntry &entry = editEntryAt(index);
+            LogBufferElement *l = entry.getLast();
+            unsigned short d = l->getDropped();
+            if ((dropped + d) > USHRT_MAX) {
+                removeAt(index);
+            } else {
+                l->setDropped(dropped + d);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    size_t add(LogBufferElement *e) {
+        LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
+        android::hash_t hash = android::hash_type(key.getKey());
+        return android::BasicHashtable<uint64_t, LogBufferElementEntry>::
+            add(hash, LogBufferElementEntry(key.getKey(), e));
+    }
+
+};
+
 // prune "pruneRows" of type "id" from the buffer.
 //
 // mLogElementsLock must be held when this function is called.
@@ -301,7 +363,7 @@
 
         bool kick = false;
         bool leading = true;
-        LogBufferElement *last = NULL;
+        LogBufferElementLast last;
         for(it = mLogElements.begin(); it != mLogElements.end();) {
             LogBufferElement *e = *it;
 
@@ -322,24 +384,18 @@
                 continue;
             }
 
-            pid_t pid = e->getPid();
-
             // merge any drops
-            if (last && dropped
-             && ((dropped + last->getDropped()) < USHRT_MAX)
-             && (last->getPid() == pid)
-             && (last->getTid() == e->getTid())) {
+            if (dropped && last.merge(e, dropped)) {
                 it = mLogElements.erase(it);
                 stats.erase(e);
                 delete e;
-                last->setDropped(dropped + last->getDropped());
                 continue;
             }
 
             leading = false;
 
             if (hasBlacklist && mPrune.naughty(e)) {
-                last = NULL;
+                last.clear();
                 it = erase(it);
                 if (dropped) {
                     continue;
@@ -361,13 +417,13 @@
             }
 
             if (dropped) {
-                last = e;
+                last.add(e);
                 ++it;
                 continue;
             }
 
             if (e->getUid() != worst) {
-                last = NULL;
+                last.clear();
                 ++it;
                 continue;
             }
@@ -382,17 +438,12 @@
             unsigned short len = e->getMsgLen();
             stats.drop(e);
             e->setDropped(1);
-            // merge any drops
-            if (last
-             && (last->getDropped() < (USHRT_MAX - 1))
-             && (last->getPid() == pid)
-             && (last->getTid() == e->getTid())) {
+            if (last.merge(e, 1)) {
                 it = mLogElements.erase(it);
                 stats.erase(e);
                 delete e;
-                last->setDropped(last->getDropped() + 1);
             } else {
-                last = e;
+                last.add(e);
                 ++it;
             }
             if (worst_sizes < second_worst_sizes) {
@@ -400,6 +451,7 @@
             }
             worst_sizes -= len;
         }
+        last.clear();
 
         if (!kick || !mPrune.worstUidEnabled()) {
             break; // the following loop will ask bad clients to skip/drop
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a2b8f59..a5ea60a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -248,6 +248,7 @@
     mkdir /data/misc/bluedroid 0770 bluetooth net_bt_stack
     mkdir /data/misc/bluetooth 0770 system system
     mkdir /data/misc/keystore 0700 keystore keystore
+    mkdir /data/misc/gatekeeper 0700 system system
     mkdir /data/misc/keychain 0771 system system
     mkdir /data/misc/net 0750 root shell
     mkdir /data/misc/radio 0770 system radio