Merge "Oboe: make liboboe.so public"
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..b44c296
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1 @@
+subdirs = ["*"]
diff --git a/include/log/log.h b/include/log/log.h
index d6f0eb5..ece9ea6 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -24,7 +24,7 @@
 #include <stdint.h>  /* uint16_t, int32_t */
 #include <stdio.h>
 #include <sys/types.h>
-#include <time.h>    /* clock_gettime */
+#include <time.h>
 #include <unistd.h>
 
 #include <android/log.h>
@@ -812,6 +812,54 @@
 void __android_log_close();
 #endif
 
+#ifndef __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE
+#ifndef __ANDROID_API__
+#define __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE 1
+#elif __ANDROID_API__ > 25 /* > OC */
+#define __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE 1
+#else
+#define __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE 0
+#endif
+#endif
+
+#if __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE
+
+/*
+ * if last is NULL, caller _must_ provide a consistent value for seconds.
+ *
+ * Return -1 if we can not acquire a lock, which below will permit the logging,
+ * error on allowing a log message through.
+ */
+int __android_log_ratelimit(time_t seconds, time_t* last);
+
+/*
+ * Usage:
+ *
+ *   // Global default and state
+ *   IF_ALOG_RATELIMIT() {
+ *      ALOG*(...);
+ *   }
+ *
+ *   // local state, 10 seconds ratelimit
+ *   static time_t local_state;
+ *   IF_ALOG_RATELIMIT_LOCAL(10, &local_state) {
+ *     ALOG*(...);
+ *   }
+ */
+
+#define IF_ALOG_RATELIMIT() \
+      if (__android_log_ratelimit(0, NULL) > 0)
+#define IF_ALOG_RATELIMIT_LOCAL(seconds, state) \
+      if (__android_log_ratelimit(seconds, state) > 0)
+
+#else
+
+/* No ratelimiting as API unsupported */
+#define IF_ALOG_RATELIMIT() if (1)
+#define IF_ALOG_RATELIMIT_LOCAL(...) if (1)
+
+#endif
+
 #if defined(__clang__)
 #pragma clang diagnostic pop
 #endif
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 812ac3c..8059166 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -38,6 +38,7 @@
 #include <linux/loop.h>
 #include <linux/module.h>
 
+#include <string>
 #include <thread>
 
 #include <selinux/android.h>
@@ -67,6 +68,8 @@
 #include "signal_handler.h"
 #include "util.h"
 
+using namespace std::literals::string_literals;
+
 #define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
 #define UNMOUNT_CHECK_TIMES 10
 
@@ -139,8 +142,7 @@
     }
 }
 
