Merge "Limit adb_test to first multilib"
diff --git a/liblog/log_is_loggable.c b/liblog/log_is_loggable.c
index b4711d2..0f81efc 100644
--- a/liblog/log_is_loggable.c
+++ b/liblog/log_is_loggable.c
@@ -25,13 +25,18 @@
 
 static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER;
 
-static void lock()
+static int lock()
 {
     /*
      * If we trigger a signal handler in the middle of locked activity and the
      * signal handler logs a message, we could get into a deadlock state.
      */
-    pthread_mutex_lock(&lock_loggable);
+    /*
+     *  Any contention, and we can turn around and use the non-cached method
+     * in less time than the system call associated with a mutex to deal with
+     * the contention.
+     */
+    return pthread_mutex_trylock(&lock_loggable);
 }
 
 static void unlock()
@@ -45,6 +50,12 @@
     unsigned char c;
 };
 
+static int check_cache(struct cache *cache)
+{
+    return cache->pinfo
+        && __system_property_serial(cache->pinfo) != cache->serial;
+}
+
 #define BOOLEAN_TRUE 0xFF
 #define BOOLEAN_FALSE 0xFE
 
@@ -58,6 +69,7 @@
         if (!cache->pinfo) {
             return;
         }
+        cache->serial = -1;
     }
     serial = __system_property_serial(cache->pinfo);
     if (serial == cache->serial) {
@@ -85,7 +97,7 @@
     /* calculate the size of our key temporary buffer */
     const size_t taglen = (tag && *tag) ? strlen(tag) : 0;
     /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
-    char key[sizeof(log_namespace) + taglen];
+    char key[sizeof(log_namespace) + taglen]; /* may be > PROPERTY_KEY_MAX */
     char *kp;
     size_t i;
     char c = 0;
@@ -100,49 +112,77 @@
      */
     static char *last_tag;
     static uint32_t global_serial;
-    uint32_t current_global_serial;
-    static struct cache tag_cache[2] = {
-        { NULL, -1, 0 },
-        { NULL, -1, 0 }
-    };
-    static struct cache global_cache[2] = {
-        { NULL, -1, 0 },
-        { NULL, -1, 0 }
-    };
+    /* some compilers erroneously see uninitialized use. !not_locked */
+    uint32_t current_global_serial = 0;
+    static struct cache tag_cache[2];
+    static struct cache global_cache[2];
+    int change_detected;
+    int global_change_detected;
+    int not_locked;
 
     strcpy(key, log_namespace);
 
-    lock();
+    global_change_detected = change_detected = not_locked = lock();
 
-    current_global_serial = __system_property_area_serial();
+    if (!not_locked) {
+        /*
+         *  check all known serial numbers to changes.
+         */
+        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
+            if (check_cache(&tag_cache[i])) {
+                change_detected = 1;
+            }
+        }
+        for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
+            if (check_cache(&global_cache[i])) {
+                global_change_detected = 1;
+            }
+        }
+
+        current_global_serial = __system_property_area_serial();
+        if (current_global_serial != global_serial) {
+            change_detected = 1;
+            global_change_detected = 1;
+        }
+    }
 
     if (taglen) {
-        uint32_t current_local_serial = current_global_serial;
-
-        if (!last_tag || (last_tag[0] != tag[0]) || strcmp(last_tag + 1, tag + 1)) {
-            /* invalidate log.tag.<tag> cache */
-            for(i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
-                tag_cache[i].pinfo = NULL;
-                tag_cache[i].serial = -1;
-                tag_cache[i].c = '\0';
+        int local_change_detected = change_detected;
+        if (!not_locked) {
+            if (!last_tag
+                    || (last_tag[0] != tag[0])
+                    || strcmp(last_tag + 1, tag + 1)) {
+                /* invalidate log.tag.<tag> cache */
+                for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
+                    tag_cache[i].pinfo = NULL;
+                    tag_cache[i].c = '\0';
+                }
+                free(last_tag);
+                last_tag = NULL;
+                local_change_detected = 1;
             }
-            free(last_tag);
-            last_tag = NULL;
-            current_global_serial = -1;
-        }
-        if (!last_tag) {
-            last_tag = strdup(tag);
+            if (!last_tag) {
+                last_tag = strdup(tag);
+            }
         }
         strcpy(key + sizeof(log_namespace) - 1, tag);
 
         kp = key;
-        for(i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
-            if (current_local_serial != global_serial) {
-                refresh_cache(&tag_cache[i], kp);
+        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
+            struct cache *cache = &tag_cache[i];
+            struct cache temp_cache;
+
+            if (not_locked) {
+                temp_cache.pinfo = NULL;
+                temp_cache.c = '\0';
+                cache = &temp_cache;
+            }
+            if (local_change_detected) {
+                refresh_cache(cache, kp);
             }
 
-            if (tag_cache[i].c) {
-                c = tag_cache[i].c;
+            if (cache->c) {
+                c = cache->c;
                 break;
             }
 
@@ -166,13 +206,24 @@
         key[sizeof(log_namespace) - 2] = '\0';
 
         kp = key;
-        for(i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
-            if (current_global_serial != global_serial) {
-                refresh_cache(&global_cache[i], kp);
+        for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
+            struct cache *cache = &global_cache[i];
+            struct cache temp_cache;
+
+            if (not_locked) {
+                temp_cache = *cache;
+                if (temp_cache.pinfo != cache->pinfo) { /* check atomic */
+                    temp_cache.pinfo = NULL;
+                    temp_cache.c = '\0';
+                }
+                cache = &temp_cache;
+            }
+            if (global_change_detected) {
+                refresh_cache(cache, kp);
             }
 
-            if (global_cache[i].c) {
-                c = global_cache[i].c;
+            if (cache->c) {
+                c = cache->c;
                 break;
             }
 
@@ -181,9 +232,10 @@
         break;
     }
 
-    global_serial = current_global_serial;
-
-    unlock();
+    if (!not_locked) {
+        global_serial = current_global_serial;
+        unlock();
+    }
 
     switch (toupper(c)) {
     case 'V': return ANDROID_LOG_VERBOSE;
@@ -206,70 +258,103 @@
 }
 
 /*
- * Timestamp state generally remains constant, since a change is
- * rare, we can accept a trylock failure gracefully. Use a separate
- * lock from is_loggable to keep contention down b/25563384.
+ * For properties that are read often, but generally remain constant.
+ * Since a change is rare, we will accept a trylock failure gracefully.
+ * Use a separate lock from is_loggable to keep contention down b/25563384.
  */
-static pthread_mutex_t lock_clockid = PTHREAD_MUTEX_INITIALIZER;
+struct cache2 {
+    pthread_mutex_t lock;
+    uint32_t serial;
+    const char *key_persist;
+    struct cache cache_persist;
+    const char *key_ro;
+    struct cache cache_ro;
+    unsigned char (*const evaluate)(const struct cache2 *self);
+};
 
-clockid_t android_log_clockid()
+static inline unsigned char do_cache2(struct cache2 *self)
 {
-    static struct cache r_time_cache = { NULL, -1, 0 };
-    static struct cache p_time_cache = { NULL, -1, 0 };
-    char c;
+    uint32_t current_serial;
+    int change_detected;
+    unsigned char c;
 
-    if (pthread_mutex_trylock(&lock_clockid)) {
+    if (pthread_mutex_trylock(&self->lock)) {
         /* We are willing to accept some race in this context */
-        if (!(c = p_time_cache.c)) {
-            c = r_time_cache.c;
-        }
-    } else {
-        static uint32_t serial;
-        uint32_t current_serial = __system_property_area_serial();
-        if (current_serial != serial) {
-            refresh_cache(&r_time_cache, "ro.logd.timestamp");
-            refresh_cache(&p_time_cache, "persist.logd.timestamp");
-            serial = current_serial;
-        }
-        if (!(c = p_time_cache.c)) {
-            c = r_time_cache.c;
-        }
-
-        pthread_mutex_unlock(&lock_clockid);
+        return self->evaluate(self);
     }
 
-    return (tolower(c) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME;
+    change_detected = check_cache(&self->cache_persist)
+                   || check_cache(&self->cache_ro);
+    current_serial = __system_property_area_serial();
+    if (current_serial != self->serial) {
+        change_detected = 1;
+    }
+    if (change_detected) {
+        refresh_cache(&self->cache_persist, self->key_persist);
+        refresh_cache(&self->cache_ro, self->key_ro);
+        self->serial = current_serial;
+    }
+    c = self->evaluate(self);
+
+    pthread_mutex_unlock(&self->lock);
+
+    return c;
+}
+
+static unsigned char evaluate_persist_ro(const struct cache2 *self)
+{
+    unsigned char c = self->cache_persist.c;
+
+    if (c) {
+        return c;
+    }
+
+    return self->cache_ro.c;
 }
 
 /*
- * security state generally remains constant, since a change is
- * rare, we can accept a trylock failure gracefully.
+ * Timestamp state generally remains constant, but can change at any time
+ * to handle developer requirements.
  */
-static pthread_mutex_t lock_security = PTHREAD_MUTEX_INITIALIZER;
+clockid_t android_log_clockid()
+{
+    static struct cache2 clockid = {
+        PTHREAD_MUTEX_INITIALIZER,
+        0,
+        "persist.logd.timestamp",
+        { NULL, -1, '\0' },
+        "ro.logd.timestamp",
+        { NULL, -1, '\0' },
+        evaluate_persist_ro
+    };
+
+    return (tolower(do_cache2(&clockid)) == 'm')
+        ? CLOCK_MONOTONIC
+        : CLOCK_REALTIME;
+}
+
+/*
+ * Security state generally remains constant, but the DO must be able
+ * to turn off logging should it become spammy after an attack is detected.
+ */
+static unsigned char evaluate_security(const struct cache2 *self)
+{
+    unsigned char c = self->cache_ro.c;
+
+    return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE);
+}
 
 int __android_log_security()
 {
-    static struct cache r_do_cache = { NULL, -1, BOOLEAN_FALSE };
-    static struct cache p_security_cache = { NULL, -1, BOOLEAN_FALSE };
-    int retval;
+    static struct cache2 security = {
+        PTHREAD_MUTEX_INITIALIZER,
+        0,
+        "persist.logd.security",
+        { NULL, -1, BOOLEAN_FALSE },
+        "ro.device_owner",
+        { NULL, -1, BOOLEAN_FALSE },
+        evaluate_security
+    };
 
-    if (pthread_mutex_trylock(&lock_security)) {
-        /* We are willing to accept some race in this context */
-        retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c &&
-                 (p_security_cache.c == BOOLEAN_TRUE);
-    } else {
-        static uint32_t serial;
-        uint32_t current_serial = __system_property_area_serial();
-        if (current_serial != serial) {
-            refresh_cache(&r_do_cache, "ro.device_owner");
-            refresh_cache(&p_security_cache, "persist.logd.security");
-            serial = current_serial;
-        }
-        retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c &&
-                 (p_security_cache.c == BOOLEAN_TRUE);
-
-        pthread_mutex_unlock(&lock_security);
-    }
-
-    return retval;
+    return do_cache2(&security);
 }
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 9f29a09..01fb50f 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -660,3 +660,31 @@
     StopBenchmarkTiming();
 }
 BENCHMARK(BM_is_loggable);
+
+/*
+ *	Measure the time it takes for android_log_clockid.
+ */
+static void BM_clockid(int iters) {
+    StartBenchmarkTiming();
+
+    for (int i = 0; i < iters; ++i) {
+        android_log_clockid();
+    }
+
+    StopBenchmarkTiming();
+}
+BENCHMARK(BM_clockid);
+
+/*
+ *	Measure the time it takes for __android_log_security.
+ */
+static void BM_security(int iters) {
+    StartBenchmarkTiming();
+
+    for (int i = 0; i < iters; ++i) {
+        __android_log_security();
+    }
+
+    StopBenchmarkTiming();
+}
+BENCHMARK(BM_security);
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 12aa84e..110395c 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -101,9 +101,10 @@
     if (!default_size) {
         default_size = property_get_size(global_default);
         if (!default_size) {
-            default_size = property_get_bool("ro.config.low_ram", false) ?
-                LOG_BUFFER_MIN_SIZE : // 64K
-                LOG_BUFFER_SIZE;      // 256K
+            default_size = property_get_bool("ro.config.low_ram",
+                                             BOOL_DEFAULT_FALSE)
+                ? LOG_BUFFER_MIN_SIZE // 64K
+                : LOG_BUFFER_SIZE;    // 256K
         }
     }
 
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index fccba61..fd4800e 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -44,7 +44,14 @@
 bool clientHasLogCredentials(SocketClient *cli);
 
 // Furnished in main.cpp
-bool property_get_bool(const char *key, bool def);
+#define BOOL_DEFAULT_FLAG_TRUE_FALSE 0x1
+#define BOOL_DEFAULT_FALSE       0x0     // false if property not present
+#define BOOL_DEFAULT_TRUE        0x1     // true if property not present
+#define BOOL_DEFAULT_FLAG_PERSIST    0x2 // <key>, persist.<key>, ro.<key>
+#define BOOL_DEFAULT_FLAG_ENG        0x4 // off for user
+#define BOOL_DEFAULT_FLAG_SVELTE     0x8 // off for low_ram
+
+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);
diff --git a/logd/README.property b/logd/README.property
index e4b23a9..019bd40 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -1,37 +1,53 @@
 The properties that logd responds to are:
 
 name                       type default  description
-logd.auditd                 bool  true   Enable selinux audit daemon
-logd.auditd.dmesg           bool  true   selinux audit messages duplicated and
+ro.logd.auditd             bool   true   Enable selinux audit daemon
+ro.logd.auditd.dmesg       bool   true   selinux audit messages duplicated and
                                          sent on to dmesg log
-logd.klogd                  bool depends Enable klogd daemon
-logd.statistics             bool depends Enable logcat -S statistics.
-ro.config.low_ram           bool  false  if true, logd.statistics & logd.klogd
-                                         default false
-ro.build.type               string       if user, logd.statistics & logd.klogd
-                                         default false
-persist.logd.logpersistd    string       Enable logpersist daemon, "logcatd"
+persist.logd.security      bool   false  Enable security buffer.
+ro.device_owner            bool   false  Override persist.logd.security to false
+ro.logd.kernel             bool+ svelte+ Enable klogd daemon
+ro.logd.statistics         bool+ svelte+ Enable logcat -S statistics.
+ro.build.type              string        if user, logd.statistics &
+                                         ro.logd.kernel default false.
+persist.logd.logpersistd   string        Enable logpersist daemon, "logcatd"
                                          turns on logcat -f in logd context
-persist.logd.size          number 256K   Global default size of the buffer for
+persist.logd.size          number  ro    Global default size of the buffer for
                                          all log ids at initial startup, at
                                          runtime use: logcat -b all -G <value>
-persist.logd.size.main     number 256K   Size of the buffer for the main log
-persist.logd.size.system   number 256K   Size of the buffer for the system log
-persist.logd.size.radio    number 256K   Size of the buffer for the radio log
-persist.logd.size.event    number 256K   Size of the buffer for the event log
-persist.logd.size.crash    number 256K   Size of the buffer for the crash log
-persist.logd.filter         string       Pruning filter to optimize content,
-                                         default is ro.logd.filter or
-                                         "~!" which means to prune the oldest
-                                         entries of chattiest UID. At runtime
-                                         use: logcat -P "<string>"
-persist.logd.timestamp      string       The recording timestamp source. Default
-                                         is ro.logd.timestamp. "m[onotonic]" is
-                                         the only supported key character,
-                                         otherwise assumes realtime.
+ro.logd.size               number svelte default for persist.logd.size
+persist.logd.size.<buffer> number  ro    Size of the buffer for <buffer> log
+ro.logd.size.<buffer>      number svelte default for persist.logd.size.<buffer>
+ro.config.low_ram          bool   false  if true, logd.statistics, logd.kernel
+                                         default false, logd.size 64K instead
+                                         of 256K.
+persist.logd.filter        string        Pruning filter to optimize content.
+                                         At runtime use: logcat -P "<string>"
+ro.logd.filter             string "~!"   default for persist.logd.filter.
+                                         This default means to prune the
+                                         oldest entries of chattiest UID.
+persist.logd.timestamp     string  ro    The recording timestamp source.
+                                         "m[onotonic]" is the only supported
+                                         key character, otherwise realtime.
+ro.logd.timestamp        string realtime default for persist.logd.timestamp
+log.tag                   string persist The global logging level, VERBOSE,
+                                         DEBUG, INFO, WARN, ERROR, ASSERT or
+                                         SILENT. Only the first character is
+                                         the key character.
+persist.log.tag            string build  default for log.tag
+log.tag.<tag>             string persist The <tag> specific logging level.
+persist.log.tag.<tag>      string build  default for log.tag.<tag>
 
 NB:
-- Number support multipliers (K or M) for convenience. Range is limited
+- bool+ - "true", "false" and comma separated list of "eng" (forced false if
+  ro.build.type is "user") or "svelte" (forced false if ro.config.low_ram is
+  true).
+- svelte - see ro.config.low_ram for details.
+- svelte+ - see ro.config.low_ram and ro.build.type for details.
+- ro - <base property> temporary override, ro.<base property> platform default.
+- persist - <base property> override, persist.<base property> platform default.
+- build - VERBOSE for native, DEBUG for jvm isLoggable, or developer option.
+- number - support multipliers (K or M) for convenience. Range is limited
   to between 64K and 256M for log buffer sizes. Individual log buffer ids
   such as main, system, ... override global default.
 - Pruning filter is of form of a space-separated list of [~][UID][/PID]
diff --git a/logd/main.cpp b/logd/main.cpp
index 2fcabdc..ba56e57 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -143,18 +143,72 @@
 }
 
 // Property helper
-bool property_get_bool(const char *key, bool def) {
-    char property[PROPERTY_VALUE_MAX];
-    property_get(key, property, "");
-
-    if (!strcasecmp(property, "true")) {
-        return true;
-    }
-    if (!strcasecmp(property, "false")) {
+static bool check_flag(const char *prop, const char *flag) {
+    const char *cp = strcasestr(prop, flag);
+    if (!cp) {
         return false;
     }
+    // We only will document comma (,)
+    static const char sep[] = ",:;|+ \t\f";
+    if ((cp != prop) && !strchr(sep, cp[-1])) {
+        return false;
+    }
+    cp += strlen(flag);
+    return !*cp || !!strchr(sep, *cp);
+}
 
-    return def;
+bool property_get_bool(const char *key, int flag) {
+    char def[PROPERTY_VALUE_MAX];
+    char property[PROPERTY_VALUE_MAX];
+    def[0] = '\0';
+    if (flag & BOOL_DEFAULT_FLAG_PERSIST) {
+        char newkey[PROPERTY_KEY_MAX];
+        snprintf(newkey, sizeof(newkey), "ro.%s", key);
+        property_get(newkey, property, "");
+        // persist properties set by /data require innoculation with
+        // logd-reinit. They may be set in init.rc early and function, but
+        // otherwise are defunct unless reset. Do not rely on persist
+        // properties for startup-only keys unless you are willing to restart
+        // logd daemon (not advised).
+        snprintf(newkey, sizeof(newkey), "persist.%s", key);
+        property_get(newkey, def, property);
+    }
+
+    property_get(key, property, def);
+
+    if (check_flag(property, "true")) {
+        return true;
+    }
+    if (check_flag(property, "false")) {
+        return false;
+    }
+    if (check_flag(property, "eng")) {
+       flag |= BOOL_DEFAULT_FLAG_ENG;
+    }
+    // this is really a "not" flag
+    if (check_flag(property, "svelte")) {
+       flag |= BOOL_DEFAULT_FLAG_SVELTE;
+    }
+
+    // Sanity Check
+    if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) {
+        flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE;
+        flag |= BOOL_DEFAULT_TRUE;
+    }
+
+    if ((flag & BOOL_DEFAULT_FLAG_SVELTE)
+            && property_get_bool("ro.config.low_ram",
+                                 BOOL_DEFAULT_FALSE)) {
+        return false;
+    }
+    if (flag & BOOL_DEFAULT_FLAG_ENG) {
+        property_get("ro.build.type", property, "");
+        if (!strcmp(property, "user")) {
+            return false;
+        }
+    }
+
+    return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE;
 }
 
 // Remove the static, and use this variable
@@ -266,17 +320,6 @@
     return android_lookupEventTag(map, tag);
 }
 
-static bool property_get_bool_svelte(const char *key) {
-    bool not_user;
-    {
-        char property[PROPERTY_VALUE_MAX];
-        property_get("ro.build.type", property, "");
-        not_user = !!strcmp(property, "user");
-    }
-    return property_get_bool(key, not_user
-            && !property_get_bool("ro.config.low_ram", false));
-}
-
 static void readDmesg(LogAudit *al, LogKlog *kl) {
     if (!al && !kl) {
         return;
@@ -325,7 +368,11 @@
 // transitory per-client threads are created for each reader.
 int main(int argc, char *argv[]) {
     int fdPmesg = -1;
-    bool klogd = property_get_bool_svelte("logd.klogd");
+    bool klogd = property_get_bool("logd.kernel",
+                                   BOOL_DEFAULT_TRUE |
+                                   BOOL_DEFAULT_FLAG_PERSIST |
+                                   BOOL_DEFAULT_FLAG_ENG |
+                                   BOOL_DEFAULT_FLAG_SVELTE);
     if (klogd) {
         fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY);
     }
@@ -405,7 +452,11 @@
 
     signal(SIGHUP, reinit_signal_handler);
 
-    if (property_get_bool_svelte("logd.statistics")) {
+    if (property_get_bool("logd.statistics",
+                          BOOL_DEFAULT_TRUE |
+                          BOOL_DEFAULT_FLAG_PERSIST |
+                          BOOL_DEFAULT_FLAG_ENG |
+                          BOOL_DEFAULT_FLAG_SVELTE)) {
         logBuf->enableStatistics();
     }
 
@@ -439,12 +490,17 @@
     // initiated log messages. New log entries are added to LogBuffer
     // and LogReader is notified to send updates to connected clients.
 
-    bool auditd = property_get_bool("logd.auditd", true);
-
+    bool auditd = property_get_bool("logd.auditd",
+                                    BOOL_DEFAULT_TRUE |
+                                    BOOL_DEFAULT_FLAG_PERSIST);
     LogAudit *al = NULL;
     if (auditd) {
-        bool dmesg = property_get_bool("logd.auditd.dmesg", true);
-        al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1);
+        al = new LogAudit(logBuf, reader,
+                          property_get_bool("logd.auditd.dmesg",
+                                            BOOL_DEFAULT_TRUE |
+                                            BOOL_DEFAULT_FLAG_PERSIST)
+                              ? fdDmesg
+                              : -1);
     }
 
     LogKlog *kl = NULL;
diff --git a/metricsd/collectors/averaged_statistics_collector_test.cc b/metricsd/collectors/averaged_statistics_collector_test.cc
index 9c97f00..68f9f2f 100644
--- a/metricsd/collectors/averaged_statistics_collector_test.cc
+++ b/metricsd/collectors/averaged_statistics_collector_test.cc
@@ -16,11 +16,12 @@
 
 #include "averaged_statistics_collector.h"
 
+#include <memory>
+
 #include <inttypes.h>
 
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
-#include <base/memory/scoped_ptr.h>
 #include <base/strings/stringprintf.h>
 #include <gtest/gtest.h>
 
@@ -62,7 +63,7 @@
   }
 
   // Collector used for tests.
-  scoped_ptr<AveragedStatisticsCollector> collector_;
+  std::unique_ptr<AveragedStatisticsCollector> collector_;
 
   // Temporary directory used for tests.
   base::ScopedTempDir temp_dir_;
diff --git a/metricsd/include/metrics/timer.h b/metricsd/include/metrics/timer.h
index b36ffff..c1b8ede 100644
--- a/metricsd/include/metrics/timer.h
+++ b/metricsd/include/metrics/timer.h
@@ -19,10 +19,10 @@
 #ifndef METRICS_TIMER_H_
 #define METRICS_TIMER_H_
 
+#include <memory>
 #include <string>
 
 #include <base/macros.h>
-#include <base/memory/scoped_ptr.h>
 #include <base/time/time.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
@@ -121,7 +121,7 @@
   TimerState timer_state_;
 
   // Wrapper for the calls to the system clock.
-  scoped_ptr<ClockWrapper> clock_wrapper_;
+  std::unique_ptr<ClockWrapper> clock_wrapper_;
 
   DISALLOW_COPY_AND_ASSIGN(Timer);
 };
diff --git a/metricsd/metrics_collector.cc b/metricsd/metrics_collector.cc
index e9edf2e..a5daab5 100644
--- a/metricsd/metrics_collector.cc
+++ b/metricsd/metrics_collector.cc
@@ -19,6 +19,8 @@
 #include <sysexits.h>
 #include <time.h>
 
+#include <memory>
+
 #include <base/bind.h>
 #include <base/files/file_path.h>
 #include <base/files/file_util.h>
@@ -665,7 +667,7 @@
 }
 
 void MetricsCollector::SendAndResetDailyUseSample(
-    const scoped_ptr<PersistentInteger>& use) {
+    const unique_ptr<PersistentInteger>& use) {
   SendSample(use->Name(),
              use->GetAndClear(),
              1,                        // value of first bucket
@@ -674,7 +676,7 @@
 }
 
 void MetricsCollector::SendAndResetCrashIntervalSample(
-    const scoped_ptr<PersistentInteger>& interval) {
+    const unique_ptr<PersistentInteger>& interval) {
   SendSample(interval->Name(),
              interval->GetAndClear(),
              1,                        // value of first bucket
@@ -683,7 +685,7 @@
 }
 
 void MetricsCollector::SendAndResetCrashFrequencySample(
-    const scoped_ptr<PersistentInteger>& frequency) {
+    const unique_ptr<PersistentInteger>& frequency) {
   SendSample(frequency->Name(),
              frequency->GetAndClear(),
              1,                        // value of first bucket
diff --git a/metricsd/metrics_collector.h b/metricsd/metrics_collector.h
index 422ed7c..45ef63d 100644
--- a/metricsd/metrics_collector.h
+++ b/metricsd/metrics_collector.h
@@ -20,11 +20,11 @@
 #include <stdint.h>
 
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
 #include <base/files/file_path.h>
-#include <base/memory/scoped_ptr.h>
 #include <base/time/time.h>
 #include <brillo/daemons/dbus_daemon.h>
 #include <libweaved/command.h>
@@ -38,6 +38,7 @@
 #include "persistent_integer.h"
 
 using chromeos_metrics::PersistentInteger;
+using std::unique_ptr;
 
 class MetricsCollector : public brillo::DBusDaemon {
  public:
@@ -151,18 +152,17 @@
 
   // Sends a sample representing the number of seconds of active use
   // for a 24-hour period and reset |use|.
-  void SendAndResetDailyUseSample(
-      const scoped_ptr<PersistentInteger>& use);
+  void SendAndResetDailyUseSample(const unique_ptr<PersistentInteger>& use);
 
   // Sends a sample representing a time interval between two crashes of the
   // same type and reset |interval|.
   void SendAndResetCrashIntervalSample(
-      const scoped_ptr<PersistentInteger>& interval);
+      const unique_ptr<PersistentInteger>& interval);
 
   // Sends a sample representing a frequency of crashes of some type and reset
   // |frequency|.
   void SendAndResetCrashFrequencySample(
-      const scoped_ptr<PersistentInteger>& frequency);
+      const unique_ptr<PersistentInteger>& frequency);
 
   // Initializes vm and disk stats reporting.
   void StatsReporterInit();
@@ -241,36 +241,36 @@
   base::TimeDelta latest_cpu_use_microseconds_;
 
   // Persistent values and accumulators for crash statistics.
-  scoped_ptr<PersistentInteger> daily_cycle_;
-  scoped_ptr<PersistentInteger> weekly_cycle_;
-  scoped_ptr<PersistentInteger> version_cycle_;
+  unique_ptr<PersistentInteger> daily_cycle_;
+  unique_ptr<PersistentInteger> weekly_cycle_;
+  unique_ptr<PersistentInteger> version_cycle_;
 
   // Active use accumulated in a day.
-  scoped_ptr<PersistentInteger> daily_active_use_;
+  unique_ptr<PersistentInteger> daily_active_use_;
   // Active use accumulated since the latest version update.
-  scoped_ptr<PersistentInteger> version_cumulative_active_use_;
+  unique_ptr<PersistentInteger> version_cumulative_active_use_;
 
   // The CPU time accumulator.  This contains the CPU time, in milliseconds,
   // used by the system since the most recent OS version update.
-  scoped_ptr<PersistentInteger> version_cumulative_cpu_use_;
+  unique_ptr<PersistentInteger> version_cumulative_cpu_use_;
 
-  scoped_ptr<PersistentInteger> user_crash_interval_;
-  scoped_ptr<PersistentInteger> kernel_crash_interval_;
-  scoped_ptr<PersistentInteger> unclean_shutdown_interval_;
+  unique_ptr<PersistentInteger> user_crash_interval_;
+  unique_ptr<PersistentInteger> kernel_crash_interval_;
+  unique_ptr<PersistentInteger> unclean_shutdown_interval_;
 
-  scoped_ptr<PersistentInteger> any_crashes_daily_count_;
-  scoped_ptr<PersistentInteger> any_crashes_weekly_count_;
-  scoped_ptr<PersistentInteger> user_crashes_daily_count_;
-  scoped_ptr<PersistentInteger> user_crashes_weekly_count_;
-  scoped_ptr<PersistentInteger> kernel_crashes_daily_count_;
-  scoped_ptr<PersistentInteger> kernel_crashes_weekly_count_;
-  scoped_ptr<PersistentInteger> kernel_crashes_version_count_;
-  scoped_ptr<PersistentInteger> unclean_shutdowns_daily_count_;
-  scoped_ptr<PersistentInteger> unclean_shutdowns_weekly_count_;
+  unique_ptr<PersistentInteger> any_crashes_daily_count_;
+  unique_ptr<PersistentInteger> any_crashes_weekly_count_;
+  unique_ptr<PersistentInteger> user_crashes_daily_count_;
+  unique_ptr<PersistentInteger> user_crashes_weekly_count_;
+  unique_ptr<PersistentInteger> kernel_crashes_daily_count_;
+  unique_ptr<PersistentInteger> kernel_crashes_weekly_count_;
+  unique_ptr<PersistentInteger> kernel_crashes_version_count_;
+  unique_ptr<PersistentInteger> unclean_shutdowns_daily_count_;
+  unique_ptr<PersistentInteger> unclean_shutdowns_weekly_count_;
 
-  scoped_ptr<CpuUsageCollector> cpu_usage_collector_;
-  scoped_ptr<DiskUsageCollector> disk_usage_collector_;
-  scoped_ptr<AveragedStatisticsCollector> averaged_stats_collector_;
+  unique_ptr<CpuUsageCollector> cpu_usage_collector_;
+  unique_ptr<DiskUsageCollector> disk_usage_collector_;
+  unique_ptr<AveragedStatisticsCollector> averaged_stats_collector_;
 
   std::unique_ptr<weaved::Device> device_;
 };
diff --git a/metricsd/persistent_integer_test.cc b/metricsd/persistent_integer_test.cc
index 55d6cbc..bf76261 100644
--- a/metricsd/persistent_integer_test.cc
+++ b/metricsd/persistent_integer_test.cc
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
+#include <memory>
 
 #include <base/compiler_specific.h>
 #include <base/files/file_enumerator.h>
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
+#include <gtest/gtest.h>
 
 #include "persistent_integer.h"
 
@@ -38,7 +39,7 @@
 };
 
 TEST_F(PersistentIntegerTest, BasicChecks) {
-  scoped_ptr<PersistentInteger> pi(
+  std::unique_ptr<PersistentInteger> pi(
       new PersistentInteger(kBackingFileName, temp_dir_.path()));
 
   // Test initialization.
diff --git a/metricsd/timer.cc b/metricsd/timer.cc
index 0c2c119..06fc336 100644
--- a/metricsd/timer.cc
+++ b/metricsd/timer.cc
@@ -18,8 +18,6 @@
 
 #include <string>
 
-#include <base/memory/scoped_ptr.h>
-
 #include "metrics/metrics_library.h"
 
 namespace chromeos_metrics {
diff --git a/metricsd/timer_test.cc b/metricsd/timer_test.cc
index bc7a2a1..7a67e11 100644
--- a/metricsd/timer_test.cc
+++ b/metricsd/timer_test.cc
@@ -16,9 +16,9 @@
 
 #include <stdint.h>
 
-#include <base/memory/scoped_ptr.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <memory>
 
 #include "metrics/metrics_library_mock.h"
 #include "metrics/timer.h"
@@ -61,7 +61,7 @@
   virtual void TearDown() {}
 
   Timer timer_;
-  scoped_ptr<ClockWrapperMock> clock_wrapper_mock_;
+  std::unique_ptr<ClockWrapperMock> clock_wrapper_mock_;
   base::TimeTicks stime, etime, stime2, etime2, stime3, etime3;
 };
 
@@ -436,7 +436,7 @@
 
   TimerReporter timer_reporter_;
   MetricsLibraryMock lib_;
-  scoped_ptr<ClockWrapperMock> clock_wrapper_mock_;
+  std::unique_ptr<ClockWrapperMock> clock_wrapper_mock_;
   base::TimeTicks stime, etime;
 };
 
diff --git a/metricsd/uploader/system_profile_cache.h b/metricsd/uploader/system_profile_cache.h
index 0a21ad4..f9c484c 100644
--- a/metricsd/uploader/system_profile_cache.h
+++ b/metricsd/uploader/system_profile_cache.h
@@ -19,12 +19,12 @@
 
 #include <stdint.h>
 
+#include <memory>
 #include <string>
 
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
-#include "base/memory/scoped_ptr.h"
 #include "persistent_integer.h"
 #include "uploader/proto/system_profile.pb.h"
 #include "uploader/system_profile_setter.h"
@@ -80,7 +80,7 @@
   bool initialized_;
   bool testing_;
   base::FilePath metrics_directory_;
-  scoped_ptr<chromeos_metrics::PersistentInteger> session_id_;
+  std::unique_ptr<chromeos_metrics::PersistentInteger> session_id_;
   SystemProfile profile_;
 };
 
diff --git a/metricsd/uploader/upload_service.cc b/metricsd/uploader/upload_service.cc
index ea8427a..2fb30c3 100644
--- a/metricsd/uploader/upload_service.cc
+++ b/metricsd/uploader/upload_service.cc
@@ -18,6 +18,7 @@
 
 #include <sysexits.h>
 
+#include <memory>
 #include <string>
 
 #include <base/bind.h>
@@ -169,7 +170,7 @@
   if (!current_log_)
     return;
 
-  scoped_ptr<MetricsLog> staged_log;
+  std::unique_ptr<MetricsLog> staged_log;
   staged_log.swap(current_log_);
   staged_log->CloseLog();
   if (!staged_log->PopulateSystemProfile(system_profile_setter_.get())) {
diff --git a/metricsd/uploader/upload_service.h b/metricsd/uploader/upload_service.h
index fe064b8..1d36121 100644
--- a/metricsd/uploader/upload_service.h
+++ b/metricsd/uploader/upload_service.h
@@ -17,6 +17,7 @@
 #ifndef METRICS_UPLOADER_UPLOAD_SERVICE_H_
 #define METRICS_UPLOADER_UPLOAD_SERVICE_H_
 
+#include <memory>
 #include <string>
 
 #include <base/metrics/histogram_base.h>
@@ -141,11 +142,11 @@
   // Returns the current log. If there is no current log, creates it first.
   MetricsLog* GetOrCreateCurrentLog();
 
-  scoped_ptr<SystemProfileSetter> system_profile_setter_;
+  std::unique_ptr<SystemProfileSetter> system_profile_setter_;
   base::HistogramSnapshotManager histogram_snapshot_manager_;
-  scoped_ptr<Sender> sender_;
+  std::unique_ptr<Sender> sender_;
   chromeos_metrics::PersistentInteger failed_upload_count_;
-  scoped_ptr<MetricsLog> current_log_;
+  std::unique_ptr<MetricsLog> current_log_;
   std::shared_ptr<CrashCounters> counters_;
 
   base::TimeDelta upload_interval_;
diff --git a/metricsd/uploader/upload_service_test.cc b/metricsd/uploader/upload_service_test.cc
index 0e2ba8f..ec507e8 100644
--- a/metricsd/uploader/upload_service_test.cc
+++ b/metricsd/uploader/upload_service_test.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
+#include <memory>
 
 #include <base/at_exit.h>
 #include <base/files/file_util.h>
@@ -23,6 +23,7 @@
 #include <base/metrics/sparse_histogram.h>
 #include <base/metrics/statistics_recorder.h>
 #include <base/sys_info.h>
+#include <gtest/gtest.h>
 
 #include "constants.h"
 #include "persistent_integer.h"
@@ -86,15 +87,15 @@
   }
 
   const metrics::SystemProfileProto_Stability GetCurrentStability() {
-    EXPECT_TRUE(upload_service_->current_log_);
+    EXPECT_TRUE(upload_service_->current_log_.get());
 
     return upload_service_->current_log_->uma_proto()->system_profile().stability();
   }
 
   base::ScopedTempDir dir_;
-  scoped_ptr<UploadService> upload_service_;
+  std::unique_ptr<UploadService> upload_service_;
 
-  scoped_ptr<base::AtExitManager> exit_manager_;
+  std::unique_ptr<base::AtExitManager> exit_manager_;
   std::shared_ptr<CrashCounters> counters_;
 };