Merge "Add a PREUPLOAD.cfg file to run git-clang-format on every commit"
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index c08b922..92e9039 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -283,6 +283,8 @@
             D("[ %s: writing strings failed: errno=%d]", USB_FFS_ADB_EP0, errno);
             goto err;
         }
+        //Signal only when writing the descriptors to ffs
+        android::base::SetProperty("sys.usb.ffs.ready", "1");
     }
 
     h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
@@ -358,7 +360,6 @@
             }
             std::this_thread::sleep_for(1s);
         }
-        android::base::SetProperty("sys.usb.ffs.ready", "1");
 
         D("[ usb_thread - registering device ]");
         register_usb_transport(usb, 0, 0, 1);
diff --git a/init/Android.mk b/init/Android.mk
index 2fc6f19..5bcfb7b 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -119,7 +119,14 @@
     mapping_sepolicy.cil \
     nonplat_sepolicy.cil \
     plat_sepolicy.cil \
+    plat_sepolicy.cil.sha256 \
     secilc
+
+# Include precompiled policy, unless told otherwise
+ifneq ($(PRODUCT_PRECOMPILED_SEPOLICY),false)
+LOCAL_REQUIRED_MODULES += precompiled_sepolicy precompiled_sepolicy.plat.sha256
+endif
+
 else
 # Use monolithic SELinux policy
 LOCAL_REQUIRED_MODULES += sepolicy
diff --git a/init/init.cpp b/init/init.cpp
index 81f228c..38178a7 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -715,6 +715,44 @@
     }
 }
 
+static bool read_first_line(const char* file, std::string* line) {
+    line->clear();
+
+    std::string contents;
+    if (!android::base::ReadFileToString(file, &contents, true /* follow symlinks */)) {
+        return false;
+    }
+    std::istringstream in(contents);
+    std::getline(in, *line);
+    return true;
+}
+
+static bool selinux_find_precompiled_split_policy(std::string* file) {
+    file->clear();
+
+    static constexpr const char precompiled_sepolicy[] = "/vendor/etc/selinux/precompiled_sepolicy";
+    if (access(precompiled_sepolicy, R_OK) == -1) {
+        return false;
+    }
+    std::string actual_plat_id;
+    if (!read_first_line("/system/etc/selinux/plat_sepolicy.cil.sha256", &actual_plat_id)) {
+        PLOG(INFO) << "Failed to read /system/etc/selinux/plat_sepolicy.cil.sha256";
+        return false;
+    }
+    std::string precompiled_plat_id;
+    if (!read_first_line("/vendor/etc/selinux/precompiled_sepolicy.plat.sha256",
+                         &precompiled_plat_id)) {
+        PLOG(INFO) << "Failed to read /vendor/etc/selinux/precompiled_sepolicy.plat.sha256";
+        return false;
+    }
+    if ((actual_plat_id.empty()) || (actual_plat_id != precompiled_plat_id)) {
+        return false;
+    }
+
+    *file = precompiled_sepolicy;
+    return true;
+}
+
 static constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";
 
 static bool selinux_is_split_policy_device() { return access(plat_policy_cil_file, R_OK) != -1; }
@@ -734,6 +772,22 @@
     // secilc is invoked to compile the above three policy files into a single monolithic policy
     // file. This file is then loaded into the kernel.
 
+    // Load precompiled policy from vendor image, if a matching policy is found there. The policy
+    // must match the platform policy on the system image.
+    std::string precompiled_sepolicy_file;
+    if (selinux_find_precompiled_split_policy(&precompiled_sepolicy_file)) {
+        android::base::unique_fd fd(
+            open(precompiled_sepolicy_file.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY));
+        if (fd != -1) {
+            if (selinux_android_load_policy_from_fd(fd, precompiled_sepolicy_file.c_str()) < 0) {
+                LOG(ERROR) << "Failed to load SELinux policy from " << precompiled_sepolicy_file;
+                return false;
+            }
+            return true;
+        }
+    }
+    // No suitable precompiled policy could be loaded
+
     LOG(INFO) << "Compiling SELinux policy";
 
     // We store the output of the compilation on /dev because this is the most convenient tmpfs
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 310dbf4..bb8c3af 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -26,6 +26,7 @@
     "logger_read.c",
     "logger_write.c",
     "logprint.c",
+    "stderr_write.c",
 ]
 liblog_host_sources = [
     "fake_log_device.c",
diff --git a/liblog/config_write.c b/liblog/config_write.c
index 583dcff..6a6c220 100644
--- a/liblog/config_write.c
+++ b/liblog/config_write.c
@@ -78,6 +78,29 @@
                                     &fakeLoggerWrite);
 #endif
     }
