Merge "WA: Fix adb wait-for-device command"
diff --git a/crash_reporter/Android.mk b/crash_reporter/Android.mk
index 565963c..bc023b0 100644
--- a/crash_reporter/Android.mk
+++ b/crash_reporter/Android.mk
@@ -41,7 +41,6 @@
 LOCAL_MODULE := libcrash
 LOCAL_CPP_EXTENSION := $(crash_reporter_cpp_extension)
 LOCAL_C_INCLUDES := $(crash_reporter_includes)
-LOCAL_RTTI_FLAG := -frtti
 LOCAL_SHARED_LIBRARIES := libchrome \
     libbinder \
     libbrillo \
@@ -63,7 +62,6 @@
     crash_sender \
     crash_server
 LOCAL_INIT_RC := crash_reporter.rc
-LOCAL_RTTI_FLAG := -frtti
 LOCAL_SHARED_LIBRARIES := libchrome \
     libbinder \
     libbrillo \
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index de0f943..9e4f1f7 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -62,7 +62,7 @@
 LOCAL_SRC_FILES_x86_64 := x86_64/crashglue.S
 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -fstack-protector-all -Werror -Wno-free-nonheap-object
+LOCAL_CFLAGS += -fstack-protector-all -Werror -Wno-free-nonheap-object -Wno-date-time
 #LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_SHARED_LIBRARIES := libcutils liblog libc
 
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 0afa895..58b629b 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -24,11 +24,12 @@
 #include <dirent.h>
 #include <time.h>
 
-#include <sys/ptrace.h>
-#include <sys/wait.h>
 #include <elf.h>
-#include <sys/stat.h>
 #include <sys/poll.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
 
 #include <selinux/android.h>
 
@@ -363,6 +364,37 @@
   }
 #endif
 
+  // Fork a child to handle the rest of the request.
+  pid_t fork_pid = fork();
+  if (fork_pid == -1) {
+    ALOGE("debuggerd: failed to fork: %s\n", strerror(errno));
+    return;
+  } else if (fork_pid != 0) {
+    waitpid(fork_pid, nullptr, 0);
+    return;
+  }
+
+  // Open the tombstone file if we need it.
+  std::string tombstone_path;
+  int tombstone_fd = -1;
+  switch (request.action) {
+    case DEBUGGER_ACTION_DUMP_TOMBSTONE:
+    case DEBUGGER_ACTION_CRASH:
+      tombstone_fd = open_tombstone(&tombstone_path);
+      if (tombstone_fd == -1) {
+        ALOGE("debuggerd: failed to open tombstone file: %s\n", strerror(errno));
+        exit(1);
+      }
+      break;
+
+    case DEBUGGER_ACTION_DUMP_BACKTRACE:
+      break;
+
+    default:
+      ALOGE("debuggerd: unexpected request action: %d", request.action);
+      exit(1);
+  }
+
   // At this point, the thread that made the request is blocked in
   // a read() call.  If the thread has crashed, then this gives us
   // time to PTRACE_ATTACH to it before it has a chance to really fault.
@@ -374,19 +406,32 @@
   // See details in bionic/libc/linker/debugger.c, in function
   // debugger_signal_handler().
   if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) {
-    ALOGE("ptrace attach failed: %s\n", strerror(errno));
-    return;
+    ALOGE("debuggerd: ptrace attach failed: %s\n", strerror(errno));
+    exit(1);
+  }
+
+  // Generate the backtrace map before dropping privileges.
+  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(request.pid));
+
+  // Now that we've done everything that requires privileges, we can drop them.
+  if (setresgid(AID_DEBUGGERD, AID_DEBUGGERD, AID_DEBUGGERD) != 0) {
+    ALOGE("debuggerd: failed to setresgid");
+    exit(1);
+  }
+
+  if (setresuid(AID_DEBUGGERD, AID_DEBUGGERD, AID_DEBUGGERD) != 0) {
+    ALOGE("debuggerd: failed to setresuid");
+    exit(1);
   }
 
   bool detach_failed = false;
   bool tid_unresponsive = false;
   bool attach_gdb = should_attach_gdb(&request);
   if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
-    ALOGE("failed responding to client: %s\n", strerror(errno));
-    return;
+    ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno));
+    exit(1);
   }
 
-  std::unique_ptr<char> tombstone_path;
   int total_sleep_time_usec = 0;
   while (true) {
     int signal = wait_for_sigstop(request.tid, &total_sleep_time_usec, &detach_failed);
@@ -399,9 +444,9 @@
       case SIGSTOP:
         if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
           ALOGV("stopped -- dumping to tombstone\n");
-          tombstone_path.reset(engrave_tombstone(
-            request.pid, request.tid, signal, request.original_si_code, request.abort_msg_address,
-            true, &detach_failed, &total_sleep_time_usec));
+          engrave_tombstone(tombstone_fd, backtrace_map.get(), request.pid, request.tid, signal,
+                            request.original_si_code, request.abort_msg_address, true,
+                            &detach_failed, &total_sleep_time_usec);
         } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
           ALOGV("stopped -- dumping to fd\n");
           dump_backtrace(fd, -1, request.pid, request.tid, &detach_failed, &total_sleep_time_usec);
