merge in master-release history after reset to bb8e90e87e9dd89a47a659e0e4a669177d750d52
diff --git a/adf/libadf/adf.c b/adf/libadf/adf.c
index 871629e..1d19152 100644
--- a/adf/libadf/adf.c
+++ b/adf/libadf/adf.c
@@ -768,7 +768,7 @@
         const __u32 *formats, size_t n_formats,
         adf_id_t *interface, adf_id_t *overlay_engine)
 {
-    adf_id_t *intfs;
+    adf_id_t *intfs = NULL;
     ssize_t n_intfs = adf_interfaces(dev, &intfs);
 
     if (n_intfs < 0)
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index 01ce0be..4721da9 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -144,6 +144,9 @@
         close(pipe_fds[0]);
         write(pipe_fds[1], "oops", 4);
         return EXIT_SUCCESS;
+    } else if (!strcmp(arg, "SIGTRAP")) {
+        raise(SIGTRAP);
+        return EXIT_SUCCESS;
     } else if (!strcmp(arg, "heap-usage")) {
         abuse_heap();
     }
@@ -164,6 +167,7 @@
     fprintf(stderr, "  LOG_ALWAYS_FATAL_IF   call LOG_ALWAYS_FATAL\n");
     fprintf(stderr, "  SIGPIPE               cause a SIGPIPE\n");
     fprintf(stderr, "  SIGSEGV               cause a SIGSEGV (synonym: crash)\n");
+    fprintf(stderr, "  SIGTRAP               cause a SIGTRAP\n");
     fprintf(stderr, "prefix any of the above with 'thread-' to not run\n");
     fprintf(stderr, "on the process' main thread.\n");
     return EXIT_SUCCESS;
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 76bd7a3..3726c38 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -54,97 +54,56 @@
   int32_t original_si_code;
 };
 
-static int write_string(const char* file, const char* string) {
-  int len;
-  int fd;
-  ssize_t amt;
-  fd = open(file, O_RDWR);
-  len = strlen(string);
-  if (fd < 0)
-    return -errno;
-  amt = write(fd, string, len);
-  close(fd);
-  return amt >= 0 ? 0 : -errno;
-}
-
-static void init_debug_led() {
-  // trout leds
-  write_string("/sys/class/leds/red/brightness", "0");
-  write_string("/sys/class/leds/green/brightness", "0");
-  write_string("/sys/class/leds/blue/brightness", "0");
-  write_string("/sys/class/leds/red/device/blink", "0");
-  // sardine leds
-  write_string("/sys/class/leds/left/cadence", "0,0");
-}
-
-static void enable_debug_led() {
-  // trout leds
-  write_string("/sys/class/leds/red/brightness", "255");
-  // sardine leds
-  write_string("/sys/class/leds/left/cadence", "1,0");
-}
-
-static void disable_debug_led() {
-  // trout leds
-  write_string("/sys/class/leds/red/brightness", "0");
-  // sardine leds
-  write_string("/sys/class/leds/left/cadence", "0,0");
-}
-
 static void wait_for_user_action(pid_t pid) {
-  // First log a helpful message
+  // Find out the name of the process that crashed.
+  char path[64];
+  snprintf(path, sizeof(path), "/proc/%d/exe", pid);
+
+  char exe[PATH_MAX];
+  int count;
+  if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) {
+    LOG("readlink('%s') failed: %s", path, strerror(errno));
+    strlcpy(exe, "unknown", sizeof(exe));
+  } else {
+    exe[count] = '\0';
+  }
+
+  // Turn "/system/bin/app_process" into "app_process".
+  // gdbserver doesn't cope with full paths (though we should fix that
+  // and remove this).
+  char* name = strrchr(exe, '/');
+  if (name == NULL) {
+    name = exe; // No '/' found.
+  } else {
+    ++name; // Skip the '/'.
+  }
+
+  // Explain how to attach the debugger.
   LOG(    "********************************************************\n"
-          "* Process %d has been suspended while crashing.  To\n"
-          "* attach gdbserver for a gdb connection on port 5039\n"
+          "* Process %d has been suspended while crashing.\n"
+          "* To attach gdbserver for a gdb connection on port 5039\n"
           "* and start gdbclient:\n"
           "*\n"
-          "*     gdbclient app_process :5039 %d\n"
+          "*     gdbclient %s :5039 %d\n"
           "*\n"
-          "* Wait for gdb to start, then press HOME or VOLUME DOWN key\n"
+          "* Wait for gdb to start, then press the VOLUME DOWN key\n"
           "* to let the process continue crashing.\n"
           "********************************************************\n",
-          pid, pid);
+          pid, name, pid);
 