+
+    if (__android_log_frontend & LOGGER_STDERR) {
+        extern struct android_log_transport_write stderrLoggerWrite;
+
+        /*
+         * stderr logger should be primary if we can be the only one, or if
+         * already in the primary list.  Otherwise land in the persist list.
+         * Remember we can be called here if we are already initialized.
+         */
+        if (list_empty(&__android_log_transport_write)) {
+            __android_log_add_transport(&__android_log_transport_write,
+                                        &stderrLoggerWrite);
+        } else {
+            struct android_log_transport_write *transp;
+            write_transport_for_each(transp, &__android_log_transport_write) {
+                if (transp == &stderrLoggerWrite) {
+                    return;
+                }
+            }
+            __android_log_add_transport(&__android_log_persist_write,
+                                        &stderrLoggerWrite);
+        }
+    }
 }
 
 LIBLOG_HIDDEN void __android_log_config_write_close() {
diff --git a/liblog/include/log/log_frontend.h b/liblog/include/log/log_frontend.h
index 9527779..5efa548 100644
--- a/liblog/include/log/log_frontend.h
+++ b/liblog/include/log/log_frontend.h
@@ -17,11 +17,12 @@
 /*
  * Logging frontends, bit mask to select features. Function returns selection.
  */
-#define LOGGER_DEFAULT 0x0
-#define LOGGER_LOGD    0x1
-#define LOGGER_KERNEL  0x2 /* Reserved/Deprecated */
-#define LOGGER_NULL    0x4 /* Does not release resources of other selections */
-#define LOGGER_LOCAL   0x8 /* logs sent to local memory */
+#define LOGGER_DEFAULT 0x00
+#define LOGGER_LOGD    0x01
+#define LOGGER_KERNEL  0x02 /* Reserved/Deprecated */
+#define LOGGER_NULL    0x04 /* Does not release resources of other selections */
+#define LOGGER_LOCAL   0x08 /* logs sent to local memory */
+#define LOGGER_STDERR  0x10 /* logs sent to stderr */
 
 /* Both return the selected frontend flag mask, or negative errno */
 int android_set_log_frontend(int frontend_flag);
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index e149e68..2a97101 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -664,9 +664,9 @@
         return retval;
     }
 
-    __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD;
+    __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
 