-static int wipe_data_via_recovery(const std::string& reason) {
-    const std::vector<std::string> options = {"--wipe_data", std::string() + "--reason=" + reason};
+static int reboot_into_recovery(const std::vector<std::string>& options) {
     std::string err;
     if (!write_bootloader_message(options, &err)) {
         LOG(ERROR) << "failed to set bootloader message: " << err;
@@ -338,7 +340,10 @@
 
     if (e4crypt_is_native()) {
         if (e4crypt_set_directory_policy(args[1].c_str())) {
-            wipe_data_via_recovery(std::string() + "set_policy_failed:" + args[1]);
+            const std::vector<std::string> options = {
+                "--prompt_and_wipe_data",
+                "--reason=set_policy_failed:"s + args[1]};
+            reboot_into_recovery(options);
             return -1;
         }
     }
@@ -559,7 +564,8 @@
     } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
         /* Setup a wipe via recovery, and reboot into recovery */
         PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
-        ret = wipe_data_via_recovery("fs_mgr_mount_all");
+        const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
+        ret = reboot_into_recovery(options);
         /* If reboot worked, there is no return. */
     } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
         if (e4crypt_install_keyring()) {
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 2424dba..be47fc3 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -21,6 +21,7 @@
     "config_write.c",
     "logger_name.c",
     "logger_lock.c",
+    "log_ratelimit.cpp",
 ]
 liblog_host_sources = [
     "fake_log_device.c",
diff --git a/liblog/log_ratelimit.cpp b/liblog/log_ratelimit.cpp
new file mode 100644
index 0000000..dfd4b8f
--- /dev/null
+++ b/liblog/log_ratelimit.cpp
@@ -0,0 +1,86 @@
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <log/log.h>
+
+#include "log_portability.h"
+
+// Global default if 'last' argument in __android_log_ratelimit is NULL
+static time_t g_last_clock;
+// Global above can not deal well with callers playing games with the
+// seconds argument, so we will also hold on to the maximum value
+// ever provided and use that to gain consistency.  If the caller
+// provides their own 'last' argument, then they can play such games
+// of varying the 'seconds' argument to their pleasure.
+static time_t g_last_seconds;
+static const time_t last_seconds_default = 10;
+static const time_t last_seconds_max = 24 * 60 * 60; // maximum of a day
+static const time_t last_seconds_min = 2; // granularity
+// Lock to protect last_clock and last_seconds, but also 'last'
+// argument (not NULL) as supplied to __android_log_ratelimit.
+static pthread_mutex_t lock_ratelimit = PTHREAD_MUTEX_INITIALIZER;
+
+// if last is NULL, caller _must_ provide a consistent value for
+// seconds, otherwise we will take the maximum ever issued and hold
+// on to that.  Preserves value of non-zero errno.  Return -1 if we
+// can not acquire a lock, 0 if we are not to log a message, and 1
+// if we are ok to log a message.  Caller should check > 0 for true.
+LIBLOG_ABI_PUBLIC int __android_log_ratelimit(time_t seconds, time_t* last) {
+    int save_errno = errno;
+
+    // Two reasons for trylock failure:
+    //   1. In a signal handler. Must prevent deadlock
+    //   2. Too many threads calling __android_log_ratelimit.
+    //      Bonus to not print if they race here because that
+    //      dovetails the goal of ratelimiting. One may print
+    //      and the others will wait their turn ...
+    if (pthread_mutex_trylock(&lock_ratelimit)) {
+        if (save_errno) errno = save_errno;
+        return -1;
+    }
+
+    if (seconds == 0) {
+        seconds = last_seconds_default;
+    } else if (seconds < last_seconds_min) {
+        seconds = last_seconds_min;
+    } else if (seconds > last_seconds_max) {
+        seconds = last_seconds_max;
+    }
+
+    if (!last) {
+        if (g_last_seconds > seconds) {
+            seconds = g_last_seconds;
+        } else if (g_last_seconds < seconds) {
+            g_last_seconds = seconds;
+        }
+        last = &g_last_clock;
+    }
+
+    time_t now = time(NULL);
+    if ((now == (time_t)-1) || ((*last + seconds) > now)) {
+        pthread_mutex_unlock(&lock_ratelimit);
+        if (save_errno) errno = save_errno;
+        return 0;
+    }
+    *last = now;
+    pthread_mutex_unlock(&lock_ratelimit);
+    if (save_errno) errno = save_errno;
+    return 1;
+}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index d07d774..01a562c 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -2870,3 +2870,35 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
+
+TEST(liblog, __android_log_ratelimit) {
+    time_t state = 0;
+
+    errno = 42;
+    // Prime
+    __android_log_ratelimit(3, &state);
+    EXPECT_EQ(errno, 42);
+    // Check
+    EXPECT_FALSE(__android_log_ratelimit(3, &state));
+    sleep(1);
+    EXPECT_FALSE(__android_log_ratelimit(3, &state));
+    sleep(4);
+    EXPECT_TRUE(__android_log_ratelimit(3, &state));
+    sleep(5);
+    EXPECT_TRUE(__android_log_ratelimit(3, &state));
+
+    // API checks
+    IF_ALOG_RATELIMIT_LOCAL(3, &state) {
+        EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT_LOCAL(3, &state)");
+    }
+
+    IF_ALOG_RATELIMIT() {
+        ;
+    } else {
+        EXPECT_TRUE(0 == "IF_ALOG_RATELIMIT()");
+    }
+    IF_ALOG_RATELIMIT() {
+        EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT()");
+    }
+    // Do not test default seconds, to allow liblog to tune freely
+}
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index a5d435f..cc65d47 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -534,10 +534,9 @@
 class LogBufferElementKey {
     const union {
         struct {
-            uint16_t uid;
+            uint32_t uid;
             uint16_t pid;
             uint16_t tid;
-            uint16_t padding;
         } __packed;
         uint64_t value;
     } __packed;
@@ -546,8 +545,8 @@
     LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid):
             uid(uid),
             pid(pid),
-            tid(tid),
-            padding(0) {
+            tid(tid)
+    {
     }
     explicit LogBufferElementKey(uint64_t key):value(key) { }
 
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 6e63015..273150e 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -309,7 +309,7 @@
             if ((spaces <= 0) && pruned.length()) {
                 spaces = 1;
             }
-            if ((spaces > 0) && (pruned.length() != 0)) {
+            if (spaces > 0) {
                 change += android::base::StringPrintf("%*s", (int)spaces, "");
             }
             pruned = change + pruned;
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index 613771c..7acef6d 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -17,11 +17,12 @@
 #ifndef _LOGD_LOG_STATISTICS_H__
 #define _LOGD_LOG_STATISTICS_H__
 
-#include <memory>
+#include <ctype.h>
 #include <stdlib.h>
 #include <sys/types.h>
 
 #include <algorithm> // std::max
+#include <memory>
 #include <string>    // std::string
 #include <unordered_map>
 
@@ -211,14 +212,16 @@
                                     EntryBaseConstants::total_len
                                         - name.length() - drop_len - 1);
 
-        if (pruned.length()) {
-            return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
-                                               (int)size_len, size.c_str(),
-                                               (int)drop_len, pruned.c_str());
-        } else {
-            return android::base::StringPrintf("%s%*s\n", name.c_str(),
-                                               (int)size_len, size.c_str());
-        }
+        std::string ret = android::base::StringPrintf("%s%*s%*s",
+                                                      name.c_str(),
+                                                      (int)size_len, size.c_str(),
+                                                      (int)drop_len, pruned.c_str());
+        // remove any trailing spaces
+        size_t pos = ret.size();
+        size_t len = 0;
+        while (pos && isspace(ret[--pos])) ++len;
+        if (len) ret.erase(pos + 1, len);
+        return ret + "\n";
     }
 };
 
