Merge "Use Minijail for privilege dropping."
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 5ccd80e..bc1c0ca 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -94,6 +94,7 @@
 #define AID_NVRAM         1050  /* Access-controlled NVRAM */
 #define AID_DNS           1051  /* DNS resolution daemon (system: netd) */
 #define AID_DNS_TETHER    1052  /* DNS resolution daemon (tether: dnsmasq) */
+#define AID_WEBVIEW_ZYGOTE 1053 /* WebView zygote process */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL         2000  /* adb and debug shell user */
@@ -207,6 +208,7 @@
     { "nvram",         AID_NVRAM, },
     { "dns",           AID_DNS, },
     { "dns_tether",    AID_DNS_TETHER, },
+    { "webview_zygote", AID_WEBVIEW_ZYGOTE, },
 
     { "shell",         AID_SHELL, },
     { "cache",         AID_CACHE, },
diff --git a/init/init.cpp b/init/init.cpp
index fe2aee4..fc3e80f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -444,6 +444,22 @@
     }
 }
 
+// Set the UDC controller for the ConfigFS USB Gadgets.
+// Read the UDC controller in use from "/sys/class/udc".
+// In case of multiple UDC controllers select the first one.
+static void set_usb_controller() {
+    std::unique_ptr<DIR, decltype(&closedir)>dir(opendir("/sys/class/udc"), closedir);
+    if (!dir) return;
+
+    dirent* dp;
+    while ((dp = readdir(dir.get())) != nullptr) {
+        if (dp->d_name[0] == '.') continue;
+
+        property_set("sys.usb.controller", dp->d_name);
+        break;
+    }
+}
+
 int main(int argc, char** argv) {
     if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
@@ -536,6 +552,7 @@
     property_load_boot_defaults();
     export_oem_lock_status();
     start_property_service();
+    set_usb_controller();
 
     const BuiltinFunctionMap function_map;
     Action::set_function_map(&function_map);
diff --git a/liblog/pmsg_reader.c b/liblog/pmsg_reader.c
index 2e4fc5d..a4eec65 100644
--- a/liblog/pmsg_reader.c
+++ b/liblog/pmsg_reader.c
@@ -144,6 +144,7 @@
     struct __attribute__((__packed__)) {
         android_pmsg_log_header_t p;
         android_log_header_t l;
+        uint8_t prio;
     } buf;
     static uint8_t preread_count;
     bool is_system;
@@ -180,11 +181,16 @@
         if (preread_count != sizeof(buf)) {
             return preread_count ? -EIO : -EAGAIN;
         }
-        if ((buf.p.magic != LOGGER_MAGIC)
-         || (buf.p.len <= sizeof(buf))
-         || (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD))
-         || (buf.l.id >= LOG_ID_MAX)
-         || (buf.l.realtime.tv_nsec >= NS_PER_SEC)) {
+        if ((buf.p.magic != LOGGER_MAGIC) ||
+                (buf.p.len <= sizeof(buf)) ||
+                (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD)) ||
+                (buf.l.id >= LOG_ID_MAX) ||
+                (buf.l.realtime.tv_nsec >= NS_PER_SEC) ||
+                ((buf.l.id != LOG_ID_EVENTS) &&
+                    (buf.l.id != LOG_ID_SECURITY) &&
+                    ((buf.prio == ANDROID_LOG_UNKNOWN) ||
+                        (buf.prio == ANDROID_LOG_DEFAULT) ||
+                        (buf.prio >= ANDROID_LOG_SILENT)))) {
             do {
                 memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count);
             } while (preread_count && (buf.p.magic != LOGGER_MAGIC));