-    frontend_flag &= LOGGER_LOCAL | LOGGER_LOGD;
+    frontend_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
 
     if (__android_log_frontend != frontend_flag) {
         __android_log_frontend = frontend_flag;
@@ -695,7 +695,7 @@
     if (write_to_log == __write_to_log_null) {
         ret = LOGGER_NULL;
     } else {
-        __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD;
+        __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
         ret = __android_log_frontend;
         if ((write_to_log != __write_to_log_init) &&
             (write_to_log != __write_to_log_daemon)) {
diff --git a/liblog/stderr_write.c b/liblog/stderr_write.c
new file mode 100644
index 0000000..b739299
--- /dev/null
+++ b/liblog/stderr_write.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*
+ * stderr write handler.  Output is logcat-like, and responds to
+ * logcat's environment variables ANDROID_PRINTF_LOG and
+ * ANDROID_LOG_TAGS to filter output.
+ *
+ * This transport only provides a writer, that means that it does not
+ * provide an End-To-End capability as the logs are effectively _lost_
+ * to the stderr file stream.  The purpose of this transport is to
+ * supply a means for command line tools to report their logging
+ * to the stderr stream, in line with all other activities.
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <log/event_tag_map.h>
+#include <log/log.h>
+#include <log/logprint.h>
+#include <log/uio.h>
+
+#include "log_portability.h"
+#include "logger.h"
+
+static int stderrOpen();
+static void stderrClose();
+static int stderrAvailable(log_id_t logId);
+static int stderrWrite(log_id_t logId, struct timespec* ts,
+                       struct iovec* vec, size_t nr);
+
+struct stderrContext {
+    AndroidLogFormat* logformat;
+#if defined(__ANDROID__)
+    EventTagMap* eventTagMap;
+#endif
+};
+
+LIBLOG_HIDDEN struct android_log_transport_write stderrLoggerWrite = {
+    .node = { &stderrLoggerWrite.node, &stderrLoggerWrite.node },
+    .context.private = NULL,
+    .name = "stderr",
+    .available = stderrAvailable,
+    .open = stderrOpen,
+    .close = stderrClose,
+    .write = stderrWrite,
+};
+
+static int stderrOpen()
+{
+    struct stderrContext* ctx;
+    const char* envStr;
+    bool setFormat;
+
+    if (!stderr || (fileno(stderr) < 0)) {
+        return -EBADF;
+    }
+
+    if (stderrLoggerWrite.context.private) {
+        return fileno(stderr);
+    }
+
+    ctx = calloc(1, sizeof(struct stderrContext));
+    if (!ctx) {
+        return -ENOMEM;
+    }
+
+    ctx->logformat = android_log_format_new();
+    if (!ctx->logformat) {
+        free(ctx);
+        return -ENOMEM;
+    }
+
+    envStr = getenv("ANDROID_PRINTF_LOG");
+    setFormat = false;
+
+    if (envStr) {
+        char* formats = strdup(envStr);
+        char* sv = NULL;
+        char* arg = formats;
+        while (!!(arg = strtok_r(arg, ",:; \t\n\r\f", &sv))) {
+            AndroidLogPrintFormat format = android_log_formatFromString(arg);
+            arg = NULL;
+            if (format == FORMAT_OFF) {
+                continue;
+            }
+            if (android_log_setPrintFormat(ctx->logformat, format) <= 0) {
+                continue;
+            }
+            setFormat = true;
+        }
+        free(formats);
+    }
+    if (!setFormat) {
+        AndroidLogPrintFormat format = android_log_formatFromString(
+                "threadtime");
+        android_log_setPrintFormat(ctx->logformat, format);
+    }
+    envStr = getenv("ANDROID_LOG_TAGS");
+    if (envStr) {
+        android_log_addFilterString(ctx->logformat, envStr);
+    }
+    stderrLoggerWrite.context.private = ctx;
+
+    return fileno(stderr);
+}
+
+static void stderrClose()
+{
+    struct stderrContext* ctx = stderrLoggerWrite.context.private;
+
+    if (ctx) {
+        stderrLoggerWrite.context.private = NULL;
+        if (ctx->logformat) {
+            android_log_format_free(ctx->logformat);
+            ctx->logformat = NULL;
+        }
+#if defined(__ANDROID__)
+        if (ctx->eventTagMap) {
+            android_closeEventTagMap(ctx->eventTagMap);
+            ctx->eventTagMap = NULL;
+        }
+#endif
+    }
+}
+
+static int stderrAvailable(log_id_t logId)
+{
+    if ((logId >= LOG_ID_MAX) || (logId == LOG_ID_KERNEL)) {
+        return -EINVAL;
+    }
+    return 1;
+}
+
+static int stderrWrite(log_id_t logId, struct timespec* ts,
+                       struct iovec* vec, size_t nr)
+{
+    struct log_msg log_msg;
+    AndroidLogEntry entry;
+    char binaryMsgBuf[1024];
+    int err;
+    size_t i;
+    struct stderrContext* ctx = stderrLoggerWrite.context.private;
+
+    if (!ctx) return -EBADF;
+    if (!vec || !nr) return -EINVAL;
+
+    log_msg.entry.len = 0;
+    log_msg.entry.hdr_size = sizeof(log_msg.entry);
+    log_msg.entry.pid = getpid();
+#ifdef __BIONIC__
+    log_msg.entry.tid = gettid();
+#else
+    log_msg.entry.tid = getpid();
+#endif
+    log_msg.entry.sec = ts->tv_sec;
+    log_msg.entry.nsec = ts->tv_nsec;
+    log_msg.entry.lid = logId;
+    log_msg.entry.uid = __android_log_uid();
+
+    for (i = 0; i < nr; ++i) {
+        size_t len = vec[i].iov_len;
+        if ((log_msg.entry.len + len) > LOGGER_ENTRY_MAX_PAYLOAD) {
+            len = LOGGER_ENTRY_MAX_PAYLOAD - log_msg.entry.len;
+        }
+        if (!len) continue;
+        memcpy(log_msg.entry.msg + log_msg.entry.len, vec[i].iov_base, len);
+        log_msg.entry.len += len;
+    }
+
+    if ((logId == LOG_ID_EVENTS) || (logId == LOG_ID_SECURITY)) {
+#if defined(__ANDROID__)
+        if (!ctx->eventTagMap) {
+            ctx->eventTagMap = android_openEventTagMap(NULL);
+        }
+#endif
+        err = android_log_processBinaryLogBuffer(&log_msg.entry_v1,
+                                                 &entry,
+#if defined(__ANDROID__)
+                                                 ctx->eventTagMap,
+#else
+                                                 NULL,
+#endif
+                                                 binaryMsgBuf,
+                                                 sizeof(binaryMsgBuf));
+    } else {
+        err = android_log_processLogBuffer(&log_msg.entry_v1, &entry);
+    }
+
+    /* print known truncated data, in essence logcat --debug */
+    if ((err < 0) && !entry.message) return -EINVAL;
+
+    if (!android_log_shouldPrintLine(ctx->logformat, entry.tag, entry.priority)) {
+        return log_msg.entry.len;
+    }
+
+    err = android_log_printLogLine(ctx->logformat, fileno(stderr), &entry);
+    if (err < 0) return errno ? -errno : -EINVAL;
+    return log_msg.entry.len;
+}
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index cfea452..0e6432c 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -57,6 +57,8 @@
 test_src_files := \
     liblog_test_default.cpp \
     liblog_test_local.cpp \
+    liblog_test_stderr.cpp \
+    liblog_test_stderr_local.cpp \
     log_id_test.cpp \
     log_radio_test.cpp \
     log_read_test.cpp \
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index bc0ea4c..2537fac 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -47,7 +47,7 @@
 #endif
 #endif
 
-#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL))
+#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL) || !defined(USING_LOGGER_STDERR))
 #ifdef liblog // a binary clue that we are overriding the test names
 // Does not support log reading blocking feature yet
 // Does not support LOG_ID_SECURITY (unless we set LOGGER_LOCAL | LOGGER_LOGD)
@@ -62,6 +62,11 @@
 #define USING_LOGGER_DEFAULT
 #endif
 #endif
+#ifdef USING_LOGGER_STDERR
+# define SUPPORTS_END_TO_END 0
+#else
+# define SUPPORTS_END_TO_END 1
+#endif
 
 // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
 // non-syscall libs. Since we are only using this in the emergency of
@@ -98,7 +103,7 @@
     usleep(1000);
 }
 
-#if (defined(__ANDROID__) && !defined(USING_LOGGER_LOCAL))
+#if (defined(__ANDROID__) && defined(USING_LOGGER_DEFAULT))
 static std::string popenToString(std::string command) {
     std::string ret;
 
@@ -176,8 +181,8 @@
         LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
 
     log_time ts(CLOCK_MONOTONIC);
-    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-#ifndef USING_LOGGER_LOCAL
+    EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
+#ifdef USING_LOGGER_DEFAULT
     // Check that we can close and reopen the logger
     bool pmsgActiveAfter__android_log_btwrite;
     bool logdwActiveAfter__android_log_btwrite;
@@ -200,8 +205,8 @@
 #endif
 
     log_time ts1(CLOCK_MONOTONIC);
-    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
-#ifndef USING_LOGGER_LOCAL
+    EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
+#ifdef USING_LOGGER_DEFAULT
     if (getuid() == AID_ROOT) {
         pmsgActiveAfter__android_log_btwrite = isPmsgActive();
         logdwActiveAfter__android_log_btwrite = isLogdwActive();
@@ -220,7 +225,7 @@
             break;
         }
 
-        ASSERT_EQ(log_msg.entry.pid, pid);
+        EXPECT_EQ(log_msg.entry.pid, pid);
 
         if ((log_msg.entry.len != sizeof(android_log_event_long_t))
          || (log_msg.id() != LOG_ID_EVENTS)) {
@@ -242,8 +247,8 @@
         }
     }
 
-    EXPECT_EQ(1, count);
-    EXPECT_EQ(1, second_count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, second_count);
 
     android_logger_list_close(logger_list);
 #else
@@ -251,6 +256,54 @@
 #endif
 }
 
+#if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL))
+static void print_frontend(const char* prefix, int logger) {
+    static const char orstr[] = " | ";
+
+    if (!prefix) {
+        prefix = "";
+    }
+    if (logger < 0) {
+        fprintf(stderr, "%s%s\n", prefix, strerror(-logger));
+        return;
+    }
+
+    if (logger == LOGGER_DEFAULT) {
+        fprintf(stderr, "%sLOGGER_DEFAULT", prefix);
+        prefix = orstr;
+    }
+    if (logger & LOGGER_LOGD) {
+        fprintf(stderr, "%sLOGGER_LOGD", prefix);
+        prefix = orstr;
+    }
+    if (logger & LOGGER_KERNEL) {
+        fprintf(stderr, "%sLOGGER_KERNEL", prefix);
+        prefix = orstr;
+    }
+    if (logger & LOGGER_NULL) {
+        fprintf(stderr, "%sLOGGER_NULL", prefix);
+        prefix = orstr;
+    }
+    if (logger & LOGGER_LOCAL) {
+        fprintf(stderr, "%sLOGGER_LOCAL", prefix);
+        prefix = orstr;
+    }
+    if (logger & LOGGER_STDERR) {
+        fprintf(stderr, "%sLOGGER_STDERR", prefix);
+        prefix = orstr;
+    }
+    logger &= ~(LOGGER_LOGD | LOGGER_KERNEL | LOGGER_NULL | LOGGER_LOCAL |
+                LOGGER_STDERR);
+    if (logger) {
+        fprintf(stderr, "%s0x%x", prefix, logger);
+        prefix = orstr;
+    }
+    if (prefix == orstr) {
+        fprintf(stderr, "\n");
+    }
+}
+#endif
+
 // This test makes little sense standalone, and requires the tests ahead
 // and behind us, to make us whole.  We could incorporate a prefix and
 // suffix test to make this standalone, but opted to not complicate this.
@@ -261,10 +314,14 @@
 #endif
 
     int logger = android_get_log_frontend();
+    print_frontend("android_get_log_frontend = ", logger);
     EXPECT_NE(LOGGER_NULL, logger);
 
-    EXPECT_EQ(LOGGER_NULL, android_set_log_frontend(LOGGER_NULL));
-    EXPECT_EQ(LOGGER_NULL, android_get_log_frontend());
+    int ret;
+    EXPECT_EQ(LOGGER_NULL, ret = android_set_log_frontend(LOGGER_NULL));
+    print_frontend("android_set_log_frontend = ", ret);
+    EXPECT_EQ(LOGGER_NULL, ret = android_get_log_frontend());
+    print_frontend("android_get_log_frontend = ", ret);
 
     pid_t pid = getpid();
 
@@ -273,7 +330,7 @@
         LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
 
     log_time ts(CLOCK_MONOTONIC);
-    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
+    EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
 
     usleep(1000000);
 
@@ -285,7 +342,7 @@
             break;
         }
 