diff --git a/storaged/EventLogTags.logtags b/storaged/EventLogTags.logtags
index 2e25d4a..ee92dd1 100644
--- a/storaged/EventLogTags.logtags
+++ b/storaged/EventLogTags.logtags
@@ -36,4 +36,4 @@
 
 2732 storaged_disk_stats (type|3),(start_time|2|3),(end_time|2|3),(read_ios|2|1),(read_merges|2|1),(read_sectors|2|1),(read_ticks|2|3),(write_ios|2|1),(write_merges|2|1),(write_sectors|2|1),(write_ticks|2|3),(o_in_flight|2|1),(io_ticks|2|3),(io_in_queue|2|1)
 
-2733 storaged_emmc_info (mmc_ver|3),(eol|1),(lifetime_a|1),(lifetime_b|1)
\ No newline at end of file
+2733 storaged_emmc_info (mmc_ver|3),(eol|1),(lifetime_a|1),(lifetime_b|1)
diff --git a/storaged/main.cpp b/storaged/main.cpp
index bd1166a..31ada68 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -290,9 +290,8 @@
         sort_running_tasks_info(res);
         log_console_running_tasks_info(res);
 
-
         return 0;
     }
 
     return 0;
-}
\ No newline at end of file
+}
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 1402208..7b0c3ad 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -20,7 +20,6 @@
 #include <time.h>
 #include <unistd.h>
 
-
 #include <android-base/logging.h>
 
 #include <storaged.h>
@@ -42,12 +41,12 @@
     if (parse_disk_stats(DISK_STATS_PATH, &curr)) {
         struct disk_stats inc = get_inc_disk_stats(&mPrevious, &curr);
         add_disk_stats(&inc, &mAccumulate);
-        #ifdef DEBUG
+#ifdef DEBUG
 //            log_kernel_disk_stats(&mPrevious, "prev stats");
 //            log_kernel_disk_stats(&curr, "curr stats");
 //            log_kernel_disk_stats(&inc, "inc stats");
 //            log_kernel_disk_stats(&mAccumulate, "accumulated stats");
-        #endif
+#endif
         mPrevious = curr;
     }
 }
@@ -103,10 +102,10 @@
         if (UNLIKELY(detect(&perf))) {
             mStall = true;
             add_disk_stats(&inc, &mAccumulate);
-            #ifdef DEBUG
+#ifdef DEBUG
             log_kernel_disk_perf(&mMean, "stalled_mean");
             log_kernel_disk_perf(&mStd, "stalled_std");
-            #endif
+#endif
         } else {
             if (mStall) {
                 log_kernel_disk_stats(&mAccumulate, "stalled");
@@ -208,4 +207,4 @@
     }
 
     mTimer += mConfig.periodic_chores_interval_unit;
-}
\ No newline at end of file
+}
diff --git a/storaged/storaged_utils.cpp b/storaged/storaged_utils.cpp
index 9c0b625..5e04888 100644
--- a/storaged/storaged_utils.cpp
+++ b/storaged/storaged_utils.cpp
@@ -16,15 +16,15 @@
 
 #define LOG_TAG "storaged"
 
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <linux/time.h>
-
 #include <dirent.h>
-#include <stdio.h>
+#include <fcntl.h>
+#include <linux/time.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <time.h>
 #include <unistd.h>
 
 #include <sstream>
@@ -32,18 +32,16 @@
 #include <unordered_map>
 
 #include <android-base/file.h>
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <android-base/logging.h>
+#include <cutils/klog.h>
 #include <log/log.h>
 #include <log/log_event_list.h>
-#include <cutils/klog.h>
 
 #include <storaged.h>
 #include <storaged_utils.h>
 
-#include <time.h>
-
 #define SECTOR_SIZE ( 512 )
 #define SEC_TO_MSEC ( 1000 )
 #define MSEC_TO_USEC ( 1000 )
@@ -416,7 +414,7 @@
             }
         }
     }
-    { // update critical area
+    {   // update critical area
         // this is really fast!
         std::unique_ptr<lock_t> lock(new lock_t(&mSem));
         mRunning = tasks_latest;
diff --git a/storaged/tests/storaged_test.cpp b/storaged/tests/storaged_test.cpp
index 4ca9839..99b21ac 100644
--- a/storaged/tests/storaged_test.cpp
+++ b/storaged/tests/storaged_test.cpp
@@ -23,7 +23,6 @@
 #include <unistd.h>
 
 #include <gtest/gtest.h>
-//#include <private/android_logger.h>
 
 #include <storaged.h>               // data structures
 #include <storaged_utils.h>         // functions to test