@@ -409,7 +454,7 @@
           ALOGV("stopped -- continuing\n");
           status = ptrace(PTRACE_CONT, request.tid, 0, 0);
           if (status) {
-            ALOGE("ptrace continue failed: %s\n", strerror(errno));
+            ALOGE("debuggerd: ptrace continue failed: %s\n", strerror(errno));
           }
           continue;  // loop again
         }
@@ -432,21 +477,21 @@
         kill(request.pid, SIGSTOP);
         // don't dump sibling threads when attaching to GDB because it
         // makes the process less reliable, apparently...
-        tombstone_path.reset(engrave_tombstone(
-          request.pid, request.tid, signal, request.original_si_code, request.abort_msg_address,
-          !attach_gdb, &detach_failed, &total_sleep_time_usec));
+        engrave_tombstone(tombstone_fd, backtrace_map.get(), request.pid, request.tid, signal,
+                          request.original_si_code, request.abort_msg_address, !attach_gdb,
+                          &detach_failed, &total_sleep_time_usec);
         break;
 
       default:
-        ALOGE("process stopped due to unexpected signal %d\n", signal);
+        ALOGE("debuggerd: process stopped due to unexpected signal %d\n", signal);
         break;
     }
     break;
   }
 
   if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
-    if (tombstone_path) {
-      write(fd, tombstone_path.get(), strlen(tombstone_path.get()));
+    if (!tombstone_path.empty()) {
+      write(fd, tombstone_path.c_str(), tombstone_path.length());
     }
   }
 
@@ -457,7 +502,7 @@
       kill(request.pid, SIGSTOP);
     }
     if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
-      ALOGE("ptrace detach from %d failed: %s", request.tid, strerror(errno));
+      ALOGE("debuggerd: ptrace detach from %d failed: %s", request.tid, strerror(errno));
       detach_failed = true;
     } else if (attach_gdb) {
       // if debug.db.uid is set, its value indicates if we should wait
@@ -468,16 +513,9 @@
     }
   }
 
-  // resume stopped process (so it can crash in peace).
+  // Resume the stopped process so it can crash in peace, and exit.
   kill(request.pid, SIGCONT);
-
-  // If we didn't successfully detach, we're still the parent, and the
-  // actual parent won't receive a death notification via wait(2).  At this point
-  // there's not much we can do about that.
-  if (detach_failed) {
-    ALOGE("debuggerd committing suicide to free the zombie!\n");
-    kill(getpid(), SIGKILL);
-  }
+  exit(0);
 }
 
 static int do_server() {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 5f422e3..b2f203d 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -632,7 +632,7 @@
 }
 
 // Dumps all information about the specified pid to the tombstone.
-static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, int si_code,
+static bool dump_crash(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid, int signal, int si_code,
                        uintptr_t abort_msg_address, bool dump_sibling_threads,
                        int* total_sleep_time_usec) {
   // don't copy log messages to tombstone unless this is a dev device
@@ -659,8 +659,7 @@
     dump_signal_info(log, tid, signal, si_code);
   }
 
-  std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid));
-  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map.get()));
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
   dump_abort_message(backtrace.get(), log, abort_msg_address);
   dump_registers(log, tid);
   if (backtrace->Unwind(0)) {
@@ -669,8 +668,8 @@
     ALOGE("Unwind failed: pid = %d, tid = %d", pid, tid);
   }
   dump_memory_and_code(log, backtrace.get());