-        ASSERT_EQ(log_msg.entry.pid, pid);
+        EXPECT_EQ(log_msg.entry.pid, pid);
 
         if ((log_msg.entry.len != sizeof(android_log_event_long_t))
          || (log_msg.id() != LOG_ID_EVENTS)) {
@@ -307,8 +364,10 @@
 
     android_logger_list_close(logger_list);
 
-    EXPECT_EQ(logger, android_set_log_frontend(logger));
-    EXPECT_EQ(logger, android_get_log_frontend());
+    EXPECT_EQ(logger, ret = android_set_log_frontend(logger));
+    print_frontend("android_set_log_frontend = ", ret);
+    EXPECT_EQ(logger, ret = android_get_log_frontend());
+    print_frontend("android_get_log_frontend = ", ret);
 
     // False negative if liblog.__android_log_btwrite__android_logger_list_read
     // fails above, so we will likely succeed. But we will have so many
@@ -350,7 +409,7 @@
     log_time ts(CLOCK_REALTIME);
 #endif
 
-    ASSERT_LT(0, __android_log_bswrite(0, message));
+    EXPECT_LT(0, __android_log_bswrite(0, message));
     size_t num_lines = 1, size = 0, length = 0, total = 0;
     const char *cp = message;
     while (*cp) {
@@ -382,7 +441,7 @@
             break;
         }
 
-        ASSERT_EQ(log_msg.entry.pid, pid);
+        EXPECT_EQ(log_msg.entry.pid, pid);
 
         if ((log_msg.entry.sec < (ts.tv_sec - 1))
          || ((ts.tv_sec + 1) < log_msg.entry.sec)
@@ -413,19 +472,26 @@
             int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
                 &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
             EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
-            if (processBinaryLogBuffer == 0) {
+            if ((processBinaryLogBuffer == 0) || entry.message) {
                 size_t line_overhead = 20;
                 if (pid > 99999) ++line_overhead;
                 if (pid > 999999) ++line_overhead;
                 fflush(stderr);
-                EXPECT_EQ((int)((line_overhead * num_lines) + size),
-                    android_log_printLogLine(logformat, fileno(stderr), &entry));
+                if (processBinaryLogBuffer) {
+                    EXPECT_GT((int)((line_overhead * num_lines) + size),
+                              android_log_printLogLine(logformat,
+                                                       fileno(stderr), &entry));
+                } else {
+                    EXPECT_EQ((int)((line_overhead * num_lines) + size),
+                              android_log_printLogLine(logformat,
+                                                       fileno(stderr), &entry));
+                }
             }
             android_log_format_free(logformat);
         }
     }
 
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 
     android_logger_list_close(logger_list);
 #else
@@ -527,7 +593,7 @@
         android_log_format_free(logformat);
     }
 
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 
     android_logger_list_close(logger_list);
 #else