@@ -202,10 +208,12 @@
             uid = get_best_effective_uid();
             is_system = uid_has_log_permission(uid);
             if (is_system || (uid == buf.p.uid)) {
+                char *msg = is_system ?
+                    log_msg->entry_v4.msg :
+                    log_msg->entry_v3.msg;
+                *msg = buf.prio;
                 ret = TEMP_FAILURE_RETRY(read(transp->context.fd,
-                                          is_system ?
-                                              log_msg->entry_v4.msg :
-                                              log_msg->entry_v3.msg,
+                                          msg + sizeof(buf.prio),
                                           buf.p.len - sizeof(buf)));
                 if (ret < 0) {
                     return -errno;
@@ -214,7 +222,7 @@
                     return -EIO;
                 }
 
-                log_msg->entry_v4.len = buf.p.len - sizeof(buf);
+                log_msg->entry_v4.len = buf.p.len - sizeof(buf) + sizeof(buf.prio);
                 log_msg->entry_v4.hdr_size = is_system ?
                     sizeof(log_msg->entry_v4) :
                     sizeof(log_msg->entry_v3);
@@ -227,7 +235,7 @@
                     log_msg->entry_v4.uid = buf.p.uid;
                 }
 
-                return ret + log_msg->entry_v4.hdr_size;
+                return ret + sizeof(buf.prio) + log_msg->entry_v4.hdr_size;
             }
         }
 
diff --git a/logd/Android.mk b/logd/Android.mk
index 203943c..84ea7a2 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -38,7 +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
+event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004
 
 LOCAL_CFLAGS := -Werror $(event_flag)
 
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index db65978..fa95733 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -313,16 +313,16 @@
     LogBufferElement *element = *it;
     log_id_t id = element->getLogId();
 