-  if (map.get() != nullptr) {
-    dump_all_maps(backtrace.get(), map.get(), log, tid);
+  if (map) {
+    dump_all_maps(backtrace.get(), map, log, tid);
   }
 
   if (want_logs) {
@@ -679,7 +678,7 @@
 
   bool detach_failed = false;
   if (dump_sibling_threads) {
-    detach_failed = dump_sibling_thread_report(log, pid, tid, total_sleep_time_usec, map.get());
+    detach_failed = dump_sibling_thread_report(log, pid, tid, total_sleep_time_usec, map);
   }
 
   if (want_logs) {
@@ -698,53 +697,57 @@
   return detach_failed;
 }
 
-// find_and_open_tombstone - find an available tombstone slot, if any, of the
+// open_tombstone - find an available tombstone slot, if any, of the
 // form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no
 // file is available, we reuse the least-recently-modified file.
-//
-// Returns the path of the tombstone file, allocated using malloc().  Caller must free() it.
-static char* find_and_open_tombstone(int* fd) {
+int open_tombstone(std::string* out_path) {
   // In a single pass, find an available slot and, in case none
   // exist, find and record the least-recently-modified file.
   char path[128];
+  int fd = -1;
   int oldest = -1;
   struct stat oldest_sb;
   for (int i = 0; i < MAX_TOMBSTONES; i++) {
     snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, i);
 
     struct stat sb;
-    if (!stat(path, &sb)) {
+    if (stat(path, &sb) == 0) {
       if (oldest < 0 || sb.st_mtime < oldest_sb.st_mtime) {
         oldest = i;
         oldest_sb.st_mtime = sb.st_mtime;
       }
       continue;
     }
-    if (errno != ENOENT)
-      continue;
+    if (errno != ENOENT) continue;
 
-    *fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600);
-    if (*fd < 0)
-      continue;   // raced ?
+    fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600);
+    if (fd < 0) continue;  // raced ?
 
-    fchown(*fd, AID_SYSTEM, AID_SYSTEM);
-    return strdup(path);
+    if (out_path) {
+      *out_path = path;
+    }
+    fchown(fd, AID_SYSTEM, AID_SYSTEM);
+    return fd;
   }
 
   if (oldest < 0) {
-    ALOGE("Failed to find a valid tombstone, default to using tombstone 0.\n");
+    ALOGE("debuggerd: failed to find a valid tombstone, default to using tombstone 0.\n");
     oldest = 0;
   }
 
   // we didn't find an available file, so we clobber the oldest one
   snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, oldest);
-  *fd = open(path, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600);
-  if (*fd < 0) {
-    ALOGE("failed to open tombstone file '%s': %s\n", path, strerror(errno));
-    return NULL;
+  fd = open(path, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600);
+  if (fd < 0) {
+    ALOGE("debuggerd: failed to open tombstone file '%s': %s\n", path, strerror(errno));
+    return -1;
   }
-  fchown(*fd, AID_SYSTEM, AID_SYSTEM);
-  return strdup(path);
+
+  if (out_path) {
+    *out_path = path;
+  }
+  fchown(fd, AID_SYSTEM, AID_SYSTEM);
+  return fd;
 }
 
 static int activity_manager_connect() {
@@ -777,49 +780,27 @@
   return amfd;
 }
 
-char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
-                        uintptr_t abort_msg_address, bool dump_sibling_threads,
-                        bool* detach_failed, int* total_sleep_time_usec) {
-
+void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid, int signal,
+                       int original_si_code, uintptr_t abort_msg_address, bool dump_sibling_threads,
+                       bool* detach_failed, int* total_sleep_time_usec) {
   log_t log;
   log.current_tid = tid;
   log.crashed_tid = tid;
 
-  if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) {
-    ALOGE("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
-  }
-
-  if (chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM) == -1) {
-    ALOGE("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
-  }
-
-  int fd = -1;
-  char* path = NULL;
-  if (selinux_android_restorecon(TOMBSTONE_DIR, 0) == 0) {
-    path = find_and_open_tombstone(&fd);
-  } else {
-    ALOGE("Failed to restore security context, not writing tombstone.\n");
-  }
-
-  if (fd < 0) {
-    ALOGE("Skipping tombstone write, nothing to do.\n");
+  if (tombstone_fd < 0) {
+    ALOGE("debuggerd: skipping tombstone write, nothing to do.\n");
     *detach_failed = false;
-    return NULL;
+    return;
   }
 
-  log.tfd = fd;
+  log.tfd = tombstone_fd;
   // Preserve amfd since it can be modified through the calls below without
   // being closed.
   int amfd = activity_manager_connect();
   log.amfd = amfd;
-  *detach_failed = dump_crash(&log, pid, tid, signal, original_si_code, abort_msg_address,
+  *detach_failed = dump_crash(&log, map, pid, tid, signal, original_si_code, abort_msg_address,
                               dump_sibling_threads, total_sleep_time_usec);
 
-  _LOG(&log, logtype::BACKTRACE, "\nTombstone written to: %s\n", path);
-
-  // Either of these file descriptors can be -1, any error is ignored.
+  // This file descriptor can be -1, any error is ignored.
   close(amfd);
-  close(fd);
-
-  return path;
 }
diff --git a/debuggerd/tombstone.h b/debuggerd/tombstone.h
index 7e2b2fe..5f2d239 100644
--- a/debuggerd/tombstone.h
+++ b/debuggerd/tombstone.h
@@ -17,15 +17,23 @@
 #ifndef _DEBUGGERD_TOMBSTONE_H
 #define _DEBUGGERD_TOMBSTONE_H
 
-#include <stddef.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include <sys/types.h>
+#include <string>
+
+class BacktraceMap;
+
+/* Create and open a tombstone file for writing.
+ * Returns a writable file descriptor, or -1 with errno set appropriately.
+ * If out_path is non-null, *out_path is set to the path of the tombstone file.
+ */
+int open_tombstone(std::string* path);
 
 /* Creates a tombstone file and writes the crash dump to it.
  * Returns the path of the tombstone, which must be freed using free(). */
-char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
-                        uintptr_t abort_msg_address,
-                        bool dump_sibling_threads, bool* detach_failed,
-                        int* total_sleep_time_usec);
+void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid, int signal,
+                       int original_si_code, uintptr_t abort_msg_address, bool dump_sibling_threads,
+                       bool* detach_failed, int* total_sleep_time_usec);
 
 #endif // _DEBUGGERD_TOMBSTONE_H
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 5b66366..bd17485 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -282,8 +282,6 @@
             "  getvar <variable>                        Display a bootloader variable.\n"
             "  set_active <suffix>                      Sets the active slot. If slots are\n"
             "                                           not supported, this does nothing.\n"