@@ -1058,10 +1124,14 @@
 
     android_logger_list_close(logger_list);
 
+#if SUPPORTS_END_TO_END
     EXPECT_EQ(true, matches);
 
     EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
 #else
+    EXPECT_EQ(false, matches);
+#endif
+#else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
@@ -1123,7 +1193,7 @@
         android_log_format_free(logformat);
     }
 
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 
     android_logger_list_close(logger_list);
 #else
@@ -1184,6 +1254,11 @@
 
     android_logger_list_close(logger_list);
 
+#if !SUPPORTS_END_TO_END
+    max_len = max_len ?
+        max_len :
+        LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag);
+#endif
     EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
               static_cast<size_t>(max_len));
 
@@ -1255,14 +1330,14 @@
     android_logger_list_close(logger_list1);
     android_logger_list_close(logger_list2);
 
-    EXPECT_EQ(num, count1);
-    EXPECT_EQ(num - 10, count2);
+    EXPECT_EQ(num * SUPPORTS_END_TO_END, count1);
+    EXPECT_EQ((num - 10) * SUPPORTS_END_TO_END, count2);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
 
-#ifndef USING_LOGGER_LOCAL // Do not retest logprint
+#ifdef USING_LOGGER_DEFAULT // Do not retest logprint
 static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
     return android_log_shouldPrintLine(p_format, tag, pri)
         && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