-  // wait for HOME or VOLUME DOWN key
+  // Wait for VOLUME DOWN.
   if (init_getevent() == 0) {
-    int ms = 1200 / 10;
-    int dit = 1;
-    int dah = 3*dit;
-    int _       = -dit;
-    int ___     = 3*_;
-    int _______ = 7*_;
-    const int codes[] = {
-      dit,_,dit,_,dit,___,dah,_,dah,_,dah,___,dit,_,dit,_,dit,_______
-    };
-    size_t s = 0;
-    input_event e;
-    bool done = false;
-    init_debug_led();
-    enable_debug_led();
-    do {
-      int timeout = abs(codes[s]) * ms;
-      int res = get_event(&e, timeout);
-      if (res == 0) {
-        if (e.type == EV_KEY
-            && (e.code == KEY_HOME || e.code == KEY_VOLUMEDOWN)
-            && e.value == 0) {
-          done = true;
-        }
-      } else if (res == 1) {
-        if (++s >= sizeof(codes)/sizeof(*codes))
-          s = 0;
-        if (codes[s] > 0) {
-          enable_debug_led();
-        } else {
-          disable_debug_led();
+    while (true) {
+      input_event e;
+      if (get_event(&e, -1) == 0) {
+        if (e.type == EV_KEY && e.code == KEY_VOLUMEDOWN && e.value == 0) {
+          break;
         }
       }
-    } while (!done);
+    }
     uninit_getevent();
   }
 
-  // don't forget to turn debug led off
-  disable_debug_led();
   LOG("debuggerd resuming process %d", pid);
 }
 
@@ -322,15 +281,16 @@
               }
               break;
 
-            case SIGILL:
             case SIGABRT:
             case SIGBUS:
             case SIGFPE:
-            case SIGSEGV:
+            case SIGILL:
             case SIGPIPE:
+            case SIGSEGV:
 #ifdef SIGSTKFLT
             case SIGSTKFLT:
 #endif
+            case SIGTRAP:
               XLOG("stopped -- fatal signal\n");
               // Send a SIGSTOP to the process to make all of
               // the non-signaled threads stop moving.  Without