-            "                                           note: suffixes starting with a '-'\n"
-            "                                           must use set_active -- <suffix>\n"
             "  boot <kernel> [ <ramdisk> [ <second> ] ] Download and boot kernel.\n"
             "  flash:raw boot <kernel> [ <ramdisk> [ <second> ] ]\n"
             "                                           Create bootimage and flash it.\n"
@@ -320,9 +318,10 @@
             "                                           device supports slots. This will be\n"
             "                                           added to all partition names that use\n"
             "                                           slots. 'all' can be given to refer\n"
-            "                                           to all slots. If this is not given,\n"
-            "                                           slotted partitions will default to\n"
-            "                                           the current active slot.\n"
+            "                                           to all slots. 'other' can be given to\n"
+            "                                           refer to a non-current slot. If this\n"
+            "                                           flag is not used, slotted partitions\n"
+            "                                           will default to the current active slot.\n"
             "  -a, --set-active[=<suffix>]              Sets the active slot. If no suffix is\n"
             "                                           provided, this will default to the value\n"
             "                                           given by --slot. If slots are not\n"
@@ -739,12 +738,28 @@
             if (!suffixes.empty()) {
                 return suffixes[0];
             } else {
-                fprintf(stderr, "No known slots.\n");
-                exit(1);
+                die("No known slots.");
             }
         }
     }
+
     std::vector<std::string> suffixes = get_suffixes(transport);
+
+    if (strcmp(slot, "other") == 0) {
+        std::string current_slot;
+        if (!fb_getvar(transport, "current-slot", &current_slot)) {
+            die("Failed to identify current slot.");
+        }
+        if (!suffixes.empty()) {
+            for (size_t i = 0; i < suffixes.size(); i++) {
+                if (current_slot == suffixes[i])
+                    return suffixes[(i+1)%suffixes.size()];
+            }
+        } else {
+            die("No known slots.");
+        }
+    }
+
     for (const std::string &suffix : suffixes) {
         if (suffix == slot)
             return slot;
@@ -1411,7 +1426,6 @@
             std::string slot = verify_slot(transport, argv[1], false);
             fb_set_active(slot.c_str());
             skip(2);
-            wants_reboot = true;
         } else if(!strcmp(*argv, "oem")) {
             argc = do_oem_command(argc, argv);
         } else if(!strcmp(*argv, "flashing")) {
diff --git a/include/binderwrapper/binder_wrapper.h b/include/binderwrapper/binder_wrapper.h
index 921c4ed..ccda825 100644
--- a/include/binderwrapper/binder_wrapper.h
+++ b/include/binderwrapper/binder_wrapper.h
@@ -30,6 +30,7 @@
 class IBinder;
 
 // Wraps libbinder to make it testable.
+// NOTE: Static methods of this class are not thread-safe.
 class BinderWrapper {
  public:
   virtual ~BinderWrapper() {}
@@ -50,6 +51,10 @@
   // InitForTesting().
   static BinderWrapper* Get();
 
+  // Returns the singleton instance if it was previously created by Create() or
+  // set by InitForTesting(), or creates a new one by calling Create().
+  static BinderWrapper* GetOrCreateInstance();
+
   // Gets the binder for communicating with the service identified by
   // |service_name|, returning null immediately if it doesn't exist.
   virtual sp<IBinder> GetService(const std::string& service_name) = 0;
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index bbe4486..9876e34 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -83,6 +83,10 @@
 #define AID_TLSDATE       1039  /* tlsdate unprivileged user */
 #define AID_MEDIA_EX      1040  /* mediaextractor process */
 #define AID_AUDIOSERVER   1041  /* audioserver process */
+#define AID_METRICS_COLL  1042  /* metrics_collector process */
+#define AID_METRICSD      1043  /* metricsd process */
+#define AID_WEBSERV       1044  /* webservd process */
+#define AID_DEBUGGERD     1045  /* debuggerd unprivileged user */
 
 #define AID_SHELL         2000  /* adb and debug shell user */
 #define AID_CACHE         2001  /* cache access */
@@ -184,6 +188,10 @@
     { "tlsdate",       AID_TLSDATE, },
     { "mediaex",       AID_MEDIA_EX, },
     { "audioserver",   AID_AUDIOSERVER, },
+    { "metrics_coll",  AID_METRICS_COLL },
+    { "metricsd",      AID_METRICSD },
+    { "webserv",       AID_WEBSERV },
+    { "debuggerd",     AID_DEBUGGERD, },
 
     { "shell",         AID_SHELL, },
     { "cache",         AID_CACHE, },
diff --git a/libbinderwrapper/binder_wrapper.cc b/libbinderwrapper/binder_wrapper.cc
index 0b5ff96..ca9c1df 100644
--- a/libbinderwrapper/binder_wrapper.cc
+++ b/libbinderwrapper/binder_wrapper.cc
@@ -50,4 +50,11 @@
   return instance_;
 }
 
+// static
+BinderWrapper* BinderWrapper::GetOrCreateInstance() {
+  if (!instance_)
+    instance_ = new RealBinderWrapper();
+  return instance_;
+}
+
 }  // namespace android
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 878feb8..ee883f0 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -71,6 +71,7 @@
         //       $(LOCAL_PATH)/event.logtags)
         // so make sure we do not regret hard-coding it as follows:
         "-DLIBLOG_LOG_TAG=1005",