-    {   // start of scope for uid found iterator
-        LogBufferIteratorMap::iterator found =
-            mLastWorstUid[id].find(element->getUid());
-        if ((found != mLastWorstUid[id].end())
-                && (it == found->second)) {
-            mLastWorstUid[id].erase(found);
+    {   // start of scope for found iterator
+        int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ?
+                element->getTag() : element->getUid();
+        LogBufferIteratorMap::iterator found = mLastWorst[id].find(key);
+        if ((found != mLastWorst[id].end()) && (it == found->second)) {
+            mLastWorst[id].erase(found);
         }
     }
 
-    if (element->getUid() == AID_SYSTEM) {
+    if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (element->getUid() == AID_SYSTEM)) {
         // start of scope for pid found iterator
         LogBufferPidIteratorMap::iterator found =
             mLastWorstPidOfSystem[id].find(element->getPid());
@@ -544,48 +544,31 @@
     bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty();
     while (!clearAll && (pruneRows > 0)) {
         // recalculate the worst offender on every batched pass
-        uid_t worst = (uid_t) -1;
+        int worst = -1; // not valid for getUid() or getKey()
         size_t worst_sizes = 0;
         size_t second_worst_sizes = 0;
         pid_t worstPid = 0; // POSIX guarantees PID != 0
 
         if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) {
-            {   // begin scope for UID sorted list
-                std::unique_ptr<const UidEntry *[]> sorted = stats.sort(
-                    AID_ROOT, (pid_t)0, 2, id);
+            // Calculate threshold as 12.5% of available storage
+            size_t threshold = log_buffer_size(id) / 8;
 
-                if (sorted.get() && sorted[0] && sorted[1]) {
-                    worst_sizes = sorted[0]->getSizes();
-                    // Calculate threshold as 12.5% of available storage
-                    size_t threshold = log_buffer_size(id) / 8;
-                    if ((worst_sizes > threshold)
-                        // Allow time horizon to extend roughly tenfold, assume
-                        // average entry length is 100 characters.
-                            && (worst_sizes > (10 * sorted[0]->getDropped()))) {
-                        worst = sorted[0]->getKey();
-                        second_worst_sizes = sorted[1]->getSizes();
-                        if (second_worst_sizes < threshold) {
-                            second_worst_sizes = threshold;
-                        }
-                    }
-                }
-            }
+            if ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) {
+                stats.sortTags(AID_ROOT, (pid_t)0, 2, id).findWorst(
+                    worst, worst_sizes, second_worst_sizes, threshold);
+            } else {
+                stats.sort(AID_ROOT, (pid_t)0, 2, id).findWorst(
+                    worst, worst_sizes, second_worst_sizes, threshold);
 
-            if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) {
-                // begin scope of PID sorted list
-                std::unique_ptr<const PidEntry *[]> sorted = stats.sort(
-                    worst, (pid_t)0, 2, id, worst);
-                if (sorted.get() && sorted[0] && sorted[1]) {
-                    worstPid = sorted[0]->getKey();
-                    second_worst_sizes = worst_sizes
-                                       - sorted[0]->getSizes()
-                                       + sorted[1]->getSizes();
+                if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) {
+                    stats.sortPids(worst, (pid_t)0, 2, id).findWorst(
+                        worstPid, worst_sizes, second_worst_sizes);
                 }
             }
         }
 
         // skip if we have neither worst nor naughty filters
-        if ((worst == (uid_t) -1) && !hasBlacklist) {
+        if ((worst == -1) && !hasBlacklist) {
             break;
         }
 
@@ -597,10 +580,10 @@
         // - coalesce chatty tags
         // - check age-out of preserved logs
         bool gc = pruneRows <= 1;
-        if (!gc && (worst != (uid_t) -1)) {
-            {   // begin scope for uid worst found iterator
-                LogBufferIteratorMap::iterator found = mLastWorstUid[id].find(worst);
-                if ((found != mLastWorstUid[id].end())
+        if (!gc && (worst != -1)) {
+            {   // begin scope for worst found iterator
+                LogBufferIteratorMap::iterator found = mLastWorst[id].find(worst);
+                if ((found != mLastWorst[id].end())
                         && (found->second != mLogElements.end())) {
                     leading = false;
                     it = found->second;
@@ -658,6 +641,10 @@
                 continue;
             }
 
+            int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ?
+                    element->getTag() :
+                    element->getUid();
+
             if (hasBlacklist && mPrune.naughty(element)) {
                 last.clear(element);
                 it = erase(it);
@@ -670,7 +657,7 @@
                     break;
                 }
 
-                if (element->getUid() == worst) {
+                if (key == worst) {
                     kick = true;
                     if (worst_sizes < second_worst_sizes) {
                         break;
@@ -689,20 +676,19 @@
                 last.add(element);
                 if (worstPid
                         && ((!gc && (element->getPid() == worstPid))
-                            || (mLastWorstPidOfSystem[id].find(element->getPid())
+                           || (mLastWorstPidOfSystem[id].find(element->getPid())
                                 == mLastWorstPidOfSystem[id].end()))) {
-                    mLastWorstPidOfSystem[id][element->getUid()] = it;
+                    mLastWorstPidOfSystem[id][key] = it;
                 }
-                if ((!gc && !worstPid && (element->getUid() == worst))
-                        || (mLastWorstUid[id].find(element->getUid())
-                            == mLastWorstUid[id].end())) {
-                    mLastWorstUid[id][element->getUid()] = it;
+                if ((!gc && !worstPid && (key == worst))
+                        || (mLastWorst[id].find(key) == mLastWorst[id].end())) {
+                    mLastWorst[id][key] = it;
                 }
                 ++it;
                 continue;
             }
 
-            if ((element->getUid() != worst)
+            if ((key != worst)
                     || (worstPid && (element->getPid() != worstPid))) {
                 leading = false;
                 last.clear(element);
@@ -734,9 +720,9 @@
                                     == mLastWorstPidOfSystem[id].end()))) {
                         mLastWorstPidOfSystem[id][worstPid] = it;
                     }
-                    if ((!gc && !worstPid) || (mLastWorstUid[id].find(worst)
-                                == mLastWorstUid[id].end())) {
-                        mLastWorstUid[id][worst] = it;
+                    if ((!gc && !worstPid) ||
+                         (mLastWorst[id].find(worst) == mLastWorst[id].end())) {
+                        mLastWorst[id][worst] = it;
                     }
                     ++it;
                 }
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 7e99236..b390a0c 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -89,7 +89,7 @@
     typedef std::unordered_map<uid_t,
                                LogBufferElementCollection::iterator>
                 LogBufferIteratorMap;
-    LogBufferIteratorMap mLastWorstUid[LOG_ID_MAX];
+    LogBufferIteratorMap mLastWorst[LOG_ID_MAX];
     // watermark of any worst/chatty pid of system processing
     typedef std::unordered_map<pid_t,
                                LogBufferElementCollection::iterator>
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index eb5194c..3e6e586 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -181,7 +181,7 @@
         android_log_event_string_t *event =
             reinterpret_cast<android_log_event_string_t *>(buffer);
 
-        event->header.tag = htole32(LOGD_LOG_TAG);
+        event->header.tag = htole32(CHATTY_LOG_TAG);
         event->type = EVENT_TYPE_STRING;
         event->length = htole32(len);
     } else {
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 02a4a75..86d33b2 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -152,6 +152,15 @@
 
     pidTable.drop(element->getPid(), element);
     tidTable.drop(element->getTid(), element);
+
+    uint32_t tag = element->getTag();
+    if (tag) {
+        if (log_id == LOG_ID_SECURITY) {
+            securityTagTable.drop(tag, element);
+        } else {
+            tagTable.drop(tag, element);
+        }
+    }
 }
 
 // caller must own and free character string
@@ -284,7 +293,7 @@
             if ((spaces <= 0) && pruned.length()) {
                 spaces = 1;
             }
-            if (spaces > 0) {
+            if ((spaces > 0) && (pruned.length() != 0)) {
                 change += android::base::StringPrintf("%*s", (int)spaces, "");
             }
             pruned = change + pruned;
@@ -438,6 +447,10 @@
                                                    getSizes());
 
     std::string pruned = "";
+    size_t dropped = getDropped();
+    if (dropped) {
+        pruned = android::base::StringPrintf("%zu", dropped);
+    }
 
     return formatLine(name, size, pruned);
 }
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index b32c27d..71ad73a 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -203,7 +203,7 @@
     EntryBaseDropped():dropped(0) { }
     EntryBaseDropped(LogBufferElement *element):
             EntryBase(element),
-            dropped(element->getDropped()){
+            dropped(element->getDropped()) {
     }
 
     size_t getDropped() const { return dropped; }
@@ -370,13 +370,13 @@
     std::string format(const LogStatistics &stat, log_id_t id) const;
 };
 
-struct TagEntry : public EntryBase {
+struct TagEntry : public EntryBaseDropped {
     const uint32_t tag;
     pid_t pid;
     uid_t uid;
 
     TagEntry(LogBufferElement *element):
-            EntryBase(element),
+            EntryBaseDropped(element),
             tag(element->getTag()),
             pid(element->getPid()),
             uid(element->getUid()) {
@@ -401,6 +401,43 @@
     std::string format(const LogStatistics &stat, log_id_t id) const;
 };
 
+template <typename TEntry>
+class LogFindWorst {
+    std::unique_ptr<const TEntry *[]> sorted;
+
+public:
+
+    LogFindWorst(std::unique_ptr<const TEntry *[]> &&sorted) : sorted(std::move(sorted)) { }
+
+    void findWorst(int &worst,
+                    size_t &worst_sizes, size_t &second_worst_sizes,
+                    size_t threshold) {
+        if (sorted.get() && sorted[0] && sorted[1]) {
+            worst_sizes = sorted[0]->getSizes();
+            if ((worst_sizes > threshold)
+                // Allow time horizon to extend roughly tenfold, assume
+                // average entry length is 100 characters.
+                    && (worst_sizes > (10 * sorted[0]->getDropped()))) {
+                worst = sorted[0]->getKey();
+                second_worst_sizes = sorted[1]->getSizes();
+                if (second_worst_sizes < threshold) {
+                    second_worst_sizes = threshold;
+                }
+            }
+        }
+    }
+
+    void findWorst(int &worst,
+                    size_t worst_sizes, size_t &second_worst_sizes) {
+        if (sorted.get() && sorted[0] && sorted[1]) {
+            worst = sorted[0]->getKey();
+            second_worst_sizes = worst_sizes
+                               - sorted[0]->getSizes()
+                               + sorted[1]->getSizes();
+        }
+    }
+};
+
 // Log Statistics
 class LogStatistics {
     friend UidEntry;
@@ -451,13 +488,14 @@
         --mDroppedElements[log_id];
     }
 
-    std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid,
-                                             size_t len, log_id id) {
-        return uidTable[id].sort(uid, pid, len);
+    LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) {
+        return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len));
     }
-    std::unique_ptr<const PidEntry *[]> sort(uid_t uid, pid_t pid,
-                                             size_t len, log_id id, uid_t) {
-        return pidSystemTable[id].sort(uid, pid, len);
+    LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) {
+        return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len));
+    }
+    LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) {
+        return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len));
     }
 
     // fast track current value by id only
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index aa4b6e1..fc66330 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -56,7 +56,8 @@
 bool property_get_bool(const char *key, int def);
 
 static inline bool worstUidEnabledForLogid(log_id_t id) {
-    return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || (id == LOG_ID_RADIO);
+    return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) ||
+            (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS);
 }
 
 template <int (*cmp)(const char *l, const char *r, const size_t s)>
diff --git a/logd/event.logtags b/logd/event.logtags
index db8c19b..0d24df0 100644
--- a/logd/event.logtags
+++ b/logd/event.logtags
@@ -34,4 +34,4 @@
 # TODO: generate ".java" and ".h" files with integer constants from this file.
 
 1003  auditd (avc|3)
-1004  logd (dropped|3)
+1004  chatty (dropped|3)
diff --git a/logd/main.cpp b/logd/main.cpp
index 3095f7f..69ba896 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -212,7 +212,7 @@
 }
 
 static int fdDmesg = -1;
-void inline android::prdebug(const char *fmt, ...) {
+void android::prdebug(const char *fmt, ...) {
     if (fdDmesg < 0) {
         return;
     }
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index c9e2ddd..4852fa4 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -33,7 +33,6 @@
 OUR_TOOLS := \
     getevent \
     newfs_msdos \
-    sendevent \
 
 ALL_TOOLS = $(BSD_TOOLS) $(OUR_TOOLS)
 
diff --git a/toolbox/sendevent.c b/toolbox/sendevent.c
deleted file mode 100644
index 4d0ca17..0000000
--- a/toolbox/sendevent.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/input.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-int sendevent_main(int argc, char *argv[])
-{
-    int fd;
-    ssize_t ret;
-    int version;
-    struct input_event event;
-
-    if(argc != 5) {
-        fprintf(stderr, "use: %s device type code value\n", argv[0]);
-        return 1;
-    }
-
-    fd = open(argv[1], O_RDWR);
-    if(fd < 0) {
-        fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
-        return 1;
-    }
-    if (ioctl(fd, EVIOCGVERSION, &version)) {
-        fprintf(stderr, "could not get driver version for %s, %s\n", argv[optind], strerror(errno));
-        return 1;
-    }
-    memset(&event, 0, sizeof(event));
-    event.type = atoi(argv[2]);
-    event.code = atoi(argv[3]);
-    event.value = atoi(argv[4]);
-    ret = write(fd, &event, sizeof(event));
-    if(ret < (ssize_t) sizeof(event)) {
-        fprintf(stderr, "write event failed, %s\n", strerror(errno));
-        return -1;
-    }
-    return 0;
-}