Merge "Revert "Error correction: Use libfec in fs_mgr""
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 817917e..3495a71 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -88,8 +88,11 @@
     __le32 fs_count;
     __le32 hs_count;
     __le32 ss_count;
+    __le32 os_count;
     struct func_desc fs_descs, hs_descs;
     struct ss_func_desc ss_descs;
+    struct usb_os_desc_header os_header;
+    struct usb_ext_compat_desc os_desc;
 } __attribute__((packed));
 
 static struct func_desc fs_descriptors = {
@@ -181,6 +184,24 @@
     },
 };
 
+struct usb_ext_compat_desc os_desc_compat = {
+    .bFirstInterfaceNumber = 0,
+    .Reserved1 = cpu_to_le32(1),
+    .CompatibleID = {0},
+    .SubCompatibleID = {0},
+    .Reserved2 = {0},
+};
+
+static struct usb_os_desc_header os_desc_header = {
+    .interface = cpu_to_le32(1),
+    .dwLength = cpu_to_le32(sizeof(os_desc_header) + sizeof(os_desc_compat)),
+    .bcdVersion = cpu_to_le32(1),
+    .wIndex = cpu_to_le32(4),
+    .bCount = cpu_to_le32(1),
+    .Reserved = cpu_to_le32(0),
+};
+
+
 #define STR_INTERFACE_ "ADB Interface"
 
 static const struct {
@@ -332,13 +353,16 @@
     v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
     v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
     v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
-                                 FUNCTIONFS_HAS_SS_DESC;
+                                 FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
     v2_descriptor.fs_count = 3;
     v2_descriptor.hs_count = 3;
     v2_descriptor.ss_count = 5;
+    v2_descriptor.os_count = 1;
     v2_descriptor.fs_descs = fs_descriptors;
     v2_descriptor.hs_descs = hs_descriptors;
     v2_descriptor.ss_descs = ss_descriptors;
+    v2_descriptor.os_header = os_desc_header;
+    v2_descriptor.os_desc = os_desc_compat;
 
     if (h->control < 0) { // might have already done this before
         D("OPENING %s", USB_FFS_ADB_EP0);
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index ae56b4c..2a9d1d3 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -35,8 +35,8 @@
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/key_value_store.h>
-#include <chromeos/process.h>
+#include <brillo/key_value_store.h>
+#include <brillo/process.h>
 
 namespace {
 
@@ -340,7 +340,7 @@
 bool CrashCollector::GetLogContents(const FilePath &config_path,
                                     const std::string &exec_name,
                                     const FilePath &output_file) {
-  chromeos::KeyValueStore store;
+  brillo::KeyValueStore store;
   if (!store.Load(config_path)) {
     LOG(INFO) << "Unable to read log configuration file "
               << config_path.value();
@@ -351,7 +351,7 @@
   if (!store.GetString(exec_name, &command))
     return false;
 
-  chromeos::ProcessImpl diag_process;
+  brillo::ProcessImpl diag_process;
   diag_process.AddArg(kShellPath);
   diag_process.AddStringOption("-c", command);
   diag_process.RedirectOutput(output_file.value());
diff --git a/crash_reporter/crash_collector_test.cc b/crash_reporter/crash_collector_test.cc
index 32cbe9f..d00a5b5 100644
--- a/crash_reporter/crash_collector_test.cc
+++ b/crash_reporter/crash_collector_test.cc
@@ -22,14 +22,14 @@
 #include <base/files/file_util.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/syslog_logging.h>
 #include <gtest/gtest.h>
 
 #include "crash_collector.h"
 
 using base::FilePath;
 using base::StringPrintf;
-using chromeos::FindLog;
+using brillo::FindLog;
 using ::testing::Invoke;
 using ::testing::Return;
 
@@ -54,7 +54,7 @@
     collector_.Initialize(CountCrash, IsMetrics);
     test_dir_ = FilePath("test");
     base::CreateDirectory(test_dir_);
-    chromeos::ClearLog();
+    brillo::ClearLog();
   }
 
   void TearDown() {
@@ -208,7 +208,7 @@
             symlink(kMetaFileBasename,
                     meta_symlink_path.value().c_str()));
   ASSERT_TRUE(base::PathExists(meta_symlink_path));
-  chromeos::ClearLog();
+  brillo::ClearLog();
   collector_.WriteCrashMetaData(meta_symlink_path,
                                 "kernel",
                                 payload_file.value());
@@ -221,7 +221,7 @@
   // Test target of dangling symlink is not created.
   base::DeleteFile(meta_file, false);
   ASSERT_FALSE(base::PathExists(meta_file));
-  chromeos::ClearLog();
+  brillo::ClearLog();
   collector_.WriteCrashMetaData(meta_symlink_path, "kernel",
                                 payload_file.value());
   EXPECT_FALSE(base::PathExists(meta_file));
diff --git a/crash_reporter/crash_reporter.cc b/crash_reporter/crash_reporter.cc
index 7872f7b..3955fe5 100644
--- a/crash_reporter/crash_reporter.cc
+++ b/crash_reporter/crash_reporter.cc
@@ -25,9 +25,9 @@
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/flag_helper.h>
-#include <chromeos/process.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/flag_helper.h>
+#include <brillo/process.h>
+#include <brillo/syslog_logging.h>
 #include <metrics/metrics_library.h>
 
 #include "kernel_collector.h"
@@ -102,7 +102,7 @@
   // Note: This will mean that the dbus-send process will become a zombie and
   // reparent to init for reaping, but that's OK -- see above.
 
-  chromeos::ProcessImpl dbus_send;
+  brillo::ProcessImpl dbus_send;
   dbus_send.AddArg("/system/bin/dbus-send");
   dbus_send.AddArg("--type=signal");
   dbus_send.AddArg("--system");
@@ -183,10 +183,10 @@
   }
 
   // Accumulate logs to help in diagnosing failures during user collection.
-  chromeos::LogToString(true);
+  brillo::LogToString(true);
   // Handle the crash, get the name of the process from procfs.
   bool handled = user_collector->HandleCrash(user, nullptr);
-  chromeos::LogToString(false);
+  brillo::LogToString(false);
   if (!handled)
     return 1;
   return 0;
@@ -198,9 +198,9 @@
   CHECK(!udev_event.empty()) << "--udev= must be set";
 
   // Accumulate logs to help in diagnosing failures during user collection.
-  chromeos::LogToString(true);
+  brillo::LogToString(true);
   bool handled = udev_collector->HandleCrash(udev_event);
-  chromeos::LogToString(false);
+  brillo::LogToString(false);
   if (!handled)
     return 1;
   return 0;
@@ -209,9 +209,9 @@
 static int HandleKernelWarning(KernelWarningCollector
                                *kernel_warning_collector) {
   // Accumulate logs to help in diagnosing failures during collection.
-  chromeos::LogToString(true);
+  brillo::LogToString(true);
   bool handled = kernel_warning_collector->Collect();
-  chromeos::LogToString(false);
+  brillo::LogToString(false);
   if (!handled)
     return 1;
   return 0;
@@ -278,9 +278,9 @@
   OpenStandardFileDescriptors();
   FilePath my_path = base::MakeAbsoluteFilePath(FilePath(argv[0]));
   s_metrics_lib.Init();
-  chromeos::FlagHelper::Init(argc, argv, "Chromium OS Crash Reporter");
-  chromeos::OpenLog(my_path.BaseName().value().c_str(), true);
-  chromeos::InitLog(chromeos::kLogToSyslog);
+  brillo::FlagHelper::Init(argc, argv, "Chromium OS Crash Reporter");
+  brillo::OpenLog(my_path.BaseName().value().c_str(), true);
+  brillo::InitLog(brillo::kLogToSyslog);
 
   KernelCollector kernel_collector;
   kernel_collector.Initialize(CountKernelCrash, IsFeedbackAllowed);
diff --git a/crash_reporter/crash_reporter_logs_test.cc b/crash_reporter/crash_reporter_logs_test.cc
index c9ca02d..e778002 100644
--- a/crash_reporter/crash_reporter_logs_test.cc
+++ b/crash_reporter/crash_reporter_logs_test.cc
@@ -17,7 +17,7 @@
 #include <string>
 
 #include <base/files/file_path.h>
-#include <chromeos/key_value_store.h>
+#include <brillo/key_value_store.h>
 #include <gtest/gtest.h>
 
 namespace {
@@ -32,7 +32,7 @@
 
 // Tests that the config file is parsable and that Chrome is listed.
 TEST(CrashReporterLogsTest, ReadConfig) {
-  chromeos::KeyValueStore store;
+  brillo::KeyValueStore store;
   ASSERT_TRUE(store.Load(base::FilePath(kConfigFile)));
   std::string command;
   EXPECT_TRUE(store.GetString(kChromeExecName, &command));
diff --git a/crash_reporter/crash_sender b/crash_reporter/crash_sender
index 8a422dd..e38d410 100755
--- a/crash_reporter/crash_sender
+++ b/crash_reporter/crash_sender
@@ -292,7 +292,7 @@
   local kind="$(get_kind "${meta_path}")"
   local exec_name="$(get_key_value "${meta_path}" "exec_name")"
   local url="$(getprop crash_reporter.server)"
-  local brillo_version="$(get_key_value "${meta_path}" "ver")"
+  local bdk_version="$(get_key_value "${meta_path}" "bdk_version")"
   local hwclass="$(get_hardware_class)"
   local write_payload_size="$(get_key_value "${meta_path}" "payload_size")"
   local log="$(get_key_value "${meta_path}" "log")"
@@ -370,12 +370,12 @@
   fi
 
   # If ID or VERSION_ID is undefined, we use the default product name
-  # and CHROMEOS_RELEASE_VERSION from /etc/lsb-release.
+  # and bdk_version from /etc/os-release.d.
   if [ "${product}" = "undefined" ]; then
     product="${BRILLO_PRODUCT}"
   fi
   if [ "${version}" = "undefined" ]; then
-    version="${brillo_version}"
+    version="${bdk_version}"
   fi
 
   local image_type
@@ -460,6 +460,7 @@
     --capath "${RESTRICTED_CERTIFICATES_PATH}" --ciphers HIGH \
     -F "prod=${product}" \
     -F "ver=${version}" \
+    -F "bdk_version=${bdk_version}" \
     -F "hwclass=${hwclass}" \
     -F "exec_name=${exec_name}" \
     -F "model_manifest_id=${model_manifest_id}" \
diff --git a/crash_reporter/kernel_collector_test.cc b/crash_reporter/kernel_collector_test.cc
index e690b77..cdb0ae7 100644
--- a/crash_reporter/kernel_collector_test.cc
+++ b/crash_reporter/kernel_collector_test.cc
@@ -22,13 +22,13 @@
 #include <base/files/scoped_temp_dir.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/syslog_logging.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
 using base::StringPrintf;
-using chromeos::FindLog;
-using chromeos::GetLog;
+using brillo::FindLog;
+using brillo::GetLog;
 
 namespace {
 
@@ -78,7 +78,7 @@
 
     test_crash_directory_ = scoped_temp_dir_.path().Append("crash_directory");
     ASSERT_TRUE(base::CreateDirectory(test_crash_directory_));
-    chromeos::ClearLog();
+    brillo::ClearLog();
   }
 
   FilePath test_kcrash_;
@@ -282,7 +282,7 @@
   ASSERT_EQ(1, s_crashes);
   ASSERT_TRUE(FindLog("(handling)"));
   static const char kNamePrefix[] = "Stored kcrash to ";
-  std::string log = chromeos::GetLog();
+  std::string log = brillo::GetLog();
   size_t pos = log.find(kNamePrefix);
   ASSERT_NE(std::string::npos, pos)
       << "Did not find string \"" << kNamePrefix << "\" in log: {\n"
diff --git a/crash_reporter/list_proxies.cc b/crash_reporter/list_proxies.cc
index a39441d..d445557 100644
--- a/crash_reporter/list_proxies.cc
+++ b/crash_reporter/list_proxies.cc
@@ -28,8 +28,8 @@
 #include <base/strings/string_tokenizer.h>
 #include <base/strings/string_util.h>
 #include <base/values.h>
-#include <chromeos/daemons/dbus_daemon.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/daemons/dbus_daemon.h>
+#include <brillo/syslog_logging.h>
 
 #include "libcrosservice/dbus-proxies.h"
 
@@ -111,7 +111,7 @@
 // must be called, which blocks on the D-Bus call to Chrome.  The call returns
 // after either the timeout or the proxy has been resolved.  The resolved
 // proxies can then be accessed through the proxies() function.
-class ProxyResolver : public chromeos::DBusDaemon {
+class ProxyResolver : public brillo::DBusDaemon {
  public:
   ProxyResolver(const std::string& source_url,
                 const std::string& signal_interface,
@@ -138,7 +138,7 @@
         timeout_callback_.callback(),
         timeout_);
 
-    return chromeos::DBusDaemon::Run();
+    return brillo::DBusDaemon::Run();
   }
 
  protected:
@@ -162,7 +162,7 @@
       return;
     }
 
-    chromeos::ErrorPtr error;
+    brillo::ErrorPtr error;
     call_proxy_->ResolveNetworkProxy(source_url_,
                                      signal_interface_,
                                      signal_name_,
@@ -189,7 +189,7 @@
   }
 
   int OnInit() override {
-    int return_code = chromeos::DBusDaemon::OnInit();
+    int return_code = brillo::DBusDaemon::OnInit();
     if (return_code != EX_OK)
       return return_code;
 
@@ -276,13 +276,13 @@
   }
 
   // Default to logging to syslog.
-  int init_flags = chromeos::kLogToSyslog;
+  int init_flags = brillo::kLogToSyslog;
   // Log to stderr if a TTY (and "-quiet" wasn't passed), or if "-verbose"
   // was passed.
 
   if ((!quiet && isatty(STDERR_FILENO)) || verbose)
-    init_flags |= chromeos::kLogToStderr;
-  chromeos::InitLog(init_flags);
+    init_flags |= brillo::kLogToStderr;
+  brillo::InitLog(init_flags);
 
   std::string url;
   base::CommandLine::StringVector urls = cl->GetArgs();
diff --git a/crash_reporter/testrunner.cc b/crash_reporter/testrunner.cc
index a8c717e..744cf10 100644
--- a/crash_reporter/testrunner.cc
+++ b/crash_reporter/testrunner.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <chromeos/test_helpers.h>
+#include <brillo/test_helpers.h>
 #include <gtest/gtest.h>
 
 int main(int argc, char** argv) {
diff --git a/crash_reporter/udev_collector.cc b/crash_reporter/udev_collector.cc
index 576fdbd..1e018db 100644
--- a/crash_reporter/udev_collector.cc
+++ b/crash_reporter/udev_collector.cc
@@ -27,7 +27,7 @@
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/process.h>
+#include <brillo/process.h>
 
 using base::FilePath;
 
@@ -120,7 +120,7 @@
   }
 
   // Compress the output using gzip.
-  chromeos::ProcessImpl gzip_process;
+  brillo::ProcessImpl gzip_process;
   gzip_process.AddArg(kGzipPath);
   gzip_process.AddArg(crash_path.value());
   int process_result = gzip_process.Run();
diff --git a/crash_reporter/udev_collector_test.cc b/crash_reporter/udev_collector_test.cc
index a6643fb..5474f48 100644
--- a/crash_reporter/udev_collector_test.cc
+++ b/crash_reporter/udev_collector_test.cc
@@ -18,7 +18,7 @@
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/syslog_logging.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -141,7 +141,7 @@
                               kLogConfigFileContents,
                               strlen(kLogConfigFileContents)));
 
-    chromeos::ClearLog();
+    brillo::ClearLog();
   }
 
   UdevCollectorMock collector_;
diff --git a/crash_reporter/unclean_shutdown_collector_test.cc b/crash_reporter/unclean_shutdown_collector_test.cc
index c5c0662..3bdeca1 100644
--- a/crash_reporter/unclean_shutdown_collector_test.cc
+++ b/crash_reporter/unclean_shutdown_collector_test.cc
@@ -20,12 +20,12 @@
 
 #include <base/files/file_util.h>
 #include <base/strings/string_util.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/syslog_logging.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
-using ::chromeos::FindLog;
+using ::brillo::FindLog;
 
 namespace {
 
@@ -65,7 +65,7 @@
     base::DeleteFile(test_unclean_, true);
     // Set up an alternate power manager state file as well
     collector_.powerd_suspended_file_ = FilePath(kTestSuspended);
-    chromeos::ClearLog();
+    brillo::ClearLog();
   }
 
  protected:
diff --git a/crash_reporter/user_collector.cc b/crash_reporter/user_collector.cc
index c4f02af..53fbb14 100644
--- a/crash_reporter/user_collector.cc
+++ b/crash_reporter/user_collector.cc
@@ -37,8 +37,9 @@
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
-#include <chromeos/process.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/osrelease_reader.h>
+#include <brillo/process.h>
+#include <brillo/syslog_logging.h>
 #include <cutils/properties.h>
 #include <private/android_filesystem_config.h>
 
@@ -64,6 +65,8 @@
 // The property containing the product id.
 const char kProductIDProperty[] = "ro.product.product_id";
 
+static const char kBdkVersionKey[] = "bdk_version";
+
 
 using base::FilePath;
 using base::StringPrintf;
@@ -187,7 +190,7 @@
   AddCrashMetaData("sig", kCollectionErrorSignature);
   AddCrashMetaData("error_type", GetErrorTypeSignature(error_type));
   std::string dump_basename = FormatDumpBasename(exec, time(nullptr), pid);
-  std::string error_log = chromeos::GetLog();
+  std::string error_log = brillo::GetLog();
   FilePath diag_log_path = GetCrashPath(crash_path, dump_basename, "diaglog");
   if (GetLogContents(FilePath(log_config_path_), kCollectionErrorSignature,
                      diag_log_path)) {
@@ -367,7 +370,7 @@
                                       const FilePath &minidump_path,
                                       const FilePath &temp_directory) {
   FilePath output_path = temp_directory.Append("output");
-  chromeos::ProcessImpl core2md;
+  brillo::ProcessImpl core2md;
   core2md.RedirectOutput(output_path.value());
   core2md.AddArg(kCoreToMinidumpConverterPath);
   core2md.AddArg(core_path.value());
@@ -511,6 +514,15 @@
   property_get(kProductIDProperty, value, "undefined");
   AddCrashMetaUploadData("prod", value);
 
+  brillo::OsReleaseReader reader;
+  reader.Load();
+  std::string bdk_version = "undefined";
+  if (!reader.GetString(kBdkVersionKey, &bdk_version)) {
+    LOG(ERROR) << "Could not read " << kBdkVersionKey
+               << " from /etc/os-release.d/";
+  }
+  AddCrashMetaData(kBdkVersionKey, bdk_version);
+
   ErrorType error_type =
       ConvertCoreToMinidump(pid, container_dir, core_path, minidump_path);
   if (error_type != kErrorNone) {
diff --git a/crash_reporter/user_collector_test.cc b/crash_reporter/user_collector_test.cc
index 1dfac2a..72e61e6 100644
--- a/crash_reporter/user_collector_test.cc
+++ b/crash_reporter/user_collector_test.cc
@@ -23,12 +23,12 @@
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
 #include <base/strings/string_split.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/syslog_logging.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
-using chromeos::FindLog;
+using brillo::FindLog;
 
 namespace {
 
@@ -73,7 +73,7 @@
     base::DeleteFile(FilePath("test"), true);
     mkdir("test", 0777);
     pid_ = getpid();
-    chromeos::ClearLog();
+    brillo::ClearLog();
   }
 
  protected:
@@ -222,7 +222,7 @@
       "GetSymlinkTarget failed - Path /proc/0 DirectoryExists: 0"));
   EXPECT_TRUE(FindLog("stat /proc/0/exe failed: -1 2"));
 
-  chromeos::ClearLog();
+  brillo::ClearLog();
   pid_t my_pid = getpid();
   EXPECT_TRUE(collector_.GetExecutableBaseNameFromPid(my_pid, &base_name));
   EXPECT_FALSE(FindLog("Readlink failed"));
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 5cfc02f..1de8e64 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -217,7 +217,7 @@
     return len;
 }
 
-// Prune at most 10% of the log entries or 256, whichever is less.
+// Prune at most 10% of the log entries or maxPrune, whichever is less.
 //
 // mLogElementsLock must be held when this function is called.
 void LogBuffer::maybePrune(log_id_t id) {
@@ -225,21 +225,24 @@
     unsigned long maxSize = log_buffer_size(id);
     if (sizes > maxSize) {
         size_t sizeOver = sizes - ((maxSize * 9) / 10);
-        size_t elements = stats.elements(id);
-        size_t minElements = elements / 10;
+        size_t elements = stats.realElements(id);
+        size_t minElements = elements / 100;
+        if (minElements < minPrune) {
+            minElements = minPrune;
+        }
         unsigned long pruneRows = elements * sizeOver / sizes;
-        if (pruneRows <= minElements) {
+        if (pruneRows < minElements) {
             pruneRows = minElements;
         }
-        if (pruneRows > 256) {
-            pruneRows = 256;
+        if (pruneRows > maxPrune) {
+            pruneRows = maxPrune;
         }
         prune(id, pruneRows);
     }
 }
 
 LogBufferElementCollection::iterator LogBuffer::erase(
-        LogBufferElementCollection::iterator it, bool engageStats) {
+        LogBufferElementCollection::iterator it, bool coalesce) {
     LogBufferElement *e = *it;
     log_id_t id = e->getLogId();
 
@@ -248,10 +251,10 @@
         mLastWorstUid[id].erase(f);
     }
     it = mLogElements.erase(it);
-    if (engageStats) {
-        stats.subtract(e);
-    } else {
+    if (coalesce) {
         stats.erase(e);
+    } else {
+        stats.subtract(e);
     }
     delete e;
 
@@ -286,7 +289,7 @@
 
 public:
 
-    bool merge(LogBufferElement *e, unsigned short dropped) {
+    bool coalesce(LogBufferElement *e, unsigned short dropped) {
         LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
         LogBufferElementMap::iterator it = map.find(key.getKey());
         if (it != map.end()) {
@@ -454,7 +457,7 @@
         it = mLogElements.begin();
         // Perform at least one mandatory garbage collection cycle in following
         // - clear leading chatty tags
-        // - merge chatty tags
+        // - coalesce chatty tags
         // - check age-out of preserved logs
         bool gc = pruneRows <= 1;
         if (!gc && (worst != (uid_t) -1)) {
@@ -493,9 +496,8 @@
                 continue;
             }
 
-            // merge any drops
-            if (dropped && last.merge(e, dropped)) {
-                it = erase(it, false);
+            if (dropped && last.coalesce(e, dropped)) {
+                it = erase(it, true);
                 continue;
             }
 
@@ -526,7 +528,6 @@
                 break;
             }
 
-            // unmerged drop message
             if (dropped) {
                 last.add(e);
                 if ((!gc && (e->getUid() == worst))
@@ -560,8 +561,8 @@
             } else {
                 stats.drop(e);
                 e->setDropped(1);
-                if (last.merge(e, 1)) {
-                    it = erase(it, false);
+                if (last.coalesce(e, 1)) {
+                    it = erase(it, true);
                 } else {
                     last.add(e);
                     if (!gc || (mLastWorstUid[id].find(worst)
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 371c796..7ed92e9 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -85,10 +85,14 @@
     void unlock() { pthread_mutex_unlock(&mLogElementsLock); }
 
 private:
+
+    static constexpr size_t minPrune = 4;
+    static constexpr size_t maxPrune = 256;
+
     void maybePrune(log_id_t id);
     bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
     LogBufferElementCollection::iterator erase(
-        LogBufferElementCollection::iterator it, bool engageStats = true);
+        LogBufferElementCollection::iterator it, bool coalesce = false);
 };
 
 #endif // _LOGD_LOG_BUFFER_H__
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index c3b10ad..fdb2576 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -27,6 +27,7 @@
     log_id_for_each(id) {
         mSizes[id] = 0;
         mElements[id] = 0;
+        mDroppedElements[id] = 0;
         mSizesTotal[id] = 0;
         mElementsTotal[id] = 0;
     }
@@ -93,6 +94,9 @@
     unsigned short size = element->getMsgLen();
     mSizes[log_id] -= size;
     --mElements[log_id];
+    if (element->getDropped()) {
+        --mDroppedElements[log_id];
+    }
 
     if (log_id == LOG_ID_KERNEL) {
         return;
@@ -119,6 +123,7 @@
     log_id_t log_id = element->getLogId();
     unsigned short size = element->getMsgLen();
     mSizes[log_id] -= size;
+    ++mDroppedElements[log_id];
 
     uidTable[log_id].drop(element->getUid(), element);
 
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index dd13380..6943820 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -374,6 +374,7 @@
 class LogStatistics {
     size_t mSizes[LOG_ID_MAX];
     size_t mElements[LOG_ID_MAX];
+    size_t mDroppedElements[LOG_ID_MAX];
     size_t mSizesTotal[LOG_ID_MAX];
     size_t mElementsTotal[LOG_ID_MAX];
     bool enable;
@@ -403,8 +404,12 @@
     void subtract(LogBufferElement *entry);
     // entry->setDropped(1) must follow this call
     void drop(LogBufferElement *entry);
-    // Correct for merging two entries referencing dropped content
-    void erase(LogBufferElement *e) { --mElements[e->getLogId()]; }
+    // Correct for coalescing two entries referencing dropped content
+    void erase(LogBufferElement *element) {
+        log_id_t log_id = element->getLogId();
+        --mElements[log_id];
+        --mDroppedElements[log_id];
+    }
 
     std::unique_ptr<const UidEntry *[]> sort(size_t len, log_id id) {
         return uidTable[id].sort(len);
@@ -413,6 +418,9 @@
     // fast track current value by id only
     size_t sizes(log_id_t id) const { return mSizes[id]; }
     size_t elements(log_id_t id) const { return mElements[id]; }
+    size_t realElements(log_id_t id) const {
+        return mElements[id] - mDroppedElements[id];
+    }
     size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
     size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
 
diff --git a/metricsd/metrics_daemon.cc b/metricsd/metrics_daemon.cc
index 2ea5bbd..2b7e98c 100644
--- a/metricsd/metrics_daemon.cc
+++ b/metricsd/metrics_daemon.cc
@@ -140,7 +140,7 @@
     version_cumulative_cpu_use_->Set(0);
   }
 
-  return chromeos::DBusDaemon::Run();
+  return brillo::DBusDaemon::Run();
 }
 
 void MetricsDaemon::RunUploaderTest() {
@@ -242,8 +242,8 @@
 }
 
 int MetricsDaemon::OnInit() {
-  int return_code = dbus_enabled_ ? chromeos::DBusDaemon::OnInit() :
-      chromeos::Daemon::OnInit();
+  int return_code = dbus_enabled_ ? brillo::DBusDaemon::OnInit() :
+      brillo::Daemon::OnInit();
   if (return_code != EX_OK)
     return return_code;
 
@@ -326,7 +326,7 @@
           << error.name << ": " << error.message;
     }
   }
-  chromeos::DBusDaemon::OnShutdown(return_code);
+  brillo::DBusDaemon::OnShutdown(return_code);
 }
 
 void MetricsDaemon::OnEnableMetrics(const std::weak_ptr<weaved::Command>& cmd) {
@@ -368,7 +368,7 @@
   if (!device_)
     return;
 
-  chromeos::VariantDictionary state_change{
+  brillo::VariantDictionary state_change{
     { "_metrics._AnalyticsReportingState",
       metrics_lib_->AreMetricsEnabled() ? "enabled" : "disabled" }
   };
diff --git a/metricsd/metrics_daemon.h b/metricsd/metrics_daemon.h
index 146108a..3d691c5 100644
--- a/metricsd/metrics_daemon.h
+++ b/metricsd/metrics_daemon.h
@@ -26,7 +26,7 @@
 #include <base/files/file_path.h>
 #include <base/memory/scoped_ptr.h>
 #include <base/time/time.h>
-#include <chromeos/daemons/dbus_daemon.h>
+#include <brillo/daemons/dbus_daemon.h>
 #include <libweaved/command.h>
 #include <libweaved/device.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
@@ -39,7 +39,7 @@
 
 using chromeos_metrics::PersistentInteger;
 
-class MetricsDaemon : public chromeos::DBusDaemon {
+class MetricsDaemon : public brillo::DBusDaemon {
  public:
   MetricsDaemon();
   ~MetricsDaemon();
diff --git a/metricsd/metrics_daemon_main.cc b/metricsd/metrics_daemon_main.cc
index df13944..50c279d 100644
--- a/metricsd/metrics_daemon_main.cc
+++ b/metricsd/metrics_daemon_main.cc
@@ -18,8 +18,8 @@
 #include <base/command_line.h>
 #include <base/logging.h>
 #include <base/strings/string_util.h>
-#include <chromeos/flag_helper.h>
-#include <chromeos/syslog_logging.h>
+#include <brillo/flag_helper.h>
+#include <brillo/syslog_logging.h>
 #include <rootdev.h>
 
 #include "constants.h"
@@ -79,11 +79,11 @@
                 metrics::kMetricsDirectory,
                 "Root of the configuration files (testing only)");
 
-  chromeos::FlagHelper::Init(argc, argv, "Chromium OS Metrics Daemon");
+  brillo::FlagHelper::Init(argc, argv, "Chromium OS Metrics Daemon");
 
   // Also log to stderr when not running as daemon.
-  chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogHeader |
-                    (FLAGS_daemon ? 0 : chromeos::kLogToStderr));
+  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogHeader |
+                  (FLAGS_daemon ? 0 : brillo::kLogToStderr));
 
   if (FLAGS_daemon && daemon(0, 0) != 0) {
     return errno;
diff --git a/metricsd/metrics_daemon_test.cc b/metricsd/metrics_daemon_test.cc
index 3a8fc3a..d3c9a23 100644
--- a/metricsd/metrics_daemon_test.cc
+++ b/metricsd/metrics_daemon_test.cc
@@ -20,7 +20,7 @@
 #include <base/files/file_util.h>
 #include <base/files/scoped_temp_dir.h>
 #include <base/strings/string_number_conversions.h>
-#include <chromeos/flag_helper.h>
+#include <brillo/flag_helper.h>
 #include <gtest/gtest.h>
 
 #include "constants.h"
@@ -43,7 +43,7 @@
 class MetricsDaemonTest : public testing::Test {
  protected:
   virtual void SetUp() {
-    chromeos::FlagHelper::Init(0, nullptr, "");
+    brillo::FlagHelper::Init(0, nullptr, "");
     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     scaling_max_freq_path_ = temp_dir_.path().Append("scaling_max");
     cpu_max_freq_path_ = temp_dir_.path().Append("cpu_freq_max");
diff --git a/metricsd/uploader/sender_http.cc b/metricsd/uploader/sender_http.cc
index 953afc1..4b572a6 100644
--- a/metricsd/uploader/sender_http.cc
+++ b/metricsd/uploader/sender_http.cc
@@ -20,8 +20,8 @@
 
 #include <base/logging.h>
 #include <base/strings/string_number_conversions.h>
-#include <chromeos/http/http_utils.h>
-#include <chromeos/mime_utils.h>
+#include <brillo/http/http_utils.h>
+#include <brillo/mime_utils.h>
 
 HttpSender::HttpSender(const std::string server_url)
     : server_url_(server_url) {}
@@ -31,14 +31,14 @@
   const std::string hash =
       base::HexEncode(content_hash.data(), content_hash.size());
 
-  chromeos::http::HeaderList headers = {{"X-Chrome-UMA-Log-SHA1", hash}};
-  chromeos::ErrorPtr error;
-  auto response = chromeos::http::PostTextAndBlock(
+  brillo::http::HeaderList headers = {{"X-Chrome-UMA-Log-SHA1", hash}};
+  brillo::ErrorPtr error;
+  auto response = brillo::http::PostTextAndBlock(
       server_url_,
       content,
-      chromeos::mime::application::kWwwFormUrlEncoded,
+      brillo::mime::application::kWwwFormUrlEncoded,
       headers,
-      chromeos::http::Transport::CreateDefault(),
+      brillo::http::Transport::CreateDefault(),
       &error);
   if (!response || response->ExtractDataAsString() != "OK") {
     if (error) {