@@ -1331,9 +1406,9 @@
 
     android_log_format_free(p_format);
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
-#ifndef USING_LOGGER_LOCAL // Do not retest property handling
+#ifdef USING_LOGGER_DEFAULT // Do not retest property handling
 TEST(liblog, is_loggable) {
 #ifdef __ANDROID__
     static const char tag[] = "is_loggable";
@@ -1632,12 +1707,12 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
 // Following tests the specific issues surrounding error handling wrt logd.
 // Kills logd and toss all collected data, equivalent to logcat -b all -c,
 // except we also return errors to the logging callers.
-#ifndef USING_LOGGER_LOCAL
+#ifdef USING_LOGGER_DEFAULT
 #ifdef TEST_PREFIX
 // helper to liblog.enoent to count end-to-end matching logging messages.
 static int count_matching_ts(log_time ts) {
@@ -1687,7 +1762,7 @@
     TEST_PREFIX
     log_time ts(CLOCK_MONOTONIC);
     EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-    EXPECT_EQ(1, count_matching_ts(ts));
+    EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts));
 
     // This call will fail if we are setuid(AID_SYSTEM), beware of any
     // test prior to this one playing with setuid and causing interference.
@@ -1732,18 +1807,18 @@
 
     ts = log_time(CLOCK_MONOTONIC);
     EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-    EXPECT_EQ(1, count_matching_ts(ts));
+    EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts));
 
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
-#endif // !USING_LOCAL_LOGGER
+#endif // USING_LOCAL_LOGD
 
 // Below this point we run risks of setuid(AID_SYSTEM) which may affect others.
 
 // Do not retest properties, and cannot log into LOG_ID_SECURITY
-#ifndef USING_LOGGER_LOCAL
+#ifdef USING_LOGGER_DEFAULT
 TEST(liblog, __security) {
 #ifdef __ANDROID__
     static const char persist_key[] = "persist.logd.security";
@@ -1929,7 +2004,7 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
 #ifdef TEST_PREFIX
 static void android_errorWriteWithInfoLog_helper(int TAG, const char* SUBTAG,
@@ -2047,7 +2122,7 @@
             max_payload_buf,
             200,
             count);
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2063,7 +2138,7 @@
             max_payload_buf,
             sizeof(max_payload_buf),
             count);
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2095,7 +2170,7 @@
             max_payload_buf,
             200,
             count);
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2118,6 +2193,46 @@
 
     count = 0;
 
+    // Do a Before and After on the count to measure the effect. Decrement
+    // what we find in Before to set the stage.
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+    for (;;) {
+        log_msg log_msg;
+        if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
+
+        char *eventData = log_msg.msg();
+        if (!eventData) continue;
+
+        // Tag
+        int tag = get4LE(eventData);
+        eventData += 4;
+
+        if (tag != TAG) continue;
+
+        if (!SUBTAG) {
+            // This tag should not have been written because the data was null
+            --count;
+            break;
+        }
+
+        // List type
+        eventData++;
+        // Number of elements in list
+        eventData++;
+        // Element #1: string type for subtag
+        eventData++;
+
+        eventData +=4;
+
+        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) continue;
+        --count;
+    }
+
+    android_logger_list_close(logger_list);
+
+    // Do an After on the count to measure the effect.
     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
         LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
 