@@ -406,38 +366,36 @@
 }
 
 static int do_server() {
-  int s;
-  struct sigaction act;
-  int logsocket = -1;
-
-  // debuggerd crashes can't be reported to debuggerd.  Reset all of the
-  // crash handlers.
-  signal(SIGILL, SIG_DFL);
+  // debuggerd crashes can't be reported to debuggerd.
+  // Reset all of the crash handlers.
   signal(SIGABRT, SIG_DFL);
   signal(SIGBUS, SIG_DFL);
   signal(SIGFPE, SIG_DFL);
+  signal(SIGILL, SIG_DFL);
   signal(SIGSEGV, SIG_DFL);
 #ifdef SIGSTKFLT
   signal(SIGSTKFLT, SIG_DFL);
 #endif
+  signal(SIGTRAP, SIG_DFL);
 
   // Ignore failed writes to closed sockets
   signal(SIGPIPE, SIG_IGN);
 
-  logsocket = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
+  int logsocket = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
   if (logsocket < 0) {
     logsocket = -1;
   } else {
     fcntl(logsocket, F_SETFD, FD_CLOEXEC);
   }
 
+  struct sigaction act;
   act.sa_handler = SIG_DFL;
   sigemptyset(&act.sa_mask);
   sigaddset(&act.sa_mask,SIGCHLD);
   act.sa_flags = SA_NOCLDWAIT;
   sigaction(SIGCHLD, &act, 0);
 
-  s = socket_local_server(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+  int s = socket_local_server(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
   if (s < 0)
     return 1;
   fcntl(s, F_SETFD, FD_CLOEXEC);
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 749752b..01845d9 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -31,9 +31,10 @@
 
 #include <private/android_filesystem_config.h>
 
+#include <cutils/properties.h>
 #include <log/log.h>
 #include <log/logger.h>
-#include <cutils/properties.h>
+#include <log/logprint.h>
 
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
@@ -57,10 +58,10 @@
 
 static bool signal_has_si_addr(int sig) {
   switch (sig) {
-    case SIGILL:
-    case SIGFPE:
-    case SIGSEGV:
     case SIGBUS:
+    case SIGFPE:
+    case SIGILL:
+    case SIGSEGV:
       return true;
     default:
       return false;
@@ -69,16 +70,17 @@
 
 static const char* get_signame(int sig) {
   switch(sig) {
-    case SIGILL: return "SIGILL";
     case SIGABRT: return "SIGABRT";
     case SIGBUS: return "SIGBUS";
     case SIGFPE: return "SIGFPE";
-    case SIGSEGV: return "SIGSEGV";
+    case SIGILL: return "SIGILL";
     case SIGPIPE: return "SIGPIPE";
+    case SIGSEGV: return "SIGSEGV";
 #if defined(SIGSTKFLT)
     case SIGSTKFLT: return "SIGSTKFLT";
 #endif
     case SIGSTOP: return "SIGSTOP";
+    case SIGTRAP: return "SIGTRAP";
     default: return "?";
   }
 }
@@ -459,6 +461,8 @@
 // that don't match the specified pid, and writes them to the tombstone file.
 //
 // If "tail" is non-zero, log the last "tail" number of lines.
+static EventTagMap* g_eventTagMap = NULL;
+
 static void dump_log_file(
     log_t* log, pid_t pid, const char* filename, unsigned int tail) {
   bool first = true;
@@ -517,6 +521,27 @@
       hdr_size = sizeof(log_entry.entry_v1);
     }
     char* msg = reinterpret_cast<char*>(log_entry.buf) + hdr_size;
+
+    char timeBuf[32];
+    time_t sec = static_cast<time_t>(entry->sec);
+    struct tm tmBuf;
+    struct tm* ptm;
+    ptm = localtime_r(&sec, &tmBuf);
+    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
+
+    if (log_entry.id() == LOG_ID_EVENTS) {
+      if (!g_eventTagMap) {
+        g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+      }
+      AndroidLogEntry e;
+      char buf[512];
+      android_log_processBinaryLogBuffer(entry, &e, g_eventTagMap, buf, sizeof(buf));
+      _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n",
+         timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
+         'I', e.tag, e.message);
+      continue;
+    }
+
     unsigned char prio = msg[0];
     char* tag = msg + 1;
     msg = tag + strlen(tag) + 1;
@@ -529,13 +554,6 @@
 
     char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?');
 
-    char timeBuf[32];
-    time_t sec = static_cast<time_t>(entry->sec);
-    struct tm tmBuf;
-    struct tm* ptm;
-    ptm = localtime_r(&sec, &tmBuf);
-    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
-
     // Look for line breaks ('\n') and display each text line
     // on a separate line, prefixed with the header, like logcat does.
     do {
@@ -559,6 +577,7 @@
 static void dump_logs(log_t* log, pid_t pid, unsigned int tail) {
   dump_log_file(log, pid, "system", tail);
   dump_log_file(log, pid, "main", tail);
+  dump_log_file(log, pid, "events", tail);
 }
 
 static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) {
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 3a140ab..9c04c21 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -32,6 +32,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -576,7 +577,7 @@
     if (!status) {
         limit = strtoul(response, NULL, 0);
         if (limit > 0) {
-            fprintf(stderr, "target reported max download size of %lld bytes\n",
+            fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n",
                     limit);
         }
     }
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 715c2ed..1d238b1 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -7,6 +7,7 @@
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := healthd_board_default.cpp
 LOCAL_MODULE := libhealthd.default
+LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -24,7 +25,7 @@
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
 
-LOCAL_CFLAGS := -D__STDC_LIMIT_MACROS
+LOCAL_CFLAGS := -D__STDC_LIMIT_MACROS -Werror
 
 ifeq ($(strip $(BOARD_CHARGER_DISABLE_INIT_BLANK)),true)
 LOCAL_CFLAGS += -DCHARGER_DISABLE_INIT_BLANK
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 9368225..ac649ce 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -37,7 +37,7 @@
 namespace android {
 
 struct sysfsStringEnumMap {
-    char* s;
+    const char* s;
     int val;
 };
 
@@ -271,10 +271,12 @@
 status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
     status_t ret = BAD_VALUE;
 
+    val->valueInt64 = LONG_MIN;
+
     switch(id) {
     case BATTERY_PROP_CHARGE_COUNTER:
         if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
-            val->valueInt =
+            val->valueInt64 =
                 getIntField(mHealthdConfig->batteryChargeCounterPath);
             ret = NO_ERROR;
         } else {
@@ -284,7 +286,7 @@
 
     case BATTERY_PROP_CURRENT_NOW:
         if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
-            val->valueInt =
+            val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCurrentNowPath);
             ret = NO_ERROR;
         } else {
@@ -294,7 +296,7 @@
 
     case BATTERY_PROP_CURRENT_AVG:
         if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
-            val->valueInt =
+            val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
             ret = NO_ERROR;
         } else {
@@ -304,7 +306,7 @@
 
     case BATTERY_PROP_CAPACITY:
         if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
-            val->valueInt =
+            val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCapacityPath);
             ret = NO_ERROR;
         } else {
@@ -312,13 +314,14 @@
         }
         break;
 
+    case BATTERY_PROP_ENERGY_COUNTER:
+        ret = NAME_NOT_FOUND;
+        break;
+
     default:
         break;
     }
 
-    if (ret != NO_ERROR)
-        val->valueInt = INT_MIN;
-
     return ret;
 }
 
diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp
index 272b6d7..74bcbfd 100644
--- a/healthd/BatteryPropertiesRegistrar.cpp
+++ b/healthd/BatteryPropertiesRegistrar.cpp
@@ -76,7 +76,7 @@
     return healthd_get_property(id, val);
 }
 
-status_t BatteryPropertiesRegistrar::dump(int fd, const Vector<String16>& args) {
+status_t BatteryPropertiesRegistrar::dump(int fd, const Vector<String16>& /*args*/) {
     IPCThreadState* self = IPCThreadState::self();
     const int pid = self->getCallingPid();
     const int uid = self->getCallingUid();
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 8363c41..5fe2965 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -118,7 +118,7 @@
     .battery_update = healthd_mode_nop_battery_update,
 };
 
-static void healthd_mode_nop_init(struct healthd_config *config) {
+static void healthd_mode_nop_init(struct healthd_config* /*config*/) {
 }
 
 static int healthd_mode_nop_preparetowait(void) {
@@ -129,7 +129,7 @@
 }
 
 static void healthd_mode_nop_battery_update(
-    struct android::BatteryProperties *props) {
+    struct android::BatteryProperties* /*props*/) {
 }
 
 int healthd_register_event(int fd, void (*handler)(uint32_t)) {
@@ -205,7 +205,7 @@
 }
 
 #define UEVENT_MSG_LEN 1024
-static void uevent_event(uint32_t epevents) {
+static void uevent_event(uint32_t /*epevents*/) {
     char msg[UEVENT_MSG_LEN+2];
     char *cp;
     int n;
@@ -246,7 +246,7 @@
                    "register for uevent events failed\n");
 }
 
-static void wakealarm_event(uint32_t epevents) {
+static void wakealarm_event(uint32_t /*epevents*/) {
     unsigned long long wakeups;
 
     if (read(wakealarm_fd, &wakeups, sizeof(wakeups)) == -1) {
diff --git a/healthd/healthd_mode_android.cpp b/healthd/healthd_mode_android.cpp
index 4887c8c..fd153a2 100644
--- a/healthd/healthd_mode_android.cpp
+++ b/healthd/healthd_mode_android.cpp
@@ -42,11 +42,11 @@
     return -1;
 }
 
-static void binder_event(uint32_t epevents) {
+static void binder_event(uint32_t /*epevents*/) {
     IPCThreadState::self()->handlePolledCommands();
 }
 
-void healthd_mode_android_init(struct healthd_config *config) {
+void healthd_mode_android_init(struct healthd_config* /*config*/) {
     ProcessState::self()->setThreadPoolMaxThreadCount(0);
     IPCThreadState::self()->disableBackgroundScheduling(true);
     IPCThreadState::self()->setupPolling(&gBinderFd);
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 710f5b6..cfac312 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -17,6 +17,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <linux/input.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -249,7 +250,7 @@
         return autosuspend_disable();
 }
 #else
-static int request_suspend(bool enable)
+static int request_suspend(bool /*enable*/)
 {
     return 0;
 }
@@ -274,7 +275,7 @@
 }
 
 /* returns the last y-offset of where the surface ends */
-static int draw_surface_centered(struct charger *charger, gr_surface surface)
+static int draw_surface_centered(struct charger* /*charger*/, gr_surface surface)
 {
     int w;
     int h;
@@ -356,7 +357,7 @@
         reset_animation(batt_anim);
         charger->next_screen_transition = -1;
         gr_fb_blank(true);
-        LOGV("[%lld] animation done\n", now);
+        LOGV("[%" PRId64 "] animation done\n", now);
         if (!charger->charger_connected)
             request_suspend(true);
         return;
@@ -369,7 +370,7 @@
         int batt_cap;
         int ret;
 
-        LOGV("[%lld] animation starting\n", now);
+        LOGV("[%" PRId64 "] animation starting\n", now);
         batt_cap = get_battery_capacity();
         if (batt_cap >= 0 && batt_anim->num_frames != 0) {
             int i;
@@ -399,7 +400,7 @@
      * the cycle counter and exit
      */
     if (batt_anim->num_frames == 0 || batt_anim->capacity < 0) {
-        LOGV("[%lld] animation missing or unknown battery status\n", now);
+        LOGV("[%" PRId64 "] animation missing or unknown battery status\n", now);
         charger->next_screen_transition = now + BATTERY_UNKNOWN_TIME;
         batt_anim->cur_cycle++;
         return;
@@ -449,13 +450,13 @@
     charger->keys[code].down = down;
     charger->keys[code].pending = true;
     if (down) {
-        LOGV("[%lld] key[%d] down\n", now, code);
+        LOGV("[%" PRId64 "] key[%d] down\n", now, code);
     } else {
         int64_t duration = now - charger->keys[code].timestamp;
         int64_t secs = duration / 1000;
         int64_t msecs = duration - secs * 1000;
-        LOGV("[%lld] key[%d] up (was down for %lld.%lldsec)\n", now,
-            code, secs, msecs);
+        LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n",
+             now, code, secs, msecs);
     }
 
     return 0;
@@ -488,7 +489,7 @@
         if (key->down) {
             int64_t reboot_timeout = key->timestamp + POWER_ON_KEY_TIME;
             if (now >= reboot_timeout) {
-                LOGI("[%lld] rebooting\n", now);
+                LOGI("[%" PRId64 "] rebooting\n", now);
                 android_reboot(ANDROID_RB_RESTART, 0, 0);
             } else {
                 /* if the key is pressed but timeout hasn't expired,
@@ -525,10 +526,10 @@
         request_suspend(false);
         if (charger->next_pwr_check == -1) {
             charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME;
-            LOGI("[%lld] device unplugged: shutting down in %lld (@ %lld)\n",
-                 now, UNPLUGGED_SHUTDOWN_TIME, charger->next_pwr_check);
+            LOGI("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n",
+                 now, (int64_t)UNPLUGGED_SHUTDOWN_TIME, charger->next_pwr_check);
         } else if (now >= charger->next_pwr_check) {
-            LOGI("[%lld] shutting down\n", now);
+            LOGI("[%" PRId64 "] shutting down\n", now);
             android_reboot(ANDROID_RB_POWEROFF, 0, 0);
         } else {
             /* otherwise we already have a shutdown timer scheduled */
@@ -536,7 +537,7 @@
     } else {
         /* online supply present, reset shutdown timer if set */
         if (charger->next_pwr_check != -1) {
-            LOGI("[%lld] device plugged in: shutdown cancelled\n", now);
+            LOGI("[%" PRId64 "] device plugged in: shutdown cancelled\n", now);
             kick_animation(charger->batt_anim);
         }
         charger->next_pwr_check = -1;
@@ -585,7 +586,7 @@
     struct input_event ev;
     int ret;
 
-    LOGV("[%lld] next screen: %lld next key: %lld next pwr: %lld\n", now,
+    LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", now,
          charger->next_screen_transition, charger->next_key_check,
          charger->next_pwr_check);
 
@@ -617,7 +618,7 @@
     return 0;
 }
 
-static void charger_event_handler(uint32_t epevents)
+static void charger_event_handler(uint32_t /*epevents*/)
 {
     int ret;
 
@@ -626,7 +627,7 @@
         ev_dispatch();
 }
 
-void healthd_mode_charger_init(struct healthd_config *config)
+void healthd_mode_charger_init(struct healthd_config* /*config*/)
 {
     int ret;
     struct charger *charger = &charger_state;
diff --git a/include/system/audio.h b/include/system/audio.h
index 1b7d81a..2bc35c6 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -590,6 +590,22 @@
         return false;
 }
 
+/* Returns the number of channels from an input channel mask,
+ * used in the context of audio input or recording.
+ */
+static inline uint32_t audio_channel_count_from_in_mask(audio_channel_mask_t channel)
+{
+    return popcount(channel & AUDIO_CHANNEL_IN_ALL);
+}
+
+/* Returns the number of channels from an output channel mask,
+ * used in the context of audio output or playback.
+ */
+static inline uint32_t audio_channel_count_from_out_mask(audio_channel_mask_t channel)
+{
+    return popcount(channel & AUDIO_CHANNEL_OUT_ALL);
+}
+
 /* Derive an output channel mask from a channel count.
  * This is to be used when the content channel mask is unknown. The 1, 2, 4, 5, 6, 7 and 8 channel
  * cases are mapped to the standard game/home-theater layouts, but note that 4 is mapped to quad,
diff --git a/init/init_parser.c b/init/init_parser.c
index 02e5bdc..7800082 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -760,7 +760,7 @@
         break;
     case K_setenv: { /* name value */
         struct svcenvinfo *ei;
-        if (nargs < 2) {
+        if (nargs < 3) {
             parse_error(state, "setenv option requires name and value arguments\n");
             break;
         }
diff --git a/init/property_service.c b/init/property_service.c
index 8247ef4..b25f998 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -91,6 +91,7 @@
     { "log.",             AID_SHELL,    0 },
     { "service.adb.root", AID_SHELL,    0 },
     { "service.adb.tcp.port", AID_SHELL,    0 },
+    { "persist.logd.size",AID_SYSTEM,   0 },
     { "persist.sys.",     AID_SYSTEM,   0 },
     { "persist.service.", AID_SYSTEM,   0 },
     { "persist.security.", AID_SYSTEM,   0 },
diff --git a/libdiskconfig/config_mbr.c b/libdiskconfig/config_mbr.c
index 7641b29..7b6ca1c 100644
--- a/libdiskconfig/config_mbr.c
+++ b/libdiskconfig/config_mbr.c
@@ -208,6 +208,26 @@
 }
 
 
+static struct write_list *
+mk_mbr_sig()
+{
+    struct write_list *item;
+    if (!(item = alloc_wl(sizeof(uint16_t)))) {
+        ALOGE("Unable to allocate memory for MBR signature.");
+        return NULL;
+    }
+
+    {
+        /* DO NOT DEREFERENCE */
+        struct pc_boot_record *mbr = (void *)PC_MBR_DISK_OFFSET;
+        /* grab the offset in mbr where to write mbr signature. */
+        item->offset = (loff_t)((uintptr_t)((uint8_t *)(&mbr->mbr_sig)));
+    }
+
+    *((uint16_t*)item->data) = PC_BIOS_BOOT_SIG;
+    return item;
+}
+
 struct write_list *
 config_mbr(struct disk_info *dinfo)
 {
@@ -276,6 +296,13 @@
         wlist_add(&wr_list, temp_wr);
     }
 
+    if ((temp_wr = mk_mbr_sig()))
+        wlist_add(&wr_list, temp_wr);
+    else {
+        ALOGE("Cannot set MBR signature");
+        goto fail;
+    }
+
     return wr_list;
 
 nospace:
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 3082216..2eb9318 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -209,7 +209,8 @@
                       sizeof(kATxtContents)));
 
   // Assert that the total length of the file is sane
-  ASSERT_EQ(data_size + sizeof(kATxtContents), lseek64(fd, 0, SEEK_END));
+  ASSERT_EQ(data_size + static_cast<ssize_t>(sizeof(kATxtContents)),
+            lseek64(fd, 0, SEEK_END));
 
   close(fd);
 }
@@ -247,4 +248,3 @@
 
   return RUN_ALL_TESTS();
 }
-
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index db4fddd..ed2c241 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -623,20 +623,21 @@
     }
 
     if (!devices) {
-        devices = new log_device_t("main", false, 'm');
+        dev = devices = new log_device_t("main", false, 'm');
         android::g_devCount = 1;
         if (android_name_to_log_id("system") == LOG_ID_SYSTEM) {
-            devices->next = new log_device_t("system", false, 's');
+            dev = dev->next = new log_device_t("system", false, 's');
             android::g_devCount++;
         }
         if (android_name_to_log_id("crash") == LOG_ID_CRASH) {
-            if (devices->next) {
-                devices->next->next = new log_device_t("crash", false, 'c');
-            } else {
-                devices->next = new log_device_t("crash", false, 'c');
-            }
+            dev = dev->next = new log_device_t("crash", false, 'c');
             android::g_devCount++;
         }
+        if (android_name_to_log_id("events") == LOG_ID_EVENTS) {
+            dev = dev->next = new log_device_t("events", true, 'e');
+            android::g_devCount++;
+            needBinary = true;
+        }
     }
 
     if (android::g_logRotateSizeKBytes != 0
diff --git a/logd/Android.mk b/logd/Android.mk
index 9f4c64f..188511f 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -17,7 +17,8 @@
     LogStatistics.cpp \
     LogWhiteBlackList.cpp \
     libaudit.c \
-    LogAudit.cpp
+    LogAudit.cpp \
+    event.logtags
 
 LOCAL_SHARED_LIBRARIES := \
     libsysutils \
@@ -25,7 +26,7 @@
     libcutils \
     libutils
 
-LOCAL_CFLAGS := -Werror
+LOCAL_CFLAGS := -Werror $(shell sed -n 's/^\([0-9]*\)[ \t]*auditd[ \t].*/-DAUDITD_LOG_TAG=\1/p' $(LOCAL_PATH)/event.logtags)
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index add0f0e..0651a92 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -54,9 +54,6 @@
     return true;
 }
 
-#define AUDIT_LOG_ID   LOG_ID_MAIN
-#define AUDIT_LOG_PRIO ANDROID_LOG_WARN
-
 int LogAudit::logPrint(const char *fmt, ...) {
     if (fmt == NULL) {
         return -EINVAL;
@@ -115,43 +112,30 @@
         strcpy(pidptr, cp);
     }
 
-    static const char comm_str[] = " comm=\"";
-    char *comm = strstr(str, comm_str);
-    if (comm) {
-        cp = comm;
-        comm += sizeof(comm_str) - 1;
-        char *ecomm = strchr(comm, '"');
-        if (ecomm) {
-            *ecomm = '\0';
-        }
-        comm = strdup(comm);
-        if (ecomm) {
-            strcpy(cp, ecomm + 1);
-        }
-    } else if (pid == getpid()) {
-        pid = tid;
-        comm = strdup("auditd");
-    } else if (!(comm = logbuf->pidToName(pid))) {
-        comm = strdup("unknown");
-    }
-
-    size_t l = strlen(comm) + 1;
-    size_t n = l + strlen(str) + 2;
+    size_t n = strlen(str);
+    n += sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
 
     char *newstr = reinterpret_cast<char *>(malloc(n));
     if (!newstr) {
-        free(comm);
         free(str);
         return -ENOMEM;
     }
 
-    *newstr = AUDIT_LOG_PRIO;
-    strcpy(newstr + 1, comm);
-    free(comm);
-    strcpy(newstr + 1 + l, str);
+    char *msg = newstr;
+    *msg++ = AUDITD_LOG_TAG & 0xFF;
+    *msg++ = (AUDITD_LOG_TAG >> 8) & 0xFF;
+    *msg++ = (AUDITD_LOG_TAG >> 16) & 0xFF;
+    *msg++ = (AUDITD_LOG_TAG >> 24) & 0xFF;
+    *msg++ = EVENT_TYPE_STRING;
+    size_t l = n - sizeof(uint32_t) - sizeof(uint8_t) - sizeof(uint32_t);
+    *msg++ = l & 0xFF;
+    *msg++ = (l >> 8) & 0xFF;
+    *msg++ = (l >> 16) & 0xFF;
+    *msg++ = (l >> 24) & 0xFF;
+    memcpy(msg, str, l);
     free(str);
 
-    logbuf->log(AUDIT_LOG_ID, now, uid, pid, tid, newstr,
+    logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, newstr,
                 (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
     reader->notifyNewLog();
 
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index dc9d47e..ae167aa 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/user.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -32,6 +33,34 @@
 // Default
 #define LOG_BUFFER_SIZE (256 * 1024) // Tuned on a per-platform basis here?
 #define log_buffer_size(id) mMaxSize[id]
+#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
+#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
+
+static bool valid_size(unsigned long value) {
+    if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) {
+        return false;
+    }
+
+    long pages = sysconf(_SC_PHYS_PAGES);
+    if (pages < 1) {
+        return true;
+    }
+
+    long pagesize = sysconf(_SC_PAGESIZE);
+    if (pagesize <= 1) {
+        pagesize = PAGE_SIZE;
+    }
+
+    // maximum memory impact a somewhat arbitrary ~3%
+    pages = (pages + 31) / 32;
+    unsigned long maximum = pages * pagesize;
+
+    if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) {
+        return true;
+    }
+
+    return value <= maximum;
+}
 
 static unsigned long property_get_size(const char *key) {
     char property[PROPERTY_VALUE_MAX];
@@ -56,6 +85,10 @@
         value = 0;
     }
 
+    if (!valid_size(value)) {
+        value = 0;
+    }
+
     return value;
 }
 
@@ -64,18 +97,38 @@
     pthread_mutex_init(&mLogElementsLock, NULL);
     dgram_qlen_statistics = false;
 
-    static const char global_default[] = "persist.logd.size";
-    unsigned long default_size = property_get_size(global_default);
+    static const char global_tuneable[] = "persist.logd.size"; // Settings App
+    static const char global_default[] = "ro.logd.size";       // BoardConfig.mk
+
+    unsigned long default_size = property_get_size(global_tuneable);
+    if (!default_size) {
+        default_size = property_get_size(global_default);
+    }
 
     log_id_for_each(i) {
-        setSize(i, LOG_BUFFER_SIZE);
-        setSize(i, default_size);
-
         char key[PROP_NAME_MAX];
-        snprintf(key, sizeof(key), "%s.%s",
-                 global_default, android_log_id_to_name(i));
 
-        setSize(i, property_get_size(key));
+        snprintf(key, sizeof(key), "%s.%s",
+                 global_tuneable, android_log_id_to_name(i));
+        unsigned long property_size = property_get_size(key);
+
+        if (!property_size) {
+            snprintf(key, sizeof(key), "%s.%s",
+                     global_default, android_log_id_to_name(i));
+            property_size = property_get_size(key);
+        }
+
+        if (!property_size) {
+            property_size = default_size;
+        }
+
+        if (!property_size) {
+            property_size = LOG_BUFFER_SIZE;
+        }
+
+        if (setSize(i, property_size)) {
+            setSize(i, LOG_BUFFER_MIN_SIZE);
+        }
     }
 }
 
@@ -339,7 +392,7 @@
 // set the total space allocated to "id"
 int LogBuffer::setSize(log_id_t id, unsigned long size) {
     // Reasonable limits ...
-    if ((size < (64 * 1024)) || ((256 * 1024 * 1024) < size)) {
+    if (!valid_size(size)) {
         return -1;
     }
     pthread_mutex_lock(&mLogElementsLock);
diff --git a/logd/LogCommand.cpp b/logd/LogCommand.cpp
index 0873e63..e4c138e 100644
--- a/logd/LogCommand.cpp
+++ b/logd/LogCommand.cpp
@@ -64,7 +64,7 @@
     }
 
     gid_t gid = cli->getGid();
-    if ((gid == AID_ROOT) || (gid == AID_LOG)) {
+    if ((gid == AID_ROOT) || (gid == AID_SYSTEM) || (gid == AID_LOG)) {
         return true;
     }
 
diff --git a/logd/event.logtags b/logd/event.logtags
new file mode 100644
index 0000000..a63f034
--- /dev/null
+++ b/logd/event.logtags
@@ -0,0 +1,36 @@
+# The entries in this file map a sparse set of log tag numbers to tag names.
+# This is installed on the device, in /system/etc, and parsed by logcat.
+#
+# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
+# negative values alone for now.)
+#
+# Tag names are one or more ASCII letters and numbers or underscores, i.e.
+# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
+# impacts log readability, the latter makes regex searches more annoying).
+#
+# Tag numbers and names are separated by whitespace.  Blank lines and lines
+# starting with '#' are ignored.
+#
+# Optionally, after the tag names can be put a description for the value(s)
+# of the tag. Description are in the format
+#    (<name>|data type[|data unit])
+# Multiple values are separated by commas.
+#
+# The data type is a number from the following values:
+# 1: int
+# 2: long
+# 3: string
+# 4: list
+#
+# The data unit is a number taken from the following list:
+# 1: Number of objects
+# 2: Number of bytes
+# 3: Number of milliseconds
+# 4: Number of allocations
+# 5: Id
+# 6: Percent
+# Default value for data of type int/long is 2 (bytes).
+#
+# TODO: generate ".java" and ".h" files with integer constants from this file.
+
+1003  auditd (avc|3)