+        "-DSNET_EVENT_LOG_TAG=1397638484",
     ],
     compile_multilib: "both",
     stl: "none",
diff --git a/liblog/Android.mk b/liblog/Android.mk
index 4ab5006..a183db8 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -22,7 +22,7 @@
 #       's/^\([0-9]*\)[ \t]*liblog[ \t].*/-DLIBLOG_LOG_TAG=\1/p' \
 #       $(LOCAL_PATH)/event.logtags)
 # so make sure we do not regret hard-coding it as follows:
-liblog_cflags := -DLIBLOG_LOG_TAG=1005 -DSNET_EVENT_LOG_TAG=1397638484
+liblog_cflags := -DLIBLOG_LOG_TAG=1005
 
 liblog_host_sources := logd_write.c log_event_write.c fake_log_device.c event.logtags
 liblog_target_sources := logd_write.c log_event_write.c event_tag_map.c log_time.cpp log_is_loggable.c
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index ec86e6b..5406c50 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -221,48 +221,50 @@
             return -EPERM;
         }
     } else if (log_id == LOG_ID_EVENTS) {
+        static atomic_uintptr_t map;
+        int ret;
+        const char *tag;
+        EventTagMap *m, *f;
+
         if (vec[0].iov_len < 4) {
             return -EINVAL;
         }
-        if (((uint32_t *)vec[0].iov_base)[0] != htole32(SNET_EVENT_LOG_TAG)) {
-            static atomic_uintptr_t map;
-            int ret;
-            const char *tag = NULL;
-            EventTagMap *m, *f = NULL;
 
-            m = (EventTagMap *)atomic_load(&map);
+        tag = NULL;
+        f = NULL;
+        m = (EventTagMap *)atomic_load(&map);
+
+        if (!m) {
+            ret = trylock();
+            m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */
             if (!m) {
-                ret = trylock();
-                m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */
-                if (!m) {
-                    m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
-                    if (ret) { /* trylock failed, local copy, mark for close */
-                        f = m;
-                    } else {
-                        if (!m) { /* One chance to open map file */
-                            m = (EventTagMap *)(uintptr_t)-1LL;
-                        }
-                        atomic_store(&map, (uintptr_t)m);
+                m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+                if (ret) { /* trylock failed, use local copy, mark for close */
+                    f = m;
+                } else {
+                    if (!m) { /* One chance to open map file */
+                        m = (EventTagMap *)(uintptr_t)-1LL;
                     }
-                }
-                if (!ret) { /* trylock succeeded, unlock */
-                    unlock();
+                    atomic_store(&map, (uintptr_t)m);
                 }
             }
-            if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
-                tag = android_lookupEventTag(
+            if (!ret) { /* trylock succeeded, unlock */
+                unlock();
+            }
+        }
+        if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
+            tag = android_lookupEventTag(
                                     m,
                                     htole32(((uint32_t *)vec[0].iov_base)[0]));
-            }
-            ret = __android_log_is_loggable(ANDROID_LOG_INFO,
-                                            tag,
-                                            ANDROID_LOG_VERBOSE);
-            if (f) { /* local copy marked for close */
-                android_closeEventTagMap(f);
-            }
-            if (!ret) {
-                return -EPERM;
-            }
+        }
+        ret = __android_log_is_loggable(ANDROID_LOG_INFO,
+                                        tag,
+                                        ANDROID_LOG_VERBOSE);
+        if (f) { /* local copy marked for close */
+            android_closeEventTagMap(f);
+        }
+        if (!ret) {
+            return -EPERM;
         }
     } else {
         /* Validate the incoming tag, tag content can not split across iovec */
diff --git a/logd/Android.mk b/logd/Android.mk
index d19c255..feca8d5 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -38,9 +38,7 @@
 #  event_flag := $(call event_logtags,auditd)
 #  event_flag += $(call event_logtags,logd)
 # so make sure we do not regret hard-coding it as follows:
-event_flag := -DAUDITD_LOG_TAG=1003 \
-              -DLOGD_LOG_TAG=1004 \
-              -DSNET_EVENT_LOG_TAG=1397638484
+event_flag := -DAUDITD_LOG_TAG=1003 -DLOGD_LOG_TAG=1004
 
 LOCAL_CFLAGS := -Werror $(event_flag)
 
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1b829c6..707527b 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -32,7 +32,7 @@
 #include "LogReader.h"
 
 // Default
-#define LOG_BUFFER_SIZE (256 * 1024) // Tuned on a per-platform basis here?
+#define LOG_BUFFER_SIZE (256 * 1024) // Tuned with ro.logd.size per-platform
 #define log_buffer_size(id) mMaxSize[id]
 #define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
 #define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
@@ -205,20 +205,16 @@
 
     LogBufferElement *elem = new LogBufferElement(log_id, realtime,
                                                   uid, pid, tid, msg, len);
-    if (log_id != LOG_ID_SECURITY) { // whitelist LOG_ID_SECURITY
+    if (log_id != LOG_ID_SECURITY) {
         int prio = ANDROID_LOG_INFO;
-        const char *tag = (const char *)-1;
+        const char *tag = NULL;
         if (log_id == LOG_ID_EVENTS) {
-            // whitelist "snet_event_log"
-            if (elem->getTag() != SNET_EVENT_LOG_TAG) {
-                tag = android::tagToName(elem->getTag());
-            }
+            tag = android::tagToName(elem->getTag());
         } else {
             prio = *msg;
             tag = msg + 1;
         }
-        if ((tag != (const char *)-1) &&
-                !__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
+        if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
             // Log traffic received to total
             pthread_mutex_lock(&mLogElementsLock);
             stats.add(elem);
diff --git a/logd/README.property b/logd/README.property
index 75d9eb0..22f86b9 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -15,7 +15,11 @@
 persist.logd.size          number  ro    Global default size of the buffer for
                                          all log ids at initial startup, at
                                          runtime use: logcat -b all -G <value>
-ro.logd.size               number svelte default for persist.logd.size
+ro.logd.size               number svelte default for persist.logd.size. Larger
+                                         platform default sizes than 256KB are
+                                         known to not scale well under log spam
+                                         pressure. Address the spam first,
+                                         resist increasing the log buffer.
 persist.logd.size.<buffer> number  ro    Size of the buffer for <buffer> log
 ro.logd.size.<buffer>      number svelte default for persist.logd.size.<buffer>
 ro.config.low_ram          bool   false  if true, logd.statistics, logd.kernel
diff --git a/metricsd/Android.mk b/metricsd/Android.mk
index 2149a4b..7381703 100644
--- a/metricsd/Android.mk
+++ b/metricsd/Android.mk
@@ -28,7 +28,7 @@
   collectors/cpu_usage_collector.cc \
   collectors/disk_usage_collector.cc \
   metrics_collector.cc \
-  metrics_collector_service_trampoline.cc \
+  metrics_collector_service_impl.cc \
   persistent_integer.cc
 
 metricsd_common := \
@@ -102,15 +102,14 @@
 # ==========================================================
 include $(CLEAR_VARS)
 LOCAL_MODULE := libmetricscollectorservice
+LOCAL_CLANG := true
 LOCAL_SHARED_LIBRARIES := libbinder libbrillo-binder libchrome libutils
 LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SRC_FILES := \
   aidl/android/brillo/metrics/IMetricsCollectorService.aidl \
-  metrics_collector_service_impl.cc \
   metrics_collector_service_client.cc
-LOCAL_RTTI_FLAG := -fno-rtti
 include $(BUILD_STATIC_LIBRARY)
 
 # Shared library for metrics.
@@ -122,7 +121,6 @@
 LOCAL_CLANG := true
 LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
 LOCAL_CPPFLAGS := $(metrics_CPPFLAGS)
-LOCAL_RTTI_FLAG := -frtti
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SHARED_LIBRARIES := $(libmetrics_shared_libraries)
 LOCAL_SRC_FILES := $(libmetrics_sources)
@@ -166,7 +164,6 @@
 LOCAL_CPPFLAGS := $(metrics_CPPFLAGS)
 LOCAL_INIT_RC := metrics_collector.rc
 LOCAL_REQUIRED_MODULES := metrics.json
-LOCAL_RTTI_FLAG := -frtti
 LOCAL_SHARED_LIBRARIES := $(metrics_collector_shared_libraries)
 LOCAL_SRC_FILES := $(metrics_collector_common) \
   metrics_collector_main.cc
@@ -213,7 +210,6 @@
 LOCAL_CLANG := true
 LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
 LOCAL_CPPFLAGS := $(metrics_CPPFLAGS) -Wno-sign-compare
-LOCAL_RTTI_FLAG := -frtti
 LOCAL_SHARED_LIBRARIES := $(metrics_collector_shared_libraries)
 LOCAL_SRC_FILES := $(metrics_collector_tests_sources) \
   $(metrics_collector_common)
diff --git a/metricsd/metrics_collector.cc b/metricsd/metrics_collector.cc
index a5daab5..97690dd 100644
--- a/metricsd/metrics_collector.cc
+++ b/metricsd/metrics_collector.cc
@@ -30,12 +30,13 @@
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
+#include <brillo/binder_watcher.h>
 #include <brillo/osrelease_reader.h>
 #include <dbus/dbus.h>
 #include <dbus/message.h>
 
 #include "constants.h"
-#include "metrics_collector_service_trampoline.h"
+#include "metrics_collector_service_impl.h"
 
 using base::FilePath;
 using base::StringPrintf;
@@ -128,10 +129,18 @@
     version_cumulative_cpu_use_->Set(0);
   }
 
-  // Start metricscollectorservice via trampoline
-  MetricsCollectorServiceTrampoline metricscollectorservice_trampoline(this);
-  metricscollectorservice_trampoline.Run();
+  // Start metricscollectorservice
+  android::sp<BnMetricsCollectorServiceImpl> metrics_collector_service =
+      new BnMetricsCollectorServiceImpl(this);
+  android::status_t status = android::defaultServiceManager()->addService(
+      metrics_collector_service->getInterfaceDescriptor(),
+      metrics_collector_service);
+  CHECK(status == android::OK)
+      << "failed to register service metricscollectorservice";
 
+  // Watch Binder events in the main loop
+  brillo::BinderWatcher binder_watcher;
+  CHECK(binder_watcher.Init()) << "Binder FD watcher init failed";
   return brillo::DBusDaemon::Run();
 }
 
diff --git a/metricsd/metrics_collector.rc b/metricsd/metrics_collector.rc
index 2e7e0ae..3dcb2d7 100644
--- a/metricsd/metrics_collector.rc
+++ b/metricsd/metrics_collector.rc
@@ -1,4 +1,4 @@
 service metricscollector /system/bin/metrics_collector --foreground --logtosyslog
     class late_start
-    user system
-    group system dbus
+    user metrics_coll
+    group metrics_coll dbus
diff --git a/metricsd/metrics_collector_service_impl.cc b/metricsd/metrics_collector_service_impl.cc
index dbb0578..4d9a05a 100644
--- a/metricsd/metrics_collector_service_impl.cc
+++ b/metricsd/metrics_collector_service_impl.cc
@@ -18,27 +18,18 @@
 
 #include <binder/IServiceManager.h>
 #include <binder/Status.h>
-#include <brillo/binder_watcher.h>
 #include <utils/Errors.h>
 
-#include "metrics_collector_service_trampoline.h"
+#include "metrics_collector.h"
 
 using namespace android;
 
 BnMetricsCollectorServiceImpl::BnMetricsCollectorServiceImpl(
-    MetricsCollectorServiceTrampoline* metrics_collector_service_trampoline) {
-  metrics_collector_service_trampoline_ = metrics_collector_service_trampoline;
-}
-
-void BnMetricsCollectorServiceImpl::Run() {
-  status_t status =
-      defaultServiceManager()->addService(getInterfaceDescriptor(), this);
-  CHECK(status == OK) << "libmetricscollectorservice: failed to add service";
-  binder_watcher_.reset(new ::brillo::BinderWatcher);
-  CHECK(binder_watcher_->Init()) << "Binder FD watcher init failed";
+    MetricsCollector* metrics_collector)
+    : metrics_collector_(metrics_collector) {
 }
 
 android::binder::Status BnMetricsCollectorServiceImpl::notifyUserCrash() {
-  metrics_collector_service_trampoline_->ProcessUserCrash();
+  metrics_collector_->ProcessUserCrash();
   return android::binder::Status::ok();
 }
diff --git a/metricsd/metrics_collector_service_impl.h b/metricsd/metrics_collector_service_impl.h
index bdcab50..8db418a 100644
--- a/metricsd/metrics_collector_service_impl.h
+++ b/metricsd/metrics_collector_service_impl.h
@@ -18,45 +18,31 @@
 #define METRICSD_METRICS_COLLECTOR_SERVICE_IMPL_H_
 
 // metrics_collector binder service implementation.  Constructed by
-// MetricsCollectorServiceTrampoline, which we use to call back into
-// MetricsCollector.  The trampoline isolates us from the -frtti code of
-// metrics_collector / libbrillo.
+// MetricsCollector.
 
 #include "android/brillo/metrics/BnMetricsCollectorService.h"
 
-#include <memory>
-
 #include <binder/Status.h>
-#include <brillo/binder_watcher.h>
 
-class MetricsCollectorServiceTrampoline;
-
-//#include "metrics_collector_service_trampoline.h"
+class MetricsCollector;
 
 class BnMetricsCollectorServiceImpl
     : public android::brillo::metrics::BnMetricsCollectorService {
  public:
-  // Passed a this pointer from the MetricsCollectorServiceTrampoline
-  // object that constructs us.
+  // Passed a this pointer from the MetricsCollector object that constructs us.
   explicit BnMetricsCollectorServiceImpl(
-      MetricsCollectorServiceTrampoline* metrics_collector_service_trampoline);
+      MetricsCollector* metrics_collector_service);
 
   virtual ~BnMetricsCollectorServiceImpl() = default;
 
-  // Starts the binder main loop.
-  void Run();
-
   // Called by crash_reporter to report a userspace crash event.  We relay
-  // this to MetricsCollector using the trampoline.
+  // this to MetricsCollector.
   android::binder::Status notifyUserCrash();
 
  private:
-  // Trampoline object that constructs us, we use this to call MetricsCollector
-  // methods via the trampoline.
-  MetricsCollectorServiceTrampoline* metrics_collector_service_trampoline_;
-
-  // BinderWatcher object we construct for handling Binder traffic
-  std::unique_ptr<brillo::BinderWatcher> binder_watcher_;
+  // MetricsCollector object that constructs us, we use this to call back
+  // to it.
+  MetricsCollector* metrics_collector_;
 };
 
 #endif  // METRICSD_METRICS_COLLECTOR_SERVICE_IMPL_H_
diff --git a/metricsd/metrics_collector_service_trampoline.cc b/metricsd/metrics_collector_service_trampoline.cc
deleted file mode 100644
index 12b80a1..0000000
--- a/metricsd/metrics_collector_service_trampoline.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 "metrics_collector_service_trampoline.h"
-#include "metrics_collector.h"
-#include "metrics_collector_service_impl.h"
-
-MetricsCollectorServiceTrampoline::MetricsCollectorServiceTrampoline(
-    MetricsCollector* metrics_collector) {
-  metrics_collector_ = metrics_collector;
-}
-
-void MetricsCollectorServiceTrampoline::Run() {
-  // Start metricscollectorservice binder service
-  metrics_collector_service.reset(new BnMetricsCollectorServiceImpl(this));
-  metrics_collector_service->Run();
-}
-
-void MetricsCollectorServiceTrampoline::ProcessUserCrash() {
-  metrics_collector_->ProcessUserCrash();
-}
diff --git a/metricsd/metrics_collector_service_trampoline.h b/metricsd/metrics_collector_service_trampoline.h
deleted file mode 100644
index 5da9fa5..0000000
--- a/metricsd/metrics_collector_service_trampoline.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 METRICSD_METRICS_COLLECTOR_SERVICE_TRAMPOLINE_H_
-#define METRICSD_METRICS_COLLECTOR_SERVICE_TRAMPOLINE_H_
-
-// Trampoline between the -fno-rtti compile of libmetricsservice and the
-// -frtti compile of metrics_collector.  MetricsCollectorServiceTrampoline
-// is called from MetricsCollector to run the IMetricsCollectorService
-// server, and acts as a go-between for calls from server back to
-// MetricsCollector.
-
-#include <memory>
-
-#include "metrics_collector_service_impl.h"
-
-// Forward declaration of MetricsCollector.  Don't include the header file
-// for the class here, as it pulls in -frtti stuff.
-class MetricsCollector;
-
-class MetricsCollectorServiceTrampoline {
- public:
-  // Constructor take a this pointer from the MetricsCollector class that
-  // constructs these objects.
-  explicit MetricsCollectorServiceTrampoline(
-      MetricsCollector* metrics_collector);
-
-  // Initialize and run the IMetricsCollectorService
-  void Run();
-
-  // Called from IMetricsCollectorService to trampoline into the
-  // MetricsCollector method of the same name.
-  void ProcessUserCrash();
-
- private:
-  // The MetricsCollector object that constructs us, for which we act as
-  // the go-between for MetricsCollectorServiceImpl use.
-  MetricsCollector* metrics_collector_;
-
-  // The IMetricsCollectorService implementation we construct.
-  std::unique_ptr<BnMetricsCollectorServiceImpl> metrics_collector_service;
-};
-
-#endif  // METRICSD_METRICS_COLLECTOR_SERVICE_TRAMPOLINE_H_
diff --git a/metricsd/metricsd.rc b/metricsd/metricsd.rc
index 359d0d1..825c87f 100644
--- a/metricsd/metricsd.rc
+++ b/metricsd/metricsd.rc
@@ -1,9 +1,9 @@
 on post-fs-data
-    mkdir /data/misc/metrics 0770 system system
-    mkdir /data/misc/metricsd 0700 system system
-    mkdir /data/misc/metrics_collector 0700 system system
+    mkdir /data/misc/metrics 0750 metrics_coll system
+    mkdir /data/misc/metricsd 0700 metricsd metricsd
+    mkdir /data/misc/metrics_collector 0700 metrics_coll metrics_coll
 
 service metricsd /system/bin/metricsd --foreground --logtosyslog
     class late_start
-    user system
+    user metricsd
     group system dbus inet