@@ -2184,7 +2299,7 @@
 #ifdef TEST_PREFIX
     int count;
     android_errorWriteLog_helper(123456785, "test-subtag", count);
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2703,7 +2818,7 @@
         EXPECT_EQ(0, strcmp(expected_string, msgBuf));
     }
 
-    EXPECT_EQ(1, count);
+    EXPECT_EQ(SUPPORTS_END_TO_END, count);
 
     android_logger_list_close(logger_list);
 }
@@ -2789,7 +2904,7 @@
 #endif
 }
 
-#ifndef USING_LOGGER_LOCAL // Do not retest logger list handling
+#ifdef USING_LOGGER_DEFAULT // Do not retest logger list handling
 TEST(liblog, create_android_logger_overflow) {
     android_log_context ctx;
 
@@ -2829,9 +2944,9 @@
                                            msgBuf, sizeof(msgBuf)), 0);
     EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]");
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
-#ifndef USING_LOGGER_LOCAL // Do not retest pmsg functionality
+#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality
 #ifdef __ANDROID__
 static const char __pmsg_file[] =
         "/data/william-shakespeare/MuchAdoAboutNothing.txt";
@@ -2957,9 +3072,9 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
-#ifndef USING_LOGGER_LOCAL // Do not retest event mapping functionality
+#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality
 #ifdef __ANDROID__
 // must be: '<needle:> 0 kB'
 static bool isZero(const std::string &content, std::string::size_type pos,
@@ -3063,9 +3178,9 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
-#ifndef USING_LOGGER_LOCAL // Do not retest ratelimit
+#ifdef USING_LOGGER_DEFAULT // Do not retest ratelimit
 TEST(liblog, __android_log_ratelimit) {
     time_t state = 0;
 
@@ -3097,9 +3212,9 @@
     }
     // Do not test default seconds, to allow liblog to tune freely
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
 
-#ifndef USING_LOGGER_LOCAL // Do not retest event mapping functionality
+#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality
 TEST(liblog, android_lookupEventTagNum) {
 #ifdef __ANDROID__
     EventTagMap* map = android_openEventTagMap(NULL);
@@ -3115,4 +3230,4 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
-#endif // !USING_LOGGER_LOCAL
+#endif // USING_LOGGER_DEFAULT
diff --git a/liblog/tests/liblog_test_stderr.cpp b/liblog/tests/liblog_test_stderr.cpp
new file mode 100644
index 0000000..f0cb192
--- /dev/null
+++ b/liblog/tests/liblog_test_stderr.cpp
@@ -0,0 +1,5 @@
+#include <log/log_frontend.h>
+#define liblog liblog_stderr
+#define TEST_PREFIX android_set_log_frontend(LOGGER_STDERR);
+#define USING_LOGGER_STDERR
+#include "liblog_test.cpp"
diff --git a/liblog/tests/liblog_test_stderr_local.cpp b/liblog/tests/liblog_test_stderr_local.cpp
new file mode 100644
index 0000000..1555b4e
--- /dev/null
+++ b/liblog/tests/liblog_test_stderr_local.cpp
@@ -0,0 +1,4 @@
+#include <log/log_frontend.h>
+#define liblog liblog_stderr_local
+#define TEST_PREFIX android_set_log_frontend(LOGGER_LOCAL | LOGGER_STDERR);
+#include "liblog_test.cpp"
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 3cd36f9..4da5030 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -56,6 +56,25 @@
 
 #define DEFAULT_MAX_ROTATED_LOGS 4
 
+struct log_device_t {
+    const char* device;
+    bool binary;
+    struct logger* logger;
+    struct logger_list* logger_list;
+    bool printed;
+
+    log_device_t* next;
+
+    log_device_t(const char* d, bool b) {
+        device = d;
+        binary = b;
+        next = nullptr;
+        printed = false;
+        logger = nullptr;
+        logger_list = nullptr;
+    }
+};
+
 struct android_logcat_context_internal {
     // status
     volatile std::atomic_int retval;  // valid if thread_stopped set
@@ -91,15 +110,15 @@
     int printBinary;
     int devCount;  // >1 means multiple
     pcrecpp::RE* regex;
+    log_device_t* devices;
+    EventTagMap* eventTagMap;
     // 0 means "infinite"
     size_t maxCount;
     size_t printCount;
+
     bool printItAnyways;
     bool debug;
-
-    // static variables
     bool hasOpenedEventTagMap;
-    EventTagMap* eventTagMap;
 };
 
 // Creates a context associated with this logcat instance
@@ -127,25 +146,6 @@
 // logd prefixes records with a length field
 #define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t)
 
-struct log_device_t {
-    const char* device;
-    bool binary;
-    struct logger* logger;
-    struct logger_list* logger_list;
-    bool printed;
-
-    log_device_t* next;
-
-    log_device_t(const char* d, bool b) {
-        device = d;
-        binary = b;
-        next = nullptr;
-        printed = false;
-        logger = nullptr;
-        logger_list = nullptr;
-    }
-};
-
 namespace android {
 
 enum helpType { HELP_FALSE, HELP_TRUE, HELP_FORMAT };
@@ -738,7 +738,6 @@
     const char* setId = nullptr;
     int mode = ANDROID_LOG_RDONLY;
     std::string forceFilters;
-    log_device_t* devices = nullptr;
     log_device_t* dev;
     struct logger_list* logger_list;
     size_t tail_lines = 0;
@@ -1117,7 +1116,7 @@
                     if (!(idMask & (1 << i))) continue;
 
                     bool found = false;
-                    for (dev = devices; dev; dev = dev->next) {
+                    for (dev = context->devices; dev; dev = dev->next) {
                         if (!strcmp(name, dev->device)) {
                             found = true;
                             break;
@@ -1134,7 +1133,7 @@
                         dev->next = d;
                         dev = d;
                     } else {
-                        devices = dev = d;
+                        context->devices = dev = d;
                     }
                     context->devCount++;
                 }
@@ -1287,8 +1286,8 @@
         context->printItAnyways = false;
     }
 
-    if (!devices) {
-        dev = devices = new log_device_t("main", false);
+    if (!context->devices) {
+        dev = context->devices = new log_device_t("main", false);
         context->devCount = 1;
         if (android_name_to_log_id("system") == LOG_ID_SYSTEM) {
             dev = dev->next = new log_device_t("system", false);
@@ -1384,7 +1383,7 @@
         }
     }
 
-    dev = devices;
+    dev = context->devices;
     if (tail_time != log_time::EPOCH) {
         logger_list = android_logger_list_alloc_time(mode, tail_time, pid);
     } else {
@@ -1595,7 +1594,7 @@
         }
 
         log_device_t* d;
-        for (d = devices; d; d = d->next) {
+        for (d = context->devices; d; d = d->next) {
             if (android_name_to_log_id(d->device) == log_msg.id()) break;
         }
         if (!d) {
@@ -1617,6 +1616,11 @@
     }
 
 close:
+    // Short and sweet. Implemented generic version in android_logcat_destroy.
+    while (!!(dev = context->devices)) {
+        context->devices = dev->next;
+        delete dev;
+    }
     android_logger_list_free(logger_list);
 
 exit:
@@ -1790,6 +1794,20 @@
 
     android_closeEventTagMap(context->eventTagMap);
 
+    // generic cleanup of devices list to handle all possible dirty cases
+    log_device_t* dev;
+    while (!!(dev = context->devices)) {
+        struct logger_list* logger_list = dev->logger_list;
+        if (logger_list) {
+            for (log_device_t* d = dev; d; d = d->next) {
+                if (d->logger_list == logger_list) d->logger_list = nullptr;
+            }
+            android_logger_list_free(logger_list);
+        }
+        context->devices = dev->next;
+        delete dev;
+    }
+
     int retval = context->retval;
 
     free(context);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 757e1ff..c025d13 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -290,6 +290,10 @@
     # /data, which in turn can only be loaded when system properties are present.
     trigger post-fs-data
 
+    # Now we can start zygote for file base encryption devices in
+    # init.{$device}.rc
+    trigger zygote-start
+
     # Load persist properties and override properties (if enabled) from /data.
     trigger load_persist_props_action
 
@@ -564,7 +568,6 @@
     chown system system /sys/class/leds/red/device/grpfreq
     chown system system /sys/class/leds/red/device/grppwm
     chown system system /sys/class/leds/red/device/blink
-    chown system system /sys/class/timed_output/vibrator/enable
     chown system system /sys/module/sco/parameters/disable_esco
     chown system system /sys/kernel/ipv4/tcp_wmem_min
     chown system system /sys/kernel/ipv4/tcp_wmem_def