Merge "Merge SP1A.201015.001 Change-Id: Idf7137d68ac83320742eace6e055045c3279f769" into s-keystone-qcom-dev
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 0b4a925..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-filegroup {
-    name: "android_filesystem_config_header",
-    srcs: ["include/private/android_filesystem_config.h"],
-}
diff --git a/OWNERS b/OWNERS
index 682a067..4f8e433 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1,2 @@
 enh@google.com
+baligh@google.com
diff --git a/adb/Android.bp b/adb/Android.bp
index df2c0f9..5c1e1fe 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -25,6 +25,7 @@
         "-Wextra",
         "-Werror",
         "-Wexit-time-destructors",
+        "-Wno-non-virtual-dtor",
         "-Wno-unused-parameter",
         "-Wno-missing-field-initializers",
         "-Wthread-safety",
diff --git a/adb/client/bugreport.cpp b/adb/client/bugreport.cpp
index f2e722a..b765a30 100644
--- a/adb/client/bugreport.cpp
+++ b/adb/client/bugreport.cpp
@@ -224,7 +224,8 @@
         // 'bugreport' would generate a lot of output the user might not be prepared to handle).
         fprintf(stderr,
                 "Failed to get bugreportz version: 'bugreportz -v' returned '%s' (code %d).\n"
-                "If the device does not run Android 7.0 or above, try 'adb bugreport' instead.\n",
+                "If the device does not run Android 7.0 or above, try this instead:\n"
+                "\tadb bugreport > bugreport.txt\n",
                 bugz_output.c_str(), status);
         return status != 0 ? status : -1;
     }
diff --git a/cli-test/cli-test.cpp b/cli-test/cli-test.cpp
index d6e27ee..d1ef1b4 100644
--- a/cli-test/cli-test.cpp
+++ b/cli-test/cli-test.cpp
@@ -146,6 +146,13 @@
       test->befores.push_back(line);
     } else if (Match(&line, "after:")) {
       test->afters.push_back(line);
+    } else if (Match(&line, "expected-exit-status:")) {
+      char* end_p;
+      errno = 0;
+      test->exit_status = strtol(line.c_str(), &end_p, 10);
+      if (errno != 0 || *end_p != '\0') {
+        Die(0, "%s:%zu: bad exit status: \"%s\"", g_file, g_line, line.c_str());
+      }
     } else if (Match(&line, "expected-stdout:")) {
       // Collect tab-indented lines.
       std::string text;
@@ -231,15 +238,15 @@
       V("running command \"%s\"", test.command.c_str());
       CapturedStdout test_stdout;
       CapturedStderr test_stderr;
-      int exit_status = system(test.command.c_str());
+      int status = system(test.command.c_str());
       test_stdout.Stop();
       test_stderr.Stop();
 
-      V("exit status %d", exit_status);
-      if (exit_status != test.exit_status) {
+      V("system() returned status %d", status);
+      if (WEXITSTATUS(status) != test.exit_status) {
         failed = true;
         fprintf(stderr, "Incorrect exit status: expected %d but %s\n", test.exit_status,
-                ExitStatusToString(exit_status).c_str());
+                ExitStatusToString(status).c_str());
       }
 
       if (!CheckOutput("stdout", test_stdout.str(), test.expected_stdout, FILES)) failed = true;
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index b54da86..e16a3a2 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -342,6 +342,12 @@
     apex_available: [
         "com.android.runtime",
     ],
+
+    product_variables: {
+        experimental_mte: {
+            cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
+        },
+    },
 }
 
 cc_binary {
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index d7cb972..5280121 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -40,6 +40,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
+#include <bionic/mte_kernel.h>
 #include <bionic/reserved_signals.h>
 #include <cutils/sockets.h>
 #include <log/log.h>
@@ -486,6 +487,17 @@
         continue;
       }
 
+#ifdef ANDROID_EXPERIMENTAL_MTE
+      struct iovec iov = {
+          &info.tagged_addr_ctrl,
+          sizeof(info.tagged_addr_ctrl),
+      };
+      if (ptrace(PTRACE_GETREGSET, thread, NT_ARM_TAGGED_ADDR_CTRL,
+                 reinterpret_cast<void*>(&iov)) == -1) {
+        info.tagged_addr_ctrl = -1;
+      }
+#endif
+
       if (thread == g_target_thread) {
         // Read the thread's registers along with the rest of the crash info out of the pipe.
         ReadCrashInfo(input_pipe, &siginfo, &info.registers, &process_info);
@@ -585,8 +597,8 @@
   }
 
   // TODO: Use seccomp to lock ourselves down.
-  unwindstack::UnwinderFromPid unwinder(256, vm_pid);
-  if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
+  unwindstack::UnwinderFromPid unwinder(256, vm_pid, unwindstack::Regs::CurrentArch());
+  if (!unwinder.Init()) {
     LOG(FATAL) << "Failed to init unwinder object.";
   }
 
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 108787e..5ed9e57 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -309,6 +309,11 @@
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
   ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
+
+  if (mte_supported()) {
+    // Test that the default TAGGED_ADDR_CTRL value is set.
+    ASSERT_MATCH(result, R"(tagged_addr_ctrl: 000000000007fff3)");
+  }
 }
 
 TEST_F(CrasherTest, tagged_fault_addr) {
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index 9bcbdb3..e103c82 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -82,16 +82,12 @@
     thread.pid = getpid();
     thread.tid = gettid();
     thread.thread_name = get_thread_name(gettid());
-    unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch();
-    thread.registers.reset(unwindstack::Regs::CreateFromUcontext(arch, ucontext));
+    thread.registers.reset(
+        unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
 
     // TODO: Create this once and store it in a global?
     unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid());
-    if (unwinder.Init(arch)) {
-      dump_backtrace_thread(output_fd, &unwinder, thread);
-    } else {
-      async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Unable to init unwinder.");
-    }
+    dump_backtrace_thread(output_fd, &unwinder, thread);
   }
   __linker_disable_fallback_allocator();
 }
@@ -237,6 +233,8 @@
   // Fetch output fd from tombstoned.
   unique_fd tombstone_socket, output_fd;
   if (!tombstoned_connect(getpid(), &tombstone_socket, &output_fd, kDebuggerdNativeBacktrace)) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "missing crash_dump_fallback() in selinux policy?");
     goto exit;
   }
 
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index f5a873c..c543a83 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -18,8 +18,9 @@
 
 #include "libdebuggerd/backtrace.h"
 
-#include <errno.h>
 #include <dirent.h>
+#include <errno.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -65,7 +66,11 @@
   unwinder->SetRegs(thread.registers.get());
   unwinder->Unwind();
   if (unwinder->NumFrames() == 0) {
-    _LOG(&log, logtype::THREAD, "Unwind failed: tid = %d", thread.tid);
+    _LOG(&log, logtype::THREAD, "Unwind failed: tid = %d\n", thread.tid);
+    if (unwinder->LastErrorCode() != unwindstack::ERROR_NONE) {
+      _LOG(&log, logtype::THREAD, "  Error code: %s\n", unwinder->LastErrorCodeString());
+      _LOG(&log, logtype::THREAD, "  Error address: 0x%" PRIx64 "\n", unwinder->LastErrorAddress());
+    }
     return;
   }
 
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/types.h b/debuggerd/libdebuggerd/include/libdebuggerd/types.h
index 04c4b5c..30e75e1 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/types.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/types.h
@@ -23,6 +23,7 @@
 
 struct ThreadInfo {
   std::unique_ptr<unwindstack::Regs> registers;
+  long tagged_addr_ctrl = -1;
 
   pid_t uid;
 
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 7af99c9..d88c5a9 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -180,6 +180,9 @@
   _LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s  >>> %s <<<\n", thread_info.pid,
        thread_info.tid, thread_info.thread_name.c_str(), thread_info.process_name.c_str());
   _LOG(log, logtype::HEADER, "uid: %d\n", thread_info.uid);
+  if (thread_info.tagged_addr_ctrl != -1) {
+    _LOG(log, logtype::HEADER, "tagged_addr_ctrl: %016lx\n", thread_info.tagged_addr_ctrl);
+  }
 }
 
 static std::string get_addr_string(uint64_t addr) {
@@ -404,7 +407,11 @@
   unwinder->SetRegs(regs_copy.get());
   unwinder->Unwind();
   if (unwinder->NumFrames() == 0) {
-    _LOG(log, logtype::THREAD, "Failed to unwind");
+    _LOG(log, logtype::THREAD, "Failed to unwind\n");
+    if (unwinder->LastErrorCode() != unwindstack::ERROR_NONE) {
+      _LOG(log, logtype::THREAD, "  Error code: %s\n", unwinder->LastErrorCodeString());
+      _LOG(log, logtype::THREAD, "  Error address: 0x%" PRIx64 "\n", unwinder->LastErrorAddress());
+    }
   } else {
     _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
     log_backtrace(log, unwinder, "    ");
@@ -575,8 +582,8 @@
       .siginfo = siginfo,
   };
 
-  unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid);
-  if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
+  unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid, unwindstack::Regs::CurrentArch());
+  if (!unwinder.Init()) {
     LOG(FATAL) << "Failed to init unwinder object.";
   }
 
diff --git a/debuggerd/tombstoned/tombstoned.rc b/debuggerd/tombstoned/tombstoned.rc
index b4a1e71..c39f4e4 100644
--- a/debuggerd/tombstoned/tombstoned.rc
+++ b/debuggerd/tombstoned/tombstoned.rc
@@ -6,6 +6,3 @@
     socket tombstoned_intercept seqpacket 0666 system system
     socket tombstoned_java_trace seqpacket 0666 system system
     writepid /dev/cpuset/system-background/tasks
-
-on post-fs-data
-    start tombstoned
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 81ebf43..fe05553 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -126,7 +126,7 @@
     shared_libs: [
         "android.hardware.boot@1.0",
         "android.hardware.boot@1.1",
-        "android.hardware.fastboot@1.0",
+        "android.hardware.fastboot@1.1",
         "android.hardware.health@2.0",
         "libasyncio",
         "libbase",
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 2553353..2b2a0bf 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -164,6 +164,28 @@
     return device->WriteOkay(message);
 }
 
+bool OemPostWipeData(FastbootDevice* device) {
+    auto fastboot_hal = device->fastboot_hal();
+    if (!fastboot_hal) {
+        return false;
+    }
+
+    Result ret;
+    auto ret_val = fastboot_hal->doOemSpecificErase([&](Result result) { ret = result; });
+    if (!ret_val.isOk()) {
+        return false;
+    }
+    if (ret.status == Status::NOT_SUPPORTED) {
+        return false;
+    } else if (ret.status != Status::SUCCESS) {
+        device->WriteStatus(FastbootResult::FAIL, ret.message);
+    } else {
+        device->WriteStatus(FastbootResult::OKAY, "Erasing succeeded");
+    }
+
+    return true;
+}
+
 bool EraseHandler(FastbootDevice* device, const std::vector<std::string>& args) {
     if (args.size() < 2) {
         return device->WriteStatus(FastbootResult::FAIL, "Invalid arguments");
@@ -184,7 +206,18 @@
         return device->WriteStatus(FastbootResult::FAIL, "Partition doesn't exist");
     }
     if (wipe_block_device(handle.fd(), get_block_device_size(handle.fd())) == 0) {
-        return device->WriteStatus(FastbootResult::OKAY, "Erasing succeeded");
+        //Perform oem PostWipeData if Android userdata partition has been erased
+        bool support_oem_postwipedata = false;
+        if (partition_name == "userdata") {
+            support_oem_postwipedata = OemPostWipeData(device);
+        }
+
+        if (!support_oem_postwipedata) {
+            return device->WriteStatus(FastbootResult::OKAY, "Erasing succeeded");
+        } else {
+            //Write device status in OemPostWipeData(), so just return true
+            return true;
+        }
     }
     return device->WriteStatus(FastbootResult::FAIL, "Erasing failed");
 }
@@ -195,6 +228,11 @@
         return device->WriteStatus(FastbootResult::FAIL, "Unable to open fastboot HAL");
     }
 
+    //Disable "oem postwipedata userdata" to prevent user wipe oem userdata only.
+    if (args[0] == "oem postwipedata userdata") {
+        return device->WriteStatus(FastbootResult::FAIL, "Unable to do oem postwipedata userdata");
+    }
+
     Result ret;
     auto ret_val = fastboot_hal->doOemCommand(args[0], [&](Result result) { ret = result; });
     if (!ret_val.isOk()) {
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 1b0859f..35f3de0 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -22,7 +22,7 @@
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <android/hardware/boot/1.0/IBootControl.h>
-#include <android/hardware/fastboot/1.0/IFastboot.h>
+#include <android/hardware/fastboot/1.1/IFastboot.h>
 #include <fs_mgr.h>
 #include <fs_mgr/roots.h>
 #include <healthhalutils/HealthHalUtils.h>
@@ -37,7 +37,7 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::boot::V1_0::IBootControl;
 using ::android::hardware::boot::V1_0::Slot;
-using ::android::hardware::fastboot::V1_0::IFastboot;
+using ::android::hardware::fastboot::V1_1::IFastboot;
 using ::android::hardware::health::V2_0::get_health_service;
 
 namespace sph = std::placeholders;
@@ -139,7 +139,13 @@
 bool FastbootDevice::HandleData(bool read, std::vector<char>* data) {
     auto read_write_data_size = read ? this->get_transport()->Read(data->data(), data->size())
                                      : this->get_transport()->Write(data->data(), data->size());
-    if (read_write_data_size == -1 || static_cast<size_t>(read_write_data_size) != data->size()) {
+    if (read_write_data_size == -1) {
+        LOG(ERROR) << (read ? "read from" : "write to") << " transport failed";
+        return false;
+    }
+    if (static_cast<size_t>(read_write_data_size) != data->size()) {
+        LOG(ERROR) << (read ? "read" : "write") << " expected " << data->size() << " bytes, got "
+                   << read_write_data_size;
         return false;
     }
     return true;
diff --git a/fastboot/device/fastboot_device.h b/fastboot/device/fastboot_device.h
index bbe8172..23be721 100644
--- a/fastboot/device/fastboot_device.h
+++ b/fastboot/device/fastboot_device.h
@@ -24,7 +24,7 @@
 
 #include <android/hardware/boot/1.0/IBootControl.h>
 #include <android/hardware/boot/1.1/IBootControl.h>
-#include <android/hardware/fastboot/1.0/IFastboot.h>
+#include <android/hardware/fastboot/1.1/IFastboot.h>
 #include <android/hardware/health/2.0/IHealth.h>
 
 #include "commands.h"
@@ -53,7 +53,7 @@
         return boot_control_hal_;
     }
     android::sp<android::hardware::boot::V1_1::IBootControl> boot1_1() { return boot1_1_; }
-    android::sp<android::hardware::fastboot::V1_0::IFastboot> fastboot_hal() {
+    android::sp<android::hardware::fastboot::V1_1::IFastboot> fastboot_hal() {
         return fastboot_hal_;
     }
     android::sp<android::hardware::health::V2_0::IHealth> health_hal() { return health_hal_; }
@@ -67,7 +67,7 @@
     android::sp<android::hardware::boot::V1_0::IBootControl> boot_control_hal_;
     android::sp<android::hardware::boot::V1_1::IBootControl> boot1_1_;
     android::sp<android::hardware::health::V2_0::IHealth> health_hal_;
-    android::sp<android::hardware::fastboot::V1_0::IFastboot> fastboot_hal_;
+    android::sp<android::hardware::fastboot::V1_1::IFastboot> fastboot_hal_;
     std::vector<char> download_data_;
     std::string active_slot_;
 };
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index c653167..2caced4 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -248,7 +248,12 @@
 }
 
 ssize_t ClientUsbTransport::Read(void* data, size_t len) {
-    if (handle_ == nullptr || len > SSIZE_MAX) {
+    if (handle_ == nullptr) {
+        LOG(ERROR) << "ClientUsbTransport: no handle";
+        return -1;
+    }
+    if (len > SSIZE_MAX) {
+        LOG(ERROR) << "ClientUsbTransport: maximum length exceeds bounds";
         return -1;
     }
     char* char_data = static_cast<char*>(data);
@@ -258,6 +263,7 @@
         auto bytes_read_now =
                 handle_->read(handle_.get(), char_data, bytes_to_read, true /* allow_partial */);
         if (bytes_read_now < 0) {
+            PLOG(ERROR) << "ClientUsbTransport: read failed";
             return bytes_read_total == 0 ? -1 : bytes_read_total;
         }
         bytes_read_total += bytes_read_now;
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index e425284..a0bc44d 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -99,7 +99,3 @@
         "liblog",
     ],
 }
-
-vts_config {
-    name: "VtsKernelLibdmTest",
-}
diff --git a/fs_mgr/libdm/AndroidTest.xml b/fs_mgr/libdm/AndroidTest.xml
deleted file mode 100644
index b4e0c23..0000000
--- a/fs_mgr/libdm/AndroidTest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-<configuration description="Config for VTS VtsKernelLibdmTest">
-    <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
-        <option name="abort-on-push-failure" value="false"/>
-        <option name="push-group" value="HostDrivenTest.push"/>
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-      <option name="test-module-name" value="VtsKernelLibdmTest"/>
-        <option name="binary-test-source" value="_32bit::DATA/nativetest/libdm_test/libdm_test" />
-        <option name="binary-test-source" value="_64bit::DATA/nativetest64/libdm_test/libdm_test" />
-        <option name="binary-test-type" value="gtest"/>
-        <option name="test-timeout" value="1m"/>
-        <option name="precondition-first-api-level" value="29" />
-    </test>
-</configuration>
-
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index a779a78..9517bd3 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -107,7 +107,3 @@
     name: "vts_kernel_liblp_test",
     defaults: ["liblp_test_defaults"],
 }
-
-vts_config {
-    name: "VtsKernelLiblpTest",
-}
diff --git a/fs_mgr/liblp/AndroidTest.xml b/fs_mgr/liblp/AndroidTest.xml
deleted file mode 100644
index 2eb0ad1..0000000
--- a/fs_mgr/liblp/AndroidTest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-<configuration description="Config for VTS VtsKernelLiblpTest">
-    <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
-        <option name="abort-on-push-failure" value="false"/>
-        <option name="push-group" value="HostDrivenTest.push"/>
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-      <option name="test-module-name" value="VtsKernelLiblpTest"/>
-        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_kernel_liblp_test/vts_kernel_liblp_test" />
-        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_kernel_liblp_test/vts_kernel_liblp_test" />
-        <option name="binary-test-type" value="gtest"/>
-        <option name="test-timeout" value="1m"/>
-        <option name="precondition-first-api-level" value="29" />
-    </test>
-</configuration>
-
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 0bb1b87..6e81c8b 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -30,6 +30,7 @@
     static_libs: [
         "libdm",
         "libfstab",
+        "libsnapshot_cow",
         "update_metadata-protos",
     ],
     whole_static_libs: [
@@ -38,7 +39,9 @@
         "libfstab",
     ],
     header_libs: [
+        "libchrome",
         "libfiemap_headers",
+        "libupdate_engine_headers",
     ],
     export_static_lib_headers: [
         "update_metadata-protos",
@@ -158,6 +161,38 @@
     ramdisk_available: true,
 }
 
+cc_defaults {
+    name: "libsnapshot_snapuserd_defaults",
+    defaults: [
+        "fs_mgr_defaults",
+    ],
+    cflags: [
+        "-D_FILE_OFFSET_BITS=64",
+        "-Wall",
+        "-Werror",
+    ],
+    export_include_dirs: ["include"],
+    srcs: [
+        "snapuserd_client.cpp",
+    ],
+}
+
+cc_library_static {
+    name: "libsnapshot_snapuserd",
+    defaults: [
+        "libsnapshot_snapuserd_defaults",
+    ],
+    recovery_available: true,
+    static_libs: [
+        "libcutils_sockets",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+    ramdisk_available: true,
+}
+
 cc_library_static {
     name: "libsnapshot_test_helpers",
     defaults: ["libsnapshot_defaults"],
@@ -232,12 +267,6 @@
     defaults: ["libsnapshot_test_defaults"],
 }
 
-// For VTS 10
-vts_config {
-    name: "VtsLibsnapshotTest",
-    test_config: "VtsLibsnapshotTest.xml"
-}
-
 cc_binary {
     name: "snapshotctl",
     srcs: [
@@ -313,8 +342,10 @@
         "libprotobuf-mutator",
     ],
     header_libs: [
+        "libchrome",
         "libfiemap_headers",
         "libstorage_literals_headers",
+        "libupdate_engine_headers",
     ],
     proto: {
         type: "full",
@@ -353,7 +384,9 @@
         "fs_mgr_defaults",
     ],
     srcs: [
+	"snapuserd_server.cpp",
         "snapuserd.cpp",
+	"snapuserd_daemon.cpp",
     ],
 
     cflags: [
@@ -364,6 +397,7 @@
     static_libs: [
         "libbase",
         "libbrotli",
+	"libcutils_sockets",
         "liblog",
         "libdm",
         "libz",
@@ -503,6 +537,8 @@
         "libbrotli",
         "libgtest",
         "libsnapshot_cow",
+	"libsnapshot_snapuserd",
+        "libcutils_sockets",
         "libz",
     ],
     header_libs: [
diff --git a/fs_mgr/libsnapshot/VtsLibsnapshotTest.xml b/fs_mgr/libsnapshot/VtsLibsnapshotTest.xml
deleted file mode 100644
index b53b51e..0000000
--- a/fs_mgr/libsnapshot/VtsLibsnapshotTest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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.
--->
-<configuration description="Config for VTS VtsLibsnapshotTest">
-    <option name="config-descriptor:metadata" key="plan" value="vts-kernel"/>
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
-        <option name="abort-on-push-failure" value="false"/>
-        <option name="push-group" value="HostDrivenTest.push"/>
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-        <option name="test-module-name" value="VtsLibsnapshotTest"/>
-        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_libsnapshot_test/vts_libsnapshot_test"/>
-        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_libsnapshot_test/vts_libsnapshot_test"/>
-        <option name="binary-test-type" value="gtest"/>
-        <option name="test-timeout" value="5m"/>
-    </test>
-</configuration>
diff --git a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
index 80acb4a..75e54f7 100644
--- a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
@@ -26,6 +26,7 @@
 #include <android-base/unique_fd.h>
 #include <gtest/gtest.h>
 #include <libsnapshot/cow_writer.h>
+#include <libsnapshot/snapuserd_client.h>
 #include <storage_literals/storage_literals.h>
 
 namespace android {
@@ -43,17 +44,29 @@
         cow_product_ = std::make_unique<TemporaryFile>();
         ASSERT_GE(cow_product_->fd, 0) << strerror(errno);
 
+        cow_system_1_ = std::make_unique<TemporaryFile>();
+        ASSERT_GE(cow_system_1_->fd, 0) << strerror(errno);
+
+        cow_product_1_ = std::make_unique<TemporaryFile>();
+        ASSERT_GE(cow_product_1_->fd, 0) << strerror(errno);
+
         size_ = 100_MiB;
     }
 
     void TearDown() override {
         cow_system_ = nullptr;
         cow_product_ = nullptr;
+
+        cow_system_1_ = nullptr;
+        cow_product_1_ = nullptr;
     }
 
     std::unique_ptr<TemporaryFile> cow_system_;
     std::unique_ptr<TemporaryFile> cow_product_;
 
+    std::unique_ptr<TemporaryFile> cow_system_1_;
+    std::unique_ptr<TemporaryFile> cow_product_1_;
+
     unique_fd sys_fd_;
     unique_fd product_fd_;
     size_t size_;
@@ -71,12 +84,14 @@
 
     void Init();
     void CreateCowDevice(std::unique_ptr<TemporaryFile>& cow);
-    void CreateSystemDmUser();
-    void CreateProductDmUser();
+    void CreateSystemDmUser(std::unique_ptr<TemporaryFile>& cow);
+    void CreateProductDmUser(std::unique_ptr<TemporaryFile>& cow);
     void StartSnapuserdDaemon();
     void CreateSnapshotDevices();
+    void SwitchSnapshotDevices();
 
-    void TestIO(unique_fd& snapshot_fd, std::unique_ptr<uint8_t[]>&& buf);
+    void TestIO(unique_fd& snapshot_fd, std::unique_ptr<uint8_t[]>& buffer);
+    SnapuserdClient client_;
 };
 
 void SnapuserdTest::Init() {
@@ -112,7 +127,7 @@
     // Read from system partition from offset 0 of size 100MB
     ASSERT_EQ(ReadFullyAtOffset(sys_fd_, system_buffer_.get(), size_, 0), true);
 
-    // Read from system partition from offset 0 of size 100MB
+    // Read from product partition from offset 0 of size 100MB
     ASSERT_EQ(ReadFullyAtOffset(product_fd_, product_buffer_.get(), size_, 0), true);
 }
 
@@ -167,9 +182,10 @@
     ASSERT_EQ(lseek(cow->fd, 0, SEEK_SET), 0);
 }
 
-void SnapuserdTest::CreateSystemDmUser() {
+void SnapuserdTest::CreateSystemDmUser(std::unique_ptr<TemporaryFile>& cow) {
     unique_fd system_a_fd;
     std::string cmd;
+    system_device_name_.clear();
 
     // Create a COW device. Number of sectors is chosen random which can
     // hold at least 400MB of data
@@ -180,7 +196,7 @@
     int err = ioctl(system_a_fd.get(), BLKGETSIZE, &system_blksize_);
     ASSERT_GE(err, 0);
 
-    std::string str(cow_system_->path);
+    std::string str(cow->path);
     std::size_t found = str.find_last_of("/\\");
     ASSERT_NE(found, std::string::npos);
     system_device_name_ = str.substr(found + 1);
@@ -189,9 +205,10 @@
     system(cmd.c_str());
 }
 
-void SnapuserdTest::CreateProductDmUser() {
+void SnapuserdTest::CreateProductDmUser(std::unique_ptr<TemporaryFile>& cow) {
     unique_fd product_a_fd;
     std::string cmd;
+    product_device_name_.clear();
 
     // Create a COW device. Number of sectors is chosen random which can
     // hold at least 400MB of data
@@ -202,7 +219,7 @@
     int err = ioctl(product_a_fd.get(), BLKGETSIZE, &product_blksize_);
     ASSERT_GE(err, 0);
 
-    std::string str(cow_product_->path);
+    std::string str(cow->path);
     std::size_t found = str.find_last_of("/\\");
     ASSERT_NE(found, std::string::npos);
     product_device_name_ = str.substr(found + 1);
@@ -212,15 +229,16 @@
 }
 
 void SnapuserdTest::StartSnapuserdDaemon() {
-    // Start the snapuserd daemon
-    if (fork() == 0) {
-        const char* argv[] = {"/system/bin/snapuserd",       cow_system_->path,
-                              "/dev/block/mapper/system_a",  cow_product_->path,
-                              "/dev/block/mapper/product_a", nullptr};
-        if (execv(argv[0], const_cast<char**>(argv))) {
-            ASSERT_TRUE(0);
-        }
-    }
+    int ret;
+
+    ret = client_.StartSnapuserd();
+    ASSERT_EQ(ret, 0);
+
+    ret = client_.InitializeSnapuserd(cow_system_->path, "/dev/block/mapper/system_a");
+    ASSERT_EQ(ret, 0);
+
+    ret = client_.InitializeSnapuserd(cow_product_->path, "/dev/block/mapper/product_a");
+    ASSERT_EQ(ret, 0);
 }
 
 void SnapuserdTest::CreateSnapshotDevices() {
@@ -243,9 +261,29 @@
     system(cmd.c_str());
 }
 
-void SnapuserdTest::TestIO(unique_fd& snapshot_fd, std::unique_ptr<uint8_t[]>&& buf) {
+void SnapuserdTest::SwitchSnapshotDevices() {
+    std::string cmd;
+
+    cmd = "dmctl create system-snapshot-1 -ro snapshot 0 " + std::to_string(system_blksize_);
+    cmd += " /dev/block/mapper/system_a";
+    cmd += " /dev/block/mapper/" + system_device_name_;
+    cmd += " P 8";
+
+    system(cmd.c_str());
+
+    cmd.clear();
+
+    cmd = "dmctl create product-snapshot-1 -ro snapshot 0 " + std::to_string(product_blksize_);
+    cmd += " /dev/block/mapper/product_a";
+    cmd += " /dev/block/mapper/" + product_device_name_;
+    cmd += " P 8";
+
+    system(cmd.c_str());
+}
+
+void SnapuserdTest::TestIO(unique_fd& snapshot_fd, std::unique_ptr<uint8_t[]>& buffer) {
     loff_t offset = 0;
-    std::unique_ptr<uint8_t[]> buffer = std::move(buf);
+    // std::unique_ptr<uint8_t[]> buffer = std::move(buf);
 
     std::unique_ptr<uint8_t[]> snapuserd_buffer = std::make_unique<uint8_t[]>(size_);
 
@@ -326,8 +364,8 @@
     CreateCowDevice(cow_system_);
     CreateCowDevice(cow_product_);
 
-    CreateSystemDmUser();
-    CreateProductDmUser();
+    CreateSystemDmUser(cow_system_);
+    CreateProductDmUser(cow_product_);
 
     StartSnapuserdDaemon();
 
@@ -335,11 +373,44 @@
 
     snapshot_fd.reset(open("/dev/block/mapper/system-snapshot", O_RDONLY));
     ASSERT_TRUE(snapshot_fd > 0);
-    TestIO(snapshot_fd, std::move(system_buffer_));
+    TestIO(snapshot_fd, system_buffer_);
 
     snapshot_fd.reset(open("/dev/block/mapper/product-snapshot", O_RDONLY));
     ASSERT_TRUE(snapshot_fd > 0);
-    TestIO(snapshot_fd, std::move(product_buffer_));
+    TestIO(snapshot_fd, product_buffer_);
+
+    // Sequence of operations for transition
+    CreateCowDevice(cow_system_1_);
+    CreateCowDevice(cow_product_1_);
+
+    CreateSystemDmUser(cow_system_1_);
+    CreateProductDmUser(cow_product_1_);
+
+    std::vector<std::pair<std::string, std::string>> vec;
+    vec.push_back(std::make_pair(cow_system_1_->path, "/dev/block/mapper/system_a"));
+    vec.push_back(std::make_pair(cow_product_1_->path, "/dev/block/mapper/product_a"));
+
+    // Start the second stage deamon and send the devices
+    ASSERT_EQ(client_.RestartSnapuserd(vec), 0);
+
+    // TODO: This is not switching snapshot device but creates a new table;
+    // however, it should serve the testing purpose.
+    SwitchSnapshotDevices();
+
+    // Stop the first stage daemon
+    ASSERT_EQ(client_.StopSnapuserd(true), 0);
+
+    // Test the IO again with the second stage daemon
+    snapshot_fd.reset(open("/dev/block/mapper/system-snapshot-1", O_RDONLY));
+    ASSERT_TRUE(snapshot_fd > 0);
+    TestIO(snapshot_fd, system_buffer_);
+
+    snapshot_fd.reset(open("/dev/block/mapper/product-snapshot-1", O_RDONLY));
+    ASSERT_TRUE(snapshot_fd > 0);
+    TestIO(snapshot_fd, product_buffer_);
+
+    // Stop the second stage daemon
+    ASSERT_EQ(client_.StopSnapuserd(false), 0);
 }
 
 }  // namespace snapshot
diff --git a/fs_mgr/libsnapshot/cow_writer.cpp b/fs_mgr/libsnapshot/cow_writer.cpp
index 4cf2119..70fdac1 100644
--- a/fs_mgr/libsnapshot/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/cow_writer.cpp
@@ -32,6 +32,45 @@
 
 static_assert(sizeof(off_t) == sizeof(uint64_t));
 
+bool ICowWriter::AddCopy(uint64_t new_block, uint64_t old_block) {
+    if (!ValidateNewBlock(new_block)) {
+        return false;
+    }
+    return EmitCopy(new_block, old_block);
+}
+
+bool ICowWriter::AddRawBlocks(uint64_t new_block_start, const void* data, size_t size) {
+    if (size % options_.block_size != 0) {
+        LOG(ERROR) << "AddRawBlocks: size " << size << " is not a multiple of "
+                   << options_.block_size;
+        return false;
+    }
+
+    uint64_t num_blocks = size / options_.block_size;
+    uint64_t last_block = new_block_start + num_blocks - 1;
+    if (!ValidateNewBlock(last_block)) {
+        return false;
+    }
+    return EmitRawBlocks(new_block_start, data, size);
+}
+
+bool ICowWriter::AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) {
+    uint64_t last_block = new_block_start + num_blocks - 1;
+    if (!ValidateNewBlock(last_block)) {
+        return false;
+    }
+    return EmitZeroBlocks(new_block_start, num_blocks);
+}
+
+bool ICowWriter::ValidateNewBlock(uint64_t new_block) {
+    if (options_.max_blocks && new_block >= options_.max_blocks.value()) {
+        LOG(ERROR) << "New block " << new_block << " exceeds maximum block count "
+                   << options_.max_blocks.value();
+        return false;
+    }
+    return true;
+}
+
 CowWriter::CowWriter(const CowOptions& options) : ICowWriter(options), fd_(-1) {
     SetupHeaders();
 }
@@ -134,7 +173,7 @@
     return true;
 }
 
-bool CowWriter::AddCopy(uint64_t new_block, uint64_t old_block) {
+bool CowWriter::EmitCopy(uint64_t new_block, uint64_t old_block) {
     CowOperation op = {};
     op.type = kCowCopyOp;
     op.new_block = new_block;
@@ -143,13 +182,7 @@
     return true;
 }
 
-bool CowWriter::AddRawBlocks(uint64_t new_block_start, const void* data, size_t size) {
-    if (size % header_.block_size != 0) {
-        LOG(ERROR) << "AddRawBlocks: size " << size << " is not a multiple of "
-                   << header_.block_size;
-        return false;
-    }
-
+bool CowWriter::EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) {
     uint64_t pos;
     if (!GetDataPos(&pos)) {
         return false;
@@ -195,7 +228,7 @@
     return true;
 }
 
-bool CowWriter::AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) {
+bool CowWriter::EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) {
     for (uint64_t i = 0; i < num_blocks; i++) {
         CowOperation op = {};
         op.type = kCowZeroOp;
@@ -291,7 +324,7 @@
     return true;
 }
 
-size_t CowWriter::GetCowSize() {
+uint64_t CowWriter::GetCowSize() {
     return header_.ops_offset + header_.num_ops * sizeof(CowOperation);
 }
 
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
index 8569161..245da0c 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
@@ -16,6 +16,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
 #include <android-base/unique_fd.h>
@@ -27,6 +28,9 @@
 struct CowOptions {
     uint32_t block_size = 4096;
     std::string compression;
+
+    // Maximum number of blocks that can be written.
+    std::optional<uint64_t> max_blocks;
 };
 
 // Interface for writing to a snapuserd COW. All operations are ordered; merges
@@ -39,20 +43,29 @@
 
     // Encode an operation that copies the contents of |old_block| to the
     // location of |new_block|.
-    virtual bool AddCopy(uint64_t new_block, uint64_t old_block) = 0;
+    bool AddCopy(uint64_t new_block, uint64_t old_block);
 
     // Encode a sequence of raw blocks. |size| must be a multiple of the block size.
-    virtual bool AddRawBlocks(uint64_t new_block_start, const void* data, size_t size) = 0;
+    bool AddRawBlocks(uint64_t new_block_start, const void* data, size_t size);
 
     // Encode a sequence of zeroed blocks. |size| must be a multiple of the block size.
-    virtual bool AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) = 0;
+    bool AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks);
 
     // Flush all pending writes. This must be called before closing the writer
     // to ensure that the correct headers and footers are written.
     virtual bool Flush() = 0;
 
     // Return number of bytes the cow image occupies on disk.
-    virtual size_t GetCowSize() = 0;
+    virtual uint64_t GetCowSize() = 0;
+
+    const CowOptions& options() { return options_; }
+
+  protected:
+    virtual bool EmitCopy(uint64_t new_block, uint64_t old_block) = 0;
+    virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) = 0;
+    virtual bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) = 0;
+
+    bool ValidateNewBlock(uint64_t new_block);
 
   protected:
     CowOptions options_;
@@ -68,13 +81,14 @@
     bool Initialize(android::base::unique_fd&& fd, OpenMode mode = OpenMode::WRITE);
     bool Initialize(android::base::borrowed_fd fd, OpenMode mode = OpenMode::WRITE);
 
-    bool AddCopy(uint64_t new_block, uint64_t old_block) override;
-    bool AddRawBlocks(uint64_t new_block_start, const void* data, size_t size) override;
-    bool AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override;
-
     bool Flush() override;
 
-    size_t GetCowSize() override;
+    uint64_t GetCowSize() override;
+
+  protected:
+    virtual bool EmitCopy(uint64_t new_block, uint64_t old_block) override;
+    virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override;
+    virtual bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override;
 
   private:
     void SetupHeaders();
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
index 4457de3..eb6ad05 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
@@ -15,6 +15,7 @@
 #pragma once
 
 #include <libsnapshot/snapshot.h>
+#include <payload_consumer/file_descriptor.h>
 
 #include <gmock/gmock.h>
 
@@ -37,6 +38,10 @@
                 (const android::fs_mgr::CreateLogicalPartitionParams& params,
                  std::string* snapshot_path),
                 (override));
+    MOCK_METHOD(std::unique_ptr<ICowWriter>, OpenSnapshotWriter,
+                (const android::fs_mgr::CreateLogicalPartitionParams& params), (override));
+    MOCK_METHOD(std::unique_ptr<FileDescriptor>, OpenSnapshotReader,
+                (const android::fs_mgr::CreateLogicalPartitionParams& params), (override));
     MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override));
     MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override));
     MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions,
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index a4a3150..6fef58a 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -35,6 +35,7 @@
 #include <update_engine/update_metadata.pb.h>
 
 #include <libsnapshot/auto_device.h>
+#include <libsnapshot/cow_writer.h>
 #include <libsnapshot/return.h>
 
 #ifndef FRIEND_TEST
@@ -43,6 +44,10 @@
 #define DEFINED_FRIEND_TEST
 #endif
 
+namespace chromeos_update_engine {
+class FileDescriptor;
+}  // namespace chromeos_update_engine
+
 namespace android {
 
 namespace fiemap {
@@ -105,6 +110,8 @@
     };
     virtual ~ISnapshotManager() = default;
 
+    using FileDescriptor = chromeos_update_engine::FileDescriptor;
+
     // Begin an update. This must be called before creating any snapshots. It
     // will fail if GetUpdateState() != None.
     virtual bool BeginUpdate() = 0;
@@ -173,11 +180,26 @@
 
     // Map a snapshotted partition for OTA clients to write to. Write-protected regions are
     // determined previously in CreateSnapshots.
+    //
     // |snapshot_path| must not be nullptr.
+    //
+    // This method will return false if ro.virtual_ab.compression.enabled is true.
     virtual bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
                                    std::string* snapshot_path) = 0;
 
-    // Unmap a snapshot device that's previously mapped with MapUpdateSnapshot.
+    // Create an ICowWriter to build a snapshot against a target partition. The partition name must
+    // be suffixed.
+    virtual std::unique_ptr<ICowWriter> OpenSnapshotWriter(
+            const android::fs_mgr::CreateLogicalPartitionParams& params) = 0;
+
+    // Open a snapshot for reading. A file-like interface is provided through the FileDescriptor.
+    // In this mode, writes are not supported. The partition name must be suffixed.
+    virtual std::unique_ptr<FileDescriptor> OpenSnapshotReader(
+            const android::fs_mgr::CreateLogicalPartitionParams& params) = 0;
+
+    // Unmap a snapshot device or CowWriter that was previously opened with MapUpdateSnapshot,
+    // OpenSnapshotWriter, or OpenSnapshotReader. All outstanding open descriptors, writers,
+    // or readers must be deleted before this is called.
     virtual bool UnmapUpdateSnapshot(const std::string& target_partition_name) = 0;
 
     // If this returns true, first-stage mount must call
@@ -288,6 +310,10 @@
     Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override;
     bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
                            std::string* snapshot_path) override;
+    std::unique_ptr<ICowWriter> OpenSnapshotWriter(
+            const android::fs_mgr::CreateLogicalPartitionParams& params) override;
+    std::unique_ptr<FileDescriptor> OpenSnapshotReader(
+            const android::fs_mgr::CreateLogicalPartitionParams& params) override;
     bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
     bool NeedSnapshotsInFirstStageMount() override;
     bool CreateLogicalAndSnapshotPartitions(
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
index 7a27fad..149f463 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
@@ -15,6 +15,7 @@
 #pragma once
 
 #include <libsnapshot/snapshot.h>
+#include <payload_consumer/file_descriptor.h>
 
 namespace android::snapshot {
 
@@ -35,6 +36,10 @@
             const chromeos_update_engine::DeltaArchiveManifest& manifest) override;
     bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
                            std::string* snapshot_path) override;
+    std::unique_ptr<ICowWriter> OpenSnapshotWriter(
+            const android::fs_mgr::CreateLogicalPartitionParams& params) override;
+    std::unique_ptr<FileDescriptor> OpenSnapshotReader(
+            const android::fs_mgr::CreateLogicalPartitionParams& params) override;
     bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
     bool NeedSnapshotsInFirstStageMount() override;
     bool CreateLogicalAndSnapshotPartitions(
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd.h b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd.h
index e757579..d495014 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd.h
@@ -14,85 +14,94 @@
 
 #pragma once
 
+#include <linux/types.h>
 #include <stdint.h>
+#include <stdlib.h>
+
+#include <csignal>
+#include <cstring>
+#include <iostream>
+#include <limits>
+#include <string>
+#include <thread>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <libdm/dm.h>
+#include <libsnapshot/cow_reader.h>
+#include <libsnapshot/cow_writer.h>
+#include <libsnapshot/snapuserd_kernel.h>
 
 namespace android {
 namespace snapshot {
 
-// Kernel COW header fields
-static constexpr uint32_t SNAP_MAGIC = 0x70416e53;
+using android::base::unique_fd;
 
-static constexpr uint32_t SNAPSHOT_DISK_VERSION = 1;
+class BufferSink : public IByteSink {
+  public:
+    void Initialize(size_t size);
+    void* GetBufPtr() { return buffer_.get(); }
+    void Clear() { memset(GetBufPtr(), 0, buffer_size_); }
+    void* GetPayloadBuffer(size_t size);
+    void* GetBuffer(size_t requested, size_t* actual) override;
+    void UpdateBufferOffset(size_t size) { buffer_offset_ += size; }
+    struct dm_user_header* GetHeaderPtr();
+    bool ReturnData(void*, size_t) override { return true; }
+    void ResetBufferOffset() { buffer_offset_ = 0; }
 
-static constexpr uint32_t NUM_SNAPSHOT_HDR_CHUNKS = 1;
-
-static constexpr uint32_t SNAPSHOT_VALID = 1;
-
-/*
- * The basic unit of block I/O is a sector. It is used in a number of contexts
- * in Linux (blk, bio, genhd). The size of one sector is 512 = 2**9
- * bytes. Variables of type sector_t represent an offset or size that is a
- * multiple of 512 bytes. Hence these two constants.
- */
-static constexpr uint32_t SECTOR_SHIFT = 9;
-
-typedef __u64 sector_t;
-typedef sector_t chunk_t;
-
-static constexpr uint32_t CHUNK_SIZE = 8;
-static constexpr uint32_t CHUNK_SHIFT = (__builtin_ffs(CHUNK_SIZE) - 1);
-
-static constexpr uint32_t BLOCK_SIZE = 4096;
-static constexpr uint32_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SIZE) - 1);
-
-// This structure represents the kernel COW header.
-// All the below fields should be in Little Endian format.
-struct disk_header {
-    uint32_t magic;
-
-    /*
-     * Is this snapshot valid.  There is no way of recovering
-     * an invalid snapshot.
-     */
-    uint32_t valid;
-
-    /*
-     * Simple, incrementing version. no backward
-     * compatibility.
-     */
-    uint32_t version;
-
-    /* In sectors */
-    uint32_t chunk_size;
-} __packed;
-
-// A disk exception is a mapping of old_chunk to new_chunk
-// old_chunk is the chunk ID of a dm-snapshot device.
-// new_chunk is the chunk ID of the COW device.
-struct disk_exception {
-    uint64_t old_chunk;
-    uint64_t new_chunk;
-} __packed;
-
-// Control structures to communicate with dm-user
-// It comprises of header and a payload
-struct dm_user_header {
-    __u64 seq;
-    __u64 type;
-    __u64 flags;
-    __u64 sector;
-    __u64 len;
-    __u64 io_in_progress;
-} __attribute__((packed));
-
-struct dm_user_payload {
-    __u8 buf[];
+  private:
+    std::unique_ptr<uint8_t[]> buffer_;
+    loff_t buffer_offset_;
+    size_t buffer_size_;
 };
 
-// Message comprising both header and payload
-struct dm_user_message {
-    struct dm_user_header header;
-    struct dm_user_payload payload;
+class Snapuserd final {
+  public:
+    Snapuserd(const std::string& in_cow_device, const std::string& in_backing_store_device)
+        : cow_device_(in_cow_device),
+          backing_store_device_(in_backing_store_device),
+          metadata_read_done_(false) {}
+
+    bool Init();
+    int Run();
+    int ReadDmUserHeader();
+    int WriteDmUserPayload(size_t size);
+    int ConstructKernelCowHeader();
+    int ReadMetadata();
+    int ZerofillDiskExceptions(size_t read_size);
+    int ReadDiskExceptions(chunk_t chunk, size_t size);
+    int ReadData(chunk_t chunk, size_t size);
+
+  private:
+    int ProcessReplaceOp(const CowOperation* cow_op);
+    int ProcessCopyOp(const CowOperation* cow_op);
+    int ProcessZeroOp();
+
+    std::string cow_device_;
+    std::string backing_store_device_;
+
+    unique_fd cow_fd_;
+    unique_fd backing_store_fd_;
+    unique_fd ctrl_fd_;
+
+    uint32_t exceptions_per_area_;
+
+    std::unique_ptr<ICowOpIter> cowop_iter_;
+    std::unique_ptr<CowReader> reader_;
+
+    // Vector of disk exception which is a
+    // mapping of old-chunk to new-chunk
+    std::vector<std::unique_ptr<uint8_t[]>> vec_;
+
+    // Index - Chunk ID
+    // Value - cow operation
+    std::vector<const CowOperation*> chunk_vec_;
+
+    bool metadata_read_done_;
+    BufferSink bufsink_;
 };
 
 }  // namespace snapshot
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_client.h b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_client.h
new file mode 100644
index 0000000..535e923
--- /dev/null
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_client.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2020 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.
+
+#pragma once
+
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace android {
+namespace snapshot {
+
+static constexpr uint32_t PACKET_SIZE = 512;
+static constexpr uint32_t MAX_CONNECT_RETRY_COUNT = 10;
+
+class SnapuserdClient {
+  private:
+    int sockfd_ = 0;
+
+    int Sendmsg(const char* msg, size_t size);
+    std::string Receivemsg();
+    int StartSnapuserdaemon(std::string socketname);
+    bool ConnectToServerSocket(std::string socketname);
+    bool ConnectToServer();
+
+    void DisconnectFromServer() { close(sockfd_); }
+
+    std::string GetSocketNameFirstStage() {
+        static std::string snapd_one("snapdone");
+        return snapd_one;
+    }
+
+    std::string GetSocketNameSecondStage() {
+        static std::string snapd_two("snapdtwo");
+        return snapd_two;
+    }
+
+  public:
+    int StartSnapuserd();
+    int StopSnapuserd(bool firstStageDaemon);
+    int RestartSnapuserd(std::vector<std::pair<std::string, std::string>>& vec);
+    int InitializeSnapuserd(std::string cow_device, std::string backing_device);
+};
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_daemon.h b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_daemon.h
new file mode 100644
index 0000000..94542d7
--- /dev/null
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_daemon.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2020 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.
+
+#pragma once
+
+#include <poll.h>
+
+#include <libsnapshot/snapuserd_server.h>
+
+namespace android {
+namespace snapshot {
+
+class Daemon {
+    // The Daemon class is a singleton to avoid
+    // instantiating more than once
+  public:
+    static Daemon& Instance() {
+        static Daemon instance;
+        return instance;
+    }
+
+    int StartServer(std::string socketname);
+    bool IsRunning();
+    void Run();
+
+  private:
+    bool is_running_;
+    std::unique_ptr<struct pollfd> poll_fd_;
+    // Signal mask used with ppoll()
+    sigset_t signal_mask_;
+
+    Daemon();
+    Daemon(Daemon const&) = delete;
+    void operator=(Daemon const&) = delete;
+
+    SnapuserdServer server_;
+    void MaskAllSignalsExceptIntAndTerm();
+    void MaskAllSignals();
+    static void SignalHandler(int signal);
+};
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h
new file mode 100644
index 0000000..1a6ba8f
--- /dev/null
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h
@@ -0,0 +1,97 @@
+// Copyright (C) 2020 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.
+
+#pragma once
+
+namespace android {
+namespace snapshot {
+
+// Kernel COW header fields
+static constexpr uint32_t SNAP_MAGIC = 0x70416e53;
+
+static constexpr uint32_t SNAPSHOT_DISK_VERSION = 1;
+
+static constexpr uint32_t NUM_SNAPSHOT_HDR_CHUNKS = 1;
+
+static constexpr uint32_t SNAPSHOT_VALID = 1;
+
+/*
+ * The basic unit of block I/O is a sector. It is used in a number of contexts
+ * in Linux (blk, bio, genhd). The size of one sector is 512 = 2**9
+ * bytes. Variables of type sector_t represent an offset or size that is a
+ * multiple of 512 bytes. Hence these two constants.
+ */
+static constexpr uint32_t SECTOR_SHIFT = 9;
+
+typedef __u64 sector_t;
+typedef sector_t chunk_t;
+
+static constexpr uint32_t CHUNK_SIZE = 8;
+static constexpr uint32_t CHUNK_SHIFT = (__builtin_ffs(CHUNK_SIZE) - 1);
+
+static constexpr uint32_t BLOCK_SIZE = 4096;
+static constexpr uint32_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SIZE) - 1);
+
+// This structure represents the kernel COW header.
+// All the below fields should be in Little Endian format.
+struct disk_header {
+    uint32_t magic;
+
+    /*
+     * Is this snapshot valid.  There is no way of recovering
+     * an invalid snapshot.
+     */
+    uint32_t valid;
+
+    /*
+     * Simple, incrementing version. no backward
+     * compatibility.
+     */
+    uint32_t version;
+
+    /* In sectors */
+    uint32_t chunk_size;
+} __packed;
+
+// A disk exception is a mapping of old_chunk to new_chunk
+// old_chunk is the chunk ID of a dm-snapshot device.
+// new_chunk is the chunk ID of the COW device.
+struct disk_exception {
+    uint64_t old_chunk;
+    uint64_t new_chunk;
+} __packed;
+
+// Control structures to communicate with dm-user
+// It comprises of header and a payload
+struct dm_user_header {
+    __u64 seq;
+    __u64 type;
+    __u64 flags;
+    __u64 sector;
+    __u64 len;
+    __u64 io_in_progress;
+} __attribute__((packed));
+
+struct dm_user_payload {
+    __u8 buf[];
+};
+
+// Message comprising both header and payload
+struct dm_user_message {
+    struct dm_user_header header;
+    struct dm_user_payload payload;
+};
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_server.h b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_server.h
new file mode 100644
index 0000000..584fe71
--- /dev/null
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_server.h
@@ -0,0 +1,103 @@
+// Copyright (C) 2020 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.
+
+#pragma once
+
+#include <cstdio>
+#include <cstring>
+#include <functional>
+#include <future>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <thread>
+#include <vector>
+
+#include <android-base/unique_fd.h>
+
+namespace android {
+namespace snapshot {
+
+static constexpr uint32_t MAX_PACKET_SIZE = 512;
+
+enum class DaemonOperations {
+    START,
+    QUERY,
+    TERMINATING,
+    STOP,
+    INVALID,
+};
+
+class Client {
+  private:
+    std::unique_ptr<std::thread> threadHandler_;
+
+  public:
+    void SetThreadHandler(std::function<void(void)> func) {
+        threadHandler_ = std::make_unique<std::thread>(func);
+    }
+
+    std::unique_ptr<std::thread>& GetThreadHandler() { return threadHandler_; }
+};
+
+class Stoppable {
+    std::promise<void> exitSignal_;
+    std::future<void> futureObj_;
+
+  public:
+    Stoppable() : futureObj_(exitSignal_.get_future()) {}
+
+    virtual ~Stoppable() {}
+
+    virtual void ThreadStart(std::string cow_device, std::string backing_device) = 0;
+
+    bool StopRequested() {
+        // checks if value in future object is available
+        if (futureObj_.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout)
+            return false;
+        return true;
+    }
+    // Request the thread to stop by setting value in promise object
+    void StopThreads() { exitSignal_.set_value(); }
+};
+
+class SnapuserdServer : public Stoppable {
+  private:
+    android::base::unique_fd sockfd_;
+    bool terminating_;
+    std::vector<std::unique_ptr<Client>> clients_vec_;
+
+    void ThreadStart(std::string cow_device, std::string backing_device) override;
+    void ShutdownThreads();
+    DaemonOperations Resolveop(std::string& input);
+    std::string GetDaemonStatus();
+    void Parsemsg(std::string const& msg, const char delim, std::vector<std::string>& out);
+
+    void SetTerminating() { terminating_ = true; }
+
+    bool IsTerminating() { return terminating_; }
+
+  public:
+    SnapuserdServer() { terminating_ = false; }
+
+    int Start(std::string socketname);
+    int AcceptClient();
+    int Receivemsg(int fd);
+    int Sendmsg(int fd, char* msg, size_t len);
+    std::string Recvmsg(int fd, int* ret);
+    android::base::borrowed_fd GetSocketFd() { return sockfd_; }
+};
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index b49f99e..0904fc7 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -27,6 +27,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <ext4_utils/ext4_utils.h>
@@ -68,6 +69,7 @@
 using android::hardware::boot::V1_1::MergeStatus;
 using chromeos_update_engine::DeltaArchiveManifest;
 using chromeos_update_engine::Extent;
+using chromeos_update_engine::FileDescriptor;
 using chromeos_update_engine::InstallOperation;
 template <typename T>
 using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>;
@@ -103,6 +105,10 @@
     metadata_dir_ = device_->GetMetadataDir();
 }
 
+static inline bool IsCompressionEnabled() {
+    return android::base::GetBoolProperty("ro.virtual_ab.compression.enabled", false);
+}
+
 static std::string GetCowName(const std::string& snapshot_name) {
     return snapshot_name + "-cow";
 }
@@ -2420,6 +2426,11 @@
 
 bool SnapshotManager::MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
                                         std::string* snapshot_path) {
+    if (IsCompressionEnabled()) {
+        LOG(ERROR) << "MapUpdateSnapshot cannot be used in compression mode.";
+        return false;
+    }
+
     auto lock = LockShared();
     if (!lock) return false;
     if (!UnmapPartitionWithSnapshot(lock.get(), params.GetPartitionName())) {
@@ -2430,6 +2441,22 @@
     return MapPartitionWithSnapshot(lock.get(), params, snapshot_path);
 }
 
+std::unique_ptr<ICowWriter> SnapshotManager::OpenSnapshotWriter(
+        const android::fs_mgr::CreateLogicalPartitionParams& params) {
+    (void)params;
+
+    LOG(ERROR) << "OpenSnapshotWriter not yet implemented";
+    return nullptr;
+}
+
+std::unique_ptr<FileDescriptor> SnapshotManager::OpenSnapshotReader(
+        const android::fs_mgr::CreateLogicalPartitionParams& params) {
+    (void)params;
+
+    LOG(ERROR) << "OpenSnapshotReader not yet implemented";
+    return nullptr;
+}
+
 bool SnapshotManager::UnmapUpdateSnapshot(const std::string& target_partition_name) {
     auto lock = LockShared();
     if (!lock) return false;
diff --git a/fs_mgr/libsnapshot/snapshot_stub.cpp b/fs_mgr/libsnapshot/snapshot_stub.cpp
index 9b6f758..8ae6305 100644
--- a/fs_mgr/libsnapshot/snapshot_stub.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stub.cpp
@@ -20,6 +20,7 @@
 
 using android::fs_mgr::CreateLogicalPartitionParams;
 using chromeos_update_engine::DeltaArchiveManifest;
+using chromeos_update_engine::FileDescriptor;
 
 namespace android::snapshot {
 
@@ -129,4 +130,16 @@
     return &snapshot_merge_stats;
 }
 
+std::unique_ptr<ICowWriter> SnapshotManagerStub::OpenSnapshotWriter(
+        const CreateLogicalPartitionParams&) {
+    LOG(ERROR) << __FUNCTION__ << " should never be called.";
+    return nullptr;
+}
+
+std::unique_ptr<FileDescriptor> SnapshotManagerStub::OpenSnapshotReader(
+        const CreateLogicalPartitionParams&) {
+    LOG(ERROR) << __FUNCTION__ << " should never be called.";
+    return nullptr;
+}
+
 }  // namespace android::snapshot
diff --git a/fs_mgr/libsnapshot/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp
index d3f4f70..3ed853f 100644
--- a/fs_mgr/libsnapshot/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd.cpp
@@ -14,25 +14,11 @@
  * limitations under the License.
  */
 
-#include <linux/types.h>
-#include <stdlib.h>
-
 #include <csignal>
-#include <cstring>
-#include <iostream>
-#include <limits>
-#include <string>
-#include <thread>
-#include <vector>
 
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-#include <libdm/dm.h>
-#include <libsnapshot/cow_reader.h>
-#include <libsnapshot/cow_writer.h>
 #include <libsnapshot/snapuserd.h>
+#include <libsnapshot/snapuserd_daemon.h>
+#include <libsnapshot/snapuserd_server.h>
 
 namespace android {
 namespace snapshot {
@@ -60,140 +46,36 @@
     const std::string uuid_;
 };
 
-class Daemon {
-    // The Daemon class is a singleton to avoid
-    // instantiating more than once
-  public:
-    static Daemon& Instance() {
-        static Daemon instance;
-        return instance;
-    }
-
-    bool IsRunning();
-
-  private:
-    bool is_running_;
-
-    Daemon();
-    Daemon(Daemon const&) = delete;
-    void operator=(Daemon const&) = delete;
-
-    static void SignalHandler(int signal);
-};
-
-Daemon::Daemon() {
-    is_running_ = true;
-    signal(SIGINT, Daemon::SignalHandler);
-    signal(SIGTERM, Daemon::SignalHandler);
+void BufferSink::Initialize(size_t size) {
+    buffer_size_ = size;
+    buffer_offset_ = 0;
+    buffer_ = std::make_unique<uint8_t[]>(size);
 }
 
-bool Daemon::IsRunning() {
-    return is_running_;
+void* BufferSink::GetPayloadBuffer(size_t size) {
+    if ((buffer_size_ - buffer_offset_) < size) return nullptr;
+
+    char* buffer = reinterpret_cast<char*>(GetBufPtr());
+    struct dm_user_message* msg = (struct dm_user_message*)(&(buffer[0]));
+    return (char*)msg->payload.buf + buffer_offset_;
 }
 
-void Daemon::SignalHandler(int signal) {
-    LOG(DEBUG) << "Snapuserd received signal: " << signal;
-    switch (signal) {
-        case SIGINT:
-        case SIGTERM: {
-            Daemon::Instance().is_running_ = false;
-            break;
-        }
+void* BufferSink::GetBuffer(size_t requested, size_t* actual) {
+    void* buf = GetPayloadBuffer(requested);
+    if (!buf) {
+        *actual = 0;
+        return nullptr;
     }
+    *actual = requested;
+    return buf;
 }
 
-class BufferSink : public IByteSink {
-  public:
-    void Initialize(size_t size) {
-        buffer_size_ = size;
-        buffer_offset_ = 0;
-        buffer_ = std::make_unique<uint8_t[]>(size);
-    }
-
-    void* GetBufPtr() { return buffer_.get(); }
-
-    void Clear() { memset(GetBufPtr(), 0, buffer_size_); }
-
-    void* GetPayloadBuffer(size_t size) {
-        if ((buffer_size_ - buffer_offset_) < size) return nullptr;
-
-        char* buffer = reinterpret_cast<char*>(GetBufPtr());
-        struct dm_user_message* msg = (struct dm_user_message*)(&(buffer[0]));
-        return (char*)msg->payload.buf + buffer_offset_;
-    }
-
-    void* GetBuffer(size_t requested, size_t* actual) override {
-        void* buf = GetPayloadBuffer(requested);
-        if (!buf) {
-            *actual = 0;
-            return nullptr;
-        }
-        *actual = requested;
-        return buf;
-    }
-
-    void UpdateBufferOffset(size_t size) { buffer_offset_ += size; }
-
-    struct dm_user_header* GetHeaderPtr() {
-        CHECK(sizeof(struct dm_user_header) <= buffer_size_);
-        char* buf = reinterpret_cast<char*>(GetBufPtr());
-        struct dm_user_header* header = (struct dm_user_header*)(&(buf[0]));
-        return header;
-    }
-
-    bool ReturnData(void*, size_t) override { return true; }
-    void ResetBufferOffset() { buffer_offset_ = 0; }
-
-  private:
-    std::unique_ptr<uint8_t[]> buffer_;
-    loff_t buffer_offset_;
-    size_t buffer_size_;
-};
-
-class Snapuserd final {
-  public:
-    Snapuserd(const std::string& in_cow_device, const std::string& in_backing_store_device)
-        : in_cow_device_(in_cow_device),
-          in_backing_store_device_(in_backing_store_device),
-          metadata_read_done_(false) {}
-
-    int Run();
-    int ReadDmUserHeader();
-    int WriteDmUserPayload(size_t size);
-    int ConstructKernelCowHeader();
-    int ReadMetadata();
-    int ZerofillDiskExceptions(size_t read_size);
-    int ReadDiskExceptions(chunk_t chunk, size_t size);
-    int ReadData(chunk_t chunk, size_t size);
-
-  private:
-    int ProcessReplaceOp(const CowOperation* cow_op);
-    int ProcessCopyOp(const CowOperation* cow_op);
-    int ProcessZeroOp();
-
-    std::string in_cow_device_;
-    std::string in_backing_store_device_;
-
-    unique_fd cow_fd_;
-    unique_fd backing_store_fd_;
-    unique_fd ctrl_fd_;
-
-    uint32_t exceptions_per_area_;
-
-    std::unique_ptr<ICowOpIter> cowop_iter_;
-    std::unique_ptr<CowReader> reader_;
-
-    // Vector of disk exception which is a
-    // mapping of old-chunk to new-chunk
-    std::vector<std::unique_ptr<uint8_t[]>> vec_;
-
-    // Index - Chunk ID
-    // Value - cow operation
-    std::vector<const CowOperation*> chunk_vec_;
-
-    bool metadata_read_done_;
-    BufferSink bufsink_;
-};
+struct dm_user_header* BufferSink::GetHeaderPtr() {
+    CHECK(sizeof(struct dm_user_header) <= buffer_size_);
+    char* buf = reinterpret_cast<char*>(GetBufPtr());
+    struct dm_user_header* header = (struct dm_user_header*)(&(buf[0]));
+    return header;
+}
 
 // Construct kernel COW header in memory
 // This header will be in sector 0. The IO
@@ -581,9 +463,12 @@
 // Read Header from dm-user misc device. This gives
 // us the sector number for which IO is issued by dm-snapshot device
 int Snapuserd::ReadDmUserHeader() {
-    if (!android::base::ReadFully(ctrl_fd_, bufsink_.GetBufPtr(), sizeof(struct dm_user_header))) {
-        PLOG(ERROR) << "Control read failed";
-        return -1;
+    int ret;
+
+    ret = read(ctrl_fd_, bufsink_.GetBufPtr(), sizeof(struct dm_user_header));
+    if (ret < 0) {
+        PLOG(ERROR) << "Control-read failed with: " << ret;
+        return ret;
     }
 
     return sizeof(struct dm_user_header);
@@ -600,22 +485,20 @@
     return sizeof(struct dm_user_header) + size;
 }
 
-// Start the daemon.
-// TODO: Handle signals
-int Snapuserd::Run() {
-    backing_store_fd_.reset(open(in_backing_store_device_.c_str(), O_RDONLY));
+bool Snapuserd::Init() {
+    backing_store_fd_.reset(open(backing_store_device_.c_str(), O_RDONLY));
     if (backing_store_fd_ < 0) {
-        LOG(ERROR) << "Open Failed: " << in_backing_store_device_;
-        return 1;
+        LOG(ERROR) << "Open Failed: " << backing_store_device_;
+        return false;
     }
 
-    cow_fd_.reset(open(in_cow_device_.c_str(), O_RDWR));
+    cow_fd_.reset(open(cow_device_.c_str(), O_RDWR));
     if (cow_fd_ < 0) {
-        LOG(ERROR) << "Open Failed: " << in_cow_device_;
-        return 1;
+        LOG(ERROR) << "Open Failed: " << cow_device_;
+        return false;
     }
 
-    std::string str(in_cow_device_);
+    std::string str(cow_device_);
     std::size_t found = str.find_last_of("/\\");
     CHECK(found != std::string::npos);
     std::string device_name = str.substr(found + 1);
@@ -625,8 +508,8 @@
     auto& dm = dm::DeviceMapper::Instance();
     std::string uuid;
     if (!dm.GetDmDeviceUuidByName(device_name, &uuid)) {
-        LOG(ERROR) << "Unable to find UUID for " << in_cow_device_;
-        return 1;
+        LOG(ERROR) << "Unable to find UUID for " << cow_device_;
+        return false;
     }
 
     LOG(DEBUG) << "UUID: " << uuid;
@@ -635,11 +518,9 @@
     ctrl_fd_.reset(open(t.control_path().c_str(), O_RDWR));
     if (ctrl_fd_ < 0) {
         LOG(ERROR) << "Unable to open " << t.control_path();
-        return 1;
+        return false;
     }
 
-    int ret = 0;
-
     // Allocate the buffer which is used to communicate between
     // daemon and dm-user. The buffer comprises of header and a fixed payload.
     // If the dm-user requests a big IO, the IO will be broken into chunks
@@ -647,138 +528,130 @@
     size_t buf_size = sizeof(struct dm_user_header) + PAYLOAD_SIZE;
     bufsink_.Initialize(buf_size);
 
-    while (true) {
-        struct dm_user_header* header = bufsink_.GetHeaderPtr();
+    return true;
+}
 
-        bufsink_.Clear();
+int Snapuserd::Run() {
+    int ret = 0;
 
-        ret = ReadDmUserHeader();
-        if (ret < 0) return ret;
+    struct dm_user_header* header = bufsink_.GetHeaderPtr();
 
-        LOG(DEBUG) << "dm-user returned " << ret << " bytes";
+    bufsink_.Clear();
 
-        LOG(DEBUG) << "msg->seq: " << std::hex << header->seq;
-        LOG(DEBUG) << "msg->type: " << std::hex << header->type;
-        LOG(DEBUG) << "msg->flags: " << std::hex << header->flags;
-        LOG(DEBUG) << "msg->sector: " << std::hex << header->sector;
-        LOG(DEBUG) << "msg->len: " << std::hex << header->len;
+    ret = ReadDmUserHeader();
+    if (ret < 0) return ret;
 
-        switch (header->type) {
-            case DM_USER_MAP_READ: {
-                size_t remaining_size = header->len;
-                loff_t offset = 0;
-                header->io_in_progress = 0;
-                ret = 0;
-                do {
-                    size_t read_size = std::min(PAYLOAD_SIZE, remaining_size);
+    LOG(DEBUG) << "dm-user returned " << ret << " bytes";
 
-                    // Request to sector 0 is always for kernel
-                    // representation of COW header. This IO should be only
-                    // once during dm-snapshot device creation. We should
-                    // never see multiple IO requests. Additionally this IO
-                    // will always be a single 4k.
-                    if (header->sector == 0) {
-                        // Read the metadata from internal COW device
-                        // and build the in-memory data structures
-                        // for all the operations in the internal COW.
-                        if (!metadata_read_done_ && ReadMetadata()) {
-                            LOG(ERROR) << "Metadata read failed";
-                            return 1;
+    LOG(DEBUG) << "msg->seq: " << std::hex << header->seq;
+    LOG(DEBUG) << "msg->type: " << std::hex << header->type;
+    LOG(DEBUG) << "msg->flags: " << std::hex << header->flags;
+    LOG(DEBUG) << "msg->sector: " << std::hex << header->sector;
+    LOG(DEBUG) << "msg->len: " << std::hex << header->len;
+
+    switch (header->type) {
+        case DM_USER_MAP_READ: {
+            size_t remaining_size = header->len;
+            loff_t offset = 0;
+            header->io_in_progress = 0;
+            ret = 0;
+            do {
+                size_t read_size = std::min(PAYLOAD_SIZE, remaining_size);
+
+                // Request to sector 0 is always for kernel
+                // representation of COW header. This IO should be only
+                // once during dm-snapshot device creation. We should
+                // never see multiple IO requests. Additionally this IO
+                // will always be a single 4k.
+                if (header->sector == 0) {
+                    // Read the metadata from internal COW device
+                    // and build the in-memory data structures
+                    // for all the operations in the internal COW.
+                    if (!metadata_read_done_ && ReadMetadata()) {
+                        LOG(ERROR) << "Metadata read failed";
+                        return 1;
+                    }
+                    metadata_read_done_ = true;
+
+                    CHECK(read_size == BLOCK_SIZE);
+                    ret = ConstructKernelCowHeader();
+                    if (ret < 0) return ret;
+                } else {
+                    // Convert the sector number to a chunk ID.
+                    //
+                    // Check if the chunk ID represents a metadata
+                    // page. If the chunk ID is not found in the
+                    // vector, then it points to a metadata page.
+                    chunk_t chunk = (header->sector >> CHUNK_SHIFT);
+
+                    if (chunk >= chunk_vec_.size()) {
+                        ret = ZerofillDiskExceptions(read_size);
+                        if (ret < 0) {
+                            LOG(ERROR) << "ZerofillDiskExceptions failed";
+                            return ret;
                         }
-                        metadata_read_done_ = true;
-
-                        CHECK(read_size == BLOCK_SIZE);
-                        ret = ConstructKernelCowHeader();
-                        if (ret < 0) return ret;
+                    } else if (chunk_vec_[chunk] == nullptr) {
+                        ret = ReadDiskExceptions(chunk, read_size);
+                        if (ret < 0) {
+                            LOG(ERROR) << "ReadDiskExceptions failed";
+                            return ret;
+                        }
                     } else {
-                        // Convert the sector number to a chunk ID.
-                        //
-                        // Check if the chunk ID represents a metadata
-                        // page. If the chunk ID is not found in the
-                        // vector, then it points to a metadata page.
-                        chunk_t chunk = (header->sector >> CHUNK_SHIFT);
-
-                        if (chunk >= chunk_vec_.size()) {
-                            ret = ZerofillDiskExceptions(read_size);
-                            if (ret < 0) {
-                                LOG(ERROR) << "ZerofillDiskExceptions failed";
-                                return ret;
-                            }
-                        } else if (chunk_vec_[chunk] == nullptr) {
-                            ret = ReadDiskExceptions(chunk, read_size);
-                            if (ret < 0) {
-                                LOG(ERROR) << "ReadDiskExceptions failed";
-                                return ret;
-                            }
-                        } else {
-                            chunk_t num_chunks_read = (offset >> BLOCK_SHIFT);
-                            ret = ReadData(chunk + num_chunks_read, read_size);
-                            if (ret < 0) {
-                                LOG(ERROR) << "ReadData failed";
-                                return ret;
-                            }
+                        chunk_t num_chunks_read = (offset >> BLOCK_SHIFT);
+                        ret = ReadData(chunk + num_chunks_read, read_size);
+                        if (ret < 0) {
+                            LOG(ERROR) << "ReadData failed";
+                            // TODO: Bug 168259959: All the error paths from this function
+                            // should send error code to dm-user thereby IO
+                            // terminates with an error from dm-user. Returning
+                            // here without sending error code will block the
+                            // IO.
+                            return ret;
                         }
                     }
+                }
 
-                    ssize_t written = WriteDmUserPayload(ret);
-                    if (written < 0) return written;
+                ssize_t written = WriteDmUserPayload(ret);
+                if (written < 0) return written;
 
-                    remaining_size -= ret;
-                    offset += ret;
-                    if (remaining_size) {
-                        LOG(DEBUG) << "Write done ret: " << ret
-                                   << " remaining size: " << remaining_size;
-                        bufsink_.GetHeaderPtr()->io_in_progress = 1;
-                    }
-                } while (remaining_size);
+                remaining_size -= ret;
+                offset += ret;
+                if (remaining_size) {
+                    LOG(DEBUG) << "Write done ret: " << ret
+                               << " remaining size: " << remaining_size;
+                    bufsink_.GetHeaderPtr()->io_in_progress = 1;
+                }
+            } while (remaining_size);
 
-                break;
-            }
-
-            case DM_USER_MAP_WRITE: {
-                // TODO: After merge operation is completed, kernel issues write
-                // to flush all the exception mappings where the merge is
-                // completed. If dm-user routes the WRITE IO, we need to clear
-                // in-memory data structures representing those exception
-                // mappings.
-                abort();
-                break;
-            }
+            break;
         }
 
-        LOG(DEBUG) << "read() finished, next message";
+        case DM_USER_MAP_WRITE: {
+            // TODO: Bug: 168311203: After merge operation is completed, kernel issues write
+            // to flush all the exception mappings where the merge is
+            // completed. If dm-user routes the WRITE IO, we need to clear
+            // in-memory data structures representing those exception
+            // mappings.
+            abort();
+            break;
+        }
     }
 
+    LOG(DEBUG) << "read() finished, next message";
+
     return 0;
 }
 
 }  // namespace snapshot
 }  // namespace android
 
-void run_thread(std::string cow_device, std::string backing_device) {
-    android::snapshot::Snapuserd snapd(cow_device, backing_device);
-    snapd.Run();
-}
-
 int main([[maybe_unused]] int argc, char** argv) {
     android::base::InitLogging(argv, &android::base::KernelLogger);
 
     android::snapshot::Daemon& daemon = android::snapshot::Daemon::Instance();
 
-    while (daemon.IsRunning()) {
-        // TODO: This is hardcoded wherein:
-        // argv[1] = system_cow, argv[2] = /dev/block/mapper/system_a
-        // argv[3] = product_cow, argv[4] = /dev/block/mapper/product_a
-        //
-        // This should be fixed based on some kind of IPC or setup a
-        // command socket and spin up the thread based when a new
-        // partition is visible.
-        std::thread system_a(run_thread, argv[1], argv[2]);
-        std::thread product_a(run_thread, argv[3], argv[4]);
-
-        system_a.join();
-        product_a.join();
-    }
+    daemon.StartServer(argv[1]);
+    daemon.Run();
 
     return 0;
 }
diff --git a/fs_mgr/libsnapshot/snapuserd_client.cpp b/fs_mgr/libsnapshot/snapuserd_client.cpp
new file mode 100644
index 0000000..bef8f5c
--- /dev/null
+++ b/fs_mgr/libsnapshot/snapuserd_client.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2020 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 <arpa/inet.h>
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <chrono>
+
+#include <android-base/logging.h>
+#include <libsnapshot/snapuserd_client.h>
+
+namespace android {
+namespace snapshot {
+
+bool SnapuserdClient::ConnectToServerSocket(std::string socketname) {
+    sockfd_ = 0;
+
+    sockfd_ =
+            socket_local_client(socketname.c_str(), ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+    if (sockfd_ < 0) {
+        LOG(ERROR) << "Failed to connect to " << socketname;
+        return false;
+    }
+
+    std::string msg = "query";
+
+    int sendRet = Sendmsg(msg.c_str(), msg.size());
+    if (sendRet < 0) {
+        LOG(ERROR) << "Failed to send query message to snapuserd daemon with socket " << socketname;
+        DisconnectFromServer();
+        return false;
+    }
+
+    std::string str = Receivemsg();
+
+    if (str.find("fail") != std::string::npos) {
+        LOG(ERROR) << "Failed to receive message from snapuserd daemon with socket " << socketname;
+        DisconnectFromServer();
+        return false;
+    }
+
+    // If the daemon is passive then fallback to secondary active daemon. Daemon
+    // is passive during transition phase. Please see RestartSnapuserd()
+    if (str.find("passive") != std::string::npos) {
+        LOG(DEBUG) << "Snapuserd is passive with socket " << socketname;
+        DisconnectFromServer();
+        return false;
+    }
+
+    CHECK(str.find("active") != std::string::npos);
+
+    return true;
+}
+
+bool SnapuserdClient::ConnectToServer() {
+    if (ConnectToServerSocket(GetSocketNameFirstStage())) return true;
+
+    if (ConnectToServerSocket(GetSocketNameSecondStage())) return true;
+
+    return false;
+}
+
+int SnapuserdClient::Sendmsg(const char* msg, size_t size) {
+    int numBytesSent = TEMP_FAILURE_RETRY(send(sockfd_, msg, size, 0));
+    if (numBytesSent < 0) {
+        LOG(ERROR) << "Send failed " << strerror(errno);
+        return -1;
+    }
+
+    if ((uint)numBytesSent < size) {
+        LOG(ERROR) << "Partial data sent " << strerror(errno);
+        return -1;
+    }
+
+    return 0;
+}
+
+std::string SnapuserdClient::Receivemsg() {
+    int ret;
+    struct timeval tv;
+    fd_set set;
+    char msg[PACKET_SIZE];
+    std::string msgStr("fail");
+
+    tv.tv_sec = 2;
+    tv.tv_usec = 0;
+    FD_ZERO(&set);
+    FD_SET(sockfd_, &set);
+    ret = select(sockfd_ + 1, &set, NULL, NULL, &tv);
+    if (ret == -1) {  // select failed
+        LOG(ERROR) << "Snapuserd:client: Select call failed";
+    } else if (ret == 0) {  // timeout
+        LOG(ERROR) << "Snapuserd:client: Select call timeout";
+    } else {
+        ret = TEMP_FAILURE_RETRY(recv(sockfd_, msg, PACKET_SIZE, 0));
+        if (ret < 0) {
+            PLOG(ERROR) << "Snapuserd:client: recv failed";
+        } else if (ret == 0) {
+            LOG(DEBUG) << "Snapuserd:client disconnected";
+        } else {
+            msgStr.clear();
+            msgStr = msg;
+        }
+    }
+    return msgStr;
+}
+
+#if 0
+std::string SnapuserdClient::Receivemsg() {
+    char msg[PACKET_SIZE];
+    std::string msgStr("fail");
+    int ret;
+
+    ret = TEMP_FAILURE_RETRY(recv(sockfd_, msg, PACKET_SIZE, 0));
+    if (ret <= 0) {
+        LOG(ERROR) << "recv failed " << strerror(errno);
+        return msgStr;
+    }
+
+    msgStr.clear();
+    msgStr = msg;
+    return msgStr;
+}
+#endif
+
+int SnapuserdClient::StopSnapuserd(bool firstStageDaemon) {
+    if (firstStageDaemon) {
+        sockfd_ = socket_local_client(GetSocketNameFirstStage().c_str(),
+                                      ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+        if (sockfd_ < 0) {
+            LOG(ERROR) << "Failed to connect to " << GetSocketNameFirstStage();
+            return -1;
+        }
+    } else {
+        if (!ConnectToServer()) {
+            LOG(ERROR) << "Failed to connect to socket " << GetSocketNameSecondStage();
+            return -1;
+        }
+    }
+
+    std::string msg = "stop";
+
+    int sendRet = Sendmsg(msg.c_str(), msg.size());
+    if (sendRet < 0) {
+        LOG(ERROR) << "Failed to send stop message to snapuserd daemon";
+        return -1;
+    }
+
+    DisconnectFromServer();
+
+    return 0;
+}
+
+int SnapuserdClient::StartSnapuserdaemon(std::string socketname) {
+    int retry_count = 0;
+
+    if (fork() == 0) {
+        const char* argv[] = {"/system/bin/snapuserd", socketname.c_str(), nullptr};
+        if (execv(argv[0], const_cast<char**>(argv))) {
+            LOG(ERROR) << "Failed to exec snapuserd daemon";
+            return -1;
+        }
+    }
+
+    // snapuserd is a daemon and will never exit; parent can't wait here
+    // to get the return code. Since Snapuserd starts the socket server,
+    // give it some time to fully launch.
+    //
+    // Try to connect to server to verify snapuserd server is started
+    while (retry_count < MAX_CONNECT_RETRY_COUNT) {
+        if (!ConnectToServer()) {
+            retry_count++;
+            std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        } else {
+            close(sockfd_);
+            return 0;
+        }
+    }
+
+    LOG(ERROR) << "Failed to start snapuserd daemon";
+    return -1;
+}
+
+int SnapuserdClient::StartSnapuserd() {
+    if (StartSnapuserdaemon(GetSocketNameFirstStage()) < 0) return -1;
+
+    return 0;
+}
+
+int SnapuserdClient::InitializeSnapuserd(std::string cow_device, std::string backing_device) {
+    int ret = 0;
+
+    if (!ConnectToServer()) {
+        LOG(ERROR) << "Failed to connect to server ";
+        return -1;
+    }
+
+    std::string msg = "start," + cow_device + "," + backing_device;
+
+    ret = Sendmsg(msg.c_str(), msg.size());
+    if (ret < 0) {
+        LOG(ERROR) << "Failed to send message " << msg << " to snapuserd daemon";
+        return -1;
+    }
+
+    std::string str = Receivemsg();
+
+    if (str.find("fail") != std::string::npos) {
+        LOG(ERROR) << "Failed to receive ack for " << msg << " from snapuserd daemon";
+        return -1;
+    }
+
+    DisconnectFromServer();
+
+    LOG(DEBUG) << "Snapuserd daemon initialized with " << msg;
+    return 0;
+}
+
+/*
+ * Transition from first stage snapuserd daemon to second stage daemon involves
+ * series of steps viz:
+ *
+ * 1: Create new dm-user devices - This is done by libsnapshot
+ *
+ * 2: Spawn the new snapuserd daemon - This is the second stage daemon which
+ * will start the server but the dm-user misc devices is not binded yet.
+ *
+ * 3: Vector to this function contains pair of cow_device and source device.
+ *    Ex: {{system_cow,system_a}, {product_cow, product_a}, {vendor_cow,
+ *    vendor_a}}. This vector will be populated by the libsnapshot.
+ *
+ * 4: Initialize the Second stage daemon passing the information from the
+ * vector. This will bind the daemon with dm-user misc device and will be ready
+ * to serve the IO. Up until this point, first stage daemon is still active.
+ * However, client library will mark the first stage daemon as passive and hence
+ * all the control message from hereon will be sent to active second stage
+ * daemon.
+ *
+ * 5: Create new dm-snapshot table. This is done by libsnapshot. When new table
+ * is created, kernel will issue metadata read once again which will be served
+ * by second stage daemon. However, any active IO will still be served by first
+ * stage daemon.
+ *
+ * 6: Swap the snapshot table atomically - This is done by libsnapshot. Once
+ * the swapping is done, all the IO will be served by second stage daemon.
+ *
+ * 7: Stop the first stage daemon. After this point second stage daemon is
+ * completely active to serve the IO and merging process.
+ *
+ */
+int SnapuserdClient::RestartSnapuserd(std::vector<std::pair<std::string, std::string>>& vec) {
+    // Connect to first-stage daemon and send a terminate-request control
+    // message. This will not terminate the daemon but will mark the daemon as
+    // passive.
+    if (!ConnectToServer()) {
+        LOG(ERROR) << "Failed to connect to server ";
+        return -1;
+    }
+
+    std::string msg = "terminate-request";
+
+    int sendRet = Sendmsg(msg.c_str(), msg.size());
+    if (sendRet < 0) {
+        LOG(ERROR) << "Failed to send message " << msg << " to snapuserd daemon";
+        return -1;
+    }
+
+    std::string str = Receivemsg();
+
+    if (str.find("fail") != std::string::npos) {
+        LOG(ERROR) << "Failed to receive ack for " << msg << " from snapuserd daemon";
+        return -1;
+    }
+
+    CHECK(str.find("success") != std::string::npos);
+
+    DisconnectFromServer();
+
+    // Start the new daemon
+    if (StartSnapuserdaemon(GetSocketNameSecondStage()) < 0) {
+        LOG(ERROR) << "Failed to start new daemon at socket " << GetSocketNameSecondStage();
+        return -1;
+    }
+
+    LOG(DEBUG) << "Second stage Snapuserd daemon created successfully at socket "
+               << GetSocketNameSecondStage();
+    CHECK(vec.size() % 2 == 0);
+
+    for (int i = 0; i < vec.size(); i++) {
+        std::string& cow_device = vec[i].first;
+        std::string& base_device = vec[i].second;
+
+        InitializeSnapuserd(cow_device, base_device);
+        LOG(DEBUG) << "Daemon initialized with " << cow_device << " and " << base_device;
+    }
+
+    return 0;
+}
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/snapuserd_daemon.cpp b/fs_mgr/libsnapshot/snapuserd_daemon.cpp
new file mode 100644
index 0000000..8e76618
--- /dev/null
+++ b/fs_mgr/libsnapshot/snapuserd_daemon.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2020 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 <android-base/logging.h>
+#include <libsnapshot/snapuserd_daemon.h>
+
+namespace android {
+namespace snapshot {
+
+int Daemon::StartServer(std::string socketname) {
+    int ret;
+
+    ret = server_.Start(socketname);
+    if (ret < 0) {
+        LOG(ERROR) << "Snapuserd daemon failed to start...";
+        exit(EXIT_FAILURE);
+    }
+
+    return ret;
+}
+
+void Daemon::MaskAllSignalsExceptIntAndTerm() {
+    sigset_t signal_mask;
+    sigfillset(&signal_mask);
+    sigdelset(&signal_mask, SIGINT);
+    sigdelset(&signal_mask, SIGTERM);
+    sigdelset(&signal_mask, SIGPIPE);
+    if (sigprocmask(SIG_SETMASK, &signal_mask, NULL) != 0) {
+        PLOG(ERROR) << "Failed to set sigprocmask";
+    }
+}
+
+void Daemon::MaskAllSignals() {
+    sigset_t signal_mask;
+    sigfillset(&signal_mask);
+    if (sigprocmask(SIG_SETMASK, &signal_mask, NULL) != 0) {
+        PLOG(ERROR) << "Couldn't mask all signals";
+    }
+}
+
+Daemon::Daemon() {
+    is_running_ = true;
+}
+
+bool Daemon::IsRunning() {
+    return is_running_;
+}
+
+void Daemon::Run() {
+    poll_fd_ = std::make_unique<struct pollfd>();
+    poll_fd_->fd = server_.GetSocketFd().get();
+    poll_fd_->events = POLLIN;
+
+    sigfillset(&signal_mask_);
+    sigdelset(&signal_mask_, SIGINT);
+    sigdelset(&signal_mask_, SIGTERM);
+
+    // Masking signals here ensure that after this point, we won't handle INT/TERM
+    // until after we call into ppoll()
+    MaskAllSignals();
+    signal(SIGINT, Daemon::SignalHandler);
+    signal(SIGTERM, Daemon::SignalHandler);
+    signal(SIGPIPE, Daemon::SignalHandler);
+
+    LOG(DEBUG) << "Snapuserd-server: ready to accept connections";
+
+    while (IsRunning()) {
+        int ret = ppoll(poll_fd_.get(), 1, nullptr, &signal_mask_);
+        MaskAllSignalsExceptIntAndTerm();
+
+        if (ret == -1) {
+            PLOG(ERROR) << "Snapuserd:ppoll error";
+            break;
+        }
+
+        if (poll_fd_->revents == POLLIN) {
+            if (server_.AcceptClient() == static_cast<int>(DaemonOperations::STOP)) {
+                Daemon::Instance().is_running_ = false;
+            }
+        }
+
+        // Mask all signals to ensure that is_running_ can't become false between
+        // checking it in the while condition and calling into ppoll()
+        MaskAllSignals();
+    }
+}
+
+void Daemon::SignalHandler(int signal) {
+    LOG(DEBUG) << "Snapuserd received signal: " << signal;
+    switch (signal) {
+        case SIGINT:
+        case SIGTERM: {
+            Daemon::Instance().is_running_ = false;
+            break;
+        }
+        case SIGPIPE: {
+            LOG(ERROR) << "Received SIGPIPE signal";
+            break;
+        }
+        default:
+            LOG(ERROR) << "Received unknown signal " << signal;
+            break;
+    }
+}
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/snapuserd_server.cpp b/fs_mgr/libsnapshot/snapuserd_server.cpp
new file mode 100644
index 0000000..1f8dd63
--- /dev/null
+++ b/fs_mgr/libsnapshot/snapuserd_server.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2020 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 <arpa/inet.h>
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <libsnapshot/snapuserd.h>
+#include <libsnapshot/snapuserd_server.h>
+
+namespace android {
+namespace snapshot {
+
+DaemonOperations SnapuserdServer::Resolveop(std::string& input) {
+    if (input == "start") return DaemonOperations::START;
+    if (input == "stop") return DaemonOperations::STOP;
+    if (input == "terminate-request") return DaemonOperations::TERMINATING;
+    if (input == "query") return DaemonOperations::QUERY;
+
+    return DaemonOperations::INVALID;
+}
+
+std::string SnapuserdServer::GetDaemonStatus() {
+    std::string msg = "";
+
+    if (IsTerminating())
+        msg = "passive";
+    else
+        msg = "active";
+
+    return msg;
+}
+
+void SnapuserdServer::Parsemsg(std::string const& msg, const char delim,
+                               std::vector<std::string>& out) {
+    std::stringstream ss(msg);
+    std::string s;
+
+    while (std::getline(ss, s, delim)) {
+        out.push_back(s);
+    }
+}
+
+// new thread
+void SnapuserdServer::ThreadStart(std::string cow_device, std::string backing_device) {
+    Snapuserd snapd(cow_device, backing_device);
+    if (!snapd.Init()) {
+        PLOG(ERROR) << "Snapuserd: Init failed";
+        return;
+    }
+
+    while (StopRequested() == false) {
+        int ret = snapd.Run();
+
+        if (ret == -ETIMEDOUT) continue;
+
+        if (ret < 0) {
+            PLOG(ERROR) << "snapd.Run() failed..." << ret;
+        }
+    }
+}
+
+void SnapuserdServer::ShutdownThreads() {
+    StopThreads();
+
+    for (auto& client : clients_vec_) {
+        auto& th = client->GetThreadHandler();
+
+        if (th->joinable()) th->join();
+    }
+}
+
+int SnapuserdServer::Sendmsg(int fd, char* msg, size_t size) {
+    int ret = TEMP_FAILURE_RETRY(send(fd, (char*)msg, size, 0));
+    if (ret < 0) {
+        PLOG(ERROR) << "Snapuserd:server: send() failed";
+        return -1;
+    }
+
+    if (ret < size) {
+        PLOG(ERROR) << "Partial data sent";
+        return -1;
+    }
+
+    return 0;
+}
+
+std::string SnapuserdServer::Recvmsg(int fd, int* ret) {
+    struct timeval tv;
+    fd_set set;
+    char msg[MAX_PACKET_SIZE];
+
+    tv.tv_sec = 2;
+    tv.tv_usec = 0;
+    FD_ZERO(&set);
+    FD_SET(fd, &set);
+    *ret = select(fd + 1, &set, NULL, NULL, &tv);
+    if (*ret == -1) {  // select failed
+        return {};
+    } else if (*ret == 0) {  // timeout
+        return {};
+    } else {
+        *ret = TEMP_FAILURE_RETRY(recv(fd, msg, MAX_PACKET_SIZE, 0));
+        if (*ret < 0) {
+            PLOG(ERROR) << "Snapuserd:server: recv failed";
+            return {};
+        } else if (*ret == 0) {
+            LOG(DEBUG) << "Snapuserd client disconnected";
+            return {};
+        } else {
+            std::string str(msg);
+            return str;
+        }
+    }
+}
+
+int SnapuserdServer::Receivemsg(int fd) {
+    char msg[MAX_PACKET_SIZE];
+    std::unique_ptr<Client> newClient;
+    int ret = 0;
+
+    while (1) {
+        memset(msg, '\0', MAX_PACKET_SIZE);
+        std::string str = Recvmsg(fd, &ret);
+
+        if (ret <= 0) {
+            LOG(DEBUG) << "recv failed with ret: " << ret;
+            return 0;
+        }
+
+        const char delim = ',';
+
+        std::vector<std::string> out;
+        Parsemsg(str, delim, out);
+        DaemonOperations op = Resolveop(out[0]);
+        memset(msg, '\0', MAX_PACKET_SIZE);
+
+        switch (op) {
+            case DaemonOperations::START: {
+                // Message format:
+                // start,<cow_device_path>,<source_device_path>
+                //
+                // Start the new thread which binds to dm-user misc device
+                newClient = std::make_unique<Client>();
+                newClient->SetThreadHandler(
+                        std::bind(&SnapuserdServer::ThreadStart, this, out[1], out[2]));
+                clients_vec_.push_back(std::move(newClient));
+                sprintf(msg, "success");
+                Sendmsg(fd, msg, MAX_PACKET_SIZE);
+                return 0;
+            }
+            case DaemonOperations::STOP: {
+                // Message format: stop
+                //
+                // Stop all the threads gracefully and then shutdown the
+                // main thread
+                ShutdownThreads();
+                return static_cast<int>(DaemonOperations::STOP);
+            }
+            case DaemonOperations::TERMINATING: {
+                // Message format: terminate-request
+                //
+                // This is invoked during transition. First stage
+                // daemon will receive this request. First stage daemon
+                // will be considered as a passive daemon from hereon.
+                SetTerminating();
+                sprintf(msg, "success");
+                Sendmsg(fd, msg, MAX_PACKET_SIZE);
+                return 0;
+            }
+            case DaemonOperations::QUERY: {
+                // Message format: query
+                //
+                // As part of transition, Second stage daemon will be
+                // created before terminating the first stage daemon. Hence,
+                // for a brief period client may have to distiguish between
+                // first stage daemon and second stage daemon.
+                //
+                // Second stage daemon is marked as active and hence will
+                // be ready to receive control message.
+                std::string dstr = GetDaemonStatus();
+                memcpy(msg, dstr.c_str(), dstr.size());
+                Sendmsg(fd, msg, MAX_PACKET_SIZE);
+                if (dstr == "active")
+                    break;
+                else
+                    return 0;
+            }
+            default: {
+                sprintf(msg, "fail");
+                Sendmsg(fd, msg, MAX_PACKET_SIZE);
+                return 0;
+            }
+        }
+    }
+}
+
+int SnapuserdServer::Start(std::string socketname) {
+    sockfd_.reset(socket_local_server(socketname.c_str(), ANDROID_SOCKET_NAMESPACE_RESERVED,
+                                      SOCK_STREAM));
+    if (sockfd_ < 0) {
+        PLOG(ERROR) << "Failed to create server socket " << socketname;
+        return -1;
+    }
+
+    LOG(DEBUG) << "Snapuserd server successfully started with socket name " << socketname;
+    return 0;
+}
+
+int SnapuserdServer::AcceptClient() {
+    int fd = accept(sockfd_.get(), NULL, NULL);
+    if (fd < 0) {
+        PLOG(ERROR) << "Socket accept failed: " << strerror(errno);
+        return -1;
+    }
+
+    return Receivemsg(fd);
+}
+
+}  // namespace snapshot
+}  // namespace android
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index f68ab87..9ed283a 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -17,7 +17,6 @@
     test_suites: [
         "cts",
         "device-tests",
-        "vts10",
     ],
     compile_multilib: "both",
     multilib: {
diff --git a/gatekeeperd/binder/android/service/gatekeeper/IGateKeeperService.aidl b/gatekeeperd/binder/android/service/gatekeeper/IGateKeeperService.aidl
index 57adaba..4646efc 100644
--- a/gatekeeperd/binder/android/service/gatekeeper/IGateKeeperService.aidl
+++ b/gatekeeperd/binder/android/service/gatekeeper/IGateKeeperService.aidl
@@ -30,7 +30,7 @@
 interface IGateKeeperService {
     /**
      * Enrolls a password, returning the handle to the enrollment to be stored locally.
-     * @param uid The Android user ID associated to this enrollment
+     * @param userId The Android user ID associated to this enrollment
      * @param currentPasswordHandle The previously enrolled handle, or null if none
      * @param currentPassword The previously enrolled plaintext password, or null if none.
      *                        If provided, must verify against the currentPasswordHandle.
@@ -38,22 +38,22 @@
      *                        upon success.
      * @return an EnrollResponse or null on failure
      */
-    GateKeeperResponse enroll(int uid, in @nullable byte[] currentPasswordHandle,
+    GateKeeperResponse enroll(int userId, in @nullable byte[] currentPasswordHandle,
             in @nullable byte[] currentPassword, in byte[] desiredPassword);
 
     /**
      * Verifies an enrolled handle against a provided, plaintext blob.
-     * @param uid The Android user ID associated to this enrollment
+     * @param userId The Android user ID associated to this enrollment
      * @param enrolledPasswordHandle The handle against which the provided password will be
      *                               verified.
      * @param The plaintext blob to verify against enrolledPassword.
      * @return a VerifyResponse, or null on failure.
      */
-    GateKeeperResponse verify(int uid, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
+    GateKeeperResponse verify(int userId, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
 
     /**
      * Verifies an enrolled handle against a provided, plaintext blob.
-     * @param uid The Android user ID associated to this enrollment
+     * @param userId The Android user ID associated to this enrollment
      * @param challenge a challenge to authenticate agaisnt the device credential. If successful
      *                  authentication occurs, this value will be written to the returned
      *                  authentication attestation.
@@ -62,22 +62,22 @@
      * @param The plaintext blob to verify against enrolledPassword.
      * @return a VerifyResponse with an attestation, or null on failure.
      */
-    GateKeeperResponse verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
+    GateKeeperResponse verifyChallenge(int userId, long challenge, in byte[] enrolledPasswordHandle,
             in byte[] providedPassword);
 
     /**
      * Retrieves the secure identifier for the user with the provided Android ID,
      * or 0 if none is found.
-     * @param uid the Android user id
+     * @param userId the Android user id
      */
-    long getSecureUserId(int uid);
+    long getSecureUserId(int userId);
 
     /**
      * Clears secure user id associated with the provided Android ID.
      * Must be called when password is set to NONE.
-     * @param uid the Android user id.
+     * @param userId the Android user id.
      */
-    void clearSecureUserId(int uid);
+    void clearSecureUserId(int userId);
 
     /**
      * Notifies gatekeeper that device setup has been completed and any potentially still existing
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index c81a80e..b982dbc 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -76,9 +76,9 @@
     virtual ~GateKeeperProxy() {
     }
 
-    void store_sid(uint32_t uid, uint64_t sid) {
+    void store_sid(uint32_t userId, uint64_t sid) {
         char filename[21];
-        snprintf(filename, sizeof(filename), "%u", uid);
+        snprintf(filename, sizeof(filename), "%u", userId);
         int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
         if (fd < 0) {
             ALOGE("could not open file: %s: %s", filename, strerror(errno));
@@ -117,18 +117,18 @@
         return false;
     }
 
-    void maybe_store_sid(uint32_t uid, uint64_t sid) {
+    void maybe_store_sid(uint32_t userId, uint64_t sid) {
         char filename[21];
-        snprintf(filename, sizeof(filename), "%u", uid);
+        snprintf(filename, sizeof(filename), "%u", userId);
         if (access(filename, F_OK) == -1) {
-            store_sid(uid, sid);
+            store_sid(userId, sid);
         }
     }
 
-    uint64_t read_sid(uint32_t uid) {
+    uint64_t read_sid(uint32_t userId) {
         char filename[21];
         uint64_t sid;
-        snprintf(filename, sizeof(filename), "%u", uid);
+        snprintf(filename, sizeof(filename), "%u", userId);
         int fd = open(filename, O_RDONLY);
         if (fd < 0) return 0;
         read(fd, &sid, sizeof(sid));
@@ -136,30 +136,30 @@
         return sid;
     }
 
-    void clear_sid(uint32_t uid) {
+    void clear_sid(uint32_t userId) {
         char filename[21];
-        snprintf(filename, sizeof(filename), "%u", uid);
+        snprintf(filename, sizeof(filename), "%u", userId);
         if (remove(filename) < 0) {
             ALOGE("%s: could not remove file [%s], attempting 0 write", __func__, strerror(errno));
-            store_sid(uid, 0);
+            store_sid(userId, 0);
         }
     }
 
-    // This should only be called on uids being passed to the GateKeeper HAL. It ensures that
+    // This should only be called on userIds being passed to the GateKeeper HAL. It ensures that
     // secure storage shared across a GSI image and a host image will not overlap.
-    uint32_t adjust_uid(uint32_t uid) {
+    uint32_t adjust_userId(uint32_t userId) {
         static constexpr uint32_t kGsiOffset = 1000000;
-        CHECK(uid < kGsiOffset);
+        CHECK(userId < kGsiOffset);
         CHECK(hw_device != nullptr);
         if (is_running_gsi) {
-            return uid + kGsiOffset;
+            return userId + kGsiOffset;
         }
-        return uid;
+        return userId;
     }
 
 #define GK_ERROR *gkResponse = GKResponse::error(), Status::ok()
 
-    Status enroll(int32_t uid, const std::optional<std::vector<uint8_t>>& currentPasswordHandle,
+    Status enroll(int32_t userId, const std::optional<std::vector<uint8_t>>& currentPasswordHandle,
                   const std::optional<std::vector<uint8_t>>& currentPassword,
                   const std::vector<uint8_t>& desiredPassword, GKResponse* gkResponse) override {
         IPCThreadState* ipc = IPCThreadState::self();
@@ -198,9 +198,10 @@
         android::hardware::hidl_vec<uint8_t> newPwd;
         newPwd.setToExternal(const_cast<uint8_t*>(desiredPassword.data()), desiredPassword.size());
 
-        uint32_t hw_uid = adjust_uid(uid);
+        uint32_t hw_userId = adjust_userId(userId);
         Return<void> hwRes = hw_device->enroll(
-                hw_uid, curPwdHandle, curPwd, newPwd, [&gkResponse](const GatekeeperResponse& rsp) {
+                hw_userId, curPwdHandle, curPwd, newPwd,
+                [&gkResponse](const GatekeeperResponse& rsp) {
                     if (rsp.code >= GatekeeperStatusCode::STATUS_OK) {
                         *gkResponse = GKResponse::ok({rsp.data.begin(), rsp.data.end()});
                     } else if (rsp.code == GatekeeperStatusCode::ERROR_RETRY_TIMEOUT &&
@@ -225,12 +226,12 @@
             const gatekeeper::password_handle_t* handle =
                     reinterpret_cast<const gatekeeper::password_handle_t*>(
                             gkResponse->payload().data());
-            store_sid(uid, handle->user_id);
+            store_sid(userId, handle->user_id);
 
             GKResponse verifyResponse;
             // immediately verify this password so we don't ask the user to enter it again
             // if they just created it.
-            auto status = verify(uid, gkResponse->payload(), desiredPassword, &verifyResponse);
+            auto status = verify(userId, gkResponse->payload(), desiredPassword, &verifyResponse);
             if (!status.isOk() || verifyResponse.response_code() != GKResponseCode::OK) {
                 LOG(ERROR) << "Failed to verify password after enrolling";
             }
@@ -239,13 +240,13 @@
         return Status::ok();
     }
 
-    Status verify(int32_t uid, const ::std::vector<uint8_t>& enrolledPasswordHandle,
+    Status verify(int32_t userId, const ::std::vector<uint8_t>& enrolledPasswordHandle,
                   const ::std::vector<uint8_t>& providedPassword, GKResponse* gkResponse) override {
-        return verifyChallenge(uid, 0 /* challenge */, enrolledPasswordHandle, providedPassword,
+        return verifyChallenge(userId, 0 /* challenge */, enrolledPasswordHandle, providedPassword,
                                gkResponse);
     }
 
-    Status verifyChallenge(int32_t uid, int64_t challenge,
+    Status verifyChallenge(int32_t userId, int64_t challenge,
                            const std::vector<uint8_t>& enrolledPasswordHandle,
                            const std::vector<uint8_t>& providedPassword,
                            GKResponse* gkResponse) override {
@@ -269,7 +270,7 @@
                 reinterpret_cast<const gatekeeper::password_handle_t*>(
                         enrolledPasswordHandle.data());
 
-        uint32_t hw_uid = adjust_uid(uid);
+        uint32_t hw_userId = adjust_userId(userId);
         android::hardware::hidl_vec<uint8_t> curPwdHandle;
         curPwdHandle.setToExternal(const_cast<uint8_t*>(enrolledPasswordHandle.data()),
                                    enrolledPasswordHandle.size());
@@ -278,7 +279,7 @@
                                  providedPassword.size());
 
         Return<void> hwRes = hw_device->verify(
-                hw_uid, challenge, curPwdHandle, enteredPwd,
+                hw_userId, challenge, curPwdHandle, enteredPwd,
                 [&gkResponse](const GatekeeperResponse& rsp) {
                     if (rsp.code >= GatekeeperStatusCode::STATUS_OK) {
                         *gkResponse = GKResponse::ok(
@@ -315,18 +316,18 @@
                 }
             }
 
-            maybe_store_sid(uid, handle->user_id);
+            maybe_store_sid(userId, handle->user_id);
         }
 
         return Status::ok();
     }
 
-    Status getSecureUserId(int32_t uid, int64_t* sid) override {
-        *sid = read_sid(uid);
+    Status getSecureUserId(int32_t userId, int64_t* sid) override {
+        *sid = read_sid(userId);
         return Status::ok();
     }
 
-    Status clearSecureUserId(int32_t uid) override {
+    Status clearSecureUserId(int32_t userId) override {
         IPCThreadState* ipc = IPCThreadState::self();
         const int calling_pid = ipc->getCallingPid();
         const int calling_uid = ipc->getCallingUid();
@@ -334,11 +335,11 @@
             ALOGE("%s: permission denied for [%d:%d]", __func__, calling_pid, calling_uid);
             return Status::ok();
         }
-        clear_sid(uid);
+        clear_sid(userId);
 
         if (hw_device) {
-            uint32_t hw_uid = adjust_uid(uid);
-            hw_device->deleteUser(hw_uid, [] (const GatekeeperResponse &){});
+            uint32_t hw_userId = adjust_userId(userId);
+            hw_device->deleteUser(hw_userId, [](const GatekeeperResponse&) {});
         }
         return Status::ok();
     }
diff --git a/include/android/log.h b/include/android/log.h
deleted file mode 120000
index 736c448..0000000
--- a/include/android/log.h
+++ /dev/null
@@ -1 +0,0 @@
-../../liblog/include/android/log.h
\ No newline at end of file
diff --git a/include/log b/include/log
deleted file mode 120000
index 714065f..0000000
--- a/include/log
+++ /dev/null
@@ -1 +0,0 @@
-../liblog/include/log
\ No newline at end of file
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
deleted file mode 120000
index f28a564..0000000
--- a/include/private/android_filesystem_config.h
+++ /dev/null
@@ -1 +0,0 @@
-../../libcutils/include/private/android_filesystem_config.h
\ No newline at end of file
diff --git a/init/Android.bp b/init/Android.bp
index 3f2cd07..13b1876 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -273,7 +273,6 @@
     test_suites: [
         "cts",
         "device-tests",
-        "vts10",
     ],
 }
 
diff --git a/init/README.md b/init/README.md
index c3b64f6..6439393 100644
--- a/init/README.md
+++ b/init/README.md
@@ -31,14 +31,13 @@
 extension.  There are typically multiple of these in multiple
 locations on the system, described below.
 
-/init.rc is the primary .rc file and is loaded by the init executable
-at the beginning of its execution.  It is responsible for the initial
-set up of the system.
+`/system/etc/init/hw/init.rc` is the primary .rc file and is loaded by the init executable at the
+beginning of its execution.  It is responsible for the initial set up of the system.
 
 Init loads all of the files contained within the
-/{system,vendor,odm}/etc/init/ directories immediately after loading
-the primary /init.rc.  This is explained in more details in the
-Imports section of this file.
+`/{system,system_ext,vendor,odm,product}/etc/init/` directories immediately after loading
+the primary `/system/etc/init/hw/init.rc`.  This is explained in more details in the
+[Imports](#imports) section of this file.
 
 Legacy devices without the first stage mount mechanism previously were
 able to import init scripts during mount_all, however that is deprecated
@@ -689,29 +688,22 @@
 
 There are only three times where the init executable imports .rc files:
 
-   1. When it imports /init.rc or the script indicated by the property
+   1. When it imports `/system/etc/init/hw/init.rc` or the script indicated by the property
       `ro.boot.init_rc` during initial boot.
-   2. When it imports /{system,vendor,odm}/etc/init/ for first stage mount
-      devices immediately after importing /init.rc.
+   2. When it imports `/{system,system_ext,vendor,odm,product}/etc/init/` immediately after
+      importing `/system/etc/init/hw/init.rc`.
    3. (Deprecated) When it imports /{system,vendor,odm}/etc/init/ or .rc files
       at specified paths during mount_all, not allowed for devices launching
       after Q.
 
-The order that files are imported is a bit complex for legacy reasons
-and to keep backwards compatibility.  It is not strictly guaranteed.
+The order that files are imported is a bit complex for legacy reasons.  The below is guaranteed:
 
-The only correct way to guarantee that a command has been run before a
-different command is to either 1) place it in an Action with an
-earlier executed trigger, or 2) place it in an Action with the same
-trigger within the same file at an earlier line.
-
-Nonetheless, the de facto order for first stage mount devices is:
-1. /init.rc is parsed then recursively each of its imports are
+1. `/system/etc/init/hw/init.rc` is parsed then recursively each of its imports are
    parsed.
-2. The contents of /system/etc/init/ are alphabetized and parsed
-   sequentially, with imports happening recursively after each file is
-   parsed.
-3. Step 2 is repeated for /vendor/etc/init then /odm/etc/init
+2. The contents of `/system/etc/init/` are alphabetized and parsed sequentially, with imports
+   happening recursively after each file is parsed.
+3. Step 2 is repeated for `/system_ext/etc/init`, `/vendor/etc/init`, `/odm/etc/init`,
+   `/product/etc/init`
 
 The below pseudocode may explain this more clearly:
 
@@ -720,13 +712,17 @@
       for (import : file.imports)
         Import(import)
 
-    Import(/init.rc)
-    Directories = [/system/etc/init, /vendor/etc/init, /odm/etc/init]
+    Import(/system/etc/init/hw/init.rc)
+    Directories = [/system/etc/init, /system_ext/etc/init, /vendor/etc/init, /odm/etc/init, /product/etc/init]
     for (directory : Directories)
       files = <Alphabetical order of directory's contents>
       for (file : files)
         Import(file)
 
+Actions are executed in the order that they are parsed.  For example the `post-fs-data` action(s)
+in `/system/etc/init/hw/init.rc` are always the first `post-fs-data` action(s) to be executed in
+order of how they appear in that file.  Then the `post-fs-data` actions of the imports of
+`/system/etc/init/hw/init.rc` in the order that they're imported, etc.
 
 Properties
 ----------
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index 053ebf8..4363f3c 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -86,6 +86,8 @@
 for a file matching the uevent `FIRMWARE`. It then forks a process to serve this firmware to the
 kernel.
 
+`/apex/*/etc/firmware` is also searched after a list of firmware directories.
+
 The list of firmware directories is customized by a `firmware_directories` line in a ueventd.rc
 file. This line takes the format of
 
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index dff7b69..ba7e6bd 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -17,6 +17,7 @@
 #include "firmware_handler.h"
 
 #include <fcntl.h>
+#include <glob.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdlib.h>
@@ -30,6 +31,7 @@
 #include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/scopeguard.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 
@@ -203,25 +205,28 @@
     }
 
     std::vector<std::string> attempted_paths_and_errors;
-
-    int booting = IsBooting();
-try_loading_again:
-    attempted_paths_and_errors.clear();
-    for (const auto& firmware_directory : firmware_directories_) {
+    auto TryLoadFirmware = [&](const std::string& firmware_directory) {
         std::string file = firmware_directory + firmware;
         unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
         if (fw_fd == -1) {
             attempted_paths_and_errors.emplace_back("firmware: attempted " + file +
                                                     ", open failed: " + strerror(errno));
-            continue;
+            return false;
         }
         struct stat sb;
         if (fstat(fw_fd, &sb) == -1) {
             attempted_paths_and_errors.emplace_back("firmware: attempted " + file +
                                                     ", fstat failed: " + strerror(errno));
-            continue;
+            return false;
         }
         LoadFirmware(firmware, root, fw_fd, sb.st_size, loading_fd, data_fd);
+        return true;
+    };
+
+    int booting = IsBooting();
+try_loading_again:
+    attempted_paths_and_errors.clear();
+    if (ForEachFirmwareDirectory(TryLoadFirmware)) {
         return;
     }
 
@@ -242,6 +247,33 @@
     write(loading_fd, "-1", 2);
 }
 
+bool FirmwareHandler::ForEachFirmwareDirectory(
+        std::function<bool(const std::string&)> handler) const {
+    for (const std::string& firmware_directory : firmware_directories_) {
+        if (std::invoke(handler, firmware_directory)) {
+            return true;
+        }
+    }
+
+    glob_t glob_result;
+    glob("/apex/*/etc/firmware/", GLOB_MARK, nullptr, &glob_result);
+    auto free_glob = android::base::make_scope_guard(std::bind(&globfree, &glob_result));
+    for (size_t i = 0; i < glob_result.gl_pathc; i++) {
+        char* apex_firmware_directory = glob_result.gl_pathv[i];
+        // Filter-out /apex/<name>@<ver> paths. The paths are bind-mounted to
+        // /apex/<name> paths, so unless we filter them out, we will look into the
+        // same apex twice.
+        if (strchr(apex_firmware_directory, '@')) {
+            continue;
+        }
+        if (std::invoke(handler, apex_firmware_directory)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 void FirmwareHandler::HandleUevent(const Uevent& uevent) {
     if (uevent.subsystem != "firmware" || uevent.action != "add") return;
 
diff --git a/init/firmware_handler.h b/init/firmware_handler.h
index b4138f1..8b758ae 100644
--- a/init/firmware_handler.h
+++ b/init/firmware_handler.h
@@ -18,6 +18,7 @@
 
 #include <pwd.h>
 
+#include <functional>
 #include <string>
 #include <vector>
 
@@ -52,6 +53,7 @@
                                            const Uevent& uevent) const;
     std::string GetFirmwarePath(const Uevent& uevent) const;
     void ProcessFirmwareEvent(const std::string& root, const std::string& firmware) const;
+    bool ForEachFirmwareDirectory(std::function<bool(const std::string&)> handler) const;
 
     std::vector<std::string> firmware_directories_;
     std::vector<ExternalFirmwareHandler> external_firmware_handlers_;
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 7a406ff..b395fde 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -860,7 +860,7 @@
     build_fingerprint += '/';
     build_fingerprint += GetProperty("ro.product.device", UNKNOWN);
     build_fingerprint += ':';
-    build_fingerprint += GetProperty("ro.build.version.release", UNKNOWN);
+    build_fingerprint += GetProperty("ro.build.version.release_or_codename", UNKNOWN);
     build_fingerprint += '/';
     build_fingerprint += GetProperty("ro.build.id", UNKNOWN);
     build_fingerprint += '/';
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index 038b59e..a506575 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -37,6 +37,12 @@
 #include "ThreadEntry.h"
 
 bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) {
+#if defined(__aarch64__)
+  // Tagged pointer after Android R would lead top byte to have random values
+  // https://source.android.com/devices/tech/debug/tagged-pointers
+  ptr &= (1ULL << 56) - 1;
+#endif
+
   if (!VerifyReadWordArgs(ptr, out_value)) {
     return false;
   }
@@ -54,6 +60,12 @@
 }
 
 size_t BacktraceCurrent::Read(uint64_t addr, uint8_t* buffer, size_t bytes) {
+#if defined(__aarch64__)
+  // Tagged pointer after Android R would lead top byte to have random values
+  // https://source.android.com/devices/tech/debug/tagged-pointers
+  addr &= (1ULL << 56) - 1;
+#endif
+
   backtrace_map_t map;
   FillInMap(addr, &map);
   if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) {
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 624711f..82ff21c 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -52,11 +52,11 @@
   unwinder.SetResolveNames(stack_map->ResolveNames());
   stack_map->SetArch(regs->Arch());
   if (stack_map->GetJitDebug() != nullptr) {
-    unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch());
+    unwinder.SetJitDebug(stack_map->GetJitDebug());
   }
 #if !defined(NO_LIBDEXFILE_SUPPORT)
   if (stack_map->GetDexFiles() != nullptr) {
-    unwinder.SetDexFiles(stack_map->GetDexFiles(), regs->Arch());
+    unwinder.SetDexFiles(stack_map->GetDexFiles());
   }
 #endif
   unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore());
@@ -180,5 +180,10 @@
 }
 
 size_t UnwindStackPtrace::Read(uint64_t addr, uint8_t* buffer, size_t bytes) {
+#if defined(__aarch64__)
+  // Tagged pointer after Android R would lead top byte to have random values
+  // https://source.android.com/devices/tech/debug/tagged-pointers
+  addr &= (1ULL << 56) - 1;
+#endif
   return memory_->Read(addr, buffer, bytes);
 }
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 04b8f66..0c75dc7 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -14,6 +14,11 @@
 // limitations under the License.
 //
 
+filegroup {
+    name: "android_filesystem_config_header",
+    srcs: ["include/private/android_filesystem_config.h"],
+}
+
 // some files must not be compiled when building against Mingw
 // they correspond to features not used by our host development tools
 // which are also hard or even impossible to port to native Win32
@@ -28,6 +33,7 @@
     name: "libcutils_headers",
     vendor_available: true,
     recovery_available: true,
+    ramdisk_available: true,
     host_supported: true,
     apex_available: [
         "//apex_available:platform",
@@ -54,6 +60,7 @@
     name: "libcutils_sockets",
     vendor_available: true,
     recovery_available: true,
+    ramdisk_available: true,
     host_supported: true,
     native_bridge_supported: true,
     apex_available: [
@@ -151,6 +158,7 @@
         "canned_fs_config.cpp",
         "iosched_policy.cpp",
         "load_file.cpp",
+        "memory.cpp",
         "native_handle.cpp",
         "properties.cpp",
         "record_stream.cpp",
@@ -193,6 +201,9 @@
                 "uevent.cpp",
             ],
         },
+        bionic: {
+            header_libs: ["bionic_libc_platform_headers"],
+        },
 
         android_arm: {
             sanitize: {
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index b9fc82e..31e1679 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -80,6 +80,7 @@
     { 00771, AID_SYSTEM,       AID_SYSTEM,       0, "data" },
     { 00755, AID_ROOT,         AID_SYSTEM,       0, "mnt" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "product/bin" },
+    { 00751, AID_ROOT,         AID_SHELL,        0, "product/apex/*/bin" },
     { 00777, AID_ROOT,         AID_ROOT,         0, "sdcard" },
     { 00751, AID_ROOT,         AID_SDCARD_R,     0, "storage" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "system/bin" },
@@ -90,6 +91,7 @@
     { 00751, AID_ROOT,         AID_SHELL,        0, "system_ext/bin" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "system_ext/apex/*/bin" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "vendor/bin" },
+    { 00751, AID_ROOT,         AID_SHELL,        0, "vendor/apex/*/bin" },
     { 00755, AID_ROOT,         AID_SHELL,        0, "vendor" },
     { 00755, AID_ROOT,         AID_ROOT,         0, 0 },
         // clang-format on
@@ -210,12 +212,14 @@
     { 00750, AID_ROOT,      AID_SHELL,     0, "init*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "odm/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "product/bin/*" },
+    { 00755, AID_ROOT,      AID_SHELL,     0, "product/apex/*bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/xbin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/apex/*/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system_ext/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system_ext/apex/*/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/bin/*" },
+    { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/apex/*bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/xbin/*" },
     { 00644, AID_ROOT,      AID_ROOT,      0, 0 },
         // clang-format on
diff --git a/libcutils/include/cutils/memory.h b/libcutils/include/cutils/memory.h
index c6476c1..0fba53c 100644
--- a/libcutils/include/cutils/memory.h
+++ b/libcutils/include/cutils/memory.h
@@ -28,6 +28,9 @@
 size_t strlcpy(char *dst, const char *src, size_t size);
 #endif
 
+// Disables memory mitigations for the entire process, and logs appropriately.
+void process_disable_memory_mitigations();
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/libcutils/memory.cpp b/libcutils/memory.cpp
new file mode 100644
index 0000000..f526520
--- /dev/null
+++ b/libcutils/memory.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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 <cutils/memory.h>
+
+#include <log/log.h>
+
+#ifdef __BIONIC__
+#include <bionic/malloc.h>
+#endif
+
+void process_disable_memory_mitigations() {
+    bool success = false;
+#ifdef __BIONIC__
+    // TODO(b/158870657) is fixed and scudo is used globally, we can assert when an
+    // an error is returned.
+
+    success = android_mallopt(M_DISABLE_MEMORY_MITIGATIONS, nullptr, 0);
+#endif
+
+    if (success) {
+        ALOGI("Disabled memory mitigations for process.");
+    } else {
+        ALOGE("Could not disable memory mitigations for process.");
+    }
+}
diff --git a/liblog b/liblog
new file mode 120000
index 0000000..71443ae
--- /dev/null
+++ b/liblog
@@ -0,0 +1 @@
+../logging/liblog
\ No newline at end of file
diff --git a/liblog/.clang-format b/liblog/.clang-format
deleted file mode 120000
index fd0645f..0000000
--- a/liblog/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../.clang-format-2
\ No newline at end of file
diff --git a/liblog/Android.bp b/liblog/Android.bp
deleted file mode 100644
index 59ab250..0000000
--- a/liblog/Android.bp
+++ /dev/null
@@ -1,155 +0,0 @@
-//
-// Copyright (C) 2008-2014 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.
-//
-
-liblog_sources = [
-    "log_event_list.cpp",
-    "log_event_write.cpp",
-    "logger_name.cpp",
-    "logger_read.cpp",
-    "logger_write.cpp",
-    "logprint.cpp",
-    "properties.cpp",
-]
-liblog_target_sources = [
-    "event_tag_map.cpp",
-    "log_time.cpp",
-    "pmsg_reader.cpp",
-    "pmsg_writer.cpp",
-    "logd_reader.cpp",
-    "logd_writer.cpp",
-]
-
-cc_library_headers {
-    name: "liblog_headers",
-    host_supported: true,
-    vendor_available: true,
-    ramdisk_available: true,
-    recovery_available: true,
-    apex_available: [
-        "//apex_available:platform",
-        "//apex_available:anyapex",
-    ],
-    min_sdk_version: "29",
-    sdk_version: "minimum",
-    native_bridge_supported: true,
-    export_include_dirs: ["include"],
-    system_shared_libs: [],
-    stl: "none",
-    target: {
-        windows: {
-            enabled: true,
-        },
-        linux_bionic: {
-            enabled: true,
-        },
-        vendor: {
-            override_export_include_dirs: ["include_vndk"],
-        },
-    },
-}
-
-// Shared and static library for host and device
-// ========================================================
-cc_library {
-    name: "liblog",
-    host_supported: true,
-    ramdisk_available: true,
-    recovery_available: true,
-    native_bridge_supported: true,
-    srcs: liblog_sources,
-
-    target: {
-        android: {
-            version_script: "liblog.map.txt",
-            srcs: liblog_target_sources,
-            // AddressSanitizer runtime library depends on liblog.
-            sanitize: {
-                address: false,
-            },
-        },
-        android_arm: {
-            // TODO: This is to work around b/24465209. Remove after root cause is fixed
-            pack_relocations: false,
-            ldflags: ["-Wl,--hash-style=both"],
-        },
-        windows: {
-            enabled: true,
-        },
-        not_windows: {
-            srcs: ["event_tag_map.cpp"],
-        },
-        linux_bionic: {
-            enabled: true,
-        },
-    },
-
-    header_libs: [
-        "libbase_headers",
-        "liblog_headers",
-    ],
-    export_header_lib_headers: ["liblog_headers"],
-
-    stubs: {
-        symbol_file: "liblog.map.txt",
-        versions: ["29", "30"],
-    },
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-        // This is what we want to do:
-        //  liblog_cflags := $(shell \
-        //   sed -n \
-        //       's/^\([0-9]*\)[ \t]*liblog[ \t].*/-DLIBLOG_LOG_TAG=\1/p' \
-        //       $(LOCAL_PATH)/event.logtags)
-        // so make sure we do not regret hard-coding it as follows:
-        "-DLIBLOG_LOG_TAG=1006",
-        "-DSNET_EVENT_LOG_TAG=1397638484",
-    ],
-    logtags: ["event.logtags"],
-    compile_multilib: "both",
-    apex_available: [
-        "//apex_available:platform",
-        // liblog is exceptionally available to the runtime APEX
-        // because the dynamic linker has to use it statically.
-        // See b/151051671
-        "com.android.runtime",
-        // DO NOT add more apex names here
-    ],
-}
-
-ndk_headers {
-    name: "liblog_ndk_headers",
-    from: "include/android",
-    to: "android",
-    srcs: ["include/android/log.h"],
-    license: "NOTICE",
-}
-
-ndk_library {
-    name: "liblog",
-    symbol_file: "liblog.map.txt",
-    first_version: "9",
-    unversioned_until: "current",
-}
-
-llndk_library {
-    name: "liblog",
-    native_bridge_supported: true,
-    symbol_file: "liblog.map.txt",
-    export_include_dirs: ["include_vndk"],
-}
diff --git a/liblog/NOTICE b/liblog/NOTICE
deleted file mode 100644
index 06a9081..0000000
--- a/liblog/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2014, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/liblog/OWNERS b/liblog/OWNERS
deleted file mode 100644
index babbe4d..0000000
--- a/liblog/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tomcherry@google.com
diff --git a/liblog/README.md b/liblog/README.md
deleted file mode 100644
index 74a2cd7..0000000
--- a/liblog/README.md
+++ /dev/null
@@ -1,161 +0,0 @@
-Android liblog
---------------
-
-Public Functions and Macros
----------------------------
-
-    /*
-     * Please limit to 24 characters for runtime is loggable,
-     * 16 characters for persist is loggable, and logcat pretty
-     * alignment with limit of 7 characters.
-    */
-    #define LOG_TAG "yourtag"
-    #include <log/log.h>
-
-    ALOG(android_priority, tag, format, ...)
-    IF_ALOG(android_priority, tag)
-    LOG_PRI(priority, tag, format, ...)
-    LOG_PRI_VA(priority, tag, format, args)
-    #define LOG_TAG NULL
-    ALOGV(format, ...)
-    SLOGV(format, ...)
-    RLOGV(format, ...)
-    ALOGV_IF(cond, format, ...)
-    SLOGV_IF(cond, format, ...)
-    RLOGV_IF(cond, format, ...)
-    IF_ALOGC()
-    ALOGD(format, ...)
-    SLOGD(format, ...)
-    RLOGD(format, ...)
-    ALOGD_IF(cond, format, ...)
-    SLOGD_IF(cond, format, ...)
-    RLOGD_IF(cond, format, ...)
-    IF_ALOGD()
-    ALOGI(format, ...)
-    SLOGI(format, ...)
-    RLOGI(format, ...)
-    ALOGI_IF(cond, format, ...)
-    SLOGI_IF(cond, format, ...)
-    RLOGI_IF(cond, format, ...)
-    IF_ALOGI()
-    ALOGW(format, ...)
-    SLOGW(format, ...)
-    RLOGW(format, ...)
-    ALOGW_IF(cond, format, ...)
-    SLOGW_IF(cond, format, ...)
-    RLOGW_IF(cond, format, ...)
-    IF_ALOGW()
-    ALOGE(format, ...)
-    SLOGE(format, ...)
-    RLOGE(format, ...)
-    ALOGE_IF(cond, format, ...)
-    SLOGE_IF(cond, format, ...)
-    RLOGE_IF(cond, format, ...)
-    IF_ALOGE()
-    LOG_FATAL(format, ...)
-    LOG_ALWAYS_FATAL(format, ...)
-    LOG_FATAL_IF(cond, format, ...)
-    LOG_ALWAYS_FATAL_IF(cond, format, ...)
-    ALOG_ASSERT(cond, format, ...)
-    LOG_EVENT_INT(tag, value)
-    LOG_EVENT_LONG(tag, value)
-
-    log_id_t android_logger_get_id(struct logger *logger)
-    int android_logger_clear(struct logger *logger)
-    int android_logger_get_log_size(struct logger *logger)
-    int android_logger_get_log_readable_size(struct logger *logger)
-    int android_logger_get_log_version(struct logger *logger)
-
-    struct logger_list *android_logger_list_alloc(int mode, unsigned int tail, pid_t pid)
-    struct logger *android_logger_open(struct logger_list *logger_list, log_id_t id)
-    struct logger_list *android_logger_list_open(log_id_t id, int mode, unsigned int tail, pid_t pid)
-    int android_logger_list_read(struct logger_list *logger_list, struct log_msg *log_msg)
-    void android_logger_list_free(struct logger_list *logger_list)
-
-    log_id_t android_name_to_log_id(const char *logName)
-    const char *android_log_id_to_name(log_id_t log_id)
-
-    android_log_context create_android_logger(uint32_t tag)
-
-    int android_log_write_list_begin(android_log_context ctx)
-    int android_log_write_list_end(android_log_context ctx)
-
-    int android_log_write_int32(android_log_context ctx, int32_t value)
-    int android_log_write_int64(android_log_context ctx, int64_t value)
-    int android_log_write_string8(android_log_context ctx, const char *value)
-    int android_log_write_string8_len(android_log_context ctx, const char *value, size_t maxlen)
-    int android_log_write_float32(android_log_context ctx, float value)
-
-    int android_log_write_list(android_log_context ctx, log_id_t id = LOG_ID_EVENTS)
-
-    android_log_context create_android_log_parser(const char *msg, size_t len)
-    android_log_list_element android_log_read_next(android_log_context ctx)
-    android_log_list_element android_log_peek_next(android_log_context ctx)
-
-    int android_log_destroy(android_log_context *ctx)
-
-Description
------------
-
-liblog represents an interface to the volatile Android Logging system for NDK (Native) applications
-and libraries.  Interfaces for either writing or reading logs.  The log buffers are divided up in
-Main, System, Radio and Events sub-logs.
-
-The logging interfaces are a series of macros, all of which can be overridden individually in order
-to control the verbosity of the application or library.  `[ASR]LOG[VDIWE]` calls are used to log to
-BAsic, System or Radio sub-logs in either the Verbose, Debug, Info, Warning or Error priorities.
-`[ASR]LOG[VDIWE]_IF` calls are used to perform thus based on a condition being true.
-`IF_ALOG[VDIWE]` calls are true if the current `LOG_TAG` is enabled at the specified priority.
-`LOG_ALWAYS_FATAL` is used to `ALOG` a message, then kill the process.  `LOG_FATAL` call is a
-variant of `LOG_ALWAYS_FATAL`, only enabled in engineering, and not release builds.  `ALOG_ASSERT`
-is used to `ALOG` a message if the condition is false; the condition is part of the logged message.
-`LOG_EVENT_(INT|LONG)` is used to drop binary content into the Events sub-log.
-
-The log reading interfaces permit opening the logs either singly or multiply, retrieving a log entry
-at a time in time sorted order, optionally limited to a specific pid and tail of the log(s) and
-finally a call closing the logs.  A single log can be opened with `android_logger_list_open()`; or
-multiple logs can be opened with `android_logger_list_alloc()`, calling in turn the
-`android_logger_open()` for each log id.  Each entry can be retrieved with
-`android_logger_list_read()`.  The log(s) can be closed with `android_logger_list_free()`.
-`ANDROID_LOG_NONBLOCK` mode will report when the log reading is done with an `EAGAIN` error return
-code, otherwise the `android_logger_list_read()` call will block for new entries.
-
-The `ANDROID_LOG_WRAP` mode flag to the `android_logger_list_alloc_time()` signals logd to quiesce
-the reader until the buffer is about to prune at the start time then proceed to dumping content.
-
-The `ANDROID_LOG_PSTORE` mode flag to the `android_logger_open()` is used to switch from the active
-logs to the persistent logs from before the last reboot.
-
-The value returned by `android_logger_open()` can be used as a parameter to the
-`android_logger_clear()` function to empty the sub-log.
-
-The value returned by `android_logger_open()` can be used as a parameter to the
-`android_logger_get_log_(size|readable_size|version)` to retrieve the sub-log maximum size, readable
-size and log buffer format protocol version respectively.  `android_logger_get_id()` returns the id
-that was used when opening the sub-log.
-
-Errors
-------
-
-If messages fail, a negative error code will be returned to the caller.
-
-The `-ENOTCONN` return code indicates that the logger daemon is stopped.
-
-The `-EBADF` return code indicates that the log access point can not be opened, or the log buffer id
-is out of range.
-
-For the `-EAGAIN` return code, this means that the logging message was temporarily backed-up either
-because of Denial Of Service (DOS) logging pressure from some chatty application or service in the
-Android system, or if too small of a value is set in /proc/sys/net/unix/max_dgram_qlen.  To aid in
-diagnosing the occurence of this, a binary event from liblog will be sent to the log daemon once a
-new message can get through indicating how many messages were dropped as a result.  Please take
-action to resolve the structural problems at the source.
-
-It is generally not advised for the caller to retry the `-EAGAIN` return code as this will only make
-the problem(s) worse and cause your application to temporarily drop to the logger daemon priority,
-BATCH scheduling policy and background task cgroup. If you require a group of messages to be passed
-atomically, merge them into one message with embedded newlines to the maximum length
-`LOGGER_ENTRY_MAX_PAYLOAD`.
-
-Other return codes from writing operation can be returned.  Since the library retries on `EINTR`,
-`-EINTR` should never be returned.
diff --git a/liblog/README.protocol.md b/liblog/README.protocol.md
deleted file mode 100644
index f247b28..0000000
--- a/liblog/README.protocol.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# liblog -> logd
-
-The data that liblog sends to logd is represented below.
-
-    struct {
-        android_log_header_t header;
-        union {
-           struct {
-                char     prio;
-                char     tag[...];
-                char     message[...];
-            } string;
-            struct {
-                android_event_header_t event_header;
-                android_event_*_t      payload[...];
-            } binary;
-        };
-    };
-
-where the embedded structs are defined as:
-
-    struct android_log_header_t {
-        uint8_t id;
-        uint16_t tid;
-        log_time realtime;
-    };
-
-    struct log_time {
-        uint32_t tv_sec = 0;
-        uint32_t tv_nsec = 0;
-    }
-
-    struct android_event_header_t {
-        int32_t tag;
-    };
-
-    struct android_event_list_t {
-        int8_t type;  // EVENT_TYPE_LIST
-        int8_t element_count;
-    };
-
-    struct android_event_float_t {
-        int8_t type;  // EVENT_TYPE_FLOAT
-        float data;
-    };
-
-    struct android_event_int_t {
-        int8_t type;   // EVENT_TYPE_INT
-        int32_t data;
-    } android_event_int_t;
-
-    struct android_event_long_t {
-        int8_t type;   // EVENT_TYPE_LONG
-        int64_t data;
-    };
-
-    struct android_event_string_t {
-        int8_t type;     // EVENT_TYPE_STRING;
-        int32_t length;
-        char data[];
-    };
-
-The payload, excluding the header, has a max size of LOGGER_ENTRY_MAX_PAYLOAD.
-
-## header
-
-The header is added immediately before sending the log message to logd.
-
-## `string` payload
-
-The `string` part of the union is for normal buffers (main, system, radio, etc) and consists of a
-single character priority, followed by a variable length null terminated string for the tag, and
-finally a variable length null terminated string for the message.
-
-This payload is used for the `__android_log_buf_write()` family of functions.
-
-## `binary` payload
-
-The `binary` part of the union is for binary buffers (events, security, etc) and consists of an
-android_event_header_t struct followed by a variable number of android_event_*_t
-(android_event_list_t, android_event_int_t, etc) structs.
-
-If multiple android_event_*_t elements are present, then they must be in a list and the first
-element in payload must be an android_event_list_t.
-
-This payload is used for the `__android_log_bwrite()` family of functions. It is additionally used
-for `android_log_write_list()` and the related functions that manipulate event lists.
-
-# logd -> liblog
-
-logd sends a `logger_entry` struct to liblog followed by the payload. The payload is identical to
-the payloads defined above. The max size of the entire message from logd is LOGGER_ENTRY_MAX_LEN.
diff --git a/liblog/event.logtags b/liblog/event.logtags
deleted file mode 100644
index 0a3b650..0000000
--- a/liblog/event.logtags
+++ /dev/null
@@ -1,37 +0,0 @@
-# The entries in this file map a sparse set of log tag numbers to tag names.
-# This is installed on the device, in /system/etc, and parsed by logcat.
-#
-# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
-# negative values alone for now.)
-#
-# Tag names are one or more ASCII letters and numbers or underscores, i.e.
-# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
-# impacts log readability, the latter makes regex searches more annoying).
-#
-# Tag numbers and names are separated by whitespace.  Blank lines and lines
-# starting with '#' are ignored.
-#
-# Optionally, after the tag names can be put a description for the value(s)
-# of the tag. Description are in the format
-#    (<name>|data type[|data unit])
-# Multiple values are separated by commas.
-#
-# The data type is a number from the following values:
-# 1: int
-# 2: long
-# 3: string
-# 4: list
-#
-# The data unit is a number taken from the following list:
-# 1: Number of objects
-# 2: Number of bytes
-# 3: Number of milliseconds
-# 4: Number of allocations
-# 5: Id
-# 6: Percent
-# s: Number of seconds (monotonic time)
-# Default value for data of type int/long is 2 (bytes).
-#
-# TODO: generate ".java" and ".h" files with integer constants from this file.
-
-1006  liblog (dropped|1)
diff --git a/liblog/event_tag_map.cpp b/liblog/event_tag_map.cpp
deleted file mode 100644
index 85556e8..0000000
--- a/liblog/event_tag_map.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2007-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 <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-
-#include <functional>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-
-#include <log/event_tag_map.h>
-#include <private/android_logger.h>
-#include <utils/FastStrcmp.h>
-#include <utils/RWLock.h>
-
-#define OUT_TAG "EventTagMap"
-
-typedef std::pair<std::string_view, std::string_view> TagFmt;
-
-// Map
-struct EventTagMap {
-#define NUM_MAPS 2
-  // memory-mapped source file; we get strings from here
-  void* mapAddr[NUM_MAPS];
-  size_t mapLen[NUM_MAPS];
-
- private:
-  std::unordered_map<uint32_t, TagFmt> Idx2TagFmt;
-  std::unordered_map<std::string_view, uint32_t> Tag2Idx;
-  // protect unordered sets
-  android::RWLock rwlock;
-
- public:
-  EventTagMap() {
-    memset(mapAddr, 0, sizeof(mapAddr));
-    memset(mapLen, 0, sizeof(mapLen));
-  }
-
-  ~EventTagMap() {
-    Idx2TagFmt.clear();
-    Tag2Idx.clear();
-    for (size_t which = 0; which < NUM_MAPS; ++which) {
-      if (mapAddr[which]) {
-        munmap(mapAddr[which], mapLen[which]);
-        mapAddr[which] = 0;
-      }
-    }
-  }
-
-  bool emplaceUnique(uint32_t tag, const TagFmt& tagfmt, bool verbose = false);
-  const TagFmt* find(uint32_t tag) const;
-  int find(std::string_view tag) const;
-};
-
-bool EventTagMap::emplaceUnique(uint32_t tag, const TagFmt& tagfmt,
-                                bool verbose) {
-  bool ret = true;
-  static const char errorFormat[] =
-      OUT_TAG ": duplicate tag entries %" PRIu32 ":%.*s:%.*s and %" PRIu32
-              ":%.*s:%.*s)\n";
-  android::RWLock::AutoWLock writeLock(rwlock);
-  {
-    auto it = Idx2TagFmt.find(tag);
-    if (it != Idx2TagFmt.end()) {
-      if (verbose) {
-        fprintf(stderr, errorFormat, it->first, (int)it->second.first.length(),
-                it->second.first.data(), (int)it->second.second.length(),
-                it->second.second.data(), tag, (int)tagfmt.first.length(),
-                tagfmt.first.data(), (int)tagfmt.second.length(),
-                tagfmt.second.data());
-      }
-      ret = false;
-    } else {
-      Idx2TagFmt.emplace(std::make_pair(tag, tagfmt));
-    }
-  }
-
-  {
-    auto it = Tag2Idx.find(tagfmt.first);
-    if (!tagfmt.second.length() && (it != Tag2Idx.end())) {
-      Tag2Idx.erase(it);
-      it = Tag2Idx.end();
-    }
-    if (it == Tag2Idx.end()) {
-      Tag2Idx.emplace(std::make_pair(tagfmt.first, tag));
-    }
-  }
-
-  return ret;
-}
-
-const TagFmt* EventTagMap::find(uint32_t tag) const {
-  android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
-  auto it = Idx2TagFmt.find(tag);
-  if (it == Idx2TagFmt.end()) return NULL;
-  return &(it->second);
-}
-
-int EventTagMap::find(std::string_view tag) const {
-  android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
-  auto it = Tag2Idx.find(std::move(tag));
-  if (it == Tag2Idx.end()) return -1;
-  return it->second;
-}
-
-// The position after the end of a valid section of the tag string,
-// caller makes sure delimited appropriately.
-static const char* endOfTag(const char* cp) {
-  while (*cp && (isalnum(*cp) || strchr("_.-@,", *cp))) ++cp;
-  return cp;
-}
-
-// Scan one tag line.
-//
-// "pData" should be pointing to the first digit in the tag number.  On
-// successful return, it will be pointing to the last character in the
-// tag line (i.e. the character before the start of the next line).
-//
-// Returns 0 on success, nonzero on failure.
-static int scanTagLine(EventTagMap* map, const char*& pData, int line_num) {
-  char* ep;
-  unsigned long val = strtoul(pData, &ep, 10);
-  const char* cp = ep;
-  if (cp == pData) {
-    fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", line_num);
-    errno = EINVAL;
-    return -1;
-  }
-
-  uint32_t tagIndex = val;
-  if (tagIndex != val) {
-    fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", line_num);
-    errno = ERANGE;
-    return -1;
-  }
-
-  while ((*++cp != '\n') && isspace(*cp)) {
-  }
-
-  if (*cp == '\n') {
-    fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", line_num);
-    errno = EINVAL;
-    return -1;
-  }
-
-  const char* tag = cp;
-  cp = endOfTag(cp);
-  size_t tagLen = cp - tag;
-
-  if (!isspace(*cp)) {
-    fprintf(stderr, OUT_TAG ": invalid tag char %c on line %d\n", *cp, line_num);
-    errno = EINVAL;
-    return -1;
-  }
-
-  while (isspace(*cp) && (*cp != '\n')) ++cp;
-  const char* fmt = NULL;
-  size_t fmtLen = 0;
-  if (*cp && (*cp != '#')) {
-    fmt = cp;
-    while (*cp && (*cp != '\n') && (*cp != '#')) ++cp;
-    while ((cp > fmt) && isspace(*(cp - 1))) --cp;
-    fmtLen = cp - fmt;
-  }
-
-  // KISS Only report identicals if they are global
-  // Ideally we want to check if there are identicals
-  // recorded for the same uid, but recording that
-  // unused detail in our database is too burdensome.
-  bool verbose = true;
-  while (*cp && (*cp != '#') && (*cp != '\n')) ++cp;
-  if (*cp == '#') {
-    do {
-      ++cp;
-    } while (isspace(*cp) && (*cp != '\n'));
-    verbose = !!fastcmp<strncmp>(cp, "uid=", strlen("uid="));
-  }
-
-  while (*cp && (*cp != '\n')) ++cp;
-#ifdef DEBUG
-  fprintf(stderr, "%d: %p: %.*s\n", line_num, tag, (int)(cp - pData), pData);
-#endif
-  pData = cp;
-
-  if (map->emplaceUnique(
-          tagIndex,
-          TagFmt(std::make_pair(std::string_view(tag, tagLen), std::string_view(fmt, fmtLen))),
-          verbose)) {
-    return 0;
-  }
-  errno = EMLINK;
-  return -1;
-}
-
-static const char* eventTagFiles[NUM_MAPS] = {
-  EVENT_TAG_MAP_FILE, "/dev/event-log-tags",
-};
-
-// Parse the tags out of the file.
-static int parseMapLines(EventTagMap* map, size_t which) {
-  const char* cp = static_cast<char*>(map->mapAddr[which]);
-  size_t len = map->mapLen[which];
-  const char* endp = cp + len;
-
-  // insist on EOL at EOF; simplifies parsing and null-termination
-  if (!len || (*(endp - 1) != '\n')) {
-#ifdef DEBUG
-    fprintf(stderr, OUT_TAG ": map file %zu[%zu] missing EOL on last line\n",
-            which, len);
-#endif
-    if (which) {  // do not propagate errors for other files
-      return 0;
-    }
-    errno = EINVAL;
-    return -1;
-  }
-
-  bool lineStart = true;
-  int lineNum = 1;
-  while (cp < endp) {
-    if (*cp == '\n') {
-      lineStart = true;
-      lineNum++;
-    } else if (lineStart) {
-      if (*cp == '#') {
-        // comment; just scan to end
-        lineStart = false;
-      } else if (isdigit(*cp)) {
-        // looks like a tag; scan it out
-        if (scanTagLine(map, cp, lineNum) != 0) {
-          if (!which || (errno != EMLINK)) {
-            return -1;
-          }
-        }
-        lineNum++;  // we eat the '\n'
-                    // leave lineStart==true
-      } else if (isspace(*cp)) {
-        // looks like leading whitespace; keep scanning
-      } else {
-        fprintf(stderr,
-                OUT_TAG
-                ": unexpected chars (0x%02x) in tag number on line %d\n",
-                *cp, lineNum);
-        errno = EINVAL;
-        return -1;
-      }
-    } else {
-      // this is a blank or comment line
-    }
-    cp++;
-  }
-
-  return 0;
-}
-
-// Open the map file and allocate a structure to manage it.
-//
-// We create a private mapping because we want to terminate the log tag
-// strings with '\0'.
-EventTagMap* android_openEventTagMap(const char* fileName) {
-  EventTagMap* newTagMap;
-  off_t end[NUM_MAPS];
-  int save_errno, fd[NUM_MAPS];
-  size_t which;
-
-  memset(fd, -1, sizeof(fd));
-  memset(end, 0, sizeof(end));
-
-  for (which = 0; which < NUM_MAPS; ++which) {
-    const char* tagfile = fileName ? fileName : eventTagFiles[which];
-
-    fd[which] = open(tagfile, O_RDONLY | O_CLOEXEC);
-    if (fd[which] < 0) {
-      if (!which) {
-        save_errno = errno;
-        fprintf(stderr, OUT_TAG ": unable to open map '%s': %s\n", tagfile,
-                strerror(save_errno));
-        goto fail_errno;
-      }
-      continue;
-    }
-    end[which] = lseek(fd[which], 0L, SEEK_END);
-    save_errno = errno;
-    (void)lseek(fd[which], 0L, SEEK_SET);
-    if (!which && (end[0] < 0)) {
-      fprintf(stderr, OUT_TAG ": unable to seek map '%s' %s\n", tagfile,
-              strerror(save_errno));
-      goto fail_close;
-    }
-    if (fileName) break;  // Only allow one as specified
-  }
-
-  newTagMap = new EventTagMap;
-  if (newTagMap == NULL) {
-    save_errno = errno;
-    goto fail_close;
-  }
-
-  for (which = 0; which < NUM_MAPS; ++which) {
-    if (fd[which] >= 0) {
-      newTagMap->mapAddr[which] =
-          mmap(NULL, end[which], which ? PROT_READ : PROT_READ | PROT_WRITE,
-               which ? MAP_SHARED : MAP_PRIVATE, fd[which], 0);
-      save_errno = errno;
-      close(fd[which]); /* fd DONE */
-      fd[which] = -1;
-      if ((newTagMap->mapAddr[which] != MAP_FAILED) &&
-          (newTagMap->mapAddr[which] != NULL)) {
-        newTagMap->mapLen[which] = end[which];
-      } else if (!which) {
-        const char* tagfile = fileName ? fileName : eventTagFiles[which];
-
-        fprintf(stderr, OUT_TAG ": mmap(%s) failed: %s\n", tagfile,
-                strerror(save_errno));
-        goto fail_unmap;
-      }
-    }
-  }
-
-  for (which = 0; which < NUM_MAPS; ++which) {
-    if (parseMapLines(newTagMap, which) != 0) {
-      delete newTagMap;
-      return NULL;
-    }
-    /* See 'fd DONE' comments above and below, no need to clean up here */
-  }
-
-  return newTagMap;
-
-fail_unmap:
-  save_errno = EINVAL;
-  delete newTagMap;
-fail_close:
-  for (which = 0; which < NUM_MAPS; ++which) close(fd[which]); /* fd DONE */
-fail_errno:
-  errno = save_errno;
-  return NULL;
-}
-
-// Close the map.
-void android_closeEventTagMap(EventTagMap* map) {
-  if (map) delete map;
-}
-
-// Look up an entry in the map.
-const char* android_lookupEventTag_len(const EventTagMap* map, size_t* len, unsigned int tag) {
-  if (len) *len = 0;
-  const TagFmt* str = map->find(tag);
-  if (!str) return NULL;
-  if (len) *len = str->first.length();
-  return str->first.data();
-}
-
-// Look up an entry in the map.
-const char* android_lookupEventFormat_len(const EventTagMap* map, size_t* len, unsigned int tag) {
-  if (len) *len = 0;
-  const TagFmt* str = map->find(tag);
-  if (!str) return NULL;
-  if (len) *len = str->second.length();
-  return str->second.data();
-}
-
diff --git a/liblog/include/android/log.h b/liblog/include/android/log.h
deleted file mode 100644
index 8a0ebf2..0000000
--- a/liblog/include/android/log.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#pragma once
-
-/**
- * @addtogroup Logging
- * @{
- */
-
-/**
- * \file
- *
- * Support routines to send messages to the Android log buffer,
- * which can later be accessed through the `logcat` utility.
- *
- * Each log message must have
- *   - a priority
- *   - a log tag
- *   - some text
- *
- * The tag normally corresponds to the component that emits the log message,
- * and should be reasonably small.
- *
- * Log message text may be truncated to less than an implementation-specific
- * limit (1023 bytes).
- *
- * Note that a newline character ("\n") will be appended automatically to your
- * log message, if not already there. It is not possible to send several
- * messages and have them appear on a single line in logcat.
- *
- * Please use logging in moderation:
- *
- *  - Sending log messages eats CPU and slow down your application and the
- *    system.
- *
- *  - The circular log buffer is pretty small, so sending many messages
- *    will hide other important log messages.
- *
- *  - In release builds, only send log messages to account for exceptional
- *    conditions.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#if !defined(__BIONIC__) && !defined(__INTRODUCED_IN)
-#define __INTRODUCED_IN(x)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Android log priority values, in increasing order of priority.
- */
-typedef enum android_LogPriority {
-  /** For internal use only.  */
-  ANDROID_LOG_UNKNOWN = 0,
-  /** The default priority, for internal use only.  */
-  ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
-  /** Verbose logging. Should typically be disabled for a release apk. */
-  ANDROID_LOG_VERBOSE,
-  /** Debug logging. Should typically be disabled for a release apk. */
-  ANDROID_LOG_DEBUG,
-  /** Informational logging. Should typically be disabled for a release apk. */
-  ANDROID_LOG_INFO,
-  /** Warning logging. For use with recoverable failures. */
-  ANDROID_LOG_WARN,
-  /** Error logging. For use with unrecoverable failures. */
-  ANDROID_LOG_ERROR,
-  /** Fatal logging. For use when aborting. */
-  ANDROID_LOG_FATAL,
-  /** For internal use only.  */
-  ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
-} android_LogPriority;
-
-/**
- * Writes the constant string `text` to the log, with priority `prio` and tag
- * `tag`.
- */
-int __android_log_write(int prio, const char* tag, const char* text);
-
-/**
- * Writes a formatted string to the log, with priority `prio` and tag `tag`.
- * The details of formatting are the same as for
- * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html).
- */
-int __android_log_print(int prio, const char* tag, const char* fmt, ...)
-    __attribute__((__format__(printf, 3, 4)));
-
-/**
- * Equivalent to `__android_log_print`, but taking a `va_list`.
- * (If `__android_log_print` is like `printf`, this is like `vprintf`.)
- */
-int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap)
-    __attribute__((__format__(printf, 3, 0)));
-
-/**
- * Writes an assertion failure to the log (as `ANDROID_LOG_FATAL`) and to
- * stderr, before calling
- * [abort(3)](http://man7.org/linux/man-pages/man3/abort.3.html).
- *
- * If `fmt` is non-null, `cond` is unused. If `fmt` is null, the string
- * `Assertion failed: %s` is used with `cond` as the string argument.
- * If both `fmt` and `cond` are null, a default string is provided.
- *
- * Most callers should use
- * [assert(3)](http://man7.org/linux/man-pages/man3/assert.3.html) from
- * `&lt;assert.h&gt;` instead, or the `__assert` and `__assert2` functions
- * provided by bionic if more control is needed. They support automatically
- * including the source filename and line number more conveniently than this
- * function.
- */
-void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...)
-    __attribute__((__noreturn__)) __attribute__((__format__(printf, 3, 4)));
-
-/**
- * Identifies a specific log buffer for __android_log_buf_write()
- * and __android_log_buf_print().
- */
-typedef enum log_id {
-  LOG_ID_MIN = 0,
-
-  /** The main log buffer. This is the only log buffer available to apps. */
-  LOG_ID_MAIN = 0,
-  /** The radio log buffer. */
-  LOG_ID_RADIO = 1,
-  /** The event log buffer. */
-  LOG_ID_EVENTS = 2,
-  /** The system log buffer. */
-  LOG_ID_SYSTEM = 3,
-  /** The crash log buffer. */
-  LOG_ID_CRASH = 4,
-  /** The statistics log buffer. */
-  LOG_ID_STATS = 5,
-  /** The security log buffer. */
-  LOG_ID_SECURITY = 6,
-  /** The kernel log buffer. */
-  LOG_ID_KERNEL = 7,
-
-  LOG_ID_MAX,
-
-  /** Let the logging function choose the best log target. */
-  LOG_ID_DEFAULT = 0x7FFFFFFF
-} log_id_t;
-
-/**
- * Writes the constant string `text` to the log buffer `id`,
- * with priority `prio` and tag `tag`.
- *
- * Apps should use __android_log_write() instead.
- */
-int __android_log_buf_write(int bufID, int prio, const char* tag, const char* text);
-
-/**
- * Writes a formatted string to log buffer `id`,
- * with priority `prio` and tag `tag`.
- * The details of formatting are the same as for
- * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html).
- *
- * Apps should use __android_log_print() instead.
- */
-int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...)
-    __attribute__((__format__(printf, 4, 5)));
-
-/**
- * Logger data struct used for writing log messages to liblog via __android_log_write_logger_data()
- * and sending log messages to user defined loggers specified in __android_log_set_logger().
- */
-struct __android_log_message {
-  /** Must be set to sizeof(__android_log_message) and is used for versioning. */
-  size_t struct_size;
-
-  /** {@link log_id_t} values. */
-  int32_t buffer_id;
-
-  /** {@link android_LogPriority} values. */
-  int32_t priority;
-
-  /** The tag for the log message. */
-  const char* tag;
-
-  /** Optional file name, may be set to nullptr. */
-  const char* file;
-
-  /** Optional line number, ignore if file is nullptr. */
-  uint32_t line;
-
-  /** The log message itself. */
-  const char* message;
-};
-
-/**
- * Prototype for the 'logger' function that is called for every log message.
- */
-typedef void (*__android_logger_function)(const struct __android_log_message* log_message);
-/**
- * Prototype for the 'abort' function that is called when liblog will abort due to
- * __android_log_assert() failures.
- */
-typedef void (*__android_aborter_function)(const char* abort_message);
-
-#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
-/**
- * Writes the log message specified by log_message.  log_message includes additional file name and
- * line number information that a logger may use.  log_message is versioned for backwards
- * compatibility.
- * This assumes that loggability has already been checked through __android_log_is_loggable().
- * Higher level logging libraries, such as libbase, first check loggability, then format their
- * buffers, then pass the message to liblog via this function, and therefore we do not want to
- * duplicate the loggability check here.
- *
- * @param log_message the log message itself, see __android_log_message.
- *
- * Available since API level 30.
- */
-void __android_log_write_log_message(struct __android_log_message* log_message) __INTRODUCED_IN(30);
-
-/**
- * Sets a user defined logger function.  All log messages sent to liblog will be set to the
- * function pointer specified by logger for processing.  It is not expected that log messages are
- * already terminated with a new line.  This function should add new lines if required for line
- * separation.
- *
- * @param logger the new function that will handle log messages.
- *
- * Available since API level 30.
- */
-void __android_log_set_logger(__android_logger_function logger) __INTRODUCED_IN(30);
-
-/**
- * Writes the log message to logd.  This is an __android_logger_function and can be provided to
- * __android_log_set_logger().  It is the default logger when running liblog on a device.
- *
- * @param log_message the log message to write, see __android_log_message.
- *
- * Available since API level 30.
- */
-void __android_log_logd_logger(const struct __android_log_message* log_message) __INTRODUCED_IN(30);
-
-/**
- * Writes the log message to stderr.  This is an __android_logger_function and can be provided to
- * __android_log_set_logger().  It is the default logger when running liblog on host.
- *
- * @param log_message the log message to write, see __android_log_message.
- *
- * Available since API level 30.
- */
-void __android_log_stderr_logger(const struct __android_log_message* log_message)
-    __INTRODUCED_IN(30);
-
-/**
- * Sets a user defined aborter function that is called for __android_log_assert() failures.  This
- * user defined aborter function is highly recommended to abort and be noreturn, but is not strictly
- * required to.
- *
- * @param aborter the new aborter function, see __android_aborter_function.
- *
- * Available since API level 30.
- */
-void __android_log_set_aborter(__android_aborter_function aborter) __INTRODUCED_IN(30);
-
-/**
- * Calls the stored aborter function.  This allows for other logging libraries to use the same
- * aborter function by calling this function in liblog.
- *
- * @param abort_message an additional message supplied when aborting, for example this is used to
- *                      call android_set_abort_message() in __android_log_default_aborter().
- *
- * Available since API level 30.
- */
-void __android_log_call_aborter(const char* abort_message) __INTRODUCED_IN(30);
-
-/**
- * Sets android_set_abort_message() on device then aborts().  This is the default aborter.
- *
- * @param abort_message an additional message supplied when aborting.  This functions calls
- *                      android_set_abort_message() with its contents.
- *
- * Available since API level 30.
- */
-void __android_log_default_aborter(const char* abort_message) __attribute__((noreturn))
-__INTRODUCED_IN(30);
-
-/**
- * Use the per-tag properties "log.tag.<tagname>" along with the minimum priority from
- * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will
- * be printed.  A non-zero result indicates yes, zero indicates false.
- *
- * If both a priority for a tag and a minimum priority are set by
- * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the
- * minimum priority needed to log.  If only one is set, then that value is used to determine the
- * minimum priority needed.  If none are set, then default_priority is used.
- *
- * @param prio         the priority to test, takes android_LogPriority values.
- * @param tag          the tag to test.
- * @param default_prio the default priority to use if no properties or minimum priority are set.
- * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not.
- *
- * Available since API level 30.
- */
-int __android_log_is_loggable(int prio, const char* tag, int default_prio) __INTRODUCED_IN(30);
-
-/**
- * Use the per-tag properties "log.tag.<tagname>" along with the minimum priority from
- * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will
- * be printed.  A non-zero result indicates yes, zero indicates false.
- *
- * If both a priority for a tag and a minimum priority are set by
- * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the
- * minimum priority needed to log.  If only one is set, then that value is used to determine the
- * minimum priority needed.  If none are set, then default_priority is used.
- *
- * @param prio         the priority to test, takes android_LogPriority values.
- * @param tag          the tag to test.
- * @param len          the length of the tag.
- * @param default_prio the default priority to use if no properties or minimum priority are set.
- * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not.
- *
- * Available since API level 30.
- */
-int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio)
-    __INTRODUCED_IN(30);
-
-/**
- * Sets the minimum priority that will be logged for this process.
- *
- * @param priority the new minimum priority to set, takes android_LogPriority values.
- * @return the previous set minimum priority as android_LogPriority values, or
- *         ANDROID_LOG_DEFAULT if none was set.
- *
- * Available since API level 30.
- */
-int32_t __android_log_set_minimum_priority(int32_t priority) __INTRODUCED_IN(30);
-
-/**
- * Gets the minimum priority that will be logged for this process.  If none has been set by a
- * previous __android_log_set_minimum_priority() call, this returns ANDROID_LOG_DEFAULT.
- *
- * @return the current minimum priority as android_LogPriority values, or
- *         ANDROID_LOG_DEFAULT if none is set.
- *
- * Available since API level 30.
- */
-int32_t __android_log_get_minimum_priority(void) __INTRODUCED_IN(30);
-
-/**
- * Sets the default tag if no tag is provided when writing a log message.  Defaults to
- * getprogname().  This truncates tag to the maximum log message size, though appropriate tags
- * should be much smaller.
- *
- * @param tag the new log tag.
- *
- * Available since API level 30.
- */
-void __android_log_set_default_tag(const char* tag) __INTRODUCED_IN(30);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-/** @} */
diff --git a/liblog/include/log/event_tag_map.h b/liblog/include/log/event_tag_map.h
deleted file mode 100644
index de49fbf..0000000
--- a/liblog/include/log/event_tag_map.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#pragma once
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags"
-
-struct EventTagMap;
-typedef struct EventTagMap EventTagMap;
-
-/*
- * Open the specified file as an event log tag map.
- *
- * Returns NULL on failure.
- */
-EventTagMap* android_openEventTagMap(const char* fileName);
-
-/*
- * Close the map.
- */
-void android_closeEventTagMap(EventTagMap* map);
-
-/*
- * Look up a tag by index.  Returns the tag string & string length, or NULL if
- * not found.  Returned string is not guaranteed to be nul terminated.
- */
-const char* android_lookupEventTag_len(const EventTagMap* map, size_t* len,
-                                       unsigned int tag);
-
-/*
- * Look up a format by index. Returns the format string & string length,
- * or NULL if not found. Returned string is not guaranteed to be nul terminated.
- */
-const char* android_lookupEventFormat_len(const EventTagMap* map, size_t* len,
-                                          unsigned int tag);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
deleted file mode 100644
index d7e9b7d..0000000
--- a/liblog/include/log/log.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2005-2014 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.
- */
-
-#pragma once
-
-/* Too many in the ecosystem assume these are included */
-#if !defined(_WIN32)
-#include <pthread.h>
-#endif
-#include <stdint.h> /* uint16_t, int32_t */
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <android/log.h>
-#include <log/log_id.h>
-#include <log/log_main.h>
-#include <log/log_radio.h>
-#include <log/log_safetynet.h>
-#include <log/log_system.h>
-#include <log/log_time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * LOG_TAG is the local tag used for the following simplified
- * logging macros.  You can change this preprocessor definition
- * before using the other macros to change the tag.
- */
-
-#ifndef LOG_TAG
-#define LOG_TAG NULL
-#endif
-
-/*
- * Normally we strip the effects of ALOGV (VERBOSE messages),
- * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the
- * release builds be defining NDEBUG.  You can modify this (for
- * example with "#define LOG_NDEBUG 0" at the top of your source
- * file) to change that behavior.
- */
-
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-/*
- * The maximum size of the log entry payload that can be
- * written to the logger. An attempt to write more than
- * this amount will result in a truncated log entry.
- */
-#define LOGGER_ENTRY_MAX_PAYLOAD 4068
-
-/*
- * Event logging.
- */
-
-/*
- * The following should not be used directly.
- */
-
-int __android_log_bwrite(int32_t tag, const void* payload, size_t len);
-int __android_log_btwrite(int32_t tag, char type, const void* payload,
-                          size_t len);
-int __android_log_bswrite(int32_t tag, const char* payload);
-
-int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len);
-
-#define android_bWriteLog(tag, payload, len) \
-  __android_log_bwrite(tag, payload, len)
-#define android_btWriteLog(tag, type, payload, len) \
-  __android_log_btwrite(tag, type, payload, len)
-
-/*
- * Event log entry types.
- */
-typedef enum {
-  /* Special markers for android_log_list_element type */
-  EVENT_TYPE_LIST_STOP = '\n', /* declare end of list  */
-  EVENT_TYPE_UNKNOWN = '?',    /* protocol error       */
-
-  /* must match with declaration in java/android/android/util/EventLog.java */
-  EVENT_TYPE_INT = 0,  /* int32_t */
-  EVENT_TYPE_LONG = 1, /* int64_t */
-  EVENT_TYPE_STRING = 2,
-  EVENT_TYPE_LIST = 3,
-  EVENT_TYPE_FLOAT = 4,
-} AndroidEventLogType;
-
-#ifndef LOG_EVENT_INT
-#define LOG_EVENT_INT(_tag, _value)                                          \
-  {                                                                          \
-    int intBuf = _value;                                                     \
-    (void)android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, sizeof(intBuf)); \
-  }
-#endif
-#ifndef LOG_EVENT_LONG
-#define LOG_EVENT_LONG(_tag, _value)                                            \
-  {                                                                             \
-    long long longBuf = _value;                                                 \
-    (void)android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf)); \
-  }
-#endif
-#ifndef LOG_EVENT_FLOAT
-#define LOG_EVENT_FLOAT(_tag, _value)                           \
-  {                                                             \
-    float floatBuf = _value;                                    \
-    (void)android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \
-                             sizeof(floatBuf));                 \
-  }
-#endif
-#ifndef LOG_EVENT_STRING
-#define LOG_EVENT_STRING(_tag, _value) \
-  (void)__android_log_bswrite(_tag, _value);
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Release any logger resources (a new log write will immediately re-acquire)
- *
- * This is specifically meant to be used by Zygote to close open file descriptors after fork()
- * and before specialization.  O_CLOEXEC is used on file descriptors, so they will be closed upon
- * exec() in normal use cases.
- *
- * Note that this is not safe to call from a multi-threaded program.
- */
-void __android_log_close(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h
deleted file mode 100644
index deadf20..0000000
--- a/liblog/include/log/log_event_list.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2005-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.
- */
-
-#pragma once
-
-#include <errno.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-#include <string>
-#endif
-
-#include <log/log.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For manipulating lists of events. */
-
-#define ANDROID_MAX_LIST_NEST_DEPTH 8
-
-/*
- * The opaque context used to manipulate lists of events.
- */
-typedef struct android_log_context_internal* android_log_context;
-
-/*
- * Elements returned when reading a list of events.
- */
-typedef struct {
-  AndroidEventLogType type;
-  uint16_t complete;
-  uint16_t len;
-  union {
-    int32_t int32;
-    int64_t int64;
-    char* string;
-    float float32;
-  } data;
-} android_log_list_element;
-
-/*
- * Creates a context associated with an event tag to write elements to
- * the list of events.
- */
-android_log_context create_android_logger(uint32_t tag);
-
-/* All lists must be braced by a begin and end call */
-/*
- * NB: If the first level braces are missing when specifying multiple
- *     elements, we will manufacturer a list to embrace it for your API
- *     convenience. For a single element, it will remain solitary.
- */
-int android_log_write_list_begin(android_log_context ctx);
-int android_log_write_list_end(android_log_context ctx);
-
-int android_log_write_int32(android_log_context ctx, int32_t value);
-int android_log_write_int64(android_log_context ctx, int64_t value);
-int android_log_write_string8(android_log_context ctx, const char* value);
-int android_log_write_string8_len(android_log_context ctx, const char* value,
-                                  size_t maxlen);
-int android_log_write_float32(android_log_context ctx, float value);
-
-/* Submit the composed list context to the specified logger id */
-/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
-int android_log_write_list(android_log_context ctx, log_id_t id);
-
-/*
- * Creates a context from a raw buffer representing a list of events to be read.
- */
-android_log_context create_android_log_parser(const char* msg, size_t len);
-
-android_log_list_element android_log_read_next(android_log_context ctx);
-android_log_list_element android_log_peek_next(android_log_context ctx);
-
-/* Reset writer context */
-int android_log_reset(android_log_context ctx);
-
-/* Reset reader context */
-int android_log_parser_reset(android_log_context ctx,
-                             const char* msg, size_t len);
-
-/* Finished with reader or writer context */
-int android_log_destroy(android_log_context* ctx);
-
-#ifdef __cplusplus
-/* android_log_list C++ helpers */
-extern "C++" {
-class android_log_event_list {
- private:
-  android_log_context ctx;
-  int ret;
-
-  android_log_event_list(const android_log_event_list&) = delete;
-  void operator=(const android_log_event_list&) = delete;
-
- public:
-  explicit android_log_event_list(int tag) : ret(0) {
-    ctx = create_android_logger(static_cast<uint32_t>(tag));
-  }
-  ~android_log_event_list() {
-    android_log_destroy(&ctx);
-  }
-
-  int close() {
-    int retval = android_log_destroy(&ctx);
-    if (retval < 0) ret = retval;
-    return retval;
-  }
-
-  /* To allow above C calls to use this class as parameter */
-  operator android_log_context() const {
-    return ctx;
-  }
-
-  /* return errors or transmit status */
-  int status() const {
-    return ret;
-  }
-
-  int begin() {
-    int retval = android_log_write_list_begin(ctx);
-    if (retval < 0) ret = retval;
-    return ret;
-  }
-  int end() {
-    int retval = android_log_write_list_end(ctx);
-    if (retval < 0) ret = retval;
-    return ret;
-  }
-
-  android_log_event_list& operator<<(int32_t value) {
-    int retval = android_log_write_int32(ctx, value);
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(uint32_t value) {
-    int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(bool value) {
-    int retval = android_log_write_int32(ctx, value ? 1 : 0);
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(int64_t value) {
-    int retval = android_log_write_int64(ctx, value);
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(uint64_t value) {
-    int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(const char* value) {
-    int retval = android_log_write_string8(ctx, value);
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(const std::string& value) {
-    int retval =
-        android_log_write_string8_len(ctx, value.data(), value.length());
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  android_log_event_list& operator<<(float value) {
-    int retval = android_log_write_float32(ctx, value);
-    if (retval < 0) ret = retval;
-    return *this;
-  }
-
-  int write(log_id_t id = LOG_ID_EVENTS) {
-    /* facilitate -EBUSY retry */
-    if ((ret == -EBUSY) || (ret > 0)) ret = 0;
-    int retval = android_log_write_list(ctx, id);
-    /* existing errors trump transmission errors */
-    if (!ret) ret = retval;
-    return ret;
-  }
-
-  int operator<<(log_id_t id) {
-    write(id);
-    android_log_destroy(&ctx);
-    return ret;
-  }
-
-  /*
-   * Append<Type> methods removes any integer promotion
-   * confusion, and adds access to string with length.
-   * Append methods are also added for all types for
-   * convenience.
-   */
-
-  bool AppendInt(int32_t value) {
-    int retval = android_log_write_int32(ctx, value);
-    if (retval < 0) ret = retval;
-    return ret >= 0;
-  }
-
-  bool AppendLong(int64_t value) {
-    int retval = android_log_write_int64(ctx, value);
-    if (retval < 0) ret = retval;
-    return ret >= 0;
-  }
-
-  bool AppendString(const char* value) {
-    int retval = android_log_write_string8(ctx, value);
-    if (retval < 0) ret = retval;
-    return ret >= 0;
-  }
-
-  bool AppendString(const char* value, size_t len) {
-    int retval = android_log_write_string8_len(ctx, value, len);
-    if (retval < 0) ret = retval;
-    return ret >= 0;
-  }
-
-  bool AppendString(const std::string& value) {
-    int retval =
-        android_log_write_string8_len(ctx, value.data(), value.length());
-    if (retval < 0) ret = retval;
-    return ret;
-  }
-
-  bool Append(const std::string& value) {
-    int retval =
-        android_log_write_string8_len(ctx, value.data(), value.length());
-    if (retval < 0) ret = retval;
-    return ret;
-  }
-
-  bool AppendFloat(float value) {
-    int retval = android_log_write_float32(ctx, value);
-    if (retval < 0) ret = retval;
-    return ret >= 0;
-  }
-
-  template <typename Tvalue>
-  bool Append(Tvalue value) {
-    *this << value;
-    return ret >= 0;
-  }
-
-  bool Append(const char* value, size_t len) {
-    int retval = android_log_write_string8_len(ctx, value, len);
-    if (retval < 0) ret = retval;
-    return ret >= 0;
-  }
-};
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log_id.h b/liblog/include/log/log_id.h
deleted file mode 100644
index 8e4faeb..0000000
--- a/liblog/include/log/log_id.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/log.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * log_id_t helpers
- */
-log_id_t android_name_to_log_id(const char* logName);
-const char* android_log_id_to_name(log_id_t log_id);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h
deleted file mode 100644
index 1bd1c8a..0000000
--- a/liblog/include/log/log_main.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include <android/log.h>
-
-__BEGIN_DECLS
-
-/*
- * Normally we strip the effects of ALOGV (VERBOSE messages),
- * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the
- * release builds be defining NDEBUG.  You can modify this (for
- * example with "#define LOG_NDEBUG 0" at the top of your source
- * file) to change that behavior.
- */
-
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/*
- * This file uses ", ## __VA_ARGS__" zero-argument token pasting to
- * work around issues with debug-only syntax errors in assertions
- * that are missing format strings.  See commit
- * 19299904343daf191267564fe32e6cd5c165cd42
- */
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
-#endif
-
-/*
- * Use __VA_ARGS__ if running a static analyzer,
- * to avoid warnings of unused variables in __VA_ARGS__.
- * Use constexpr function in C++ mode, so these macros can be used
- * in other constexpr functions without warning.
- */
-#ifdef __clang_analyzer__
-#ifdef __cplusplus
-extern "C++" {
-template <typename... Ts>
-constexpr int __fake_use_va_args(Ts...) {
-  return 0;
-}
-}
-#else
-extern int __fake_use_va_args(int, ...);
-#endif /* __cplusplus */
-#define __FAKE_USE_VA_ARGS(...) ((void)__fake_use_va_args(0, ##__VA_ARGS__))
-#else
-#define __FAKE_USE_VA_ARGS(...) ((void)(0))
-#endif /* __clang_analyzer__ */
-
-#ifndef __predict_false
-#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
-#endif
-
-#define android_writeLog(prio, tag, text) __android_log_write(prio, tag, text)
-
-#define android_printLog(prio, tag, ...) \
-  __android_log_print(prio, tag, __VA_ARGS__)
-
-#define android_vprintLog(prio, cond, tag, ...) \
-  __android_log_vprint(prio, tag, __VA_ARGS__)
-
-/*
- * Log macro that allows you to specify a number for the priority.
- */
-#ifndef LOG_PRI
-#define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__)
-#endif
-
-/*
- * Log macro that allows you to pass in a varargs ("args" is a va_list).
- */
-#ifndef LOG_PRI_VA
-#define LOG_PRI_VA(priority, tag, fmt, args) \
-  android_vprintLog(priority, NULL, tag, fmt, args)
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/* XXX Macros to work around syntax errors in places where format string
- * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
- * (happens only in debug builds).
- */
-
-/* Returns 2nd arg.  Used to substitute default value if caller's vararg list
- * is empty.
- */
-#define __android_second(dummy, second, ...) second
-
-/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
- * returns nothing.
- */
-#define __android_rest(first, ...) , ##__VA_ARGS__
-
-#define android_printAssert(cond, tag, ...)                     \
-  __android_log_assert(cond, tag,                               \
-                       __android_second(0, ##__VA_ARGS__, NULL) \
-                           __android_rest(__VA_ARGS__))
-
-/*
- * Log a fatal error.  If the given condition fails, this stops program
- * execution like a normal assertion, but also generating the given message.
- * It is NOT stripped from release builds.  Note that the condition test
- * is -inverted- from the normal assert() semantics.
- */
-#ifndef LOG_ALWAYS_FATAL_IF
-#define LOG_ALWAYS_FATAL_IF(cond, ...)                                                    \
-  ((__predict_false(cond)) ? (__FAKE_USE_VA_ARGS(__VA_ARGS__),                            \
-                              ((void)android_printAssert(#cond, LOG_TAG, ##__VA_ARGS__))) \
-                           : ((void)0))
-#endif
-
-#ifndef LOG_ALWAYS_FATAL
-#define LOG_ALWAYS_FATAL(...) \
-  (((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__)))
-#endif
-
-/*
- * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
- * are stripped out of release builds.
- */
-
-#if LOG_NDEBUG
-
-#ifndef LOG_FATAL_IF
-#define LOG_FATAL_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__)
-#endif
-#ifndef LOG_FATAL
-#define LOG_FATAL(...) __FAKE_USE_VA_ARGS(__VA_ARGS__)
-#endif
-
-#else
-
-#ifndef LOG_FATAL_IF
-#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__)
-#endif
-#ifndef LOG_FATAL
-#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
-#endif
-
-#endif
-
-/*
- * Assertion that generates a log message when the assertion fails.
- * Stripped out of release builds.  Uses the current LOG_TAG.
- */
-#ifndef ALOG_ASSERT
-#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__)
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/*
- * C/C++ logging functions.  See the logging documentation for API details.
- *
- * We'd like these to be available from C code (in case we import some from
- * somewhere), so this has a C interface.
- *
- * The output will be correct when the log file is shared between multiple
- * threads and/or multiple processes so long as the operating system
- * supports O_APPEND.  These calls have mutex-protected data structures
- * and so are NOT reentrant.  Do not use LOG in a signal handler.
- */
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Simplified macro to send a verbose log message using the current LOG_TAG.
- */
-#ifndef ALOGV
-#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
-#if LOG_NDEBUG
-#define ALOGV(...)                   \
-  do {                               \
-    __FAKE_USE_VA_ARGS(__VA_ARGS__); \
-    if (false) {                     \
-      __ALOGV(__VA_ARGS__);          \
-    }                                \
-  } while (false)
-#else
-#define ALOGV(...) __ALOGV(__VA_ARGS__)
-#endif
-#endif
-
-#ifndef ALOGV_IF
-#if LOG_NDEBUG
-#define ALOGV_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__)
-#else
-#define ALOGV_IF(cond, ...)                                                               \
-  ((__predict_false(cond))                                                                \
-       ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
-       : ((void)0))
-#endif
-#endif
-
-/*
- * Simplified macro to send a debug log message using the current LOG_TAG.
- */
-#ifndef ALOGD
-#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGD_IF
-#define ALOGD_IF(cond, ...)                                                             \
-  ((__predict_false(cond))                                                              \
-       ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
-       : ((void)0))
-#endif
-
-/*
- * Simplified macro to send an info log message using the current LOG_TAG.
- */
-#ifndef ALOGI
-#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGI_IF
-#define ALOGI_IF(cond, ...)                                                            \
-  ((__predict_false(cond))                                                             \
-       ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
-       : ((void)0))
-#endif
-
-/*
- * Simplified macro to send a warning log message using the current LOG_TAG.
- */
-#ifndef ALOGW
-#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGW_IF
-#define ALOGW_IF(cond, ...)                                                            \
-  ((__predict_false(cond))                                                             \
-       ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
-       : ((void)0))
-#endif
-
-/*
- * Simplified macro to send an error log message using the current LOG_TAG.
- */
-#ifndef ALOGE
-#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGE_IF
-#define ALOGE_IF(cond, ...)                                                             \
-  ((__predict_false(cond))                                                              \
-       ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
-       : ((void)0))
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * verbose priority.
- */
-#ifndef IF_ALOGV
-#if LOG_NDEBUG
-#define IF_ALOGV() if (false)
-#else
-#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG)
-#endif
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * debug priority.
- */
-#ifndef IF_ALOGD
-#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * info priority.
- */
-#ifndef IF_ALOGI
-#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * warn priority.
- */
-#ifndef IF_ALOGW
-#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * error priority.
- */
-#ifndef IF_ALOGE
-#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG)
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Basic log message macro.
- *
- * Example:
- *  ALOG(LOG_WARN, NULL, "Failed with error %d", errno);
- *
- * The second argument may be NULL or "" to indicate the "global" tag.
- */
-#ifndef ALOG
-#define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
-#endif
-
-/*
- * Conditional given a desired logging priority and tag.
- */
-#ifndef IF_ALOG
-#define IF_ALOG(priority, tag) if (android_testLog(ANDROID_##priority, tag))
-#endif
-
-/* --------------------------------------------------------------------- */
-
-/*
- *    IF_ALOG uses android_testLog, but IF_ALOG can be overridden.
- *    android_testLog will remain constant in its purpose as a wrapper
- *        for Android logging filter policy, and can be subject to
- *        change. It can be reused by the developers that override
- *        IF_ALOG as a convenient means to reimplement their policy
- *        over Android.
- */
-
-/*
- * Use the per-tag properties "log.tag.<tagname>" to generate a runtime
- * result of non-zero to expose a log. prio is ANDROID_LOG_VERBOSE to
- * ANDROID_LOG_FATAL. default_prio if no property. Undefined behavior if
- * any other value.
- */
-int __android_log_is_loggable(int prio, const char* tag, int default_prio);
-int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio);
-
-#if LOG_NDEBUG /* Production */
-#define android_testLog(prio, tag)                                           \
-  (__android_log_is_loggable_len(prio, tag, ((tag) && *(tag)) ? strlen(tag) : 0, \
-                                 ANDROID_LOG_DEBUG) != 0)
-#else
-#define android_testLog(prio, tag)                                           \
-  (__android_log_is_loggable_len(prio, tag, ((tag) && *(tag)) ? strlen(tag) : 0, \
-                                 ANDROID_LOG_VERBOSE) != 0)
-#endif
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-__END_DECLS
diff --git a/liblog/include/log/log_properties.h b/liblog/include/log/log_properties.h
deleted file mode 100644
index 2a0230f..0000000
--- a/liblog/include/log/log_properties.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Returns `1` if the device is debuggable or `0` if not. */
-int __android_log_is_debuggable();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log_radio.h b/liblog/include/log/log_radio.h
deleted file mode 100644
index f5525c1..0000000
--- a/liblog/include/log/log_radio.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/log.h>
-
-/*
- * Normally we strip the effects of ALOGV (VERBOSE messages),
- * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the
- * release builds be defining NDEBUG.  You can modify this (for
- * example with "#define LOG_NDEBUG 0" at the top of your source
- * file) to change that behavior.
- */
-
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#ifndef __predict_false
-#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
-#endif
-
-/*
- * Simplified macro to send a verbose radio log message using current LOG_TAG.
- */
-#ifndef RLOGV
-#define __RLOGV(...)                                                         \
-  ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, \
-                                 __VA_ARGS__))
-#if LOG_NDEBUG
-#define RLOGV(...)          \
-  do {                      \
-    if (0) {                \
-      __RLOGV(__VA_ARGS__); \
-    }                       \
-  } while (0)
-#else
-#define RLOGV(...) __RLOGV(__VA_ARGS__)
-#endif
-#endif
-
-#ifndef RLOGV_IF
-#if LOG_NDEBUG
-#define RLOGV_IF(cond, ...) ((void)0)
-#else
-#define RLOGV_IF(cond, ...)                                                \
-  ((__predict_false(cond))                                                 \
-       ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, \
-                                        LOG_TAG, __VA_ARGS__))             \
-       : (void)0)
-#endif
-#endif
-
-/*
- * Simplified macro to send a debug radio log message using  current LOG_TAG.
- */
-#ifndef RLOGD
-#define RLOGD(...)                                                         \
-  ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef RLOGD_IF
-#define RLOGD_IF(cond, ...)                                              \
-  ((__predict_false(cond))                                               \
-       ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, \
-                                        LOG_TAG, __VA_ARGS__))           \
-       : (void)0)
-#endif
-
-/*
- * Simplified macro to send an info radio log message using  current LOG_TAG.
- */
-#ifndef RLOGI
-#define RLOGI(...)                                                        \
-  ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef RLOGI_IF
-#define RLOGI_IF(cond, ...)                                             \
-  ((__predict_false(cond))                                              \
-       ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, \
-                                        LOG_TAG, __VA_ARGS__))          \
-       : (void)0)
-#endif
-
-/*
- * Simplified macro to send a warning radio log message using current LOG_TAG.
- */
-#ifndef RLOGW
-#define RLOGW(...)                                                        \
-  ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef RLOGW_IF
-#define RLOGW_IF(cond, ...)                                             \
-  ((__predict_false(cond))                                              \
-       ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, \
-                                        LOG_TAG, __VA_ARGS__))          \
-       : (void)0)
-#endif
-
-/*
- * Simplified macro to send an error radio log message using current LOG_TAG.
- */
-#ifndef RLOGE
-#define RLOGE(...)                                                         \
-  ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef RLOGE_IF
-#define RLOGE_IF(cond, ...)                                              \
-  ((__predict_false(cond))                                               \
-       ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, \
-                                        LOG_TAG, __VA_ARGS__))           \
-       : (void)0)
-#endif
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
deleted file mode 100644
index 1736934..0000000
--- a/liblog/include/log/log_read.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <android/log.h>
-#include <log/log_time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */
-
-/*
- * Native log reading interface section. See logcat for sample code.
- *
- * The preferred API is an exec of logcat. Likely uses of this interface
- * are if native code suffers from exec or filtration being too costly,
- * access to raw information, or parsing is an issue.
- */
-
-struct logger_entry {
-  uint16_t len;      /* length of the payload */
-  uint16_t hdr_size; /* sizeof(struct logger_entry) */
-  int32_t pid;       /* generating process's pid */
-  uint32_t tid;      /* generating process's tid */
-  uint32_t sec;      /* seconds since Epoch */
-  uint32_t nsec;     /* nanoseconds */
-  uint32_t lid;      /* log id of the payload, bottom 4 bits currently */
-  uint32_t uid;      /* generating process's uid */
-};
-
-/*
- * The maximum size of a log entry which can be read.
- * An attempt to read less than this amount may result
- * in read() returning EINVAL.
- */
-#define LOGGER_ENTRY_MAX_LEN (5 * 1024)
-
-struct log_msg {
-  union {
-    unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
-    struct logger_entry entry;
-  } __attribute__((aligned(4)));
-#ifdef __cplusplus
-  uint64_t nsec() const {
-    return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
-  }
-  log_id_t id() {
-    return static_cast<log_id_t>(entry.lid);
-  }
-  char* msg() {
-    unsigned short hdr_size = entry.hdr_size;
-    if (hdr_size >= sizeof(struct log_msg) - sizeof(entry)) {
-      return nullptr;
-    }
-    return reinterpret_cast<char*>(buf) + hdr_size;
-  }
-  unsigned int len() { return entry.hdr_size + entry.len; }
-#endif
-};
-
-struct logger;
-
-log_id_t android_logger_get_id(struct logger* logger);
-
-/* Clears the given log buffer. */
-int android_logger_clear(struct logger* logger);
-/* Return the allotted size for the given log buffer. */
-long android_logger_get_log_size(struct logger* logger);
-/* Set the allotted size for the given log buffer. */
-int android_logger_set_log_size(struct logger* logger, unsigned long size);
-/* Return the actual, uncompressed size that can be read from the given log buffer. */
-long android_logger_get_log_readable_size(struct logger* logger);
-/* Return the actual, compressed size that the given log buffer is consuming. */
-long android_logger_get_log_consumed_size(struct logger* logger);
-/* Deprecated.  Always returns '4' regardless of input. */
-int android_logger_get_log_version(struct logger* logger);
-
-struct logger_list;
-
-ssize_t android_logger_get_statistics(struct logger_list* logger_list,
-                                      char* buf, size_t len);
-ssize_t android_logger_get_prune_list(struct logger_list* logger_list,
-                                      char* buf, size_t len);
-int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len);
-
-/* The below values are used for the `mode` argument of the below functions. */
-/* Note that 0x00000003 were previously used and should be considered reserved. */
-#define ANDROID_LOG_NONBLOCK 0x00000800
-#define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */
-#define ANDROID_LOG_PSTORE 0x80000000
-
-struct logger_list* android_logger_list_alloc(int mode, unsigned int tail,
-                                              pid_t pid);
-struct logger_list* android_logger_list_alloc_time(int mode, log_time start,
-                                                   pid_t pid);
-void android_logger_list_free(struct logger_list* logger_list);
-/* In the purest sense, the following two are orthogonal interfaces */
-int android_logger_list_read(struct logger_list* logger_list,
-                             struct log_msg* log_msg);
-
-/* Multiple log_id_t opens */
-struct logger* android_logger_open(struct logger_list* logger_list, log_id_t id);
-/* Single log_id_t open */
-struct logger_list* android_logger_list_open(log_id_t id, int mode,
-                                             unsigned int tail, pid_t pid);
-#define android_logger_list_close android_logger_list_free
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log_safetynet.h b/liblog/include/log/log_safetynet.h
deleted file mode 100644
index b2604b5..0000000
--- a/liblog/include/log/log_safetynet.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define android_errorWriteLog(tag, subTag) \
-  __android_log_error_write(tag, subTag, -1, NULL, 0)
-
-#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \
-  __android_log_error_write(tag, subTag, uid, data, dataLen)
-
-int __android_log_error_write(int tag, const char* subTag, int32_t uid,
-                              const char* data, uint32_t dataLen);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/log/log_system.h b/liblog/include/log/log_system.h
deleted file mode 100644
index 6f40515..0000000
--- a/liblog/include/log/log_system.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/log.h>
-
-/*
- * Normally we strip the effects of ALOGV (VERBOSE messages),
- * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the
- * release builds be defining NDEBUG.  You can modify this (for
- * example with "#define LOG_NDEBUG 0" at the top of your source
- * file) to change that behavior.
- */
-
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-#ifndef __predict_false
-#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
-#endif
-
-/*
- * Simplified macro to send a verbose system log message using current LOG_TAG.
- */
-#ifndef SLOGV
-#define __SLOGV(...)                                                          \
-  ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, \
-                                 __VA_ARGS__))
-#if LOG_NDEBUG
-#define SLOGV(...)          \
-  do {                      \
-    if (0) {                \
-      __SLOGV(__VA_ARGS__); \
-    }                       \
-  } while (0)
-#else
-#define SLOGV(...) __SLOGV(__VA_ARGS__)
-#endif
-#endif
-
-#ifndef SLOGV_IF
-#if LOG_NDEBUG
-#define SLOGV_IF(cond, ...) ((void)0)
-#else
-#define SLOGV_IF(cond, ...)                                                 \
-  ((__predict_false(cond))                                                  \
-       ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, \
-                                        LOG_TAG, __VA_ARGS__))              \
-       : (void)0)
-#endif
-#endif
-
-/*
- * Simplified macro to send a debug system log message using current LOG_TAG.
- */
-#ifndef SLOGD
-#define SLOGD(...)                                                          \
-  ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef SLOGD_IF
-#define SLOGD_IF(cond, ...)                                               \
-  ((__predict_false(cond))                                                \
-       ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, \
-                                        LOG_TAG, __VA_ARGS__))            \
-       : (void)0)
-#endif
-
-/*
- * Simplified macro to send an info system log message using current LOG_TAG.
- */
-#ifndef SLOGI
-#define SLOGI(...)                                                         \
-  ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef SLOGI_IF
-#define SLOGI_IF(cond, ...)                                              \
-  ((__predict_false(cond))                                               \
-       ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, \
-                                        LOG_TAG, __VA_ARGS__))           \
-       : (void)0)
-#endif
-
-/*
- * Simplified macro to send a warning system log message using current LOG_TAG.
- */
-#ifndef SLOGW
-#define SLOGW(...)                                                         \
-  ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef SLOGW_IF
-#define SLOGW_IF(cond, ...)                                              \
-  ((__predict_false(cond))                                               \
-       ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, \
-                                        LOG_TAG, __VA_ARGS__))           \
-       : (void)0)
-#endif
-
-/*
- * Simplified macro to send an error system log message using current LOG_TAG.
- */
-#ifndef SLOGE
-#define SLOGE(...)                                                          \
-  ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, \
-                                 __VA_ARGS__))
-#endif
-
-#ifndef SLOGE_IF
-#define SLOGE_IF(cond, ...)                                               \
-  ((__predict_false(cond))                                                \
-       ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, \
-                                        LOG_TAG, __VA_ARGS__))            \
-       : (void)0)
-#endif
diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h
deleted file mode 100644
index f50764d..0000000
--- a/liblog/include/log/log_time.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <time.h>
-
-/* struct log_time is a wire-format variant of struct timespec */
-#define NS_PER_SEC 1000000000ULL
-#define US_PER_SEC 1000000ULL
-#define MS_PER_SEC 1000ULL
-
-#define LOG_TIME_SEC(t) ((t)->tv_sec)
-/* next power of two after NS_PER_SEC */
-#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
-
-#ifdef __cplusplus
-
-extern "C" {
-
-struct log_time {
- public:
-  uint32_t tv_sec = 0; /* good to Feb 5 2106 */
-  uint32_t tv_nsec = 0;
-
-  static constexpr timespec EPOCH = {0, 0};
-
-  log_time() {}
-  explicit log_time(const timespec& T)
-      : tv_sec(static_cast<uint32_t>(T.tv_sec)), tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {}
-  explicit log_time(uint32_t sec, uint32_t nsec = 0)
-      : tv_sec(sec), tv_nsec(nsec) {
-  }
-#ifdef __linux__
-  explicit log_time(clockid_t id) {
-    timespec T;
-    clock_gettime(id, &T);
-    tv_sec = static_cast<uint32_t>(T.tv_sec);
-    tv_nsec = static_cast<uint32_t>(T.tv_nsec);
-  }
-#endif
-  /* timespec */
-  bool operator==(const timespec& T) const {
-    return (tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
-           (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
-  }
-  bool operator!=(const timespec& T) const {
-    return !(*this == T);
-  }
-  bool operator<(const timespec& T) const {
-    return (tv_sec < static_cast<uint32_t>(T.tv_sec)) ||
-           ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
-            (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
-  }
-  bool operator>=(const timespec& T) const {
-    return !(*this < T);
-  }
-  bool operator>(const timespec& T) const {
-    return (tv_sec > static_cast<uint32_t>(T.tv_sec)) ||
-           ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
-            (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
-  }
-  bool operator<=(const timespec& T) const {
-    return !(*this > T);
-  }
-
-  /* log_time */
-  bool operator==(const log_time& T) const {
-    return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
-  }
-  bool operator!=(const log_time& T) const {
-    return !(*this == T);
-  }
-  bool operator<(const log_time& T) const {
-    return (tv_sec < T.tv_sec) ||
-           ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
-  }
-  bool operator>=(const log_time& T) const {
-    return !(*this < T);
-  }
-  bool operator>(const log_time& T) const {
-    return (tv_sec > T.tv_sec) ||
-           ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
-  }
-  bool operator<=(const log_time& T) const {
-    return !(*this > T);
-  }
-
-  log_time operator-=(const log_time& T) {
-    // No concept of negative time, clamp to EPOCH
-    if (*this <= T) {
-      return *this = log_time(EPOCH);
-    }
-
-    if (this->tv_nsec < T.tv_nsec) {
-      --this->tv_sec;
-      this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
-    } else {
-      this->tv_nsec -= T.tv_nsec;
-    }
-    this->tv_sec -= T.tv_sec;
-
-    return *this;
-  }
-  log_time operator-(const log_time& T) const {
-    log_time local(*this);
-    return local -= T;
-  }
-  log_time operator+=(const log_time& T) {
-    this->tv_nsec += T.tv_nsec;
-    if (this->tv_nsec >= NS_PER_SEC) {
-      this->tv_nsec -= NS_PER_SEC;
-      ++this->tv_sec;
-    }
-    this->tv_sec += T.tv_sec;
-
-    return *this;
-  }
-  log_time operator+(const log_time& T) const {
-    log_time local(*this);
-    return local += T;
-  }
-
-  uint64_t nsec() const {
-    return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
-  }
-  uint64_t usec() const {
-    return static_cast<uint64_t>(tv_sec) * US_PER_SEC +
-           tv_nsec / (NS_PER_SEC / US_PER_SEC);
-  }
-  uint64_t msec() const {
-    return static_cast<uint64_t>(tv_sec) * MS_PER_SEC +
-           tv_nsec / (NS_PER_SEC / MS_PER_SEC);
-  }
-
-  /* Add %#q for the fraction of a second to the standard library functions */
-  char* strptime(const char* s, const char* format);
-} __attribute__((__packed__));
-}
-
-#else /* __cplusplus */
-
-typedef struct log_time {
-  uint32_t tv_sec;
-  uint32_t tv_nsec;
-} __attribute__((__packed__)) log_time;
-
-#endif /* __cplusplus */
diff --git a/liblog/include/log/logprint.h b/liblog/include/log/logprint.h
deleted file mode 100644
index 7dfd914..0000000
--- a/liblog/include/log/logprint.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <android/log.h>
-#include <log/event_tag_map.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-  /* Verbs */
-  FORMAT_OFF = 0,
-  FORMAT_BRIEF,
-  FORMAT_PROCESS,
-  FORMAT_TAG,
-  FORMAT_THREAD,
-  FORMAT_RAW,
-  FORMAT_TIME,
-  FORMAT_THREADTIME,
-  FORMAT_LONG,
-  /* Adverbs. The following are modifiers to above format verbs */
-  FORMAT_MODIFIER_COLOR,     /* converts priority to color */
-  FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */
-  FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */
-  FORMAT_MODIFIER_YEAR,      /* Adds year to date */
-  FORMAT_MODIFIER_ZONE,      /* Adds zone to date, + UTC */
-  FORMAT_MODIFIER_EPOCH,     /* Print time as seconds since Jan 1 1970 */
-  FORMAT_MODIFIER_MONOTONIC, /* Print cpu time as seconds since start */
-  FORMAT_MODIFIER_UID,       /* Adds uid */
-  FORMAT_MODIFIER_DESCRIPT,  /* Adds descriptive */
-  /* private, undocumented */
-  FORMAT_MODIFIER_TIME_NSEC, /* switches from msec to nsec time precision */
-} AndroidLogPrintFormat;
-
-typedef struct AndroidLogFormat_t AndroidLogFormat;
-
-typedef struct AndroidLogEntry_t {
-  time_t tv_sec;
-  long tv_nsec;
-  android_LogPriority priority;
-  int32_t uid;
-  int32_t pid;
-  int32_t tid;
-  const char* tag;
-  size_t tagLen;
-  size_t messageLen;
-  const char* message;
-} AndroidLogEntry;
-
-AndroidLogFormat* android_log_format_new();
-
-void android_log_format_free(AndroidLogFormat* p_format);
-
-/* currently returns 0 if format is a modifier, 1 if not */
-int android_log_setPrintFormat(AndroidLogFormat* p_format,
-                               AndroidLogPrintFormat format);
-
-/**
- * Returns FORMAT_OFF on invalid string
- */
-AndroidLogPrintFormat android_log_formatFromString(const char* s);
-
-/**
- * filterExpression: a single filter expression
- * eg "AT:d"
- *
- * returns 0 on success and -1 on invalid expression
- *
- * Assumes single threaded execution
- *
- */
-
-int android_log_addFilterRule(AndroidLogFormat* p_format,
-                              const char* filterExpression);
-
-/**
- * filterString: a whitespace-separated set of filter expressions
- * eg "AT:d *:i"
- *
- * returns 0 on success and -1 on invalid expression
- *
- * Assumes single threaded execution
- *
- */
-
-int android_log_addFilterString(AndroidLogFormat* p_format,
-                                const char* filterString);
-
-/**
- * returns 1 if this log line should be printed based on its priority
- * and tag, and 0 if it should not
- */
-int android_log_shouldPrintLine(AndroidLogFormat* p_format, const char* tag,
-                                android_LogPriority pri);
-
-/**
- * Splits a wire-format buffer into an AndroidLogEntry
- * entry allocated by caller. Pointers will point directly into buf
- *
- * Returns 0 on success and -1 on invalid wire format (entry will be
- * in unspecified state)
- */
-int android_log_processLogBuffer(struct logger_entry* buf,
-                                 AndroidLogEntry* entry);
-
-/**
- * Like android_log_processLogBuffer, but for binary logs.
- *
- * If "map" is non-NULL, it will be used to convert the log tag number
- * into a string.
- */
-int android_log_processBinaryLogBuffer(struct logger_entry* buf,
-                                       AndroidLogEntry* entry,
-                                       const EventTagMap* map, char* messageBuf,
-                                       int messageBufLen);
-
-/**
- * Formats a log message into a buffer
- *
- * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer
- * If return value != defaultBuffer, caller must call free()
- * Returns NULL on malloc error
- */
-
-char* android_log_formatLogLine(AndroidLogFormat* p_format, char* defaultBuffer,
-                                size_t defaultBufferSize,
-                                const AndroidLogEntry* p_line,
-                                size_t* p_outLength);
-
-/**
- * Either print or do not print log line, based on filter
- *
- * Assumes single threaded execution
- *
- */
-int android_log_printLogLine(AndroidLogFormat* p_format, int fd,
-                             const AndroidLogEntry* entry);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h
deleted file mode 100644
index 166f387..0000000
--- a/liblog/include/private/android_logger.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-/* This file is used to define the internal protocol for the Android Logger */
-
-#pragma once
-
-/* Android private interfaces */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-#include <string>
-#endif
-
-#include <log/log.h>
-#include <log/log_event_list.h>
-
-#define LOGGER_MAGIC 'l'
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* Header Structure to pstore */
-typedef struct __attribute__((__packed__)) {
-  uint8_t magic;
-  uint16_t len;
-  uint16_t uid;
-  uint16_t pid;
-} android_pmsg_log_header_t;
-
-/* Header Structure to logd, and second header for pstore */
-typedef struct __attribute__((__packed__)) {
-  uint8_t id;
-  uint16_t tid;
-  log_time realtime;
-} android_log_header_t;
-
-/* Event Header Structure to logd */
-typedef struct __attribute__((__packed__)) {
-  int32_t tag;  // Little Endian Order
-} android_event_header_t;
-
-// Event payload EVENT_TYPE_LIST
-typedef struct __attribute__((__packed__)) {
-  int8_t type;  // EVENT_TYPE_LIST
-  int8_t element_count;
-} android_event_list_t;
-
-// Event payload EVENT_TYPE_FLOAT
-typedef struct __attribute__((__packed__)) {
-  int8_t type;  // EVENT_TYPE_FLOAT
-  float data;
-} android_event_float_t;
-
-/* Event payload EVENT_TYPE_INT */
-typedef struct __attribute__((__packed__)) {
-  int8_t type;   // EVENT_TYPE_INT
-  int32_t data;  // Little Endian Order
-} android_event_int_t;
-
-/* Event with single EVENT_TYPE_INT */
-typedef struct __attribute__((__packed__)) {
-  android_event_header_t header;
-  android_event_int_t payload;
-} android_log_event_int_t;
-
-/* Event payload EVENT_TYPE_LONG */
-typedef struct __attribute__((__packed__)) {
-  int8_t type;   // EVENT_TYPE_LONG
-  int64_t data;  // Little Endian Order
-} android_event_long_t;
-
-/* Event with single EVENT_TYPE_LONG */
-typedef struct __attribute__((__packed__)) {
-  android_event_header_t header;
-  android_event_long_t payload;
-} android_log_event_long_t;
-
-/*
- * Event payload EVENT_TYPE_STRING
- *
- * Danger: do not embed this structure into another structure.
- * This structure uses a flexible array member, and when
- * compiled using g++, __builtin_object_size(data, 1) returns
- * a bad value. This is possibly a g++ bug, or a bug due to
- * the fact that flexible array members are not supported
- * in C++.
- * http://stackoverflow.com/questions/4412749/are-flexible-array-members-valid-in-c
- */
-
-typedef struct __attribute__((__packed__)) {
-  int8_t type;     // EVENT_TYPE_STRING;
-  int32_t length;  // Little Endian Order
-  char data[];
-} android_event_string_t;
-
-/* Event with single EVENT_TYPE_STRING */
-typedef struct __attribute__((__packed__)) {
-  android_event_header_t header;
-  int8_t type;     // EVENT_TYPE_STRING;
-  int32_t length;  // Little Endian Order
-  char data[];
-} android_log_event_string_t;
-
-#define ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE 256 /* 1MB file */
-#define ANDROID_LOG_PMSG_FILE_SEQUENCE 1000
-
-ssize_t __android_log_pmsg_file_write(log_id_t logId, char prio,
-                                      const char* filename, const char* buf,
-                                      size_t len);
-
-#define LOG_ID_ANY ((log_id_t)-1)
-#define ANDROID_LOG_ANY ANDROID_LOG_UNKNOWN
-
-/* first 5 arguments match __android_log_msg_file_write, a cast is safe */
-typedef ssize_t (*__android_log_pmsg_file_read_fn)(log_id_t logId, char prio,
-                                                   const char* filename,
-                                                   const char* buf, size_t len,
-                                                   void* arg);
-
-ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio,
-                                     const char* prefix,
-                                     __android_log_pmsg_file_read_fn fn,
-                                     void* arg);
-
-int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len);
-int __android_log_security_bswrite(int32_t tag, const char* payload);
-int __android_log_security(); /* Device Owner is present */
-
-/* Retrieve the composed event buffer */
-int android_log_write_list_buffer(android_log_context ctx, const char** msg);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/liblog/include_vndk/android b/liblog/include_vndk/android
deleted file mode 120000
index a3c0320..0000000
--- a/liblog/include_vndk/android
+++ /dev/null
@@ -1 +0,0 @@
-../include/android
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log.h b/liblog/include_vndk/log/log.h
deleted file mode 100644
index ab4adc4..0000000
--- a/liblog/include_vndk/log/log.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*Special log.h file for VNDK linking modules*/
-
-#ifndef _LIBS_LOG_LOG_H
-#define _LIBS_LOG_LOG_H
-
-/* Historically vendors have depended on this header being included. */
-#include <fcntl.h>
-
-#include <android/log.h>
-#include <log/log_id.h>
-#include <log/log_main.h>
-#include <log/log_radio.h>
-#include <log/log_read.h>
-#include <log/log_safetynet.h>
-#include <log/log_system.h>
-#include <log/log_time.h>
-
-/*
- * LOG_TAG is the local tag used for the following simplified
- * logging macros.  You can change this preprocessor definition
- * before using the other macros to change the tag.
- */
-
-#ifndef LOG_TAG
-#define LOG_TAG NULL
-#endif
-
-#endif /*_LIBS_LOG_LOG_H*/
diff --git a/liblog/include_vndk/log/log_event_list.h b/liblog/include_vndk/log/log_event_list.h
deleted file mode 100644
index 1f3dd37..0000000
--- a/liblog/include_vndk/log/log_event_list.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2005-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.
- */
-
-/* Special log_event_list.h file for VNDK linking modules */
-
-#ifndef _LIBS_LOG_EVENT_LIST_H
-#define _LIBS_LOG_EVENT_LIST_H
-
-#include <stdint.h>
-
-#include <log/log_id.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The opaque context used to manipulate lists of events.
- */
-#ifndef __android_log_context_defined
-#define __android_log_context_defined
-typedef struct android_log_context_internal* android_log_context;
-#endif
-
-/*
- * Creates a context associated with an event tag to write elements to
- * the list of events.
- */
-android_log_context create_android_logger(uint32_t tag);
-
-/* All lists must be braced by a begin and end call */
-/*
- * NB: If the first level braces are missing when specifying multiple
- *     elements, we will manufacturer a list to embrace it for your API
- *     convenience. For a single element, it will remain solitary.
- */
-int android_log_write_list_begin(android_log_context ctx);
-int android_log_write_list_end(android_log_context ctx);
-
-int android_log_write_int32(android_log_context ctx, int32_t value);
-int android_log_write_int64(android_log_context ctx, int64_t value);
-int android_log_write_string8(android_log_context ctx, const char* value);
-int android_log_write_string8_len(android_log_context ctx, const char* value,
-                                  size_t maxlen);
-int android_log_write_float32(android_log_context ctx, float value);
-
-/* Submit the composed list context to the specified logger id */
-/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
-int android_log_write_list(android_log_context ctx, log_id_t id);
-
-/* Reset writer context */
-int android_log_reset(android_log_context ctx);
-
-/* Reset reader context */
-int android_log_parser_reset(android_log_context ctx,
-                             const char* msg, size_t len);
-
-/* Finished with reader or writer context */
-int android_log_destroy(android_log_context* ctx);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LIBS_LOG_EVENT_LIST_H */
diff --git a/liblog/include_vndk/log/log_id.h b/liblog/include_vndk/log/log_id.h
deleted file mode 120000
index dce92b9..0000000
--- a/liblog/include_vndk/log/log_id.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_id.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_main.h b/liblog/include_vndk/log/log_main.h
deleted file mode 120000
index f2ec018..0000000
--- a/liblog/include_vndk/log/log_main.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_main.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_properties.h b/liblog/include_vndk/log/log_properties.h
deleted file mode 120000
index bbec426..0000000
--- a/liblog/include_vndk/log/log_properties.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_properties.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_radio.h b/liblog/include_vndk/log/log_radio.h
deleted file mode 120000
index 1e12b32..0000000
--- a/liblog/include_vndk/log/log_radio.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_radio.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_read.h b/liblog/include_vndk/log/log_read.h
deleted file mode 120000
index 01de8b9..0000000
--- a/liblog/include_vndk/log/log_read.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_read.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_safetynet.h b/liblog/include_vndk/log/log_safetynet.h
deleted file mode 120000
index a4614e7..0000000
--- a/liblog/include_vndk/log/log_safetynet.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_safetynet.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_system.h b/liblog/include_vndk/log/log_system.h
deleted file mode 120000
index d0d3904..0000000
--- a/liblog/include_vndk/log/log_system.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_system.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_time.h b/liblog/include_vndk/log/log_time.h
deleted file mode 100644
index 5a09959..0000000
--- a/liblog/include_vndk/log/log_time.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2005-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _LIBS_LOG_LOG_TIME_H
-#define _LIBS_LOG_LOG_TIME_H
-
-#include <stdint.h>
-
-/* struct log_time is a wire-format variant of struct timespec */
-#ifndef NS_PER_SEC
-#define NS_PER_SEC 1000000000ULL
-#endif
-#ifndef US_PER_SEC
-#define US_PER_SEC 1000000ULL
-#endif
-#ifndef MS_PER_SEC
-#define MS_PER_SEC 1000ULL
-#endif
-
-#ifndef __struct_log_time_defined
-#define __struct_log_time_defined
-
-#define LOG_TIME_SEC(t) ((t)->tv_sec)
-/* next power of two after NS_PER_SEC */
-#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
-
-typedef struct log_time {
-  uint32_t tv_sec;
-  uint32_t tv_nsec;
-} __attribute__((__packed__)) log_time;
-
-#endif
-
-#endif /* _LIBS_LOG_LOG_TIME_H */
diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt
deleted file mode 100644
index f8d5ef0..0000000
--- a/liblog/liblog.map.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-LIBLOG {
-  global:
-    android_name_to_log_id; # apex llndk
-    android_log_id_to_name; # llndk
-    __android_log_assert;
-    __android_log_buf_print;
-    __android_log_buf_write;
-    __android_log_print;
-    __android_log_vprint;
-    __android_log_write;
-  local:
-    *;
-};
-
-LIBLOG_L {
-  global:
-    android_logger_clear; # llndk
-    android_logger_get_id; # llndk
-    android_logger_get_log_readable_size; # llndk
-    android_logger_get_log_version; # llndk
-    android_logger_get_log_size; # llndk
-    android_logger_list_alloc; # apex llndk
-    android_logger_list_alloc_time; # apex llndk
-    android_logger_list_free; # apex llndk
-    android_logger_list_open; # apex llndk
-    android_logger_list_read; # apex llndk
-    android_logger_open; # apex llndk
-    android_logger_set_log_size; # llndk
-};
-
-LIBLOG_M {
-  global:
-    android_logger_get_prune_list; # llndk
-    android_logger_set_prune_list; # llndk
-    android_logger_get_statistics; # llndk
-    __android_log_error_write; # apex llndk
-    __android_log_is_loggable;
-    create_android_logger; # apex llndk
-    android_log_destroy; # apex llndk
-    android_log_write_list_begin; # apex llndk
-    android_log_write_list_end; # apex llndk
-    android_log_write_int32; # apex llndk
-    android_log_write_int64; # apex llndk
-    android_log_write_string8; # apex llndk
-    android_log_write_string8_len; # apex llndk
-    android_log_write_float32; # apex llndk
-    android_log_write_list; # apex llndk
-
-};
-
-LIBLOG_O {
-  global:
-    __android_log_is_loggable_len;
-    __android_log_is_debuggable; # apex llndk
-};
-
-LIBLOG_Q { # introduced=29
-  global:
-    __android_log_bswrite; # apex
-    __android_log_btwrite; # apex
-    __android_log_bwrite; # apex
-    __android_log_close; # apex
-    __android_log_security; # apex
-    android_log_reset; # llndk
-    android_log_parser_reset; # llndk
-};
-
-LIBLOG_R { # introduced=30
-  global:
-    __android_log_call_aborter;
-    __android_log_default_aborter;
-    __android_log_get_minimum_priority;
-    __android_log_logd_logger;
-    __android_log_security_bswrite; # apex
-    __android_log_set_aborter;
-    __android_log_set_default_tag;
-    __android_log_set_logger;
-    __android_log_set_minimum_priority;
-    __android_log_stderr_logger;
-    __android_log_write_log_message;
-};
-
-LIBLOG_PRIVATE {
-  global:
-    __android_log_pmsg_file_read;
-    __android_log_pmsg_file_write;
-    android_openEventTagMap;
-    android_log_processBinaryLogBuffer;
-    android_log_processLogBuffer;
-    android_log_read_next;
-    android_log_write_list_buffer;
-    create_android_log_parser;
-};
diff --git a/liblog/log_event_list.cpp b/liblog/log_event_list.cpp
deleted file mode 100644
index cb70d48..0000000
--- a/liblog/log_event_list.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (C) 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 <inttypes.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <log/log_event_list.h>
-#include <private/android_logger.h>
-
-#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
-
-enum ReadWriteFlag {
-  kAndroidLoggerRead = 1,
-  kAndroidLoggerWrite = 2,
-};
-
-struct android_log_context_internal {
-  uint32_t tag;
-  unsigned pos;                                    /* Read/write position into buffer */
-  unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements   */
-  unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1];  /* pos for list counter */
-  unsigned list_nest_depth;
-  unsigned len; /* Length or raw buffer. */
-  bool overflow;
-  bool list_stop; /* next call decrement list_nest_depth and issue a stop */
-  ReadWriteFlag read_write_flag;
-  uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
-};
-
-static void init_context(android_log_context_internal* context, uint32_t tag) {
-  context->tag = tag;
-  context->read_write_flag = kAndroidLoggerWrite;
-  size_t needed = sizeof(android_event_list_t);
-  if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
-    context->overflow = true;
-  }
-  /* Everything is a list */
-  context->storage[context->pos + 0] = EVENT_TYPE_LIST;
-  context->list[0] = context->pos + 1;
-  context->pos += needed;
-}
-
-static void init_parser_context(android_log_context_internal* context, const char* msg,
-                                size_t len) {
-  len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
-  context->len = len;
-  memcpy(context->storage, msg, len);
-  context->read_write_flag = kAndroidLoggerRead;
-}
-
-android_log_context create_android_logger(uint32_t tag) {
-  android_log_context_internal* context;
-
-  context =
-      static_cast<android_log_context_internal*>(calloc(1, sizeof(android_log_context_internal)));
-  if (!context) {
-    return NULL;
-  }
-  init_context(context, tag);
-
-  return (android_log_context)context;
-}
-
-android_log_context create_android_log_parser(const char* msg, size_t len) {
-  android_log_context_internal* context;
-
-  context =
-      static_cast<android_log_context_internal*>(calloc(1, sizeof(android_log_context_internal)));
-  if (!context) {
-    return NULL;
-  }
-  init_parser_context(context, msg, len);
-
-  return (android_log_context)context;
-}
-
-int android_log_destroy(android_log_context* ctx) {
-  android_log_context_internal* context;
-
-  context = (android_log_context_internal*)*ctx;
-  if (!context) {
-    return -EBADF;
-  }
-  memset(context, 0, sizeof(*context));
-  free(context);
-  *ctx = NULL;
-  return 0;
-}
-
-int android_log_reset(android_log_context context) {
-  uint32_t tag;
-
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-
-  tag = context->tag;
-  memset(context, 0, sizeof(*context));
-  init_context(context, tag);
-
-  return 0;
-}
-
-int android_log_parser_reset(android_log_context context, const char* msg, size_t len) {
-  if (!context || (kAndroidLoggerRead != context->read_write_flag)) {
-    return -EBADF;
-  }
-
-  memset(context, 0, sizeof(*context));
-  init_parser_context(context, msg, len);
-
-  return 0;
-}
-
-int android_log_write_list_begin(android_log_context context) {
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
-    context->overflow = true;
-    return -EOVERFLOW;
-  }
-  size_t needed = sizeof(android_event_list_t);
-  if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
-    context->overflow = true;
-    return -EIO;
-  }
-  context->count[context->list_nest_depth]++;
-  context->list_nest_depth++;
-  if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
-    context->overflow = true;
-    return -EOVERFLOW;
-  }
-  if (context->overflow) {
-    return -EIO;
-  }
-  auto* event_list = reinterpret_cast<android_event_list_t*>(&context->storage[context->pos]);
-  event_list->type = EVENT_TYPE_LIST;
-  event_list->element_count = 0;
-  context->list[context->list_nest_depth] = context->pos + 1;
-  context->count[context->list_nest_depth] = 0;
-  context->pos += needed;
-  return 0;
-}
-
-int android_log_write_int32(android_log_context context, int32_t value) {
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->overflow) {
-    return -EIO;
-  }
-  size_t needed = sizeof(android_event_int_t);
-  if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
-    context->overflow = true;
-    return -EIO;
-  }
-  context->count[context->list_nest_depth]++;
-  auto* event_int = reinterpret_cast<android_event_int_t*>(&context->storage[context->pos]);
-  event_int->type = EVENT_TYPE_INT;
-  event_int->data = value;
-  context->pos += needed;
-  return 0;
-}
-
-int android_log_write_int64(android_log_context context, int64_t value) {
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->overflow) {
-    return -EIO;
-  }
-  size_t needed = sizeof(android_event_long_t);
-  if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
-    context->overflow = true;
-    return -EIO;
-  }
-  context->count[context->list_nest_depth]++;
-  auto* event_long = reinterpret_cast<android_event_long_t*>(&context->storage[context->pos]);
-  event_long->type = EVENT_TYPE_LONG;
-  event_long->data = value;
-  context->pos += needed;
-  return 0;
-}
-
-int android_log_write_string8_len(android_log_context context, const char* value, size_t maxlen) {
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->overflow) {
-    return -EIO;
-  }
-  if (!value) {
-    value = "";
-  }
-  int32_t len = strnlen(value, maxlen);
-  size_t needed = sizeof(android_event_string_t) + len;
-  if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
-    /* Truncate string for delivery */
-    len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
-    if (len <= 0) {
-      context->overflow = true;
-      return -EIO;
-    }
-  }
-  context->count[context->list_nest_depth]++;
-  auto* event_string = reinterpret_cast<android_event_string_t*>(&context->storage[context->pos]);
-  event_string->type = EVENT_TYPE_STRING;
-  event_string->length = len;
-  if (len) {
-    memcpy(&event_string->data, value, len);
-  }
-  context->pos += needed;
-  return len;
-}
-
-int android_log_write_string8(android_log_context ctx, const char* value) {
-  return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
-}
-
-int android_log_write_float32(android_log_context context, float value) {
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->overflow) {
-    return -EIO;
-  }
-  size_t needed = sizeof(android_event_float_t);
-  if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
-    context->overflow = true;
-    return -EIO;
-  }
-  context->count[context->list_nest_depth]++;
-  auto* event_float = reinterpret_cast<android_event_float_t*>(&context->storage[context->pos]);
-  event_float->type = EVENT_TYPE_FLOAT;
-  event_float->data = value;
-  context->pos += needed;
-  return 0;
-}
-
-int android_log_write_list_end(android_log_context context) {
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
-    context->overflow = true;
-    context->list_nest_depth--;
-    return -EOVERFLOW;
-  }
-  if (!context->list_nest_depth) {
-    context->overflow = true;
-    return -EOVERFLOW;
-  }
-  if (context->list[context->list_nest_depth] <= 0) {
-    context->list_nest_depth--;
-    context->overflow = true;
-    return -EOVERFLOW;
-  }
-  context->storage[context->list[context->list_nest_depth]] =
-      context->count[context->list_nest_depth];
-  context->list_nest_depth--;
-  return 0;
-}
-
-/*
- * Logs the list of elements to the event log.
- */
-int android_log_write_list(android_log_context context, log_id_t id) {
-  const char* msg;
-  ssize_t len;
-
-  if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (id != LOG_ID_STATS)) {
-    return -EINVAL;
-  }
-
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->list_nest_depth) {
-    return -EIO;
-  }
-  /* NB: if there was overflow, then log is truncated. Nothing reported */
-  context->storage[1] = context->count[0];
-  len = context->len = context->pos;
-  msg = (const char*)context->storage;
-  /* it's not a list */
-  if (context->count[0] <= 1) {
-    len -= sizeof(uint8_t) + sizeof(uint8_t);
-    if (len < 0) {
-      len = 0;
-    }
-    msg += sizeof(uint8_t) + sizeof(uint8_t);
-  }
-  return (id == LOG_ID_EVENTS)
-             ? __android_log_bwrite(context->tag, msg, len)
-             : ((id == LOG_ID_STATS) ? __android_log_stats_bwrite(context->tag, msg, len)
-                                     : __android_log_security_bwrite(context->tag, msg, len));
-}
-
-int android_log_write_list_buffer(android_log_context context, const char** buffer) {
-  const char* msg;
-  ssize_t len;
-
-  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
-    return -EBADF;
-  }
-  if (context->list_nest_depth) {
-    return -EIO;
-  }
-  if (buffer == NULL) {
-    return -EFAULT;
-  }
-  /* NB: if there was overflow, then log is truncated. Nothing reported */
-  context->storage[1] = context->count[0];
-  len = context->len = context->pos;
-  msg = (const char*)context->storage;
-  /* it's not a list */
-  if (context->count[0] <= 1) {
-    len -= sizeof(uint8_t) + sizeof(uint8_t);
-    if (len < 0) {
-      len = 0;
-    }
-    msg += sizeof(uint8_t) + sizeof(uint8_t);
-  }
-  *buffer = msg;
-  return len;
-}
-
-/*
- * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
- * If there is nothing to process, the complete field is set to non-zero. If
- * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
- * this and continues to call this function, the behavior is undefined
- * (although it won't crash).
- */
-static android_log_list_element android_log_read_next_internal(android_log_context context,
-                                                               int peek) {
-  android_log_list_element elem;
-  unsigned pos;
-
-  memset(&elem, 0, sizeof(elem));
-
-  /* Nothing to parse from this context, so return complete. */
-  if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
-      (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
-      (context->count[context->list_nest_depth] >=
-       (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
-    elem.type = EVENT_TYPE_UNKNOWN;
-    if (context &&
-        (context->list_stop || ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
-                                !context->count[context->list_nest_depth]))) {
-      elem.type = EVENT_TYPE_LIST_STOP;
-    }
-    elem.complete = true;
-    return elem;
-  }
-
-  /*
-   * Use a different variable to update the position in case this
-   * operation is a "peek".
-   */
-  pos = context->pos;
-  if (context->list_stop) {
-    elem.type = EVENT_TYPE_LIST_STOP;
-    elem.complete = !context->count[0] && (!context->list_nest_depth ||
-                                           ((context->list_nest_depth == 1) && !context->count[1]));
-    if (!peek) {
-      /* Suck in superfluous stop */
-      if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
-        context->pos = pos + 1;
-      }
-      if (context->list_nest_depth) {
-        --context->list_nest_depth;
-        if (context->count[context->list_nest_depth]) {
-          context->list_stop = false;
-        }
-      } else {
-        context->list_stop = false;
-      }
-    }
-    return elem;
-  }
-  if ((pos + 1) > context->len) {
-    elem.type = EVENT_TYPE_UNKNOWN;
-    elem.complete = true;
-    return elem;
-  }
-
-  elem.type = static_cast<AndroidEventLogType>(context->storage[pos]);
-  switch ((int)elem.type) {
-    case EVENT_TYPE_FLOAT:
-    /* Rely on union to translate elem.data.int32 into elem.data.float32 */
-    /* FALLTHRU */
-    case EVENT_TYPE_INT: {
-      elem.len = sizeof(int32_t);
-      if ((pos + sizeof(android_event_int_t)) > context->len) {
-        elem.type = EVENT_TYPE_UNKNOWN;
-        return elem;
-      }
-
-      auto* event_int = reinterpret_cast<android_event_int_t*>(&context->storage[pos]);
-      pos += sizeof(android_event_int_t);
-      elem.data.int32 = event_int->data;
-      /* common tangeable object suffix */
-      elem.complete = !context->list_nest_depth && !context->count[0];
-      if (!peek) {
-        if (!context->count[context->list_nest_depth] ||
-            !--(context->count[context->list_nest_depth])) {
-          context->list_stop = true;
-        }
-        context->pos = pos;
-      }
-      return elem;
-    }
-
-    case EVENT_TYPE_LONG: {
-      elem.len = sizeof(int64_t);
-      if ((pos + sizeof(android_event_long_t)) > context->len) {
-        elem.type = EVENT_TYPE_UNKNOWN;
-        return elem;
-      }
-
-      auto* event_long = reinterpret_cast<android_event_long_t*>(&context->storage[pos]);
-      pos += sizeof(android_event_long_t);
-      elem.data.int64 = event_long->data;
-      /* common tangeable object suffix */
-      elem.complete = !context->list_nest_depth && !context->count[0];
-      if (!peek) {
-        if (!context->count[context->list_nest_depth] ||
-            !--(context->count[context->list_nest_depth])) {
-          context->list_stop = true;
-        }
-        context->pos = pos;
-      }
-      return elem;
-    }
-
-    case EVENT_TYPE_STRING: {
-      if ((pos + sizeof(android_event_string_t)) > context->len) {
-        elem.type = EVENT_TYPE_UNKNOWN;
-        elem.complete = true;
-        return elem;
-      }
-      auto* event_string = reinterpret_cast<android_event_string_t*>(&context->storage[pos]);
-      pos += sizeof(android_event_string_t);
-      // Wire format is int32_t, but elem.len is uint16_t...
-      if (event_string->length >= UINT16_MAX) {
-        elem.type = EVENT_TYPE_UNKNOWN;
-        return elem;
-      }
-      elem.len = event_string->length;
-      if ((pos + elem.len) > context->len) {
-        elem.len = context->len - pos; /* truncate string */
-        elem.complete = true;
-        if (!elem.len) {
-          elem.type = EVENT_TYPE_UNKNOWN;
-          return elem;
-        }
-      }
-      elem.data.string = event_string->data;
-      /* common tangeable object suffix */
-      pos += elem.len;
-      elem.complete = !context->list_nest_depth && !context->count[0];
-      if (!peek) {
-        if (!context->count[context->list_nest_depth] ||
-            !--(context->count[context->list_nest_depth])) {
-          context->list_stop = true;
-        }
-        context->pos = pos;
-      }
-      return elem;
-    }
-
-    case EVENT_TYPE_LIST: {
-      if ((pos + sizeof(android_event_list_t)) > context->len) {
-        elem.type = EVENT_TYPE_UNKNOWN;
-        elem.complete = true;
-        return elem;
-      }
-      auto* event_list = reinterpret_cast<android_event_list_t*>(&context->storage[pos]);
-      pos += sizeof(android_event_list_t);
-      elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
-      if (peek) {
-        return elem;
-      }
-      if (context->count[context->list_nest_depth]) {
-        context->count[context->list_nest_depth]--;
-      }
-      context->list_stop = event_list->element_count == 0;
-      context->list_nest_depth++;
-      if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
-        context->count[context->list_nest_depth] = event_list->element_count;
-      }
-      context->pos = pos;
-      return elem;
-    }
-
-    case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
-      pos++;
-      if (!peek) {
-        context->pos = pos;
-      }
-      elem.type = EVENT_TYPE_UNKNOWN;
-      elem.complete = !context->list_nest_depth;
-      if (context->list_nest_depth > 0) {
-        elem.type = EVENT_TYPE_LIST_STOP;
-        if (!peek) {
-          context->list_nest_depth--;
-        }
-      }
-      return elem;
-
-    default:
-      elem.type = EVENT_TYPE_UNKNOWN;
-      return elem;
-  }
-}
-
-android_log_list_element android_log_read_next(android_log_context ctx) {
-  return android_log_read_next_internal(ctx, 0);
-}
-
-android_log_list_element android_log_peek_next(android_log_context ctx) {
-  return android_log_read_next_internal(ctx, 1);
-}
diff --git a/liblog/log_event_write.cpp b/liblog/log_event_write.cpp
deleted file mode 100644
index 39afd0c..0000000
--- a/liblog/log_event_write.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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 <stdint.h>
-
-#include <log/log.h>
-#include <log/log_event_list.h>
-
-#define MAX_SUBTAG_LEN 32
-
-int __android_log_error_write(int tag, const char* subTag, int32_t uid, const char* data,
-                              uint32_t dataLen) {
-  int ret = -EINVAL;
-
-  if (subTag && (data || !dataLen)) {
-    android_log_context ctx = create_android_logger(tag);
-
-    ret = -ENOMEM;
-    if (ctx) {
-      ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN);
-      if (ret >= 0) {
-        ret = android_log_write_int32(ctx, uid);
-        if (ret >= 0) {
-          ret = android_log_write_string8_len(ctx, data, dataLen);
-          if (ret >= 0) {
-            ret = android_log_write_list(ctx, LOG_ID_EVENTS);
-          }
-        }
-      }
-      android_log_destroy(&ctx);
-    }
-  }
-  return ret;
-}
diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp
deleted file mode 100644
index 14c408c..0000000
--- a/liblog/log_time.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2014 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 <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <private/android_logger.h>
-
-// Add %#q for fractional seconds to standard strptime function
-char* log_time::strptime(const char* s, const char* format) {
-  time_t now;
-#ifdef __linux__
-  *this = log_time(CLOCK_REALTIME);
-  now = tv_sec;
-#else
-  time(&now);
-  tv_sec = now;
-  tv_nsec = 0;
-#endif
-
-  struct tm* ptm;
-#if !defined(_WIN32)
-  struct tm tmBuf;
-  ptm = localtime_r(&now, &tmBuf);
-#else
-  ptm = localtime(&now);
-#endif
-
-  char fmt[strlen(format) + 1];
-  strcpy(fmt, format);
-
-  char* ret = const_cast<char*>(s);
-  char* cp;
-  for (char* f = cp = fmt;; ++cp) {
-    if (!*cp) {
-      if (f != cp) {
-        ret = ::strptime(ret, f, ptm);
-      }
-      break;
-    }
-    if (*cp != '%') {
-      continue;
-    }
-    char* e = cp;
-    ++e;
-#if (defined(__BIONIC__))
-    if (*e == 's') {
-      *cp = '\0';
-      if (*f) {
-        ret = ::strptime(ret, f, ptm);
-        if (!ret) {
-          break;
-        }
-      }
-      tv_sec = 0;
-      while (isdigit(*ret)) {
-        tv_sec = tv_sec * 10 + *ret - '0';
-        ++ret;
-      }
-      now = tv_sec;
-#if !defined(_WIN32)
-      ptm = localtime_r(&now, &tmBuf);
-#else
-      ptm = localtime(&now);
-#endif
-    } else
-#endif
-    {
-      unsigned num = 0;
-      while (isdigit(*e)) {
-        num = num * 10 + *e - '0';
-        ++e;
-      }
-      if (*e != 'q') {
-        continue;
-      }
-      *cp = '\0';
-      if (*f) {
-        ret = ::strptime(ret, f, ptm);
-        if (!ret) {
-          break;
-        }
-      }
-      unsigned long mul = NS_PER_SEC;
-      if (num == 0) {
-        num = INT_MAX;
-      }
-      tv_nsec = 0;
-      while (isdigit(*ret) && num && (mul > 1)) {
-        --num;
-        mul /= 10;
-        tv_nsec = tv_nsec + (*ret - '0') * mul;
-        ++ret;
-      }
-    }
-    f = cp = e;
-    ++f;
-  }
-
-  if (ret) {
-    tv_sec = mktime(ptm);
-    return ret;
-  }
-
-// Upon error, place a known value into the class, the current time.
-#ifdef __linux__
-  *this = log_time(CLOCK_REALTIME);
-#else
-  time(&now);
-  tv_sec = now;
-  tv_nsec = 0;
-#endif
-  return ret;
-}
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
deleted file mode 100644
index 611caed..0000000
--- a/liblog/logd_reader.cpp
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2007-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 "logd_reader.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <stdarg.h>
-#include <stdatomic.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/parseint.h>
-#include <private/android_logger.h>
-
-#include "logger.h"
-
-// Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
-// O_CLOEXEC is always set.
-static int socket_local_client(const std::string& name, int type, bool timeout) {
-  sockaddr_un addr = {.sun_family = AF_LOCAL};
-
-  std::string path = "/dev/socket/" + name;
-  if (path.size() + 1 > sizeof(addr.sun_path)) {
-    return -1;
-  }
-  strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
-
-  int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0);
-  if (fd == -1) {
-    return -1;
-  }
-
-  if (timeout) {
-    // Sending and receiving messages should be instantaneous, but we don't want to wait forever if
-    // logd is hung, so we set a gracious 2s timeout.
-    struct timeval t = {2, 0};
-    if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) == -1) {
-      return -1;
-    }
-    if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) {
-      return -1;
-    }
-  }
-
-  if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
-    close(fd);
-    return -1;
-  }
-
-  return fd;
-}
-
-/* worker for sending the command to the logger */
-ssize_t SendLogdControlMessage(char* buf, size_t buf_size) {
-  ssize_t ret;
-  size_t len;
-  char* cp;
-  int errno_save = 0;
-  int sock = socket_local_client("logd", SOCK_STREAM, true);
-  if (sock < 0) {
-    return sock;
-  }
-
-  len = strlen(buf) + 1;
-  ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
-  if (ret <= 0) {
-    goto done;
-  }
-
-  len = buf_size;
-  cp = buf;
-  while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
-    struct pollfd p;
-
-    if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
-      break;
-    }
-
-    len -= ret;
-    cp += ret;
-
-    memset(&p, 0, sizeof(p));
-    p.fd = sock;
-    p.events = POLLIN;
-
-    /* Give other side 20ms to refill pipe */
-    ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
-
-    if (ret <= 0) {
-      break;
-    }
-
-    if (!(p.revents & POLLIN)) {
-      ret = 0;
-      break;
-    }
-  }
-
-  if (ret >= 0) {
-    ret += buf_size - len;
-  }
-
-done:
-  if ((ret == -1) && errno) {
-    errno_save = errno;
-  }
-  close(sock);
-  if (errno_save) {
-    errno = errno_save;
-  }
-  return ret;
-}
-
-static int check_log_success(char* buf, ssize_t ret) {
-  if (ret < 0) {
-    return ret;
-  }
-
-  if (strncmp(buf, "success", 7)) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  return 0;
-}
-
-int android_logger_clear(struct logger* logger) {
-  if (!android_logger_is_logd(logger)) {
-    return -EINVAL;
-  }
-  uint32_t log_id = android_logger_get_id(logger);
-  char buf[512];
-  snprintf(buf, sizeof(buf), "clear %" PRIu32, log_id);
-
-  return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
-}
-
-enum class LogSizeType : uint32_t {
-  kAllotted = 0,
-  kReadable,
-  kConsumed,
-};
-
-static long GetLogSize(struct logger* logger, LogSizeType type) {
-  if (!android_logger_is_logd(logger)) {
-    return -EINVAL;
-  }
-
-  uint32_t log_id = android_logger_get_id(logger);
-  char buf[512];
-  switch (type) {
-    case LogSizeType::kAllotted:
-      snprintf(buf, sizeof(buf), "getLogSize %" PRIu32, log_id);
-      break;
-    case LogSizeType::kReadable:
-      snprintf(buf, sizeof(buf), "getLogSizeReadable %" PRIu32, log_id);
-      break;
-    case LogSizeType::kConsumed:
-      snprintf(buf, sizeof(buf), "getLogSizeUsed %" PRIu32, log_id);
-      break;
-    default:
-      abort();
-  }
-
-  ssize_t ret = SendLogdControlMessage(buf, sizeof(buf));
-  if (ret < 0) {
-    return ret;
-  }
-
-  long size;
-  if (!android::base::ParseInt(buf, &size)) {
-    return -1;
-  }
-
-  return size;
-}
-
-long android_logger_get_log_size(struct logger* logger) {
-  return GetLogSize(logger, LogSizeType::kAllotted);
-}
-
-long android_logger_get_log_readable_size(struct logger* logger) {
-  return GetLogSize(logger, LogSizeType::kReadable);
-}
-
-long android_logger_get_log_consumed_size(struct logger* logger) {
-  return GetLogSize(logger, LogSizeType::kConsumed);
-}
-
-int android_logger_set_log_size(struct logger* logger, unsigned long size) {
-  if (!android_logger_is_logd(logger)) {
-    return -EINVAL;
-  }
-
-  uint32_t log_id = android_logger_get_id(logger);
-  char buf[512];
-  snprintf(buf, sizeof(buf), "setLogSize %" PRIu32 " %lu", log_id, size);
-
-  return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
-}
-
-int android_logger_get_log_version(struct logger*) {
-  return 4;
-}
-
-ssize_t android_logger_get_statistics(struct logger_list* logger_list, char* buf, size_t len) {
-  if (logger_list->mode & ANDROID_LOG_PSTORE) {
-    return -EINVAL;
-  }
-
-  char* cp = buf;
-  size_t remaining = len;
-  size_t n;
-
-  n = snprintf(cp, remaining, "getStatistics");
-  n = MIN(n, remaining);
-  remaining -= n;
-  cp += n;
-
-  for (size_t log_id = 0; log_id < LOG_ID_MAX; ++log_id) {
-    if ((1 << log_id) & logger_list->log_mask) {
-      n = snprintf(cp, remaining, " %zu", log_id);
-      n = MIN(n, remaining);
-      remaining -= n;
-      cp += n;
-    }
-  }
-
-  if (logger_list->pid) {
-    snprintf(cp, remaining, " pid=%u", logger_list->pid);
-  }
-
-  return SendLogdControlMessage(buf, len);
-}
-ssize_t android_logger_get_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
-  if (logger_list->mode & ANDROID_LOG_PSTORE) {
-    return -EINVAL;
-  }
-
-  snprintf(buf, len, "getPruneList");
-  return SendLogdControlMessage(buf, len);
-}
-
-int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len) {
-  if (logger_list->mode & ANDROID_LOG_PSTORE) {
-    return -EINVAL;
-  }
-
-  std::string cmd = "setPruneList " + std::string{buf, len};
-
-  return check_log_success(cmd.data(), SendLogdControlMessage(cmd.data(), cmd.size()));
-}
-
-static int logdOpen(struct logger_list* logger_list) {
-  char buffer[256], *cp, c;
-  int ret, remaining, sock;
-
-  sock = atomic_load(&logger_list->fd);
-  if (sock > 0) {
-    return sock;
-  }
-
-  sock = socket_local_client("logdr", SOCK_SEQPACKET, false);
-  if (sock <= 0) {
-    if ((sock == -1) && errno) {
-      return -errno;
-    }
-    return sock;
-  }
-
-  strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream");
-  cp = buffer + strlen(buffer);
-
-  strcpy(cp, " lids");
-  cp += 5;
-  c = '=';
-  remaining = sizeof(buffer) - (cp - buffer);
-
-  for (size_t log_id = 0; log_id < LOG_ID_MAX; ++log_id) {
-    if ((1 << log_id) & logger_list->log_mask) {
-      ret = snprintf(cp, remaining, "%c%zu", c, log_id);
-      ret = MIN(ret, remaining);
-      remaining -= ret;
-      cp += ret;
-      c = ',';
-    }
-  }
-
-  if (logger_list->tail) {
-    ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
-    ret = MIN(ret, remaining);
-    remaining -= ret;
-    cp += ret;
-  }
-
-  if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
-    if (logger_list->mode & ANDROID_LOG_WRAP) {
-      // ToDo: alternate API to allow timeout to be adjusted.
-      ret = snprintf(cp, remaining, " timeout=%u", ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
-      ret = MIN(ret, remaining);
-      remaining -= ret;
-      cp += ret;
-    }
-    ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, logger_list->start.tv_sec,
-                   logger_list->start.tv_nsec);
-    ret = MIN(ret, remaining);
-    remaining -= ret;
-    cp += ret;
-  }
-
-  if (logger_list->pid) {
-    ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
-    ret = MIN(ret, remaining);
-    cp += ret;
-  }
-
-  ret = TEMP_FAILURE_RETRY(write(sock, buffer, cp - buffer));
-  int write_errno = errno;
-
-  if (ret <= 0) {
-    close(sock);
-    if (ret == -1) {
-      return -write_errno;
-    }
-    if (ret == 0) {
-      return -EIO;
-    }
-    return ret;
-  }
-
-  ret = atomic_exchange(&logger_list->fd, sock);
-  if ((ret > 0) && (ret != sock)) {
-    close(ret);
-  }
-  return sock;
-}
-
-/* Read from the selected logs */
-int LogdRead(struct logger_list* logger_list, struct log_msg* log_msg) {
-  int ret = logdOpen(logger_list);
-  if (ret < 0) {
-    return ret;
-  }
-
-  /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
-  ret = TEMP_FAILURE_RETRY(recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0));
-  if ((logger_list->mode & ANDROID_LOG_NONBLOCK) && ret == 0) {
-    return -EAGAIN;
-  }
-
-  if (ret == -1) {
-    return -errno;
-  }
-  return ret;
-}
-
-/* Close all the logs */
-void LogdClose(struct logger_list* logger_list) {
-  int sock = atomic_exchange(&logger_list->fd, -1);
-  if (sock > 0) {
-    close(sock);
-  }
-}
diff --git a/liblog/logd_reader.h b/liblog/logd_reader.h
deleted file mode 100644
index 68eef02..0000000
--- a/liblog/logd_reader.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <sys/cdefs.h>
-#include <unistd.h>
-
-#include "log/log_read.h"
-
-__BEGIN_DECLS
-
-int LogdRead(struct logger_list* logger_list, struct log_msg* log_msg);
-void LogdClose(struct logger_list* logger_list);
-
-ssize_t SendLogdControlMessage(char* buf, size_t buf_size);
-
-__END_DECLS
diff --git a/liblog/logd_writer.cpp b/liblog/logd_writer.cpp
deleted file mode 100644
index f5d19ca..0000000
--- a/liblog/logd_writer.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2007-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 "logd_writer.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <stdarg.h>
-#include <stdatomic.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include "logger.h"
-#include "uio.h"
-
-static atomic_int logd_socket;
-
-// Note that it is safe to call connect() multiple times on DGRAM Unix domain sockets, so this
-// function is used to reconnect to logd without requiring a new socket.
-static void LogdConnect() {
-  sockaddr_un un = {};
-  un.sun_family = AF_UNIX;
-  strcpy(un.sun_path, "/dev/socket/logdw");
-  TEMP_FAILURE_RETRY(connect(logd_socket, reinterpret_cast<sockaddr*>(&un), sizeof(sockaddr_un)));
-}
-
-// logd_socket should only be opened once.  If we see that logd_socket is uninitialized, we create a
-// new socket and attempt to exchange it into the atomic logd_socket.  If the compare/exchange was
-// successful, then that will be the socket used for the duration of the program, otherwise a
-// different thread has already opened and written the socket to the atomic, so close the new socket
-// and return.
-static void GetSocket() {
-  if (logd_socket != 0) {
-    return;
-  }
-
-  int new_socket = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));
-  if (new_socket <= 0) {
-    return;
-  }
-
-  int uninitialized_value = 0;
-  if (!logd_socket.compare_exchange_strong(uninitialized_value, new_socket)) {
-    close(new_socket);
-    return;
-  }
-
-  LogdConnect();
-}
-
-// This is the one exception to the above.  Zygote uses this to clean up open FD's after fork() and
-// before specialization.  It is single threaded at this point and therefore this function is
-// explicitly not thread safe.  It sets logd_socket to 0, so future logs will be safely initialized
-// whenever they happen.
-void LogdClose() {
-  if (logd_socket > 0) {
-    close(logd_socket);
-  }
-  logd_socket = 0;
-}
-
-int LogdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr) {
-  ssize_t ret;
-  static const unsigned headerLength = 1;
-  struct iovec newVec[nr + headerLength];
-  android_log_header_t header;
-  size_t i, payloadSize;
-
-  GetSocket();
-
-  if (logd_socket <= 0) {
-    return -EBADF;
-  }
-
-  /* logd, after initialization and priv drop */
-  if (getuid() == AID_LOGD) {
-    /*
-     * ignore log messages we send to ourself (logd).
-     * Such log messages are often generated by libraries we depend on
-     * which use standard Android logging.
-     */
-    return 0;
-  }
-
-  header.id = logId;
-  header.tid = gettid();
-  header.realtime.tv_sec = ts->tv_sec;
-  header.realtime.tv_nsec = ts->tv_nsec;
-
-  newVec[0].iov_base = (unsigned char*)&header;
-  newVec[0].iov_len = sizeof(header);
-
-  for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
-    newVec[i].iov_base = vec[i - headerLength].iov_base;
-    payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
-
-    if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
-      newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
-      if (newVec[i].iov_len) {
-        ++i;
-      }
-      break;
-    }
-  }
-
-  ret = TEMP_FAILURE_RETRY(writev(logd_socket, newVec, i));
-  if (ret < 0) {
-    LogdConnect();
-
-    ret = TEMP_FAILURE_RETRY(writev(logd_socket, newVec, i));
-  }
-
-  if (ret < 0) {
-    ret = -errno;
-  }
-
-  return ret;
-}
diff --git a/liblog/logd_writer.h b/liblog/logd_writer.h
deleted file mode 100644
index 41197b5..0000000
--- a/liblog/logd_writer.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <stddef.h>
-
-#include <android/log.h>
-
-int LogdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr);
-void LogdClose();
diff --git a/liblog/logger.h b/liblog/logger.h
deleted file mode 100644
index ddff19d..0000000
--- a/liblog/logger.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <stdatomic.h>
-#include <sys/cdefs.h>
-
-#include <log/log.h>
-
-#include "uio.h"
-
-__BEGIN_DECLS
-
-struct logger_list {
-  atomic_int fd;
-  int mode;
-  unsigned int tail;
-  log_time start;
-  pid_t pid;
-  uint32_t log_mask;
-};
-
-// Format for a 'logger' entry: uintptr_t where only the bottom 32 bits are used.
-// bit 31: Set if this 'logger' is for logd.
-// bit 30: Set if this 'logger' is for pmsg
-// bits 0-2: the decimal value of the log buffer.
-// Other bits are unused.
-
-#define LOGGER_LOGD (1U << 31)
-#define LOGGER_PMSG (1U << 30)
-#define LOGGER_LOG_ID_MASK ((1U << 3) - 1)
-
-inline bool android_logger_is_logd(struct logger* logger) {
-  return reinterpret_cast<uintptr_t>(logger) & LOGGER_LOGD;
-}
-
-__END_DECLS
diff --git a/liblog/logger_name.cpp b/liblog/logger_name.cpp
deleted file mode 100644
index e72290e..0000000
--- a/liblog/logger_name.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-** Copyright 2013-2014, 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 <string.h>
-#include <type_traits>
-
-#include <log/log.h>
-
-/* In the future, we would like to make this list extensible */
-static const char* LOG_NAME[LOG_ID_MAX] = {
-    /* clang-format off */
-  [LOG_ID_MAIN] = "main",
-  [LOG_ID_RADIO] = "radio",
-  [LOG_ID_EVENTS] = "events",
-  [LOG_ID_SYSTEM] = "system",
-  [LOG_ID_CRASH] = "crash",
-  [LOG_ID_STATS] = "stats",
-  [LOG_ID_SECURITY] = "security",
-  [LOG_ID_KERNEL] = "kernel",
-    /* clang-format on */
-};
-
-const char* android_log_id_to_name(log_id_t log_id) {
-  if (log_id >= LOG_ID_MAX) {
-    log_id = LOG_ID_MAIN;
-  }
-  return LOG_NAME[log_id];
-}
-
-static_assert(std::is_same<std::underlying_type<log_id_t>::type, uint32_t>::value,
-              "log_id_t must be an uint32_t");
-
-static_assert(std::is_same<std::underlying_type<android_LogPriority>::type, uint32_t>::value,
-              "log_id_t must be an uint32_t");
-
-log_id_t android_name_to_log_id(const char* logName) {
-  const char* b;
-  unsigned int ret;
-
-  if (!logName) {
-    return static_cast<log_id_t>(LOG_ID_MAX);
-  }
-
-  b = strrchr(logName, '/');
-  if (!b) {
-    b = logName;
-  } else {
-    ++b;
-  }
-
-  for (ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {
-    const char* l = LOG_NAME[ret];
-    if (l && !strcmp(b, l)) {
-      return static_cast<log_id_t>(ret);
-    }
-  }
-
-  return static_cast<log_id_t>(LOG_ID_MAX);
-}
diff --git a/liblog/logger_read.cpp b/liblog/logger_read.cpp
deleted file mode 100644
index 4937042..0000000
--- a/liblog/logger_read.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-** Copyright 2013-2014, 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 "log/log_read.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <sched.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <android/log.h>
-
-#include "logd_reader.h"
-#include "logger.h"
-#include "pmsg_reader.h"
-
-/* method for getting the associated sublog id */
-log_id_t android_logger_get_id(struct logger* logger) {
-  return static_cast<log_id_t>(reinterpret_cast<uintptr_t>(logger) & LOGGER_LOG_ID_MASK);
-}
-
-static struct logger_list* android_logger_list_alloc_internal(int mode, unsigned int tail,
-                                                              log_time start, pid_t pid) {
-  auto* logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(struct logger_list)));
-  if (!logger_list) {
-    return nullptr;
-  }
-
-  logger_list->mode = mode;
-  logger_list->start = start;
-  logger_list->tail = tail;
-  logger_list->pid = pid;
-
-  return logger_list;
-}
-
-struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
-  return android_logger_list_alloc_internal(mode, tail, log_time(0, 0), pid);
-}
-
-struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
-  return android_logger_list_alloc_internal(mode, 0, start, pid);
-}
-
-/* Open the named log and add it to the logger list */
-struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) {
-  if (!logger_list || (logId >= LOG_ID_MAX)) {
-    return nullptr;
-  }
-
-  logger_list->log_mask |= 1 << logId;
-
-  uintptr_t logger = logId;
-  logger |= (logger_list->mode & ANDROID_LOG_PSTORE) ? LOGGER_PMSG : LOGGER_LOGD;
-  return reinterpret_cast<struct logger*>(logger);
-}
-
-/* Open the single named log and make it part of a new logger list */
-struct logger_list* android_logger_list_open(log_id_t logId, int mode, unsigned int tail,
-                                             pid_t pid) {
-  struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
-
-  if (!logger_list) {
-    return NULL;
-  }
-
-  if (!android_logger_open(logger_list, logId)) {
-    android_logger_list_free(logger_list);
-    return NULL;
-  }
-
-  return logger_list;
-}
-
-int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
-  if (logger_list == nullptr || logger_list->log_mask == 0) {
-    return -EINVAL;
-  }
-
-  int ret = 0;
-
-#ifdef __ANDROID__
-  if (logger_list->mode & ANDROID_LOG_PSTORE) {
-    ret = PmsgRead(logger_list, log_msg);
-  } else {
-    ret = LogdRead(logger_list, log_msg);
-  }
-#endif
-
-  if (ret <= 0) {
-    return ret;
-  }
-
-  if (ret > LOGGER_ENTRY_MAX_LEN) {
-    ret = LOGGER_ENTRY_MAX_LEN;
-  }
-
-  if (ret < static_cast<int>(sizeof(log_msg->entry))) {
-    return -EINVAL;
-  }
-
-  if (log_msg->entry.hdr_size < sizeof(log_msg->entry) ||
-      log_msg->entry.hdr_size >= LOGGER_ENTRY_MAX_LEN - sizeof(log_msg->entry)) {
-    return -EINVAL;
-  }
-
-  if (log_msg->entry.len > ret - log_msg->entry.hdr_size) {
-    return -EINVAL;
-  }
-
-  log_msg->buf[log_msg->entry.len + log_msg->entry.hdr_size] = '\0';
-
-  return ret;
-}
-
-/* Close all the logs */
-void android_logger_list_free(struct logger_list* logger_list) {
-  if (logger_list == NULL) {
-    return;
-  }
-
-#ifdef __ANDROID__
-  if (logger_list->mode & ANDROID_LOG_PSTORE) {
-    PmsgClose(logger_list);
-  } else {
-    LogdClose(logger_list);
-  }
-#endif
-
-  free(logger_list);
-}
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
deleted file mode 100644
index 22c7eca..0000000
--- a/liblog/logger_write.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2007-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 "logger_write.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <libgen.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-#ifdef __BIONIC__
-#include <android/set_abort_message.h>
-#endif
-
-#include <atomic>
-
-#include <android-base/errno_restorer.h>
-#include <android-base/macros.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include "android/log.h"
-#include "log/log_read.h"
-#include "logger.h"
-#include "uio.h"
-
-#ifdef __ANDROID__
-#include "logd_writer.h"
-#include "pmsg_writer.h"
-#endif
-
-#if defined(__APPLE__)
-#include <pthread.h>
-#elif defined(__linux__) && !defined(__ANDROID__)
-#include <syscall.h>
-#elif defined(_WIN32)
-#include <windows.h>
-#endif
-
-using android::base::ErrnoRestorer;
-
-#define LOG_BUF_SIZE 1024
-
-#if defined(__ANDROID__)
-static int check_log_uid_permissions() {
-  uid_t uid = getuid();
-
-  /* Matches clientHasLogCredentials() in logd */
-  if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
-    uid = geteuid();
-    if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
-      gid_t gid = getgid();
-      if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
-        gid = getegid();
-        if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
-          int num_groups;
-          gid_t* groups;
-
-          num_groups = getgroups(0, NULL);
-          if (num_groups <= 0) {
-            return -EPERM;
-          }
-          groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
-          if (!groups) {
-            return -ENOMEM;
-          }
-          num_groups = getgroups(num_groups, groups);
-          while (num_groups > 0) {
-            if (groups[num_groups - 1] == AID_LOG) {
-              break;
-            }
-            --num_groups;
-          }
-          free(groups);
-          if (num_groups <= 0) {
-            return -EPERM;
-          }
-        }
-      }
-    }
-  }
-  return 0;
-}
-#endif
-
-/*
- * Release any logger resources. A new log write will immediately re-acquire.
- */
-void __android_log_close() {
-#ifdef __ANDROID__
-  LogdClose();
-  PmsgClose();
-#endif
-}
-
-#if defined(__GLIBC__) || defined(_WIN32)
-static const char* getprogname() {
-#if defined(__GLIBC__)
-  return program_invocation_short_name;
-#elif defined(_WIN32)
-  static bool first = true;
-  static char progname[MAX_PATH] = {};
-
-  if (first) {
-    char path[PATH_MAX + 1];
-    DWORD result = GetModuleFileName(nullptr, path, sizeof(path) - 1);
-    if (result == 0 || result == sizeof(path) - 1) return "";
-    path[PATH_MAX - 1] = 0;
-
-    char* path_basename = basename(path);
-
-    snprintf(progname, sizeof(progname), "%s", path_basename);
-    first = false;
-  }
-
-  return progname;
-#endif
-}
-#endif
-
-// It's possible for logging to happen during static initialization before our globals are
-// initialized, so we place this std::string in a function such that it is initialized on the first
-// call.
-std::string& GetDefaultTag() {
-  static std::string default_tag = getprogname();
-  return default_tag;
-}
-
-void __android_log_set_default_tag(const char* tag) {
-  GetDefaultTag().assign(tag, 0, LOGGER_ENTRY_MAX_PAYLOAD);
-}
-
-static std::atomic_int32_t minimum_log_priority = ANDROID_LOG_DEFAULT;
-int32_t __android_log_set_minimum_priority(int32_t priority) {
-  return minimum_log_priority.exchange(priority, std::memory_order_relaxed);
-}
-
-int32_t __android_log_get_minimum_priority() {
-  return minimum_log_priority;
-}
-
-#ifdef __ANDROID__
-static __android_logger_function logger_function = __android_log_logd_logger;
-#else
-static __android_logger_function logger_function = __android_log_stderr_logger;
-#endif
-
-void __android_log_set_logger(__android_logger_function logger) {
-  logger_function = logger;
-}
-
-void __android_log_default_aborter(const char* abort_message) {
-#ifdef __ANDROID__
-  android_set_abort_message(abort_message);
-#else
-  UNUSED(abort_message);
-#endif
-  abort();
-}
-
-static __android_aborter_function aborter_function = __android_log_default_aborter;
-
-void __android_log_set_aborter(__android_aborter_function aborter) {
-  aborter_function = aborter;
-}
-
-void __android_log_call_aborter(const char* abort_message) {
-  aborter_function(abort_message);
-}
-
-#ifdef __ANDROID__
-static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {
-  int ret;
-  struct timespec ts;
-
-  if (log_id == LOG_ID_KERNEL) {
-    return -EINVAL;
-  }
-
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  if (log_id == LOG_ID_SECURITY) {
-    if (vec[0].iov_len < 4) {
-      return -EINVAL;
-    }
-
-    ret = check_log_uid_permissions();
-    if (ret < 0) {
-      return ret;
-    }
-    if (!__android_log_security()) {
-      /* If only we could reset downstream logd counter */
-      return -EPERM;
-    }
-  } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
-    if (vec[0].iov_len < 4) {
-      return -EINVAL;
-    }
-  }
-
-  ret = LogdWrite(log_id, &ts, vec, nr);
-  PmsgWrite(log_id, &ts, vec, nr);
-
-  return ret;
-}
-#else
-static int write_to_log(log_id_t, struct iovec*, size_t) {
-  // Non-Android text logs should go to __android_log_stderr_logger, not here.
-  // Non-Android binary logs are always dropped.
-  return 1;
-}
-#endif
-
-// Copied from base/threads.cpp
-static uint64_t GetThreadId() {
-#if defined(__BIONIC__)
-  return gettid();
-#elif defined(__APPLE__)
-  uint64_t tid;
-  pthread_threadid_np(NULL, &tid);
-  return tid;
-#elif defined(__linux__)
-  return syscall(__NR_gettid);
-#elif defined(_WIN32)
-  return GetCurrentThreadId();
-#endif
-}
-
-void __android_log_stderr_logger(const struct __android_log_message* log_message) {
-  struct tm now;
-  time_t t = time(nullptr);
-
-#if defined(_WIN32)
-  localtime_s(&now, &t);
-#else
-  localtime_r(&t, &now);
-#endif
-
-  char timestamp[32];
-  strftime(timestamp, sizeof(timestamp), "%m-%d %H:%M:%S", &now);
-
-  static const char log_characters[] = "XXVDIWEF";
-  static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT,
-                "Mismatch in size of log_characters and values in android_LogPriority");
-  int32_t priority =
-      log_message->priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : log_message->priority;
-  char priority_char = log_characters[priority];
-  uint64_t tid = GetThreadId();
-
-  if (log_message->file != nullptr) {
-    fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s:%u] %s\n",
-            log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(),
-            tid, log_message->file, log_message->line, log_message->message);
-  } else {
-    fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s\n",
-            log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(),
-            tid, log_message->message);
-  }
-}
-
-void __android_log_logd_logger(const struct __android_log_message* log_message) {
-  int buffer_id = log_message->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message->buffer_id;
-
-  struct iovec vec[3];
-  vec[0].iov_base =
-      const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(&log_message->priority));
-  vec[0].iov_len = 1;
-  vec[1].iov_base = const_cast<void*>(static_cast<const void*>(log_message->tag));
-  vec[1].iov_len = strlen(log_message->tag) + 1;
-  vec[2].iov_base = const_cast<void*>(static_cast<const void*>(log_message->message));
-  vec[2].iov_len = strlen(log_message->message) + 1;
-
-  write_to_log(static_cast<log_id_t>(buffer_id), vec, 3);
-}
-
-int __android_log_write(int prio, const char* tag, const char* msg) {
-  return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
-}
-
-void __android_log_write_log_message(__android_log_message* log_message) {
-  ErrnoRestorer errno_restorer;
-
-  if (log_message->buffer_id != LOG_ID_DEFAULT && log_message->buffer_id != LOG_ID_MAIN &&
-      log_message->buffer_id != LOG_ID_SYSTEM && log_message->buffer_id != LOG_ID_RADIO &&
-      log_message->buffer_id != LOG_ID_CRASH) {
-    return;
-  }
-
-  if (log_message->tag == nullptr) {
-    log_message->tag = GetDefaultTag().c_str();
-  }
-
-#if __BIONIC__
-  if (log_message->priority == ANDROID_LOG_FATAL) {
-    android_set_abort_message(log_message->message);
-  }
-#endif
-
-  logger_function(log_message);
-}
-
-int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
-  ErrnoRestorer errno_restorer;
-
-  if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
-    return -EPERM;
-  }
-
-  __android_log_message log_message = {
-      sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, msg};
-  __android_log_write_log_message(&log_message);
-  return 1;
-}
-
-int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
-  ErrnoRestorer errno_restorer;
-
-  if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
-    return -EPERM;
-  }
-
-  __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
-
-  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
-
-  __android_log_message log_message = {
-      sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
-  __android_log_write_log_message(&log_message);
-  return 1;
-}
-
-int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
-  ErrnoRestorer errno_restorer;
-
-  if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
-    return -EPERM;
-  }
-
-  va_list ap;
-  __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
-
-  va_start(ap, fmt);
-  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
-  va_end(ap);
-
-  __android_log_message log_message = {
-      sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
-  __android_log_write_log_message(&log_message);
-  return 1;
-}
-
-int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
-  ErrnoRestorer errno_restorer;
-
-  if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
-    return -EPERM;
-  }
-
-  va_list ap;
-  __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
-
-  va_start(ap, fmt);
-  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
-  va_end(ap);
-
-  __android_log_message log_message = {
-      sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, buf};
-  __android_log_write_log_message(&log_message);
-  return 1;
-}
-
-void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
-  __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
-
-  if (fmt) {
-    va_list ap;
-    va_start(ap, fmt);
-    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
-    va_end(ap);
-  } else {
-    /* Msg not provided, log condition.  N.B. Do not use cond directly as
-     * format string as it could contain spurious '%' syntax (e.g.
-     * "%d" in "blocks%devs == 0").
-     */
-    if (cond)
-      snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
-    else
-      strcpy(buf, "Unspecified assertion failed");
-  }
-
-  // Log assertion failures to stderr for the benefit of "adb shell" users
-  // and gtests (http://b/23675822).
-  TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
-  TEMP_FAILURE_RETRY(write(2, "\n", 1));
-
-  __android_log_write(ANDROID_LOG_FATAL, tag, buf);
-  __android_log_call_aborter(buf);
-  abort();
-}
-
-int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
-  ErrnoRestorer errno_restorer;
-
-  struct iovec vec[2];
-
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = (void*)payload;
-  vec[1].iov_len = len;
-
-  return write_to_log(LOG_ID_EVENTS, vec, 2);
-}
-
-int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
-  ErrnoRestorer errno_restorer;
-
-  struct iovec vec[2];
-
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = (void*)payload;
-  vec[1].iov_len = len;
-
-  return write_to_log(LOG_ID_STATS, vec, 2);
-}
-
-int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
-  ErrnoRestorer errno_restorer;
-
-  struct iovec vec[2];
-
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = (void*)payload;
-  vec[1].iov_len = len;
-
-  return write_to_log(LOG_ID_SECURITY, vec, 2);
-}
-
-/*
- * Like __android_log_bwrite, but takes the type as well.  Doesn't work
- * for the general case where we're generating lists of stuff, but very
- * handy if we just want to dump an integer into the log.
- */
-int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
-  ErrnoRestorer errno_restorer;
-
-  struct iovec vec[3];
-
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = &type;
-  vec[1].iov_len = sizeof(type);
-  vec[2].iov_base = (void*)payload;
-  vec[2].iov_len = len;
-
-  return write_to_log(LOG_ID_EVENTS, vec, 3);
-}
-
-/*
- * Like __android_log_bwrite, but used for writing strings to the
- * event log.
- */
-int __android_log_bswrite(int32_t tag, const char* payload) {
-  ErrnoRestorer errno_restorer;
-
-  struct iovec vec[4];
-  char type = EVENT_TYPE_STRING;
-  uint32_t len = strlen(payload);
-
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = &type;
-  vec[1].iov_len = sizeof(type);
-  vec[2].iov_base = &len;
-  vec[2].iov_len = sizeof(len);
-  vec[3].iov_base = (void*)payload;
-  vec[3].iov_len = len;
-
-  return write_to_log(LOG_ID_EVENTS, vec, 4);
-}
-
-/*
- * Like __android_log_security_bwrite, but used for writing strings to the
- * security log.
- */
-int __android_log_security_bswrite(int32_t tag, const char* payload) {
-  ErrnoRestorer errno_restorer;
-
-  struct iovec vec[4];
-  char type = EVENT_TYPE_STRING;
-  uint32_t len = strlen(payload);
-
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = &type;
-  vec[1].iov_len = sizeof(type);
-  vec[2].iov_base = &len;
-  vec[2].iov_len = sizeof(len);
-  vec[3].iov_base = (void*)payload;
-  vec[3].iov_len = len;
-
-  return write_to_log(LOG_ID_SECURITY, vec, 4);
-}
diff --git a/liblog/logger_write.h b/liblog/logger_write.h
deleted file mode 100644
index eee2778..0000000
--- a/liblog/logger_write.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <string>
-
-std::string& GetDefaultTag();
diff --git a/liblog/logprint.cpp b/liblog/logprint.cpp
deleted file mode 100644
index a5c5edd..0000000
--- a/liblog/logprint.cpp
+++ /dev/null
@@ -1,1748 +0,0 @@
-/*
-**
-** Copyright 2006-2014, 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.
-*/
-
-#ifndef __MINGW32__
-#define HAVE_STRSEP
-#endif
-
-#include <log/logprint.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#ifndef __MINGW32__
-#include <pwd.h>
-#endif
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <wchar.h>
-
-#include <cutils/list.h>
-
-#include <log/log.h>
-#include <log/log_read.h>
-#include <private/android_logger.h>
-
-#define MS_PER_NSEC 1000000
-#define US_PER_NSEC 1000
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-typedef struct FilterInfo_t {
-  char* mTag;
-  android_LogPriority mPri;
-  struct FilterInfo_t* p_next;
-} FilterInfo;
-
-struct AndroidLogFormat_t {
-  android_LogPriority global_pri;
-  FilterInfo* filters;
-  AndroidLogPrintFormat format;
-  bool colored_output;
-  bool usec_time_output;
-  bool nsec_time_output;
-  bool printable_output;
-  bool year_output;
-  bool zone_output;
-  bool epoch_output;
-  bool monotonic_output;
-  bool uid_output;
-  bool descriptive_output;
-};
-
-/*
- * API issues prevent us from exposing "descriptive" in AndroidLogFormat_t
- * during android_log_processBinaryLogBuffer(), so we break layering.
- */
-static bool descriptive_output = false;
-
-/*
- * 8-bit color tags. See ECMA-48 Set Graphics Rendition in
- * [console_codes(4)](https://man7.org/linux/man-pages/man4/console_codes.4.html).
- *
- * The text manipulation character stream is defined as:
- *   ESC [ <parameter #> m
- *
- * We use "set <color> foreground" escape sequences instead of
- * "256/24-bit foreground color". This allows colors to render
- * according to user preferences in terminal emulator settings
- */
-#define ANDROID_COLOR_BLUE 34
-#define ANDROID_COLOR_DEFAULT 39
-#define ANDROID_COLOR_GREEN 32
-#define ANDROID_COLOR_RED 31
-#define ANDROID_COLOR_YELLOW 33
-
-static FilterInfo* filterinfo_new(const char* tag, android_LogPriority pri) {
-  FilterInfo* p_ret;
-
-  p_ret = (FilterInfo*)calloc(1, sizeof(FilterInfo));
-  p_ret->mTag = strdup(tag);
-  p_ret->mPri = pri;
-
-  return p_ret;
-}
-
-/* balance to above, filterinfo_free left unimplemented */
-
-/*
- * Note: also accepts 0-9 priorities
- * returns ANDROID_LOG_UNKNOWN if the character is unrecognized
- */
-static android_LogPriority filterCharToPri(char c) {
-  android_LogPriority pri;
-
-  c = tolower(c);
-
-  if (c >= '0' && c <= '9') {
-    if (c >= ('0' + ANDROID_LOG_SILENT)) {
-      pri = ANDROID_LOG_VERBOSE;
-    } else {
-      pri = (android_LogPriority)(c - '0');
-    }
-  } else if (c == 'v') {
-    pri = ANDROID_LOG_VERBOSE;
-  } else if (c == 'd') {
-    pri = ANDROID_LOG_DEBUG;
-  } else if (c == 'i') {
-    pri = ANDROID_LOG_INFO;
-  } else if (c == 'w') {
-    pri = ANDROID_LOG_WARN;
-  } else if (c == 'e') {
-    pri = ANDROID_LOG_ERROR;
-  } else if (c == 'f') {
-    pri = ANDROID_LOG_FATAL;
-  } else if (c == 's') {
-    pri = ANDROID_LOG_SILENT;
-  } else if (c == '*') {
-    pri = ANDROID_LOG_DEFAULT;
-  } else {
-    pri = ANDROID_LOG_UNKNOWN;
-  }
-
-  return pri;
-}
-
-static char filterPriToChar(android_LogPriority pri) {
-  switch (pri) {
-    /* clang-format off */
-    case ANDROID_LOG_VERBOSE: return 'V';
-    case ANDROID_LOG_DEBUG:   return 'D';
-    case ANDROID_LOG_INFO:    return 'I';
-    case ANDROID_LOG_WARN:    return 'W';
-    case ANDROID_LOG_ERROR:   return 'E';
-    case ANDROID_LOG_FATAL:   return 'F';
-    case ANDROID_LOG_SILENT:  return 'S';
-
-    case ANDROID_LOG_DEFAULT:
-    case ANDROID_LOG_UNKNOWN:
-    default:                  return '?';
-      /* clang-format on */
-  }
-}
-
-static int colorFromPri(android_LogPriority pri) {
-  switch (pri) {
-    /* clang-format off */
-    case ANDROID_LOG_VERBOSE: return ANDROID_COLOR_DEFAULT;
-    case ANDROID_LOG_DEBUG:   return ANDROID_COLOR_BLUE;
-    case ANDROID_LOG_INFO:    return ANDROID_COLOR_GREEN;
-    case ANDROID_LOG_WARN:    return ANDROID_COLOR_YELLOW;
-    case ANDROID_LOG_ERROR:   return ANDROID_COLOR_RED;
-    case ANDROID_LOG_FATAL:   return ANDROID_COLOR_RED;
-    case ANDROID_LOG_SILENT:  return ANDROID_COLOR_DEFAULT;
-
-    case ANDROID_LOG_DEFAULT:
-    case ANDROID_LOG_UNKNOWN:
-    default:                  return ANDROID_COLOR_DEFAULT;
-      /* clang-format on */
-  }
-}
-
-static android_LogPriority filterPriForTag(AndroidLogFormat* p_format, const char* tag) {
-  FilterInfo* p_curFilter;
-
-  for (p_curFilter = p_format->filters; p_curFilter != NULL; p_curFilter = p_curFilter->p_next) {
-    if (0 == strcmp(tag, p_curFilter->mTag)) {
-      if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) {
-        return p_format->global_pri;
-      } else {
-        return p_curFilter->mPri;
-      }
-    }
-  }
-
-  return p_format->global_pri;
-}
-
-/**
- * returns 1 if this log line should be printed based on its priority
- * and tag, and 0 if it should not
- */
-int android_log_shouldPrintLine(AndroidLogFormat* p_format, const char* tag,
-                                android_LogPriority pri) {
-  return pri >= filterPriForTag(p_format, tag);
-}
-
-AndroidLogFormat* android_log_format_new() {
-  AndroidLogFormat* p_ret;
-
-  p_ret = static_cast<AndroidLogFormat*>(calloc(1, sizeof(AndroidLogFormat)));
-
-  p_ret->global_pri = ANDROID_LOG_VERBOSE;
-  p_ret->format = FORMAT_BRIEF;
-  p_ret->colored_output = false;
-  p_ret->usec_time_output = false;
-  p_ret->nsec_time_output = false;
-  p_ret->printable_output = false;
-  p_ret->year_output = false;
-  p_ret->zone_output = false;
-  p_ret->epoch_output = false;
-  p_ret->monotonic_output = false;
-  p_ret->uid_output = false;
-  p_ret->descriptive_output = false;
-  descriptive_output = false;
-
-  return p_ret;
-}
-
-static list_declare(convertHead);
-
-void android_log_format_free(AndroidLogFormat* p_format) {
-  FilterInfo *p_info, *p_info_old;
-
-  p_info = p_format->filters;
-
-  while (p_info != NULL) {
-    p_info_old = p_info;
-    p_info = p_info->p_next;
-
-    free(p_info_old);
-  }
-
-  free(p_format);
-
-  /* Free conversion resource, can always be reconstructed */
-  while (!list_empty(&convertHead)) {
-    struct listnode* node = list_head(&convertHead);
-    list_remove(node);
-    LOG_ALWAYS_FATAL_IF(node == list_head(&convertHead), "corrupted list");
-    free(node);
-  }
-}
-
-int android_log_setPrintFormat(AndroidLogFormat* p_format, AndroidLogPrintFormat format) {
-  switch (format) {
-    case FORMAT_MODIFIER_COLOR:
-      p_format->colored_output = true;
-      return 0;
-    case FORMAT_MODIFIER_TIME_USEC:
-      p_format->usec_time_output = true;
-      return 0;
-    case FORMAT_MODIFIER_TIME_NSEC:
-      p_format->nsec_time_output = true;
-      return 0;
-    case FORMAT_MODIFIER_PRINTABLE:
-      p_format->printable_output = true;
-      return 0;
-    case FORMAT_MODIFIER_YEAR:
-      p_format->year_output = true;
-      return 0;
-    case FORMAT_MODIFIER_ZONE:
-      p_format->zone_output = !p_format->zone_output;
-      return 0;
-    case FORMAT_MODIFIER_EPOCH:
-      p_format->epoch_output = true;
-      return 0;
-    case FORMAT_MODIFIER_MONOTONIC:
-      p_format->monotonic_output = true;
-      return 0;
-    case FORMAT_MODIFIER_UID:
-      p_format->uid_output = true;
-      return 0;
-    case FORMAT_MODIFIER_DESCRIPT:
-      p_format->descriptive_output = true;
-      descriptive_output = true;
-      return 0;
-    default:
-      break;
-  }
-  p_format->format = format;
-  return 1;
-}
-
-#ifndef __MINGW32__
-static const char tz[] = "TZ";
-static const char utc[] = "UTC";
-#endif
-
-/**
- * Returns FORMAT_OFF on invalid string
- */
-AndroidLogPrintFormat android_log_formatFromString(const char* formatString) {
-  static AndroidLogPrintFormat format;
-
-  /* clang-format off */
-  if (!strcmp(formatString, "brief")) format = FORMAT_BRIEF;
-  else if (!strcmp(formatString, "process")) format = FORMAT_PROCESS;
-  else if (!strcmp(formatString, "tag")) format = FORMAT_TAG;
-  else if (!strcmp(formatString, "thread")) format = FORMAT_THREAD;
-  else if (!strcmp(formatString, "raw")) format = FORMAT_RAW;
-  else if (!strcmp(formatString, "time")) format = FORMAT_TIME;
-  else if (!strcmp(formatString, "threadtime")) format = FORMAT_THREADTIME;
-  else if (!strcmp(formatString, "long")) format = FORMAT_LONG;
-  else if (!strcmp(formatString, "color")) format = FORMAT_MODIFIER_COLOR;
-  else if (!strcmp(formatString, "colour")) format = FORMAT_MODIFIER_COLOR;
-  else if (!strcmp(formatString, "usec")) format = FORMAT_MODIFIER_TIME_USEC;
-  else if (!strcmp(formatString, "nsec")) format = FORMAT_MODIFIER_TIME_NSEC;
-  else if (!strcmp(formatString, "printable")) format = FORMAT_MODIFIER_PRINTABLE;
-  else if (!strcmp(formatString, "year")) format = FORMAT_MODIFIER_YEAR;
-  else if (!strcmp(formatString, "zone")) format = FORMAT_MODIFIER_ZONE;
-  else if (!strcmp(formatString, "epoch")) format = FORMAT_MODIFIER_EPOCH;
-  else if (!strcmp(formatString, "monotonic")) format = FORMAT_MODIFIER_MONOTONIC;
-  else if (!strcmp(formatString, "uid")) format = FORMAT_MODIFIER_UID;
-  else if (!strcmp(formatString, "descriptive")) format = FORMAT_MODIFIER_DESCRIPT;
-    /* clang-format on */
-
-#ifndef __MINGW32__
-  else {
-    extern char* tzname[2];
-    static const char gmt[] = "GMT";
-    char* cp = getenv(tz);
-    if (cp) {
-      cp = strdup(cp);
-    }
-    setenv(tz, formatString, 1);
-    /*
-     * Run tzset here to determine if the timezone is legitimate. If the
-     * zone is GMT, check if that is what was asked for, if not then
-     * did not match any on the system; report an error to caller.
-     */
-    tzset();
-    if (!tzname[0] ||
-        ((!strcmp(tzname[0], utc) || !strcmp(tzname[0], gmt))                  /* error? */
-         && strcasecmp(formatString, utc) && strcasecmp(formatString, gmt))) { /* ok */
-      if (cp) {
-        setenv(tz, cp, 1);
-      } else {
-        unsetenv(tz);
-      }
-      tzset();
-      format = FORMAT_OFF;
-    } else {
-      format = FORMAT_MODIFIER_ZONE;
-    }
-    free(cp);
-  }
-#endif
-
-  return format;
-}
-
-/**
- * filterExpression: a single filter expression
- * eg "AT:d"
- *
- * returns 0 on success and -1 on invalid expression
- *
- * Assumes single threaded execution
- */
-
-int android_log_addFilterRule(AndroidLogFormat* p_format, const char* filterExpression) {
-  size_t tagNameLength;
-  android_LogPriority pri = ANDROID_LOG_DEFAULT;
-
-  tagNameLength = strcspn(filterExpression, ":");
-
-  if (tagNameLength == 0) {
-    goto error;
-  }
-
-  if (filterExpression[tagNameLength] == ':') {
-    pri = filterCharToPri(filterExpression[tagNameLength + 1]);
-
-    if (pri == ANDROID_LOG_UNKNOWN) {
-      goto error;
-    }
-  }
-
-  if (0 == strncmp("*", filterExpression, tagNameLength)) {
-    /*
-     * This filter expression refers to the global filter
-     * The default level for this is DEBUG if the priority
-     * is unspecified
-     */
-    if (pri == ANDROID_LOG_DEFAULT) {
-      pri = ANDROID_LOG_DEBUG;
-    }
-
-    p_format->global_pri = pri;
-  } else {
-    /*
-     * for filter expressions that don't refer to the global
-     * filter, the default is verbose if the priority is unspecified
-     */
-    if (pri == ANDROID_LOG_DEFAULT) {
-      pri = ANDROID_LOG_VERBOSE;
-    }
-
-    char* tagName;
-
-/*
- * Presently HAVE_STRNDUP is never defined, so the second case is always taken
- * Darwin doesn't have strndup, everything else does
- */
-#ifdef HAVE_STRNDUP
-    tagName = strndup(filterExpression, tagNameLength);
-#else
-    /* a few extra bytes copied... */
-    tagName = strdup(filterExpression);
-    tagName[tagNameLength] = '\0';
-#endif /*HAVE_STRNDUP*/
-
-    FilterInfo* p_fi = filterinfo_new(tagName, pri);
-    free(tagName);
-
-    p_fi->p_next = p_format->filters;
-    p_format->filters = p_fi;
-  }
-
-  return 0;
-error:
-  return -1;
-}
-
-#ifndef HAVE_STRSEP
-/* KISS replacement helper for below */
-static char* strsep(char** stringp, const char* delim) {
-  char* token;
-  char* ret = *stringp;
-
-  if (!ret || !*ret) {
-    return NULL;
-  }
-  token = strpbrk(ret, delim);
-  if (token) {
-    *token = '\0';
-    ++token;
-  } else {
-    token = ret + strlen(ret);
-  }
-  *stringp = token;
-  return ret;
-}
-#endif
-
-/**
- * filterString: a comma/whitespace-separated set of filter expressions
- *
- * eg "AT:d *:i"
- *
- * returns 0 on success and -1 on invalid expression
- *
- * Assumes single threaded execution
- *
- */
-int android_log_addFilterString(AndroidLogFormat* p_format, const char* filterString) {
-  char* filterStringCopy = strdup(filterString);
-  char* p_cur = filterStringCopy;
-  char* p_ret;
-  int err;
-
-  /* Yes, I'm using strsep */
-  while (NULL != (p_ret = strsep(&p_cur, " \t,"))) {
-    /* ignore whitespace-only entries */
-    if (p_ret[0] != '\0') {
-      err = android_log_addFilterRule(p_format, p_ret);
-
-      if (err < 0) {
-        goto error;
-      }
-    }
-  }
-
-  free(filterStringCopy);
-  return 0;
-error:
-  free(filterStringCopy);
-  return -1;
-}
-
-/**
- * Splits a wire-format buffer into an AndroidLogEntry
- * entry allocated by caller. Pointers will point directly into buf
- *
- * Returns 0 on success and -1 on invalid wire format (entry will be
- * in unspecified state)
- */
-int android_log_processLogBuffer(struct logger_entry* buf, AndroidLogEntry* entry) {
-  entry->message = NULL;
-  entry->messageLen = 0;
-
-  entry->tv_sec = buf->sec;
-  entry->tv_nsec = buf->nsec;
-  entry->uid = -1;
-  entry->pid = buf->pid;
-  entry->tid = buf->tid;
-
-  /*
-   * format: <priority:1><tag:N>\0<message:N>\0
-   *
-   * tag str
-   *   starts at buf + buf->hdr_size + 1
-   * msg
-   *   starts at buf + buf->hdr_size + 1 + len(tag) + 1
-   *
-   * The message may have been truncated.  When that happens, we must null-terminate the message
-   * ourselves.
-   */
-  if (buf->len < 3) {
-    /*
-     * An well-formed entry must consist of at least a priority
-     * and two null characters
-     */
-    fprintf(stderr, "+++ LOG: entry too small\n");
-    return -1;
-  }
-
-  int msgStart = -1;
-  int msgEnd = -1;
-
-  int i;
-  if (buf->hdr_size < sizeof(logger_entry)) {
-    fprintf(stderr, "+++ LOG: hdr_size must be at least as big as struct logger_entry\n");
-    return -1;
-  }
-  char* msg = reinterpret_cast<char*>(buf) + buf->hdr_size;
-  entry->uid = buf->uid;
-
-  for (i = 1; i < buf->len; i++) {
-    if (msg[i] == '\0') {
-      if (msgStart == -1) {
-        msgStart = i + 1;
-      } else {
-        msgEnd = i;
-        break;
-      }
-    }
-  }
-
-  if (msgStart == -1) {
-    /* +++ LOG: malformed log message, DYB */
-    for (i = 1; i < buf->len; i++) {
-      /* odd characters in tag? */
-      if ((msg[i] <= ' ') || (msg[i] == ':') || (msg[i] >= 0x7f)) {
-        msg[i] = '\0';
-        msgStart = i + 1;
-        break;
-      }
-    }
-    if (msgStart == -1) {
-      msgStart = buf->len - 1; /* All tag, no message, print truncates */
-    }
-  }
-  if (msgEnd == -1) {
-    /* incoming message not null-terminated; force it */
-    msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */
-    msg[msgEnd] = '\0';
-  }
-
-  entry->priority = static_cast<android_LogPriority>(msg[0]);
-  entry->tag = msg + 1;
-  entry->tagLen = msgStart - 1;
-  entry->message = msg + msgStart;
-  entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart);
-
-  return 0;
-}
-
-static bool findChar(const char** cp, size_t* len, int c) {
-  while ((*len) && isspace(*(*cp))) {
-    ++(*cp);
-    --(*len);
-  }
-  if (c == INT_MAX) return *len;
-  if ((*len) && (*(*cp) == c)) {
-    ++(*cp);
-    --(*len);
-    return true;
-  }
-  return false;
-}
-
-/*
- * Recursively convert binary log data to printable form.
- *
- * This needs to be recursive because you can have lists of lists.
- *
- * If we run out of room, we stop processing immediately.  It's important
- * for us to check for space on every output element to avoid producing
- * garbled output.
- *
- * Returns 0 on success, 1 on buffer full, -1 on failure.
- */
-enum objectType {
-  TYPE_OBJECTS = '1',
-  TYPE_BYTES = '2',
-  TYPE_MILLISECONDS = '3',
-  TYPE_ALLOCATIONS = '4',
-  TYPE_ID = '5',
-  TYPE_PERCENT = '6',
-  TYPE_MONOTONIC = 's'
-};
-
-static int android_log_printBinaryEvent(const unsigned char** pEventData, size_t* pEventDataLen,
-                                        char** pOutBuf, size_t* pOutBufLen, const char** fmtStr,
-                                        size_t* fmtLen) {
-  const unsigned char* eventData = *pEventData;
-  size_t eventDataLen = *pEventDataLen;
-  char* outBuf = *pOutBuf;
-  char* outBufSave = outBuf;
-  size_t outBufLen = *pOutBufLen;
-  size_t outBufLenSave = outBufLen;
-  unsigned char type;
-  size_t outCount = 0;
-  int result = 0;
-  const char* cp;
-  size_t len;
-  int64_t lval;
-
-  if (eventDataLen < 1) return -1;
-
-  type = *eventData;
-
-  cp = NULL;
-  len = 0;
-  if (fmtStr && *fmtStr && fmtLen && *fmtLen && **fmtStr) {
-    cp = *fmtStr;
-    len = *fmtLen;
-  }
-  /*
-   * event.logtag format specification:
-   *
-   * Optionally, after the tag names can be put a description for the value(s)
-   * of the tag. Description are in the format
-   *    (<name>|data type[|data unit])
-   * Multiple values are separated by commas.
-   *
-   * The data type is a number from the following values:
-   * 1: int
-   * 2: long
-   * 3: string
-   * 4: list
-   * 5: float
-   *
-   * The data unit is a number taken from the following list:
-   * 1: Number of objects
-   * 2: Number of bytes
-   * 3: Number of milliseconds
-   * 4: Number of allocations
-   * 5: Id
-   * 6: Percent
-   * s: Number of seconds (monotonic time)
-   * Default value for data of type int/long is 2 (bytes).
-   */
-  if (!cp || !findChar(&cp, &len, '(')) {
-    len = 0;
-  } else {
-    char* outBufLastSpace = NULL;
-
-    findChar(&cp, &len, INT_MAX);
-    while (len && *cp && (*cp != '|') && (*cp != ')')) {
-      if (outBufLen <= 0) {
-        /* halt output */
-        goto no_room;
-      }
-      outBufLastSpace = isspace(*cp) ? outBuf : NULL;
-      *outBuf = *cp;
-      ++outBuf;
-      ++cp;
-      --outBufLen;
-      --len;
-    }
-    if (outBufLastSpace) {
-      outBufLen += outBuf - outBufLastSpace;
-      outBuf = outBufLastSpace;
-    }
-    if (outBufLen <= 0) {
-      /* halt output */
-      goto no_room;
-    }
-    if (outBufSave != outBuf) {
-      *outBuf = '=';
-      ++outBuf;
-      --outBufLen;
-    }
-
-    if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) {
-      static const unsigned char typeTable[] = {EVENT_TYPE_INT, EVENT_TYPE_LONG, EVENT_TYPE_STRING,
-                                                EVENT_TYPE_LIST, EVENT_TYPE_FLOAT};
-
-      if ((*cp >= '1') && (*cp < (char)('1' + (sizeof(typeTable) / sizeof(typeTable[0])))) &&
-          (type != typeTable[(size_t)(*cp - '1')]))
-        len = 0;
-
-      if (len) {
-        ++cp;
-        --len;
-      } else {
-        /* reset the format */
-        outBuf = outBufSave;
-        outBufLen = outBufLenSave;
-      }
-    }
-  }
-  outCount = 0;
-  lval = 0;
-  switch (type) {
-    case EVENT_TYPE_INT:
-      /* 32-bit signed int */
-      {
-        if (eventDataLen < sizeof(android_event_int_t)) return -1;
-        auto* event_int = reinterpret_cast<const android_event_int_t*>(eventData);
-        lval = event_int->data;
-        eventData += sizeof(android_event_int_t);
-        eventDataLen -= sizeof(android_event_int_t);
-      }
-      goto pr_lval;
-    case EVENT_TYPE_LONG:
-      /* 64-bit signed long */
-      if (eventDataLen < sizeof(android_event_long_t)) {
-        return -1;
-      }
-      {
-        auto* event_long = reinterpret_cast<const android_event_long_t*>(eventData);
-        lval = event_long->data;
-      }
-      eventData += sizeof(android_event_long_t);
-      eventDataLen -= sizeof(android_event_long_t);
-    pr_lval:
-      outCount = snprintf(outBuf, outBufLen, "%" PRId64, lval);
-      if (outCount < outBufLen) {
-        outBuf += outCount;
-        outBufLen -= outCount;
-      } else {
-        /* halt output */
-        goto no_room;
-      }
-      break;
-    case EVENT_TYPE_FLOAT:
-      /* float */
-      {
-        if (eventDataLen < sizeof(android_event_float_t)) return -1;
-        auto* event_float = reinterpret_cast<const android_event_float_t*>(eventData);
-        float fval = event_float->data;
-        eventData += sizeof(android_event_int_t);
-        eventDataLen -= sizeof(android_event_int_t);
-
-        outCount = snprintf(outBuf, outBufLen, "%f", fval);
-        if (outCount < outBufLen) {
-          outBuf += outCount;
-          outBufLen -= outCount;
-        } else {
-          /* halt output */
-          goto no_room;
-        }
-      }
-      break;
-    case EVENT_TYPE_STRING:
-      /* UTF-8 chars, not NULL-terminated */
-      {
-        if (eventDataLen < sizeof(android_event_string_t)) return -1;
-        auto* event_string = reinterpret_cast<const android_event_string_t*>(eventData);
-        unsigned int strLen = event_string->length;
-        eventData += sizeof(android_event_string_t);
-        eventDataLen -= sizeof(android_event_string_t);
-
-        if (eventDataLen < strLen) {
-          result = -1; /* mark truncated */
-          strLen = eventDataLen;
-        }
-
-        if (cp && (strLen == 0)) {
-          /* reset the format if no content */
-          outBuf = outBufSave;
-          outBufLen = outBufLenSave;
-        }
-        if (strLen < outBufLen) {
-          memcpy(outBuf, eventData, strLen);
-          outBuf += strLen;
-          outBufLen -= strLen;
-        } else {
-          if (outBufLen > 0) {
-            /* copy what we can */
-            memcpy(outBuf, eventData, outBufLen);
-            outBuf += outBufLen;
-            outBufLen -= outBufLen;
-          }
-          if (!result) result = 1; /* if not truncated, return no room */
-        }
-        eventData += strLen;
-        eventDataLen -= strLen;
-        if (result != 0) goto bail;
-        break;
-      }
-    case EVENT_TYPE_LIST:
-      /* N items, all different types */
-      {
-        if (eventDataLen < sizeof(android_event_list_t)) return -1;
-        auto* event_list = reinterpret_cast<const android_event_list_t*>(eventData);
-
-        int8_t count = event_list->element_count;
-        eventData += sizeof(android_event_list_t);
-        eventDataLen -= sizeof(android_event_list_t);
-
-        if (outBufLen <= 0) goto no_room;
-
-        *outBuf++ = '[';
-        outBufLen--;
-
-        for (int i = 0; i < count; i++) {
-          result = android_log_printBinaryEvent(&eventData, &eventDataLen, &outBuf, &outBufLen,
-                                                fmtStr, fmtLen);
-          if (result != 0) goto bail;
-
-          if (i < (count - 1)) {
-            if (outBufLen <= 0) goto no_room;
-            *outBuf++ = ',';
-            outBufLen--;
-          }
-        }
-
-        if (outBufLen <= 0) goto no_room;
-
-        *outBuf++ = ']';
-        outBufLen--;
-      }
-      break;
-    default:
-      fprintf(stderr, "Unknown binary event type %d\n", type);
-      return -1;
-  }
-  if (cp && len) {
-    if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) {
-      switch (*cp) {
-        case TYPE_OBJECTS:
-          outCount = 0;
-          /* outCount = snprintf(outBuf, outBufLen, " objects"); */
-          break;
-        case TYPE_BYTES:
-          if ((lval != 0) && ((lval % 1024) == 0)) {
-            /* repaint with multiplier */
-            static const char suffixTable[] = {'K', 'M', 'G', 'T'};
-            size_t idx = 0;
-            outBuf -= outCount;
-            outBufLen += outCount;
-            do {
-              lval /= 1024;
-              if ((lval % 1024) != 0) break;
-            } while (++idx < ((sizeof(suffixTable) / sizeof(suffixTable[0])) - 1));
-            outCount = snprintf(outBuf, outBufLen, "%" PRId64 "%cB", lval, suffixTable[idx]);
-          } else {
-            outCount = snprintf(outBuf, outBufLen, "B");
-          }
-          break;
-        case TYPE_MILLISECONDS:
-          if (((lval <= -1000) || (1000 <= lval)) && (outBufLen || (outBuf[-1] == '0'))) {
-            /* repaint as (fractional) seconds, possibly saving space */
-            if (outBufLen) outBuf[0] = outBuf[-1];
-            outBuf[-1] = outBuf[-2];
-            outBuf[-2] = outBuf[-3];
-            outBuf[-3] = '.';
-            while ((outBufLen == 0) || (*outBuf == '0')) {
-              --outBuf;
-              ++outBufLen;
-            }
-            if (*outBuf != '.') {
-              ++outBuf;
-              --outBufLen;
-            }
-            outCount = snprintf(outBuf, outBufLen, "s");
-          } else {
-            outCount = snprintf(outBuf, outBufLen, "ms");
-          }
-          break;
-        case TYPE_MONOTONIC: {
-          static const uint64_t minute = 60;
-          static const uint64_t hour = 60 * minute;
-          static const uint64_t day = 24 * hour;
-
-          /* Repaint as unsigned seconds, minutes, hours ... */
-          outBuf -= outCount;
-          outBufLen += outCount;
-          uint64_t val = lval;
-          if (val >= day) {
-            outCount = snprintf(outBuf, outBufLen, "%" PRIu64 "d ", val / day);
-            if (outCount >= outBufLen) break;
-            outBuf += outCount;
-            outBufLen -= outCount;
-            val = (val % day) + day;
-          }
-          if (val >= minute) {
-            if (val >= hour) {
-              outCount = snprintf(outBuf, outBufLen, "%" PRIu64 ":", (val / hour) % (day / hour));
-              if (outCount >= outBufLen) break;
-              outBuf += outCount;
-              outBufLen -= outCount;
-            }
-            outCount =
-                snprintf(outBuf, outBufLen, (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
-                         (val / minute) % (hour / minute));
-            if (outCount >= outBufLen) break;
-            outBuf += outCount;
-            outBufLen -= outCount;
-          }
-          outCount = snprintf(outBuf, outBufLen, (val >= minute) ? "%02" PRIu64 : "%" PRIu64 "s",
-                              val % minute);
-        } break;
-        case TYPE_ALLOCATIONS:
-          outCount = 0;
-          /* outCount = snprintf(outBuf, outBufLen, " allocations"); */
-          break;
-        case TYPE_ID:
-          outCount = 0;
-          break;
-        case TYPE_PERCENT:
-          outCount = snprintf(outBuf, outBufLen, "%%");
-          break;
-        default: /* ? */
-          outCount = 0;
-          break;
-      }
-      ++cp;
-      --len;
-      if (outCount < outBufLen) {
-        outBuf += outCount;
-        outBufLen -= outCount;
-      } else if (outCount) {
-        /* halt output */
-        goto no_room;
-      }
-    }
-    if (!findChar(&cp, &len, ')')) len = 0;
-    if (!findChar(&cp, &len, ',')) len = 0;
-  }
-
-bail:
-  *pEventData = eventData;
-  *pEventDataLen = eventDataLen;
-  *pOutBuf = outBuf;
-  *pOutBufLen = outBufLen;
-  if (cp) {
-    *fmtStr = cp;
-    *fmtLen = len;
-  }
-  return result;
-
-no_room:
-  result = 1;
-  goto bail;
-}
-
-/**
- * Convert a binary log entry to ASCII form.
- *
- * For convenience we mimic the processLogBuffer API.  There is no
- * pre-defined output length for the binary data, since we're free to format
- * it however we choose, which means we can't really use a fixed-size buffer
- * here.
- */
-int android_log_processBinaryLogBuffer(
-    struct logger_entry* buf, AndroidLogEntry* entry,
-    [[maybe_unused]] const EventTagMap* map, /* only on !__ANDROID__ */
-    char* messageBuf, int messageBufLen) {
-  size_t inCount;
-  uint32_t tagIndex;
-  const unsigned char* eventData;
-
-  entry->message = NULL;
-  entry->messageLen = 0;
-
-  entry->tv_sec = buf->sec;
-  entry->tv_nsec = buf->nsec;
-  entry->priority = ANDROID_LOG_INFO;
-  entry->uid = -1;
-  entry->pid = buf->pid;
-  entry->tid = buf->tid;
-
-  if (buf->hdr_size < sizeof(logger_entry)) {
-    fprintf(stderr, "+++ LOG: hdr_size must be at least as big as struct logger_entry\n");
-    return -1;
-  }
-  eventData = reinterpret_cast<unsigned char*>(buf) + buf->hdr_size;
-  if (buf->lid == LOG_ID_SECURITY) {
-    entry->priority = ANDROID_LOG_WARN;
-  }
-  entry->uid = buf->uid;
-  inCount = buf->len;
-  if (inCount < sizeof(android_event_header_t)) return -1;
-  auto* event_header = reinterpret_cast<const android_event_header_t*>(eventData);
-  tagIndex = event_header->tag;
-  eventData += sizeof(android_event_header_t);
-  inCount -= sizeof(android_event_header_t);
-
-  entry->tagLen = 0;
-  entry->tag = NULL;
-#ifdef __ANDROID__
-  if (map != NULL) {
-    entry->tag = android_lookupEventTag_len(map, &entry->tagLen, tagIndex);
-  }
-#endif
-
-  /*
-   * If we don't have a map, or didn't find the tag number in the map,
-   * stuff a generated tag value into the start of the output buffer and
-   * shift the buffer pointers down.
-   */
-  if (entry->tag == NULL) {
-    size_t tagLen;
-
-    tagLen = snprintf(messageBuf, messageBufLen, "[%" PRIu32 "]", tagIndex);
-    if (tagLen >= (size_t)messageBufLen) {
-      tagLen = messageBufLen - 1;
-    }
-    entry->tag = messageBuf;
-    entry->tagLen = tagLen;
-    messageBuf += tagLen + 1;
-    messageBufLen -= tagLen + 1;
-  }
-
-  /*
-   * Format the event log data into the buffer.
-   */
-  const char* fmtStr = NULL;
-  size_t fmtLen = 0;
-#ifdef __ANDROID__
-  if (descriptive_output && map) {
-    fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex);
-  }
-#endif
-
-  char* outBuf = messageBuf;
-  size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
-  int result = 0;
-
-  if ((inCount > 0) || fmtLen) {
-    result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, &outRemaining, &fmtStr,
-                                          &fmtLen);
-  }
-  if ((result == 1) && fmtStr) {
-    /* We overflowed :-(, let's repaint the line w/o format dressings */
-    eventData = reinterpret_cast<unsigned char*>(buf) + buf->hdr_size;
-    eventData += 4;
-    outBuf = messageBuf;
-    outRemaining = messageBufLen - 1;
-    result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, &outRemaining, NULL, NULL);
-  }
-  if (result < 0) {
-    fprintf(stderr, "Binary log entry conversion failed\n");
-  }
-  if (result) {
-    if (!outRemaining) {
-      /* make space to leave an indicator */
-      --outBuf;
-      ++outRemaining;
-    }
-    *outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */
-    outRemaining--;
-    /* pretend we ate all the data to prevent log stutter */
-    inCount = 0;
-    if (result > 0) result = 0;
-  }
-
-  /* eat the silly terminating '\n' */
-  if (inCount == 1 && *eventData == '\n') {
-    eventData++;
-    inCount--;
-  }
-
-  if (inCount != 0) {
-    fprintf(stderr, "Warning: leftover binary log data (%zu bytes)\n", inCount);
-  }
-
-  /*
-   * Terminate the buffer.  The NUL byte does not count as part of
-   * entry->messageLen.
-   */
-  *outBuf = '\0';
-  entry->messageLen = outBuf - messageBuf;
-  assert(entry->messageLen == (messageBufLen - 1) - outRemaining);
-
-  entry->message = messageBuf;
-
-  return result;
-}
-
-/*
- * Convert to printable from message to p buffer, return string length. If p is
- * NULL, do not copy, but still return the expected string length.
- */
-size_t convertPrintable(char* p, const char* message, size_t messageLen) {
-  char* begin = p;
-  bool print = p != NULL;
-  mbstate_t mb_state = {};
-
-  while (messageLen) {
-    char buf[6];
-    ssize_t len = sizeof(buf) - 1;
-    if ((size_t)len > messageLen) {
-      len = messageLen;
-    }
-    len = mbrtowc(nullptr, message, len, &mb_state);
-
-    if (len < 0) {
-      snprintf(buf, sizeof(buf), "\\x%02X", static_cast<unsigned char>(*message));
-      len = 1;
-    } else {
-      buf[0] = '\0';
-      if (len == 1) {
-        if (*message == '\a') {
-          strcpy(buf, "\\a");
-        } else if (*message == '\b') {
-          strcpy(buf, "\\b");
-        } else if (*message == '\t') {
-          strcpy(buf, "\t"); /* Do not escape tabs */
-        } else if (*message == '\v') {
-          strcpy(buf, "\\v");
-        } else if (*message == '\f') {
-          strcpy(buf, "\\f");
-        } else if (*message == '\r') {
-          strcpy(buf, "\\r");
-        } else if (*message == '\\') {
-          strcpy(buf, "\\\\");
-        } else if ((*message < ' ') || (*message & 0x80)) {
-          snprintf(buf, sizeof(buf), "\\x%02X", static_cast<unsigned char>(*message));
-        }
-      }
-      if (!buf[0]) {
-        strncpy(buf, message, len);
-        buf[len] = '\0';
-      }
-    }
-    if (print) {
-      strcpy(p, buf);
-    }
-    p += strlen(buf);
-    message += len;
-    messageLen -= len;
-  }
-  return p - begin;
-}
-
-#ifdef __ANDROID__
-static char* readSeconds(char* e, struct timespec* t) {
-  unsigned long multiplier;
-  char* p;
-  t->tv_sec = strtoul(e, &p, 10);
-  if (*p != '.') {
-    return NULL;
-  }
-  t->tv_nsec = 0;
-  multiplier = NS_PER_SEC;
-  while (isdigit(*++p) && (multiplier /= 10)) {
-    t->tv_nsec += (*p - '0') * multiplier;
-  }
-  return p;
-}
-
-static struct timespec* sumTimespec(struct timespec* left, struct timespec* right) {
-  left->tv_nsec += right->tv_nsec;
-  left->tv_sec += right->tv_sec;
-  if (left->tv_nsec >= (long)NS_PER_SEC) {
-    left->tv_nsec -= NS_PER_SEC;
-    left->tv_sec += 1;
-  }
-  return left;
-}
-
-static struct timespec* subTimespec(struct timespec* result, struct timespec* left,
-                                    struct timespec* right) {
-  result->tv_nsec = left->tv_nsec - right->tv_nsec;
-  result->tv_sec = left->tv_sec - right->tv_sec;
-  if (result->tv_nsec < 0) {
-    result->tv_nsec += NS_PER_SEC;
-    result->tv_sec -= 1;
-  }
-  return result;
-}
-
-static long long nsecTimespec(struct timespec* now) {
-  return (long long)now->tv_sec * NS_PER_SEC + now->tv_nsec;
-}
-
-static void convertMonotonic(struct timespec* result, const AndroidLogEntry* entry) {
-  struct listnode* node;
-  struct conversionList {
-    struct listnode node; /* first */
-    struct timespec time;
-    struct timespec convert;
-  } * list, *next;
-  struct timespec time, convert;
-
-  /* If we do not have a conversion list, build one up */
-  if (list_empty(&convertHead)) {
-    bool suspended_pending = false;
-    struct timespec suspended_monotonic = {0, 0};
-    struct timespec suspended_diff = {0, 0};
-
-    /*
-     * Read dmesg for _some_ synchronization markers and insert
-     * Anything in the Android Logger before the dmesg logging span will
-     * be highly suspect regarding the monotonic time calculations.
-     */
-    FILE* p = popen("/system/bin/dmesg", "re");
-    if (p) {
-      char* line = NULL;
-      size_t len = 0;
-      while (getline(&line, &len, p) > 0) {
-        static const char suspend[] = "PM: suspend entry ";
-        static const char resume[] = "PM: suspend exit ";
-        static const char healthd[] = "healthd";
-        static const char battery[] = ": battery ";
-        static const char suspended[] = "Suspended for ";
-        struct timespec monotonic;
-        struct tm tm;
-        char *cp, *e = line;
-        bool add_entry = true;
-
-        if (*e == '<') {
-          while (*e && (*e != '>')) {
-            ++e;
-          }
-          if (*e != '>') {
-            continue;
-          }
-        }
-        if (*e != '[') {
-          continue;
-        }
-        while (*++e == ' ') {
-          ;
-        }
-        e = readSeconds(e, &monotonic);
-        if (!e || (*e != ']')) {
-          continue;
-        }
-
-        if ((e = strstr(e, suspend))) {
-          e += sizeof(suspend) - 1;
-        } else if ((e = strstr(line, resume))) {
-          e += sizeof(resume) - 1;
-        } else if (((e = strstr(line, healthd))) &&
-                   ((e = strstr(e + sizeof(healthd) - 1, battery)))) {
-          /* NB: healthd is roughly 150us late, worth the price to
-           * deal with ntp-induced or hardware clock drift. */
-          e += sizeof(battery) - 1;
-        } else if ((e = strstr(line, suspended))) {
-          e += sizeof(suspended) - 1;
-          e = readSeconds(e, &time);
-          if (!e) {
-            continue;
-          }
-          add_entry = false;
-          suspended_pending = true;
-          suspended_monotonic = monotonic;
-          suspended_diff = time;
-        } else {
-          continue;
-        }
-        if (add_entry) {
-          /* look for "????-??-?? ??:??:??.????????? UTC" */
-          cp = strstr(e, " UTC");
-          if (!cp || ((cp - e) < 29) || (cp[-10] != '.')) {
-            continue;
-          }
-          e = cp - 29;
-          cp = readSeconds(cp - 10, &time);
-          if (!cp) {
-            continue;
-          }
-          cp = strptime(e, "%Y-%m-%d %H:%M:%S.", &tm);
-          if (!cp) {
-            continue;
-          }
-          cp = getenv(tz);
-          if (cp) {
-            cp = strdup(cp);
-          }
-          setenv(tz, utc, 1);
-          time.tv_sec = mktime(&tm);
-          if (cp) {
-            setenv(tz, cp, 1);
-            free(cp);
-          } else {
-            unsetenv(tz);
-          }
-          list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
-          list_init(&list->node);
-          list->time = time;
-          subTimespec(&list->convert, &time, &monotonic);
-          list_add_tail(&convertHead, &list->node);
-        }
-        if (suspended_pending && !list_empty(&convertHead)) {
-          list = node_to_item(list_tail(&convertHead), struct conversionList, node);
-          if (subTimespec(&time, subTimespec(&time, &list->time, &list->convert),
-                          &suspended_monotonic)
-                  ->tv_sec > 0) {
-            /* resume, what is convert factor before? */
-            subTimespec(&convert, &list->convert, &suspended_diff);
-          } else {
-            /* suspend */
-            convert = list->convert;
-          }
-          time = suspended_monotonic;
-          sumTimespec(&time, &convert);
-          /* breakpoint just before sleep */
-          list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
-          list_init(&list->node);
-          list->time = time;
-          list->convert = convert;
-          list_add_tail(&convertHead, &list->node);
-          /* breakpoint just after sleep */
-          list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
-          list_init(&list->node);
-          list->time = time;
-          sumTimespec(&list->time, &suspended_diff);
-          list->convert = convert;
-          sumTimespec(&list->convert, &suspended_diff);
-          list_add_tail(&convertHead, &list->node);
-          suspended_pending = false;
-        }
-      }
-      pclose(p);
-    }
-    /* last entry is our current time conversion */
-    list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
-    list_init(&list->node);
-    clock_gettime(CLOCK_REALTIME, &list->time);
-    clock_gettime(CLOCK_MONOTONIC, &convert);
-    clock_gettime(CLOCK_MONOTONIC, &time);
-    /* Correct for instant clock_gettime latency (syscall or ~30ns) */
-    subTimespec(&time, &convert, subTimespec(&time, &time, &convert));
-    /* Calculate conversion factor */
-    subTimespec(&list->convert, &list->time, &time);
-    list_add_tail(&convertHead, &list->node);
-    if (suspended_pending) {
-      /* manufacture a suspend @ point before */
-      subTimespec(&convert, &list->convert, &suspended_diff);
-      time = suspended_monotonic;
-      sumTimespec(&time, &convert);
-      /* breakpoint just after sleep */
-      list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
-      list_init(&list->node);
-      list->time = time;
-      sumTimespec(&list->time, &suspended_diff);
-      list->convert = convert;
-      sumTimespec(&list->convert, &suspended_diff);
-      list_add_head(&convertHead, &list->node);
-      /* breakpoint just before sleep */
-      list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
-      list_init(&list->node);
-      list->time = time;
-      list->convert = convert;
-      list_add_head(&convertHead, &list->node);
-    }
-  }
-
-  /* Find the breakpoint in the conversion list */
-  list = node_to_item(list_head(&convertHead), struct conversionList, node);
-  next = NULL;
-  list_for_each(node, &convertHead) {
-    next = node_to_item(node, struct conversionList, node);
-    if (entry->tv_sec < next->time.tv_sec) {
-      break;
-    } else if (entry->tv_sec == next->time.tv_sec) {
-      if (entry->tv_nsec < next->time.tv_nsec) {
-        break;
-      }
-    }
-    list = next;
-  }
-
-  /* blend time from one breakpoint to the next */
-  convert = list->convert;
-  if (next) {
-    unsigned long long total, run;
-
-    total = nsecTimespec(subTimespec(&time, &next->time, &list->time));
-    time.tv_sec = entry->tv_sec;
-    time.tv_nsec = entry->tv_nsec;
-    run = nsecTimespec(subTimespec(&time, &time, &list->time));
-    if (run < total) {
-      long long crun;
-
-      float f = nsecTimespec(subTimespec(&time, &next->convert, &convert));
-      f *= run;
-      f /= total;
-      crun = f;
-      convert.tv_sec += crun / (long long)NS_PER_SEC;
-      if (crun < 0) {
-        convert.tv_nsec -= (-crun) % NS_PER_SEC;
-        if (convert.tv_nsec < 0) {
-          convert.tv_nsec += NS_PER_SEC;
-          convert.tv_sec -= 1;
-        }
-      } else {
-        convert.tv_nsec += crun % NS_PER_SEC;
-        if (convert.tv_nsec >= (long)NS_PER_SEC) {
-          convert.tv_nsec -= NS_PER_SEC;
-          convert.tv_sec += 1;
-        }
-      }
-    }
-  }
-
-  /* Apply the correction factor */
-  result->tv_sec = entry->tv_sec;
-  result->tv_nsec = entry->tv_nsec;
-  subTimespec(result, result, &convert);
-}
-#endif
-
-/**
- * Formats a log message into a buffer
- *
- * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer
- * If return value != defaultBuffer, caller must call free()
- * Returns NULL on malloc error
- */
-
-char* android_log_formatLogLine(AndroidLogFormat* p_format, char* defaultBuffer,
-                                size_t defaultBufferSize, const AndroidLogEntry* entry,
-                                size_t* p_outLength) {
-#if !defined(_WIN32)
-  struct tm tmBuf;
-#endif
-  struct tm* ptm;
-  /* good margin, 23+nul for msec, 26+nul for usec, 29+nul to nsec */
-  char timeBuf[64];
-  char prefixBuf[128], suffixBuf[128];
-  char priChar;
-  int prefixSuffixIsHeaderFooter = 0;
-  char* ret;
-  time_t now;
-  unsigned long nsec;
-
-  priChar = filterPriToChar(entry->priority);
-  size_t prefixLen = 0, suffixLen = 0;
-  size_t len;
-
-  /*
-   * Get the current date/time in pretty form
-   *
-   * It's often useful when examining a log with "less" to jump to
-   * a specific point in the file by searching for the date/time stamp.
-   * For this reason it's very annoying to have regexp meta characters
-   * in the time stamp.  Don't use forward slashes, parenthesis,
-   * brackets, asterisks, or other special chars here.
-   *
-   * The caller may have affected the timezone environment, this is
-   * expected to be sensitive to that.
-   */
-  now = entry->tv_sec;
-  nsec = entry->tv_nsec;
-#if __ANDROID__
-  if (p_format->monotonic_output) {
-    struct timespec time;
-    convertMonotonic(&time, entry);
-    now = time.tv_sec;
-    nsec = time.tv_nsec;
-  }
-#endif
-  if (now < 0) {
-    nsec = NS_PER_SEC - nsec;
-  }
-  if (p_format->epoch_output || p_format->monotonic_output) {
-    ptm = NULL;
-    snprintf(timeBuf, sizeof(timeBuf), p_format->monotonic_output ? "%6lld" : "%19lld",
-             (long long)now);
-  } else {
-#if !defined(_WIN32)
-    ptm = localtime_r(&now, &tmBuf);
-#else
-    ptm = localtime(&now);
-#endif
-    strftime(timeBuf, sizeof(timeBuf), &"%Y-%m-%d %H:%M:%S"[p_format->year_output ? 0 : 3], ptm);
-  }
-  len = strlen(timeBuf);
-  if (p_format->nsec_time_output) {
-    len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%09ld", nsec);
-  } else if (p_format->usec_time_output) {
-    len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%06ld", nsec / US_PER_NSEC);
-  } else {
-    len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%03ld", nsec / MS_PER_NSEC);
-  }
-  if (p_format->zone_output && ptm) {
-    strftime(timeBuf + len, sizeof(timeBuf) - len, " %z", ptm);
-  }
-
-  /*
-   * Construct a buffer containing the log header and log message.
-   */
-  if (p_format->colored_output) {
-    prefixLen =
-        snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[%dm", colorFromPri(entry->priority));
-    prefixLen = MIN(prefixLen, sizeof(prefixBuf));
-
-    const char suffixContents[] = "\x1B[0m";
-    strcpy(suffixBuf, suffixContents);
-    suffixLen = strlen(suffixContents);
-  }
-
-  char uid[16];
-  uid[0] = '\0';
-  if (p_format->uid_output) {
-    if (entry->uid >= 0) {
-/*
- * This code is Android specific, bionic guarantees that
- * calls to non-reentrant getpwuid() are thread safe.
- */
-#ifdef __ANDROID__
-      struct passwd* pwd = getpwuid(entry->uid);
-      if (pwd && (strlen(pwd->pw_name) <= 5)) {
-        snprintf(uid, sizeof(uid), "%5s:", pwd->pw_name);
-      } else
-#endif
-      {
-        /* Not worth parsing package list, names all longer than 5 */
-        snprintf(uid, sizeof(uid), "%5d:", entry->uid);
-      }
-    } else {
-      snprintf(uid, sizeof(uid), "      ");
-    }
-  }
-
-  switch (p_format->format) {
-    case FORMAT_TAG:
-      len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c/%-8.*s: ", priChar,
-                     (int)entry->tagLen, entry->tag);
-      strcpy(suffixBuf + suffixLen, "\n");
-      ++suffixLen;
-      break;
-    case FORMAT_PROCESS:
-      len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen, "  (%.*s)\n",
-                     (int)entry->tagLen, entry->tag);
-      suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen);
-      len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c(%s%5d) ", priChar,
-                     uid, entry->pid);
-      break;
-    case FORMAT_THREAD:
-      len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c(%s%5d:%5d) ",
-                     priChar, uid, entry->pid, entry->tid);
-      strcpy(suffixBuf + suffixLen, "\n");
-      ++suffixLen;
-      break;
-    case FORMAT_RAW:
-      prefixBuf[prefixLen] = 0;
-      len = 0;
-      strcpy(suffixBuf + suffixLen, "\n");
-      ++suffixLen;
-      break;
-    case FORMAT_TIME:
-      len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,
-                     "%s %c/%-8.*s(%s%5d): ", timeBuf, priChar, (int)entry->tagLen, entry->tag, uid,
-                     entry->pid);
-      strcpy(suffixBuf + suffixLen, "\n");
-      ++suffixLen;
-      break;
-    case FORMAT_THREADTIME:
-      ret = strchr(uid, ':');
-      if (ret) {
-        *ret = ' ';
-      }
-      len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,
-                     "%s %s%5d %5d %c %-8.*s: ", timeBuf, uid, entry->pid, entry->tid, priChar,
-                     (int)entry->tagLen, entry->tag);
-      strcpy(suffixBuf + suffixLen, "\n");
-      ++suffixLen;
-      break;
-    case FORMAT_LONG:
-      len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,
-                     "[ %s %s%5d:%5d %c/%-8.*s ]\n", timeBuf, uid, entry->pid, entry->tid, priChar,
-                     (int)entry->tagLen, entry->tag);
-      strcpy(suffixBuf + suffixLen, "\n\n");
-      suffixLen += 2;
-      prefixSuffixIsHeaderFooter = 1;
-      break;
-    case FORMAT_BRIEF:
-    default:
-      len =
-          snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,
-                   "%c/%-8.*s(%s%5d): ", priChar, (int)entry->tagLen, entry->tag, uid, entry->pid);
-      strcpy(suffixBuf + suffixLen, "\n");
-      ++suffixLen;
-      break;
-  }
-
-  /* snprintf has a weird return value.   It returns what would have been
-   * written given a large enough buffer.  In the case that the prefix is
-   * longer then our buffer(128), it messes up the calculations below
-   * possibly causing heap corruption.  To avoid this we double check and
-   * set the length at the maximum (size minus null byte)
-   */
-  prefixLen += len;
-  if (prefixLen >= sizeof(prefixBuf)) {
-    prefixLen = sizeof(prefixBuf) - 1;
-    prefixBuf[sizeof(prefixBuf) - 1] = '\0';
-  }
-  if (suffixLen >= sizeof(suffixBuf)) {
-    suffixLen = sizeof(suffixBuf) - 1;
-    suffixBuf[sizeof(suffixBuf) - 2] = '\n';
-    suffixBuf[sizeof(suffixBuf) - 1] = '\0';
-  }
-
-  /* the following code is tragically unreadable */
-
-  size_t numLines;
-  char* p;
-  size_t bufferSize;
-  const char* pm;
-
-  if (prefixSuffixIsHeaderFooter) {
-    /* we're just wrapping message with a header/footer */
-    numLines = 1;
-  } else {
-    pm = entry->message;
-    numLines = 0;
-
-    /*
-     * The line-end finding here must match the line-end finding
-     * in for ( ... numLines...) loop below
-     */
-    while (pm < (entry->message + entry->messageLen)) {
-      if (*pm++ == '\n') numLines++;
-    }
-    /* plus one line for anything not newline-terminated at the end */
-    if (pm > entry->message && *(pm - 1) != '\n') numLines++;
-  }
-
-  /*
-   * this is an upper bound--newlines in message may be counted
-   * extraneously
-   */
-  bufferSize = (numLines * (prefixLen + suffixLen)) + 1;
-  if (p_format->printable_output) {
-    /* Calculate extra length to convert non-printable to printable */
-    bufferSize += convertPrintable(NULL, entry->message, entry->messageLen);
-  } else {
-    bufferSize += entry->messageLen;
-  }
-
-  if (defaultBufferSize >= bufferSize) {
-    ret = defaultBuffer;
-  } else {
-    ret = (char*)malloc(bufferSize);
-
-    if (ret == NULL) {
-      return ret;
-    }
-  }
-
-  ret[0] = '\0'; /* to start strcat off */
-
-  p = ret;
-  pm = entry->message;
-
-  if (prefixSuffixIsHeaderFooter) {
-    strcat(p, prefixBuf);
-    p += prefixLen;
-    if (p_format->printable_output) {
-      p += convertPrintable(p, entry->message, entry->messageLen);
-    } else {
-      strncat(p, entry->message, entry->messageLen);
-      p += entry->messageLen;
-    }
-    strcat(p, suffixBuf);
-    p += suffixLen;
-  } else {
-    do {
-      const char* lineStart;
-      size_t lineLen;
-      lineStart = pm;
-
-      /* Find the next end-of-line in message */
-      while (pm < (entry->message + entry->messageLen) && *pm != '\n') pm++;
-      lineLen = pm - lineStart;
-
-      strcat(p, prefixBuf);
-      p += prefixLen;
-      if (p_format->printable_output) {
-        p += convertPrintable(p, lineStart, lineLen);
-      } else {
-        strncat(p, lineStart, lineLen);
-        p += lineLen;
-      }
-      strcat(p, suffixBuf);
-      p += suffixLen;
-
-      if (*pm == '\n') pm++;
-    } while (pm < (entry->message + entry->messageLen));
-  }
-
-  if (p_outLength != NULL) {
-    *p_outLength = p - ret;
-  }
-
-  return ret;
-}
-
-/**
- * Either print or do not print log line, based on filter
- *
- * Returns count bytes written
- */
-
-int android_log_printLogLine(AndroidLogFormat* p_format, int fd, const AndroidLogEntry* entry) {
-  int ret;
-  char defaultBuffer[512];
-  char* outBuffer = NULL;
-  size_t totalLen;
-
-  outBuffer =
-      android_log_formatLogLine(p_format, defaultBuffer, sizeof(defaultBuffer), entry, &totalLen);
-
-  if (!outBuffer) return -1;
-
-  do {
-    ret = write(fd, outBuffer, totalLen);
-  } while (ret < 0 && errno == EINTR);
-
-  if (ret < 0) {
-    fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno);
-    ret = 0;
-    goto done;
-  }
-
-  if (((size_t)ret) < totalLen) {
-    fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret, (int)totalLen);
-    goto done;
-  }
-
-done:
-  if (outBuffer != defaultBuffer) {
-    free(outBuffer);
-  }
-
-  return ret;
-}
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
deleted file mode 100644
index 5640900..0000000
--- a/liblog/pmsg_reader.cpp
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Copyright (C) 2007-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 "pmsg_reader.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <cutils/list.h>
-#include <private/android_logger.h>
-
-#include "logger.h"
-
-int PmsgRead(struct logger_list* logger_list, struct log_msg* log_msg) {
-  ssize_t ret;
-  off_t current, next;
-  struct __attribute__((__packed__)) {
-    android_pmsg_log_header_t p;
-    android_log_header_t l;
-    uint8_t prio;
-  } buf;
-  static uint8_t preread_count;
-
-  memset(log_msg, 0, sizeof(*log_msg));
-
-  if (atomic_load(&logger_list->fd) <= 0) {
-    int i, fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC);
-
-    if (fd < 0) {
-      return -errno;
-    }
-    if (fd == 0) { /* Argggg */
-      fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC);
-      close(0);
-      if (fd < 0) {
-        return -errno;
-      }
-    }
-    i = atomic_exchange(&logger_list->fd, fd);
-    if ((i > 0) && (i != fd)) {
-      close(i);
-    }
-    preread_count = 0;
-  }
-
-  while (1) {
-    int fd;
-
-    if (preread_count < sizeof(buf)) {
-      fd = atomic_load(&logger_list->fd);
-      if (fd <= 0) {
-        return -EBADF;
-      }
-      ret = TEMP_FAILURE_RETRY(read(fd, &buf.p.magic + preread_count, sizeof(buf) - preread_count));
-      if (ret < 0) {
-        return -errno;
-      }
-      preread_count += ret;
-    }
-    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) ||
-        ((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));
-      continue;
-    }
-    preread_count = 0;
-
-    if ((logger_list->log_mask & (1 << buf.l.id)) &&
-        ((!logger_list->start.tv_sec && !logger_list->start.tv_nsec) ||
-         ((logger_list->start.tv_sec <= buf.l.realtime.tv_sec) &&
-          ((logger_list->start.tv_sec != buf.l.realtime.tv_sec) ||
-           (logger_list->start.tv_nsec <= buf.l.realtime.tv_nsec)))) &&
-        (!logger_list->pid || (logger_list->pid == buf.p.pid))) {
-      char* msg = reinterpret_cast<char*>(&log_msg->entry) + sizeof(log_msg->entry);
-      *msg = buf.prio;
-      fd = atomic_load(&logger_list->fd);
-      if (fd <= 0) {
-        return -EBADF;
-      }
-      ret = TEMP_FAILURE_RETRY(read(fd, msg + sizeof(buf.prio), buf.p.len - sizeof(buf)));
-      if (ret < 0) {
-        return -errno;
-      }
-      if (ret != (ssize_t)(buf.p.len - sizeof(buf))) {
-        return -EIO;
-      }
-
-      log_msg->entry.len = buf.p.len - sizeof(buf) + sizeof(buf.prio);
-      log_msg->entry.hdr_size = sizeof(log_msg->entry);
-      log_msg->entry.pid = buf.p.pid;
-      log_msg->entry.tid = buf.l.tid;
-      log_msg->entry.sec = buf.l.realtime.tv_sec;
-      log_msg->entry.nsec = buf.l.realtime.tv_nsec;
-      log_msg->entry.lid = buf.l.id;
-      log_msg->entry.uid = buf.p.uid;
-
-      return ret + sizeof(buf.prio) + log_msg->entry.hdr_size;
-    }
-
-    fd = atomic_load(&logger_list->fd);
-    if (fd <= 0) {
-      return -EBADF;
-    }
-    current = TEMP_FAILURE_RETRY(lseek(fd, (off_t)0, SEEK_CUR));
-    if (current < 0) {
-      return -errno;
-    }
-    fd = atomic_load(&logger_list->fd);
-    if (fd <= 0) {
-      return -EBADF;
-    }
-    next = TEMP_FAILURE_RETRY(lseek(fd, (off_t)(buf.p.len - sizeof(buf)), SEEK_CUR));
-    if (next < 0) {
-      return -errno;
-    }
-    if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) {
-      return -EIO;
-    }
-  }
-}
-
-void PmsgClose(struct logger_list* logger_list) {
-  int fd = atomic_exchange(&logger_list->fd, 0);
-  if (fd > 0) {
-    close(fd);
-  }
-}
-
-static void* realloc_or_free(void* ptr, size_t new_size) {
-  void* result = realloc(ptr, new_size);
-  if (!result) {
-    free(ptr);
-  }
-  return result;
-}
-
-ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio, const char* prefix,
-                                     __android_log_pmsg_file_read_fn fn, void* arg) {
-  ssize_t ret;
-  struct logger_list logger_list;
-  struct content {
-    struct listnode node;
-    struct logger_entry entry;
-  } * content;
-  struct names {
-    struct listnode node;
-    struct listnode content;
-    log_id_t id;
-    char prio;
-    char name[];
-  } * names;
-  struct listnode name_list;
-  struct listnode *node, *n;
-  size_t len, prefix_len;
-
-  if (!fn) {
-    return -EINVAL;
-  }
-
-  /* Add just enough clues in logger_list and transp to make API function */
-  memset(&logger_list, 0, sizeof(logger_list));
-
-  logger_list.mode = ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK;
-  logger_list.log_mask = (unsigned)-1;
-  if (logId != LOG_ID_ANY) {
-    logger_list.log_mask = (1 << logId);
-  }
-  logger_list.log_mask &= ~((1 << LOG_ID_KERNEL) | (1 << LOG_ID_EVENTS) | (1 << LOG_ID_SECURITY));
-  if (!logger_list.log_mask) {
-    return -EINVAL;
-  }
-
-  /* Initialize name list */
-  list_init(&name_list);
-
-  ret = SSIZE_MAX;
-
-  /* Validate incoming prefix, shift until it contains only 0 or 1 : or / */
-  prefix_len = 0;
-  if (prefix) {
-    const char *prev = NULL, *last = NULL, *cp = prefix;
-    while ((cp = strpbrk(cp, "/:"))) {
-      prev = last;
-      last = cp;
-      cp = cp + 1;
-    }
-    if (prev) {
-      prefix = prev + 1;
-    }
-    prefix_len = strlen(prefix);
-  }
-
-  /* Read the file content */
-  log_msg log_msg;
-  while (PmsgRead(&logger_list, &log_msg) > 0) {
-    const char* cp;
-    size_t hdr_size = log_msg.entry.hdr_size;
-
-    char* msg = (char*)&log_msg + hdr_size;
-    const char* split = NULL;
-
-    if (hdr_size != sizeof(log_msg.entry)) {
-      continue;
-    }
-    /* Check for invalid sequence number */
-    if (log_msg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE ||
-        (log_msg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=
-            ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {
-      continue;
-    }
-
-    /* Determine if it has <dirbase>:<filebase> format for tag */
-    len = log_msg.entry.len - sizeof(prio);
-    for (cp = msg + sizeof(prio); *cp && isprint(*cp) && !isspace(*cp) && --len; ++cp) {
-      if (*cp == ':') {
-        if (split) {
-          break;
-        }
-        split = cp;
-      }
-    }
-    if (*cp || !split) {
-      continue;
-    }
-
-    /* Filters */
-    if (prefix_len && strncmp(msg + sizeof(prio), prefix, prefix_len)) {
-      size_t offset;
-      /*
-       *   Allow : to be a synonym for /
-       * Things we do dealing with const char * and do not alloc
-       */
-      split = strchr(prefix, ':');
-      if (split) {
-        continue;
-      }
-      split = strchr(prefix, '/');
-      if (!split) {
-        continue;
-      }
-      offset = split - prefix;
-      if ((msg[offset + sizeof(prio)] != ':') || strncmp(msg + sizeof(prio), prefix, offset)) {
-        continue;
-      }
-      ++offset;
-      if ((prefix_len > offset) &&
-          strncmp(&msg[offset + sizeof(prio)], split + 1, prefix_len - offset)) {
-        continue;
-      }
-    }
-
-    if ((prio != ANDROID_LOG_ANY) && (*msg < prio)) {
-      continue;
-    }
-
-    /* check if there is an existing entry */
-    list_for_each(node, &name_list) {
-      names = node_to_item(node, struct names, node);
-      if (!strcmp(names->name, msg + sizeof(prio)) && names->id == log_msg.entry.lid &&
-          names->prio == *msg) {
-        break;
-      }
-    }
-
-    /* We do not have an existing entry, create and add one */
-    if (node == &name_list) {
-      static const char numbers[] = "0123456789";
-      unsigned long long nl;
-
-      len = strlen(msg + sizeof(prio)) + 1;
-      names = static_cast<struct names*>(calloc(1, sizeof(*names) + len));
-      if (!names) {
-        ret = -ENOMEM;
-        break;
-      }
-      strcpy(names->name, msg + sizeof(prio));
-      names->id = static_cast<log_id_t>(log_msg.entry.lid);
-      names->prio = *msg;
-      list_init(&names->content);
-      /*
-       * Insert in reverse numeric _then_ alpha sorted order as
-       * representative of log rotation:
-       *
-       *   log.10
-       *   klog.10
-       *   . . .
-       *   log.2
-       *   klog.2
-       *   log.1
-       *   klog.1
-       *   log
-       *   klog
-       *
-       * thus when we present the content, we are provided the oldest
-       * first, which when 'refreshed' could spill off the end of the
-       * pmsg FIFO but retaining the newest data for last with best
-       * chances to survive.
-       */
-      nl = 0;
-      cp = strpbrk(names->name, numbers);
-      if (cp) {
-        nl = strtoull(cp, NULL, 10);
-      }
-      list_for_each_reverse(node, &name_list) {
-        struct names* a_name = node_to_item(node, struct names, node);
-        const char* r = a_name->name;
-        int compare = 0;
-
-        unsigned long long nr = 0;
-        cp = strpbrk(r, numbers);
-        if (cp) {
-          nr = strtoull(cp, NULL, 10);
-        }
-        if (nr != nl) {
-          compare = (nl > nr) ? 1 : -1;
-        }
-        if (compare == 0) {
-          compare = strcmp(names->name, r);
-        }
-        if (compare <= 0) {
-          break;
-        }
-      }
-      list_add_head(node, &names->node);
-    }
-
-    /* Remove any file fragments that match our sequence number */
-    list_for_each_safe(node, n, &names->content) {
-      content = node_to_item(node, struct content, node);
-      if (log_msg.entry.nsec == content->entry.nsec) {
-        list_remove(&content->node);
-        free(content);
-      }
-    }
-
-    /* Add content */
-    content = static_cast<struct content*>(
-        calloc(1, sizeof(content->node) + hdr_size + log_msg.entry.len));
-    if (!content) {
-      ret = -ENOMEM;
-      break;
-    }
-    memcpy(&content->entry, &log_msg.entry, hdr_size + log_msg.entry.len);
-
-    /* Insert in sequence number sorted order, to ease reconstruction */
-    list_for_each_reverse(node, &names->content) {
-      if ((node_to_item(node, struct content, node))->entry.nsec < log_msg.entry.nsec) {
-        break;
-      }
-    }
-    list_add_head(node, &content->node);
-  }
-  PmsgClose(&logger_list);
-
-  /* Progress through all the collected files */
-  list_for_each_safe(node, n, &name_list) {
-    struct listnode *content_node, *m;
-    char* buf;
-    size_t sequence, tag_len;
-
-    names = node_to_item(node, struct names, node);
-
-    /* Construct content into a linear buffer */
-    buf = NULL;
-    len = 0;
-    sequence = 0;
-    tag_len = strlen(names->name) + sizeof(char); /* tag + nul */
-    list_for_each_safe(content_node, m, &names->content) {
-      ssize_t add_len;
-
-      content = node_to_item(content_node, struct content, node);
-      add_len = content->entry.len - tag_len - sizeof(prio);
-      if (add_len <= 0) {
-        list_remove(content_node);
-        free(content);
-        continue;
-      }
-
-      if (!buf) {
-        buf = static_cast<char*>(malloc(sizeof(char)));
-        if (!buf) {
-          ret = -ENOMEM;
-          list_remove(content_node);
-          free(content);
-          continue;
-        }
-        *buf = '\0';
-      }
-
-      /* Missing sequence numbers */
-      while (sequence < content->entry.nsec) {
-        /* plus space for enforced nul */
-        buf = static_cast<char*>(realloc_or_free(buf, len + sizeof(char) + sizeof(char)));
-        if (!buf) {
-          break;
-        }
-        buf[len] = '\f'; /* Mark missing content with a form feed */
-        buf[++len] = '\0';
-        sequence += ANDROID_LOG_PMSG_FILE_SEQUENCE;
-      }
-      if (!buf) {
-        ret = -ENOMEM;
-        list_remove(content_node);
-        free(content);
-        continue;
-      }
-      /* plus space for enforced nul */
-      buf = static_cast<char*>(realloc_or_free(buf, len + add_len + sizeof(char)));
-      if (!buf) {
-        ret = -ENOMEM;
-        list_remove(content_node);
-        free(content);
-        continue;
-      }
-      memcpy(buf + len, (char*)&content->entry + content->entry.hdr_size + tag_len + sizeof(prio),
-             add_len);
-      len += add_len;
-      buf[len] = '\0'; /* enforce trailing hidden nul */
-      sequence = content->entry.nsec + ANDROID_LOG_PMSG_FILE_SEQUENCE;
-
-      list_remove(content_node);
-      free(content);
-    }
-    if (buf) {
-      if (len) {
-        /* Buffer contains enforced trailing nul just beyond length */
-        ssize_t r;
-        *strchr(names->name, ':') = '/'; /* Convert back to filename */
-        r = (*fn)(names->id, names->prio, names->name, buf, len, arg);
-        if ((ret >= 0) && (r > 0)) {
-          if (ret == SSIZE_MAX) {
-            ret = r;
-          } else {
-            ret += r;
-          }
-        } else if (r < ret) {
-          ret = r;
-        }
-      }
-      free(buf);
-    }
-    list_remove(node);
-    free(names);
-  }
-  return (ret == SSIZE_MAX) ? -ENOENT : ret;
-}
diff --git a/liblog/pmsg_reader.h b/liblog/pmsg_reader.h
deleted file mode 100644
index b784f9f..0000000
--- a/liblog/pmsg_reader.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-#pragma once
-
-#include <sys/cdefs.h>
-#include <unistd.h>
-
-#include "log/log_read.h"
-
-__BEGIN_DECLS
-
-int PmsgRead(struct logger_list* logger_list, struct log_msg* log_msg);
-void PmsgClose(struct logger_list* logger_list);
-
-__END_DECLS
diff --git a/liblog/pmsg_writer.cpp b/liblog/pmsg_writer.cpp
deleted file mode 100644
index 8e676bd..0000000
--- a/liblog/pmsg_writer.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2007-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 "pmsg_writer.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include <log/log_properties.h>
-#include <private/android_logger.h>
-
-#include "logger.h"
-#include "uio.h"
-
-static atomic_int pmsg_fd;
-
-// pmsg_fd should only beopened once.  If we see that pmsg_fd is uninitialized, we open "/dev/pmsg0"
-// then attempt to compare/exchange it into pmsg_fd.  If the compare/exchange was successful, then
-// that will be the fd used for the duration of the program, otherwise a different thread has
-// already opened and written the fd to the atomic, so close the new fd and return.
-static void GetPmsgFd() {
-  if (pmsg_fd != 0) {
-    return;
-  }
-
-  int new_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-  if (new_fd <= 0) {
-    return;
-  }
-
-  int uninitialized_value = 0;
-  if (!pmsg_fd.compare_exchange_strong(uninitialized_value, new_fd)) {
-    close(new_fd);
-    return;
-  }
-}
-
-void PmsgClose() {
-  if (pmsg_fd > 0) {
-    close(pmsg_fd);
-  }
-  pmsg_fd = 0;
-}
-
-int PmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr) {
-  static const unsigned headerLength = 2;
-  struct iovec newVec[nr + headerLength];
-  android_log_header_t header;
-  android_pmsg_log_header_t pmsgHeader;
-  size_t i, payloadSize;
-  ssize_t ret;
-
-  if (!__android_log_is_debuggable()) {
-    if (logId != LOG_ID_EVENTS && logId != LOG_ID_SECURITY) {
-      return -1;
-    }
-
-    if (logId == LOG_ID_EVENTS) {
-      if (vec[0].iov_len < 4) {
-        return -EINVAL;
-      }
-
-      if (SNET_EVENT_LOG_TAG != *static_cast<uint32_t*>(vec[0].iov_base)) {
-        return -EPERM;
-      }
-    }
-  }
-
-  GetPmsgFd();
-
-  if (pmsg_fd <= 0) {
-    return -EBADF;
-  }
-
-  /*
-   *  struct {
-   *      // what we provide to pstore
-   *      android_pmsg_log_header_t pmsgHeader;
-   *      // what we provide to file
-   *      android_log_header_t header;
-   *      // caller provides
-   *      union {
-   *          struct {
-   *              char     prio;
-   *              char     payload[];
-   *          } string;
-   *          struct {
-   *              uint32_t tag
-   *              char     payload[];
-   *          } binary;
-   *      };
-   *  };
-   */
-
-  pmsgHeader.magic = LOGGER_MAGIC;
-  pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header);
-  pmsgHeader.uid = getuid();
-  pmsgHeader.pid = getpid();
-
-  header.id = logId;
-  header.tid = gettid();
-  header.realtime.tv_sec = ts->tv_sec;
-  header.realtime.tv_nsec = ts->tv_nsec;
-
-  newVec[0].iov_base = (unsigned char*)&pmsgHeader;
-  newVec[0].iov_len = sizeof(pmsgHeader);
-  newVec[1].iov_base = (unsigned char*)&header;
-  newVec[1].iov_len = sizeof(header);
-
-  for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
-    newVec[i].iov_base = vec[i - headerLength].iov_base;
-    payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
-
-    if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
-      newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
-      if (newVec[i].iov_len) {
-        ++i;
-      }
-      payloadSize = LOGGER_ENTRY_MAX_PAYLOAD;
-      break;
-    }
-  }
-  pmsgHeader.len += payloadSize;
-
-  ret = TEMP_FAILURE_RETRY(writev(pmsg_fd, newVec, i));
-  if (ret < 0) {
-    ret = errno ? -errno : -ENOTCONN;
-  }
-
-  if (ret > (ssize_t)(sizeof(header) + sizeof(pmsgHeader))) {
-    ret -= sizeof(header) - sizeof(pmsgHeader);
-  }
-
-  return ret;
-}
-
-/*
- * Virtual pmsg filesystem
- *
- * Payload will comprise the string "<basedir>:<basefile>\0<content>" to a
- * maximum of LOGGER_ENTRY_MAX_PAYLOAD, but scaled to the last newline in the
- * file.
- *
- * Will hijack the header.realtime.tv_nsec field for a sequence number in usec.
- */
-
-static inline const char* strnrchr(const char* buf, size_t len, char c) {
-  const char* cp = buf + len;
-  while ((--cp > buf) && (*cp != c))
-    ;
-  if (cp <= buf) {
-    return buf + len;
-  }
-  return cp;
-}
-
-/* Write a buffer as filename references (tag = <basedir>:<basename>) */
-ssize_t __android_log_pmsg_file_write(log_id_t logId, char prio, const char* filename,
-                                      const char* buf, size_t len) {
-  size_t length, packet_len;
-  const char* tag;
-  char *cp, *slash;
-  struct timespec ts;
-  struct iovec vec[3];
-
-  /* Make sure the logId value is not a bad idea */
-  if ((logId == LOG_ID_KERNEL) ||   /* Verbotten */
-      (logId == LOG_ID_EVENTS) ||   /* Do not support binary content */
-      (logId == LOG_ID_SECURITY) || /* Bad idea to allow */
-      ((unsigned)logId >= 32)) {    /* fit within logMask on arch32 */
-    return -EINVAL;
-  }
-
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  cp = strdup(filename);
-  if (!cp) {
-    return -ENOMEM;
-  }
-
-  tag = cp;
-  slash = strrchr(cp, '/');
-  if (slash) {
-    *slash = ':';
-    slash = strrchr(cp, '/');
-    if (slash) {
-      tag = slash + 1;
-    }
-  }
-
-  length = strlen(tag) + 1;
-  packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length;
-
-  vec[0].iov_base = &prio;
-  vec[0].iov_len = sizeof(char);
-  vec[1].iov_base = (unsigned char*)tag;
-  vec[1].iov_len = length;
-
-  for (ts.tv_nsec = 0, length = len; length; ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) {
-    ssize_t ret;
-    size_t transfer;
-
-    if ((ts.tv_nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >= ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {
-      len -= length;
-      break;
-    }
-
-    transfer = length;
-    if (transfer > packet_len) {
-      transfer = strnrchr(buf, packet_len - 1, '\n') - buf;
-      if ((transfer < length) && (buf[transfer] == '\n')) {
-        ++transfer;
-      }
-    }
-
-    vec[2].iov_base = (unsigned char*)buf;
-    vec[2].iov_len = transfer;
-
-    ret = PmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0]));
-
-    if (ret <= 0) {
-      free(cp);
-      return ret ? ret : (len - length);
-    }
-    length -= transfer;
-    buf += transfer;
-  }
-  free(cp);
-  return len;
-}
diff --git a/liblog/pmsg_writer.h b/liblog/pmsg_writer.h
deleted file mode 100644
index d5e1a1c..0000000
--- a/liblog/pmsg_writer.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <stddef.h>
-
-#include <android/log.h>
-
-int PmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr);
-void PmsgClose();
diff --git a/liblog/properties.cpp b/liblog/properties.cpp
deleted file mode 100644
index 88f0bf1..0000000
--- a/liblog/properties.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
-** Copyright 2014, 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 <log/log_properties.h>
-
-#include <ctype.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <algorithm>
-
-#include <private/android_logger.h>
-
-#include "logger_write.h"
-
-#ifdef __ANDROID__
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-
-static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER;
-
-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.
-   */
-  /*
-   *  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() {
-  pthread_mutex_unlock(&lock_loggable);
-}
-
-struct cache {
-  const prop_info* pinfo;
-  uint32_t serial;
-};
-
-struct cache_char {
-  struct cache cache;
-  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
-
-static void refresh_cache(struct cache_char* cache, const char* key) {
-  char buf[PROP_VALUE_MAX];
-
-  if (!cache->cache.pinfo) {
-    cache->cache.pinfo = __system_property_find(key);
-    if (!cache->cache.pinfo) {
-      return;
-    }
-  }
-  cache->cache.serial = __system_property_serial(cache->cache.pinfo);
-  __system_property_read(cache->cache.pinfo, 0, buf);
-  switch (buf[0]) {
-    case 't':
-    case 'T':
-      cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE;
-      break;
-    case 'f':
-    case 'F':
-      cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE;
-      break;
-    default:
-      cache->c = buf[0];
-  }
-}
-
-static int __android_log_level(const char* tag, size_t len) {
-  /* sizeof() is used on this array below */
-  static const char log_namespace[] = "persist.log.tag.";
-  static const size_t base_offset = 8; /* skip "persist." */
-
-  if (tag == nullptr || len == 0) {
-    auto& tag_string = GetDefaultTag();
-    tag = tag_string.c_str();
-    len = tag_string.size();
-  }
-
-  /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
-  char key[sizeof(log_namespace) + len];
-  char* kp;
-  size_t i;
-  char c = 0;
-  /*
-   * Single layer cache of four properties. Priorities are:
-   *    log.tag.<tag>
-   *    persist.log.tag.<tag>
-   *    log.tag
-   *    persist.log.tag
-   * Where the missing tag matches all tags and becomes the
-   * system global default. We do not support ro.log.tag* .
-   */
-  static char* last_tag;
-  static size_t last_tag_len;
-  static uint32_t global_serial;
-  /* some compilers erroneously see uninitialized use. !not_locked */
-  uint32_t current_global_serial = 0;
-  static struct cache_char tag_cache[2];
-  static struct cache_char global_cache[2];
-  int change_detected;
-  int global_change_detected;
-  int not_locked;
-
-  strcpy(key, log_namespace);
-
-  global_change_detected = change_detected = not_locked = lock();
-
-  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].cache)) {
-        change_detected = 1;
-      }
-    }
-    for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
-      if (check_cache(&global_cache[i].cache)) {
-        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 (len) {
-    int local_change_detected = change_detected;
-    if (!not_locked) {
-      if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) ||
-          strncmp(last_tag + 1, tag + 1, last_tag_len - 1)) {
-        /* invalidate log.tag.<tag> cache */
-        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
-          tag_cache[i].cache.pinfo = NULL;
-          tag_cache[i].c = '\0';
-        }
-        if (last_tag) last_tag[0] = '\0';
-        local_change_detected = 1;
-      }
-      if (!last_tag || !last_tag[0]) {
-        if (!last_tag) {
-          last_tag = static_cast<char*>(calloc(1, len + 1));
-          last_tag_len = 0;
-          if (last_tag) last_tag_len = len + 1;
-        } else if (len >= last_tag_len) {
-          last_tag = static_cast<char*>(realloc(last_tag, len + 1));
-          last_tag_len = 0;
-          if (last_tag) last_tag_len = len + 1;
-        }
-        if (last_tag) {
-          strncpy(last_tag, tag, len);
-          last_tag[len] = '\0';
-        }
-      }
-    }
-    strncpy(key + sizeof(log_namespace) - 1, tag, len);
-    key[sizeof(log_namespace) - 1 + len] = '\0';
-
-    kp = key;
-    for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
-      struct cache_char* cache = &tag_cache[i];
-      struct cache_char temp_cache;
-
-      if (not_locked) {
-        temp_cache.cache.pinfo = NULL;
-        temp_cache.c = '\0';
-        cache = &temp_cache;
-      }
-      if (local_change_detected) {
-        refresh_cache(cache, kp);
-      }
-
-      if (cache->c) {
-        c = cache->c;
-        break;
-      }
-
-      kp = key + base_offset;
-    }
-  }
-
-  switch (toupper(c)) { /* if invalid, resort to global */
-    case 'V':
-    case 'D':
-    case 'I':
-    case 'W':
-    case 'E':
-    case 'F': /* Not officially supported */
-    case 'A':
-    case 'S':
-    case BOOLEAN_FALSE: /* Not officially supported */
-      break;
-    default:
-      /* clear '.' after log.tag */
-      key[sizeof(log_namespace) - 2] = '\0';
-
-      kp = key;
-      for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
-        struct cache_char* cache = &global_cache[i];
-        struct cache_char temp_cache;
-
-        if (not_locked) {
-          temp_cache = *cache;
-          if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */
-            temp_cache.cache.pinfo = NULL;
-            temp_cache.c = '\0';
-          }
-          cache = &temp_cache;
-        }
-        if (global_change_detected) {
-          refresh_cache(cache, kp);
-        }
-
-        if (cache->c) {
-          c = cache->c;
-          break;
-        }
-
-        kp = key + base_offset;
-      }
-      break;
-  }
-
-  if (!not_locked) {
-    global_serial = current_global_serial;
-    unlock();
-  }
-
-  switch (toupper(c)) {
-    /* clang-format off */
-    case 'V': return ANDROID_LOG_VERBOSE;
-    case 'D': return ANDROID_LOG_DEBUG;
-    case 'I': return ANDROID_LOG_INFO;
-    case 'W': return ANDROID_LOG_WARN;
-    case 'E': return ANDROID_LOG_ERROR;
-    case 'F': /* FALLTHRU */ /* Not officially supported */
-    case 'A': return ANDROID_LOG_FATAL;
-    case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */
-    case 'S': return ANDROID_LOG_SILENT;
-      /* clang-format on */
-  }
-  return -1;
-}
-
-int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio) {
-  int minimum_log_priority = __android_log_get_minimum_priority();
-  int property_log_level = __android_log_level(tag, len);
-
-  if (property_log_level >= 0 && minimum_log_priority != ANDROID_LOG_DEFAULT) {
-    return prio >= std::min(property_log_level, minimum_log_priority);
-  } else if (property_log_level >= 0) {
-    return prio >= property_log_level;
-  } else if (minimum_log_priority != ANDROID_LOG_DEFAULT) {
-    return prio >= minimum_log_priority;
-  } else {
-    return prio >= default_prio;
-  }
-}
-
-int __android_log_is_loggable(int prio, const char* tag, int default_prio) {
-  auto len = tag ? strlen(tag) : 0;
-  return __android_log_is_loggable_len(prio, tag, len, default_prio);
-}
-
-int __android_log_is_debuggable() {
-  static int is_debuggable = [] {
-    char value[PROP_VALUE_MAX] = {};
-    return __system_property_get("ro.debuggable", value) > 0 && !strcmp(value, "1");
-  }();
-
-  return is_debuggable;
-}
-
-/*
- * 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.
- */
-struct cache2_char {
-  pthread_mutex_t lock;
-  uint32_t serial;
-  const char* key_persist;
-  struct cache_char cache_persist;
-  const char* key_ro;
-  struct cache_char cache_ro;
-  unsigned char (*const evaluate)(const struct cache2_char* self);
-};
-
-static inline unsigned char do_cache2_char(struct cache2_char* self) {
-  uint32_t current_serial;
-  int change_detected;
-  unsigned char c;
-
-  if (pthread_mutex_trylock(&self->lock)) {
-    /* We are willing to accept some race in this context */
-    return self->evaluate(self);
-  }
-
-  change_detected = check_cache(&self->cache_persist.cache) || check_cache(&self->cache_ro.cache);
-  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;
-}
-
-/*
- * 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_char* 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 cache2_char security = {
-      PTHREAD_MUTEX_INITIALIZER, 0,
-      "persist.logd.security",   {{NULL, 0xFFFFFFFF}, BOOLEAN_FALSE},
-      "ro.organization_owned",   {{NULL, 0xFFFFFFFF}, BOOLEAN_FALSE},
-      evaluate_security};
-
-  return do_cache2_char(&security);
-}
-
-#else
-
-int __android_log_is_loggable(int prio, const char*, int) {
-  int minimum_priority = __android_log_get_minimum_priority();
-  if (minimum_priority == ANDROID_LOG_DEFAULT) {
-    minimum_priority = ANDROID_LOG_INFO;
-  }
-  return prio >= minimum_priority;
-}
-
-int __android_log_is_loggable_len(int prio, const char*, size_t, int def) {
-  return __android_log_is_loggable(prio, nullptr, def);
-}
-
-int __android_log_is_debuggable() {
-  return 1;
-}
-
-#endif
diff --git a/liblog/tests/Android.bp b/liblog/tests/Android.bp
deleted file mode 100644
index a17d90c..0000000
--- a/liblog/tests/Android.bp
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// Copyright (C) 2013-2014 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.
-//
-
-// -----------------------------------------------------------------------------
-// Benchmarks.
-// -----------------------------------------------------------------------------
-
-// Build benchmarks for the device. Run with:
-//   adb shell liblog-benchmarks
-cc_benchmark {
-    name: "liblog-benchmarks",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-fno-builtin",
-    ],
-    shared_libs: [
-        "libm",
-        "libbase",
-        "libcutils",
-    ],
-    static_libs: ["liblog"],
-    srcs: ["liblog_benchmark.cpp"],
-}
-
-// -----------------------------------------------------------------------------
-// Unit tests.
-// -----------------------------------------------------------------------------
-
-cc_defaults {
-    name: "liblog-tests-defaults",
-
-    cflags: [
-        "-fstack-protector-all",
-        "-g",
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-fno-builtin",
-    ],
-    srcs: [
-        "libc_test.cpp",
-        "liblog_default_tag.cpp",
-        "liblog_global_state.cpp",
-        "liblog_test.cpp",
-        "log_id_test.cpp",
-        "log_radio_test.cpp",
-        "log_read_test.cpp",
-        "log_system_test.cpp",
-        "log_time_test.cpp",
-        "log_wrap_test.cpp",
-        "logd_writer_test.cpp",
-        "logprint_test.cpp",
-    ],
-    shared_libs: [
-        "libcutils",
-        "libbase",
-    ],
-    static_libs: ["liblog"],
-    isolated: true,
-    require_root: true,
-}
-
-// Build tests for the device (with .so). Run with:
-//   adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
-cc_test {
-    name: "liblog-unit-tests",
-    defaults: ["liblog-tests-defaults"],
-}
-
-cc_test {
-    name: "CtsLiblogTestCases",
-    defaults: ["liblog-tests-defaults"],
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
-
-    cflags: ["-DNO_PSTORE"],
-    test_suites: [
-        "cts",
-        "device-tests",
-        "vts10",
-    ],
-}
-
-cc_test_host {
-    name: "liblog-host-test",
-    static_libs: ["liblog"],
-    shared_libs: ["libbase"],
-    srcs: [
-        "liblog_host_test.cpp",
-        "liblog_default_tag.cpp",
-        "liblog_global_state.cpp",
-    ],
-    isolated: true,
-}
diff --git a/liblog/tests/AndroidTest.xml b/liblog/tests/AndroidTest.xml
deleted file mode 100644
index fcb46b1..0000000
--- a/liblog/tests/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-<configuration description="Config for CTS Logging Library test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="systems" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="cleanup" value="true" />
-        <option name="push" value="CtsLiblogTestCases->/data/local/tmp/CtsLiblogTestCases" />
-        <option name="append-bitness" value="true" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="CtsLiblogTestCases" />
-        <option name="runtime-hint" value="65s" />
-    </test>
-</configuration>
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
deleted file mode 100644
index 1f26263..0000000
--- a/liblog/tests/libc_test.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2014 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 <gtest/gtest.h>
-
-#include <errno.h>
-#include <stdio.h>
-
-TEST(libc, __pstore_append) {
-#ifdef __ANDROID__
-#ifndef NO_PSTORE
-  if (access("/dev/pmsg0", W_OK) != 0) {
-    GTEST_SKIP() << "pmsg0 not found, skipping test";
-  }
-
-  FILE* fp;
-  ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "ae")));
-  static const char message[] = "libc.__pstore_append\n";
-  ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp));
-  int fflushReturn = fflush(fp);
-  int fflushErrno = fflushReturn ? errno : 0;
-  ASSERT_EQ(0, fflushReturn);
-  ASSERT_EQ(0, fflushErrno);
-  int fcloseReturn = fclose(fp);
-  int fcloseErrno = fcloseReturn ? errno : 0;
-  ASSERT_EQ(0, fcloseReturn);
-  ASSERT_EQ(0, fcloseErrno);
-  if ((fcloseErrno == ENOMEM) || (fflushErrno == ENOMEM)) {
-    fprintf(stderr,
-            "Kernel does not have space allocated to pmsg pstore driver "
-            "configured\n");
-  }
-  if (!fcloseReturn && !fcloseErrno && !fflushReturn && !fflushReturn) {
-    fprintf(stderr,
-            "Reboot, ensure string libc.__pstore_append is in "
-            "/sys/fs/pstore/pmsg-ramoops-0\n");
-  }
-#else  /* NO_PSTORE */
-  GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
-#endif /* NO_PSTORE */
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
deleted file mode 100644
index d2f12d6..0000000
--- a/liblog/tests/liblog_benchmark.cpp
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * Copyright (C) 2013-2014 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 <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <sched.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include <unordered_set>
-
-#include <android-base/file.h>
-#include <android-base/properties.h>
-#include <benchmark/benchmark.h>
-#include <cutils/sockets.h>
-#include <log/event_tag_map.h>
-#include <log/log_read.h>
-#include <private/android_logger.h>
-
-BENCHMARK_MAIN();
-
-// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
-// non-syscall libs. Since we are benchmarking, or using this in the emergency
-// signal to stuff a terminating code, we do NOT want to introduce
-// a syscall or usleep on EAGAIN retry.
-#define LOG_FAILURE_RETRY(exp)                                           \
-  ({                                                                     \
-    typeof(exp) _rc;                                                     \
-    do {                                                                 \
-      _rc = (exp);                                                       \
-    } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \
-             (_rc == -EINTR) || (_rc == -EAGAIN));                       \
-    _rc;                                                                 \
-  })
-
-/*
- *	Measure the fastest rate we can reliabley stuff print messages into
- * the log at high pressure. Expect this to be less than double the process
- * wakeup time (2ms?)
- */
-static void BM_log_maximum_retry(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_INFO, "BM_log_maximum_retry", "%" PRIu64,
-                                          state.iterations()));
-  }
-}
-BENCHMARK(BM_log_maximum_retry);
-
-/*
- *	Measure the fastest rate we can stuff print messages into the log
- * at high pressure. Expect this to be less than double the process wakeup
- * time (2ms?)
- */
-static void BM_log_maximum(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    __android_log_print(ANDROID_LOG_INFO, "BM_log_maximum", "%" PRIu64, state.iterations());
-  }
-}
-BENCHMARK(BM_log_maximum);
-
-/*
- *	Measure the time it takes to collect the time using
- * discrete acquisition (state.PauseTiming() to state.ResumeTiming())
- * under light load. Expect this to be a syscall period (2us) or
- * data read time if zero-syscall.
- *
- * vdso support in the kernel and the library can allow
- * clock_gettime to be zero-syscall, but there there does remain some
- * benchmarking overhead to pause and resume; assumptions are both are
- * covered.
- */
-static void BM_clock_overhead(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    state.PauseTiming();
-    state.ResumeTiming();
-  }
-}
-BENCHMARK(BM_clock_overhead);
-
-static void do_clock_overhead(benchmark::State& state, clockid_t clk_id) {
-  timespec t;
-  while (state.KeepRunning()) {
-    clock_gettime(clk_id, &t);
-  }
-}
-
-static void BM_time_clock_gettime_REALTIME(benchmark::State& state) {
-  do_clock_overhead(state, CLOCK_REALTIME);
-}
-BENCHMARK(BM_time_clock_gettime_REALTIME);
-
-static void BM_time_clock_gettime_MONOTONIC(benchmark::State& state) {
-  do_clock_overhead(state, CLOCK_MONOTONIC);
-}
-BENCHMARK(BM_time_clock_gettime_MONOTONIC);
-
-static void BM_time_clock_gettime_MONOTONIC_syscall(benchmark::State& state) {
-  timespec t;
-  while (state.KeepRunning()) {
-    syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t);
-  }
-}
-BENCHMARK(BM_time_clock_gettime_MONOTONIC_syscall);
-
-static void BM_time_clock_gettime_MONOTONIC_RAW(benchmark::State& state) {
-  do_clock_overhead(state, CLOCK_MONOTONIC_RAW);
-}
-BENCHMARK(BM_time_clock_gettime_MONOTONIC_RAW);
-
-static void BM_time_clock_gettime_BOOTTIME(benchmark::State& state) {
-  do_clock_overhead(state, CLOCK_BOOTTIME);
-}
-BENCHMARK(BM_time_clock_gettime_BOOTTIME);
-
-static void BM_time_clock_getres_MONOTONIC(benchmark::State& state) {
-  timespec t;
-  while (state.KeepRunning()) {
-    clock_getres(CLOCK_MONOTONIC, &t);
-  }
-}
-BENCHMARK(BM_time_clock_getres_MONOTONIC);
-
-static void BM_time_clock_getres_MONOTONIC_syscall(benchmark::State& state) {
-  timespec t;
-  while (state.KeepRunning()) {
-    syscall(__NR_clock_getres, CLOCK_MONOTONIC, &t);
-  }
-}
-BENCHMARK(BM_time_clock_getres_MONOTONIC_syscall);
-
-static void BM_time_time(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    time_t now;
-    now = time(&now);
-  }
-}
-BENCHMARK(BM_time_time);
-
-/*
- * Measure the time it takes to submit the android logging data to pstore
- */
-static void BM_pmsg_short(benchmark::State& state) {
-  int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-  if (pstore_fd < 0) {
-    state.SkipWithError("/dev/pmsg0");
-    return;
-  }
-
-  /*
-   *  struct {
-   *      // what we provide to pstore
-   *      android_pmsg_log_header_t pmsg_header;
-   *      // what we provide to socket
-   *      android_log_header_t header;
-   *      // caller provides
-   *      union {
-   *          struct {
-   *              char     prio;
-   *              char     payload[];
-   *          } string;
-   *          struct {
-   *              uint32_t tag
-   *              char     payload[];
-   *          } binary;
-   *      };
-   *  };
-   */
-
-  struct timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  android_pmsg_log_header_t pmsg_header;
-  pmsg_header.magic = LOGGER_MAGIC;
-  pmsg_header.len =
-      sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
-  pmsg_header.uid = getuid();
-  pmsg_header.pid = getpid();
-
-  android_log_header_t header;
-  header.tid = gettid();
-  header.realtime.tv_sec = ts.tv_sec;
-  header.realtime.tv_nsec = ts.tv_nsec;
-
-  static const unsigned nr = 1;
-  static const unsigned header_length = 2;
-  struct iovec newVec[nr + header_length];
-
-  newVec[0].iov_base = (unsigned char*)&pmsg_header;
-  newVec[0].iov_len = sizeof(pmsg_header);
-  newVec[1].iov_base = (unsigned char*)&header;
-  newVec[1].iov_len = sizeof(header);
-
-  android_log_event_int_t buffer;
-
-  header.id = LOG_ID_EVENTS;
-  buffer.header.tag = 0;
-  buffer.payload.type = EVENT_TYPE_INT;
-  uint32_t snapshot = 0;
-  buffer.payload.data = snapshot;
-
-  newVec[2].iov_base = &buffer;
-  newVec[2].iov_len = sizeof(buffer);
-
-  while (state.KeepRunning()) {
-    ++snapshot;
-    buffer.payload.data = snapshot;
-    writev(pstore_fd, newVec, nr);
-  }
-  state.PauseTiming();
-  close(pstore_fd);
-}
-BENCHMARK(BM_pmsg_short);
-
-/*
- * Measure the time it takes to submit the android logging data to pstore
- * best case aligned single block.
- */
-static void BM_pmsg_short_aligned(benchmark::State& state) {
-  int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-  if (pstore_fd < 0) {
-    state.SkipWithError("/dev/pmsg0");
-    return;
-  }
-
-  /*
-   *  struct {
-   *      // what we provide to pstore
-   *      android_pmsg_log_header_t pmsg_header;
-   *      // what we provide to socket
-   *      android_log_header_t header;
-   *      // caller provides
-   *      union {
-   *          struct {
-   *              char     prio;
-   *              char     payload[];
-   *          } string;
-   *          struct {
-   *              uint32_t tag
-   *              char     payload[];
-   *          } binary;
-   *      };
-   *  };
-   */
-
-  struct timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  struct packet {
-    android_pmsg_log_header_t pmsg_header;
-    android_log_header_t header;
-    android_log_event_int_t payload;
-  };
-  alignas(8) char buf[sizeof(struct packet) + 8];
-  memset(buf, 0, sizeof(buf));
-  struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
-  if (((uintptr_t)&buffer->pmsg_header) & 7) {
-    fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
-            state.iterations());
-  }
-
-  buffer->pmsg_header.magic = LOGGER_MAGIC;
-  buffer->pmsg_header.len =
-      sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
-  buffer->pmsg_header.uid = getuid();
-  buffer->pmsg_header.pid = getpid();
-
-  buffer->header.tid = gettid();
-  buffer->header.realtime.tv_sec = ts.tv_sec;
-  buffer->header.realtime.tv_nsec = ts.tv_nsec;
-
-  buffer->header.id = LOG_ID_EVENTS;
-  buffer->payload.header.tag = 0;
-  buffer->payload.payload.type = EVENT_TYPE_INT;
-  uint32_t snapshot = 0;
-  buffer->payload.payload.data = snapshot;
-
-  while (state.KeepRunning()) {
-    ++snapshot;
-    buffer->payload.payload.data = snapshot;
-    write(pstore_fd, &buffer->pmsg_header,
-          sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) +
-              sizeof(android_log_event_int_t));
-  }
-  state.PauseTiming();
-  close(pstore_fd);
-}
-BENCHMARK(BM_pmsg_short_aligned);
-
-/*
- * Measure the time it takes to submit the android logging data to pstore
- * best case aligned single block.
- */
-static void BM_pmsg_short_unaligned1(benchmark::State& state) {
-  int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-  if (pstore_fd < 0) {
-    state.SkipWithError("/dev/pmsg0");
-    return;
-  }
-
-  /*
-   *  struct {
-   *      // what we provide to pstore
-   *      android_pmsg_log_header_t pmsg_header;
-   *      // what we provide to socket
-   *      android_log_header_t header;
-   *      // caller provides
-   *      union {
-   *          struct {
-   *              char     prio;
-   *              char     payload[];
-   *          } string;
-   *          struct {
-   *              uint32_t tag
-   *              char     payload[];
-   *          } binary;
-   *      };
-   *  };
-   */
-
-  struct timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  struct packet {
-    android_pmsg_log_header_t pmsg_header;
-    android_log_header_t header;
-    android_log_event_int_t payload;
-  };
-  alignas(8) char buf[sizeof(struct packet) + 8];
-  memset(buf, 0, sizeof(buf));
-  struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
-  if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
-    fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
-            state.iterations());
-  }
-
-  buffer->pmsg_header.magic = LOGGER_MAGIC;
-  buffer->pmsg_header.len =
-      sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
-  buffer->pmsg_header.uid = getuid();
-  buffer->pmsg_header.pid = getpid();
-
-  buffer->header.tid = gettid();
-  buffer->header.realtime.tv_sec = ts.tv_sec;
-  buffer->header.realtime.tv_nsec = ts.tv_nsec;
-
-  buffer->header.id = LOG_ID_EVENTS;
-  buffer->payload.header.tag = 0;
-  buffer->payload.payload.type = EVENT_TYPE_INT;
-  uint32_t snapshot = 0;
-  buffer->payload.payload.data = snapshot;
-
-  while (state.KeepRunning()) {
-    ++snapshot;
-    buffer->payload.payload.data = snapshot;
-    write(pstore_fd, &buffer->pmsg_header,
-          sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) +
-              sizeof(android_log_event_int_t));
-  }
-  state.PauseTiming();
-  close(pstore_fd);
-}
-BENCHMARK(BM_pmsg_short_unaligned1);
-
-/*
- * Measure the time it takes to submit the android logging data to pstore
- * best case aligned single block.
- */
-static void BM_pmsg_long_aligned(benchmark::State& state) {
-  int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-  if (pstore_fd < 0) {
-    state.SkipWithError("/dev/pmsg0");
-    return;
-  }
-
-  /*
-   *  struct {
-   *      // what we provide to pstore
-   *      android_pmsg_log_header_t pmsg_header;
-   *      // what we provide to socket
-   *      android_log_header_t header;
-   *      // caller provides
-   *      union {
-   *          struct {
-   *              char     prio;
-   *              char     payload[];
-   *          } string;
-   *          struct {
-   *              uint32_t tag
-   *              char     payload[];
-   *          } binary;
-   *      };
-   *  };
-   */
-
-  struct timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  struct packet {
-    android_pmsg_log_header_t pmsg_header;
-    android_log_header_t header;
-    android_log_event_int_t payload;
-  };
-  alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD];
-  memset(buf, 0, sizeof(buf));
-  struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
-  if (((uintptr_t)&buffer->pmsg_header) & 7) {
-    fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
-            state.iterations());
-  }
-
-  buffer->pmsg_header.magic = LOGGER_MAGIC;
-  buffer->pmsg_header.len =
-      sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
-  buffer->pmsg_header.uid = getuid();
-  buffer->pmsg_header.pid = getpid();
-
-  buffer->header.tid = gettid();
-  buffer->header.realtime.tv_sec = ts.tv_sec;
-  buffer->header.realtime.tv_nsec = ts.tv_nsec;
-
-  buffer->header.id = LOG_ID_EVENTS;
-  buffer->payload.header.tag = 0;
-  buffer->payload.payload.type = EVENT_TYPE_INT;
-  uint32_t snapshot = 0;
-  buffer->payload.payload.data = snapshot;
-
-  while (state.KeepRunning()) {
-    ++snapshot;
-    buffer->payload.payload.data = snapshot;
-    write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD);
-  }
-  state.PauseTiming();
-  close(pstore_fd);
-}
-BENCHMARK(BM_pmsg_long_aligned);
-
-/*
- * Measure the time it takes to submit the android logging data to pstore
- * best case aligned single block.
- */
-static void BM_pmsg_long_unaligned1(benchmark::State& state) {
-  int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-  if (pstore_fd < 0) {
-    state.SkipWithError("/dev/pmsg0");
-    return;
-  }
-
-  /*
-   *  struct {
-   *      // what we provide to pstore
-   *      android_pmsg_log_header_t pmsg_header;
-   *      // what we provide to socket
-   *      android_log_header_t header;
-   *      // caller provides
-   *      union {
-   *          struct {
-   *              char     prio;
-   *              char     payload[];
-   *          } string;
-   *          struct {
-   *              uint32_t tag
-   *              char     payload[];
-   *          } binary;
-   *      };
-   *  };
-   */
-
-  struct timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
-
-  struct packet {
-    android_pmsg_log_header_t pmsg_header;
-    android_log_header_t header;
-    android_log_event_int_t payload;
-  };
-  alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD];
-  memset(buf, 0, sizeof(buf));
-  struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
-  if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
-    fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
-            state.iterations());
-  }
-
-  buffer->pmsg_header.magic = LOGGER_MAGIC;
-  buffer->pmsg_header.len =
-      sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
-  buffer->pmsg_header.uid = getuid();
-  buffer->pmsg_header.pid = getpid();
-
-  buffer->header.tid = gettid();
-  buffer->header.realtime.tv_sec = ts.tv_sec;
-  buffer->header.realtime.tv_nsec = ts.tv_nsec;
-
-  buffer->header.id = LOG_ID_EVENTS;
-  buffer->payload.header.tag = 0;
-  buffer->payload.payload.type = EVENT_TYPE_INT;
-  uint32_t snapshot = 0;
-  buffer->payload.payload.data = snapshot;
-
-  while (state.KeepRunning()) {
-    ++snapshot;
-    buffer->payload.payload.data = snapshot;
-    write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD);
-  }
-  state.PauseTiming();
-  close(pstore_fd);
-}
-BENCHMARK(BM_pmsg_long_unaligned1);
-
-/*
- *	Measure the time it takes to form sprintf plus time using
- * discrete acquisition under light load. Expect this to be a syscall period
- * (2us) or sprintf time if zero-syscall time.
- */
-/* helper function */
-static void test_print(const char* fmt, ...) {
-  va_list ap;
-  char buf[1024];
-
-  va_start(ap, fmt);
-  vsnprintf(buf, sizeof(buf), fmt, ap);
-  va_end(ap);
-}
-
-#define logd_yield() sched_yield()  // allow logd to catch up
-#define logd_sleep() usleep(50)     // really allow logd to catch up
-
-/* performance test */
-static void BM_sprintf_overhead(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    test_print("BM_sprintf_overhead:%" PRIu64, state.iterations());
-    state.PauseTiming();
-    logd_yield();
-    state.ResumeTiming();
-  }
-}
-BENCHMARK(BM_sprintf_overhead);
-
-/*
- *	Measure the time it takes to submit the android printing logging call
- * using discrete acquisition discrete acquisition under light load. Expect
- * this to be a dozen or so syscall periods (40us) plus time to run *printf
- */
-static void BM_log_print_overhead(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    __android_log_print(ANDROID_LOG_INFO, "BM_log_overhead", "%" PRIu64, state.iterations());
-    state.PauseTiming();
-    logd_yield();
-    state.ResumeTiming();
-  }
-}
-BENCHMARK(BM_log_print_overhead);
-
-/*
- *	Measure the time it takes to submit the android event logging call
- * using discrete acquisition under light load. Expect this to be a long path
- * to logger to convert the unknown tag (0) into a tagname (less than 200us).
- */
-static void BM_log_event_overhead(benchmark::State& state) {
-  for (int64_t i = 0; state.KeepRunning(); ++i) {
-    // log tag number 0 is not known, nor shall it ever be known
-    __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i));
-    state.PauseTiming();
-    logd_yield();
-    state.ResumeTiming();
-  }
-}
-BENCHMARK(BM_log_event_overhead);
-
-/*
- *	Measure the time it takes to submit the android event logging call
- * using discrete acquisition under light load with a known logtag.  Expect
- * this to be a dozen or so syscall periods (less than 40us)
- */
-static void BM_log_event_overhead_42(benchmark::State& state) {
-  for (int64_t i = 0; state.KeepRunning(); ++i) {
-    // In system/core/logcat/event.logtags:
-    // # These are used for testing, do not modify without updating
-    // # tests/framework-tests/src/android/util/EventLogFunctionalTest.java.
-    // # system/core/liblog/tests/liblog_benchmark.cpp
-    // # system/core/liblog/tests/liblog_test.cpp
-    // 42    answer (to life the universe etc|3)
-    __android_log_btwrite(42, EVENT_TYPE_LONG, &i, sizeof(i));
-    state.PauseTiming();
-    logd_yield();
-    state.ResumeTiming();
-  }
-}
-BENCHMARK(BM_log_event_overhead_42);
-
-/*
- *	Measure the time it takes to submit the android event logging call
- * using discrete acquisition under very-light load (<1% CPU utilization).
- */
-static void BM_log_light_overhead(benchmark::State& state) {
-  for (int64_t i = 0; state.KeepRunning(); ++i) {
-    __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i));
-    state.PauseTiming();
-    usleep(10000);
-    state.ResumeTiming();
-  }
-}
-BENCHMARK(BM_log_light_overhead);
-
-static void caught_latency(int /*signum*/) {
-  unsigned long long v = 0xDEADBEEFA55A5AA5ULL;
-
-  LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-}
-
-static unsigned long long caught_convert(char* cp) {
-  unsigned long long l = cp[0] & 0xFF;
-  l |= (unsigned long long)(cp[1] & 0xFF) << 8;
-  l |= (unsigned long long)(cp[2] & 0xFF) << 16;
-  l |= (unsigned long long)(cp[3] & 0xFF) << 24;
-  l |= (unsigned long long)(cp[4] & 0xFF) << 32;
-  l |= (unsigned long long)(cp[5] & 0xFF) << 40;
-  l |= (unsigned long long)(cp[6] & 0xFF) << 48;
-  l |= (unsigned long long)(cp[7] & 0xFF) << 56;
-  return l;
-}
-
-static const int alarm_time = 3;
-
-/*
- *	Measure the time it takes for the logd posting call to acquire the
- * timestamp to place into the internal record.  Expect this to be less than
- * 4 syscalls (3us).  This test uses manual injection of timing because it is
- * comparing the timestamp at send, and then picking up the corresponding log
- * end-to-end long path from logd to see what actual timestamp was submitted.
- */
-static void BM_log_latency(benchmark::State& state) {
-  pid_t pid = getpid();
-
-  struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid);
-
-  if (!logger_list) {
-    fprintf(stderr, "Unable to open events log: %s\n", strerror(errno));
-    exit(EXIT_FAILURE);
-  }
-
-  signal(SIGALRM, caught_latency);
-  alarm(alarm_time);
-
-  for (size_t j = 0; state.KeepRunning() && j < 10 * state.iterations(); ++j) {
-  retry:  // We allow transitory errors (logd overloaded) to be retried.
-    log_time ts;
-    LOG_FAILURE_RETRY((ts = log_time(CLOCK_REALTIME),
-                       android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts))));
-
-    for (;;) {
-      log_msg log_msg;
-      int ret = android_logger_list_read(logger_list, &log_msg);
-      alarm(alarm_time);
-
-      if (ret <= 0) {
-        state.SkipWithError("android_logger_list_read");
-        break;
-      }
-      if ((log_msg.entry.len != (4 + 1 + 8)) ||
-          (log_msg.id() != LOG_ID_EVENTS)) {
-        continue;
-      }
-
-      char* eventData = log_msg.msg();
-
-      if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
-        continue;
-      }
-      log_time* tx = reinterpret_cast<log_time*>(eventData + 4 + 1);
-      if (ts != *tx) {
-        if (0xDEADBEEFA55A5AA5ULL == caught_convert(eventData + 4 + 1)) {
-          state.SkipWithError("signal");
-          break;
-        }
-        continue;
-      }
-
-      uint64_t start = ts.nsec();
-      uint64_t end = log_msg.nsec();
-      if (end < start) goto retry;
-      state.SetIterationTime((end - start) / (double)NS_PER_SEC);
-      break;
-    }
-  }
-
-  signal(SIGALRM, SIG_DFL);
-  alarm(0);
-
-  android_logger_list_free(logger_list);
-}
-// Default gets out of hand for this test, so we set a reasonable number of
-// iterations for a timely result.
-BENCHMARK(BM_log_latency)->UseManualTime()->Iterations(200);
-
-static void caught_delay(int /*signum*/) {
-  unsigned long long v = 0xDEADBEEFA55A5AA6ULL;
-
-  LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-}
-
-/*
- *	Measure the time it takes for the logd posting call to make it into
- * the logs. Expect this to be less than double the process wakeup time (2ms).
- */
-static void BM_log_delay(benchmark::State& state) {
-  pid_t pid = getpid();
-
-  struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid);
-
-  if (!logger_list) {
-    fprintf(stderr, "Unable to open events log: %s\n", strerror(errno));
-    exit(EXIT_FAILURE);
-  }
-
-  signal(SIGALRM, caught_delay);
-  alarm(alarm_time);
-
-  while (state.KeepRunning()) {
-    log_time ts(CLOCK_REALTIME);
-
-    LOG_FAILURE_RETRY(android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-
-    for (;;) {
-      log_msg log_msg;
-      int ret = android_logger_list_read(logger_list, &log_msg);
-      alarm(alarm_time);
-
-      if (ret <= 0) {
-        state.SkipWithError("android_logger_list_read");
-        break;
-      }
-      if ((log_msg.entry.len != (4 + 1 + 8)) ||
-          (log_msg.id() != LOG_ID_EVENTS)) {
-        continue;
-      }
-
-      char* eventData = log_msg.msg();
-
-      if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
-        continue;
-      }
-      log_time* tx = reinterpret_cast<log_time*>(eventData + 4 + 1);
-      if (ts != *tx) {
-        if (0xDEADBEEFA55A5AA6ULL == caught_convert(eventData + 4 + 1)) {
-          state.SkipWithError("signal");
-          break;
-        }
-        continue;
-      }
-
-      break;
-    }
-  }
-  state.PauseTiming();
-
-  signal(SIGALRM, SIG_DFL);
-  alarm(0);
-
-  android_logger_list_free(logger_list);
-}
-BENCHMARK(BM_log_delay);
-
-/*
- *	Measure the time it takes for __android_log_is_loggable.
- */
-static void BM_is_loggable(benchmark::State& state) {
-  static const char logd[] = "logd";
-
-  while (state.KeepRunning()) {
-    __android_log_is_loggable_len(ANDROID_LOG_WARN, logd, strlen(logd),
-                                  ANDROID_LOG_VERBOSE);
-  }
-}
-BENCHMARK(BM_is_loggable);
-
-/*
- *	Measure the time it takes for __android_log_security.
- */
-static void BM_security(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    __android_log_security();
-  }
-}
-BENCHMARK(BM_security);
-
-// Keep maps around for multiple iterations
-static std::unordered_set<uint32_t> set;
-static EventTagMap* map;
-
-static bool prechargeEventMap() {
-  if (map) return true;
-
-  fprintf(stderr, "Precharge: start\n");
-
-  map = android_openEventTagMap(NULL);
-  for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) {
-    size_t len;
-    if (android_lookupEventTag_len(map, &len, tag) == NULL) continue;
-    set.insert(tag);
-  }
-
-  fprintf(stderr, "Precharge: stop %zu\n", set.size());
-
-  return true;
-}
-
-/*
- *	Measure the time it takes for android_lookupEventTag_len
- */
-static void BM_lookupEventTag(benchmark::State& state) {
-  prechargeEventMap();
-
-  std::unordered_set<uint32_t>::const_iterator it = set.begin();
-
-  while (state.KeepRunning()) {
-    size_t len;
-    android_lookupEventTag_len(map, &len, (*it));
-    ++it;
-    if (it == set.end()) it = set.begin();
-  }
-}
-BENCHMARK(BM_lookupEventTag);
-
-/*
- *	Measure the time it takes for android_lookupEventTag_len
- */
-static uint32_t notTag = 1;
-
-static void BM_lookupEventTag_NOT(benchmark::State& state) {
-  prechargeEventMap();
-
-  while (set.find(notTag) != set.end()) {
-    ++notTag;
-    if (notTag >= USHRT_MAX) notTag = 1;
-  }
-
-  while (state.KeepRunning()) {
-    size_t len;
-    android_lookupEventTag_len(map, &len, notTag);
-  }
-
-  ++notTag;
-  if (notTag >= USHRT_MAX) notTag = 1;
-}
-BENCHMARK(BM_lookupEventTag_NOT);
-
-/*
- *	Measure the time it takes for android_lookupEventFormat_len
- */
-static void BM_lookupEventFormat(benchmark::State& state) {
-  prechargeEventMap();
-
-  std::unordered_set<uint32_t>::const_iterator it = set.begin();
-
-  while (state.KeepRunning()) {
-    size_t len;
-    android_lookupEventFormat_len(map, &len, (*it));
-    ++it;
-    if (it == set.end()) it = set.begin();
-  }
-}
-BENCHMARK(BM_lookupEventFormat);
-
-// Must be functionally identical to liblog internal SendLogdControlMessage()
-static void send_to_control(char* buf, size_t len) {
-  int sock =
-      socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM | SOCK_CLOEXEC);
-  if (sock < 0) return;
-  size_t writeLen = strlen(buf) + 1;
-
-  ssize_t ret = TEMP_FAILURE_RETRY(write(sock, buf, writeLen));
-  if (ret <= 0) {
-    close(sock);
-    return;
-  }
-  while ((ret = read(sock, buf, len)) > 0) {
-    if (((size_t)ret == len) || (len < PAGE_SIZE)) {
-      break;
-    }
-    len -= ret;
-    buf += ret;
-
-    struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 };
-
-    ret = poll(&p, 1, 20);
-    if ((ret <= 0) || !(p.revents & POLLIN)) {
-      break;
-    }
-  }
-  close(sock);
-}
-
-static void BM_lookupEventTagNum_logd_new(benchmark::State& state) {
-  fprintf(stderr,
-          "WARNING: "
-          "This test can cause logd to grow in size and hit DOS limiter\n");
-  // Make copies
-  static const char empty_event_log_tags[] = "# content owned by logd\n";
-  static const char dev_event_log_tags_path[] = "/dev/event-log-tags";
-  std::string dev_event_log_tags;
-  if (android::base::ReadFileToString(dev_event_log_tags_path,
-                                      &dev_event_log_tags) &&
-      (dev_event_log_tags.length() == 0)) {
-    dev_event_log_tags = empty_event_log_tags;
-  }
-  static const char data_event_log_tags_path[] =
-      "/data/misc/logd/event-log-tags";
-  std::string data_event_log_tags;
-  if (android::base::ReadFileToString(data_event_log_tags_path,
-                                      &data_event_log_tags) &&
-      (data_event_log_tags.length() == 0)) {
-    data_event_log_tags = empty_event_log_tags;
-  }
-
-  while (state.KeepRunning()) {
-    char buffer[256];
-    memset(buffer, 0, sizeof(buffer));
-    log_time now(CLOCK_MONOTONIC);
-    char name[64];
-    snprintf(name, sizeof(name), "a%" PRIu64, now.nsec());
-    snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"",
-             name);
-    state.ResumeTiming();
-    send_to_control(buffer, sizeof(buffer));
-    state.PauseTiming();
-  }
-
-  // Restore copies (logd still know about them, until crash or reboot)
-  if (dev_event_log_tags.length() &&
-      !android::base::WriteStringToFile(dev_event_log_tags,
-                                        dev_event_log_tags_path)) {
-    fprintf(stderr,
-            "WARNING: "
-            "failed to restore %s\n",
-            dev_event_log_tags_path);
-  }
-  if (data_event_log_tags.length() &&
-      !android::base::WriteStringToFile(data_event_log_tags,
-                                        data_event_log_tags_path)) {
-    fprintf(stderr,
-            "WARNING: "
-            "failed to restore %s\n",
-            data_event_log_tags_path);
-  }
-  fprintf(stderr,
-          "WARNING: "
-          "Restarting logd to make it forget what we just did\n");
-  system("stop logd ; start logd");
-}
-BENCHMARK(BM_lookupEventTagNum_logd_new);
-
-static void BM_lookupEventTagNum_logd_existing(benchmark::State& state) {
-  prechargeEventMap();
-
-  std::unordered_set<uint32_t>::const_iterator it = set.begin();
-
-  while (state.KeepRunning()) {
-    size_t len;
-    const char* name = android_lookupEventTag_len(map, &len, (*it));
-    std::string Name(name, len);
-    const char* format = android_lookupEventFormat_len(map, &len, (*it));
-    std::string Format(format, len);
-
-    char buffer[256];
-    snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"%s\"",
-             Name.c_str(), Format.c_str());
-
-    state.ResumeTiming();
-    send_to_control(buffer, sizeof(buffer));
-    state.PauseTiming();
-    ++it;
-    if (it == set.end()) it = set.begin();
-  }
-}
-BENCHMARK(BM_lookupEventTagNum_logd_existing);
-
-static void BM_log_verbose_overhead(benchmark::State& state) {
-  std::string test_log_tag = "liblog_verbose_tag";
-  android::base::SetProperty("log.tag." + test_log_tag, "I");
-  for (auto _ : state) {
-    __android_log_print(ANDROID_LOG_VERBOSE, test_log_tag.c_str(), "%s test log message %d %d",
-                        "test test", 123, 456);
-  }
-  android::base::SetProperty("log.tag." + test_log_tag, "");
-}
-BENCHMARK(BM_log_verbose_overhead);
diff --git a/liblog/tests/liblog_default_tag.cpp b/liblog/tests/liblog_default_tag.cpp
deleted file mode 100644
index 31b7467..0000000
--- a/liblog/tests/liblog_default_tag.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-// LOG_TAG must be unset for android-base's logging to use a default tag.
-#undef LOG_TAG
-
-#include <stdlib.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/scopeguard.h>
-#include <android/log.h>
-
-#include <gtest/gtest.h>
-
-#ifndef __ANDROID__
-static const char* getprogname() {
-  return program_invocation_short_name;
-}
-#endif
-
-TEST(liblog_default_tag, no_default_tag_libbase_write_first) {
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_tag = "";
-  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
-    message_seen = true;
-    EXPECT_EQ(expected_tag, tag);
-  });
-
-  expected_tag = getprogname();
-  LOG(WARNING) << "message";
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_default_tag, no_default_tag_liblog_write_first) {
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_tag = "";
-  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
-    message_seen = true;
-    EXPECT_EQ(expected_tag, tag);
-  });
-
-  expected_tag = getprogname();
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  LOG(WARNING) << "message";
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_default_tag, libbase_sets_default_tag) {
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_tag = "libbase_test_tag";
-  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
-    message_seen = true;
-    EXPECT_EQ(expected_tag, tag);
-  });
-  SetDefaultTag(expected_tag);
-
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  LOG(WARNING) << "message";
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_default_tag, liblog_sets_default_tag) {
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_tag = "liblog_test_tag";
-  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
-    message_seen = true;
-    EXPECT_EQ(expected_tag, tag);
-  });
-  __android_log_set_default_tag(expected_tag.c_str());
-
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  LOG(WARNING) << "message";
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_default_tag, default_tag_plus_log_severity) {
-#ifdef __ANDROID__
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_tag = "liblog_test_tag";
-  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
-    message_seen = true;
-    EXPECT_EQ(expected_tag, tag);
-  });
-  __android_log_set_default_tag(expected_tag.c_str());
-
-  auto log_tag_property = "log.tag." + expected_tag;
-  SetProperty(log_tag_property, "V");
-  auto reset_tag_property_guard = make_scope_guard([=] { SetProperty(log_tag_property, ""); });
-
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message");
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  LOG(VERBOSE) << "message";
-  EXPECT_TRUE(message_seen);
-#else
-  GTEST_SKIP() << "No log tag properties on host";
-#endif
-}
-
-TEST(liblog_default_tag, generated_default_tag_plus_log_severity) {
-#ifdef __ANDROID__
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_tag = getprogname();
-  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
-    message_seen = true;
-    EXPECT_EQ(expected_tag, tag);
-  });
-
-  // Even without any calls to SetDefaultTag(), the first message that attempts to log, will
-  // generate a default tag from getprogname() and check log.tag.<default tag> for loggability. This
-  // case checks that we can log a Verbose message when log.tag.<getprogname()> is set to 'V'.
-  auto log_tag_property = "log.tag." + expected_tag;
-  SetProperty(log_tag_property, "V");
-  auto reset_tag_property_guard = make_scope_guard([=] { SetProperty(log_tag_property, ""); });
-
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message");
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  LOG(VERBOSE) << "message";
-  EXPECT_TRUE(message_seen);
-#else
-  GTEST_SKIP() << "No log tag properties on host";
-#endif
-}
\ No newline at end of file
diff --git a/liblog/tests/liblog_global_state.cpp b/liblog/tests/liblog_global_state.cpp
deleted file mode 100644
index 1d7ff9f..0000000
--- a/liblog/tests/liblog_global_state.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#define LOG_TAG "global_state_test_tag"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android/log.h>
-
-#include <gtest/gtest.h>
-
-TEST(liblog_global_state, libbase_logs_with_libbase_SetLogger) {
-  using namespace android::base;
-  bool message_seen = false;
-  LogSeverity expected_severity = WARNING;
-  std::string expected_file = Basename(__FILE__);
-  unsigned int expected_line;
-  std::string expected_message = "libbase test message";
-
-  auto LoggerFunction = [&](LogId log_id, LogSeverity severity, const char* tag, const char* file,
-                            unsigned int line, const char* message) {
-    message_seen = true;
-    EXPECT_EQ(DEFAULT, log_id);
-    EXPECT_EQ(expected_severity, severity);
-    EXPECT_STREQ(LOG_TAG, tag);
-    EXPECT_EQ(expected_file, file);
-    EXPECT_EQ(expected_line, line);
-    EXPECT_EQ(expected_message, message);
-  };
-
-  SetLogger(LoggerFunction);
-
-  expected_line = __LINE__ + 1;
-  LOG(expected_severity) << expected_message;
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_global_state, libbase_logs_with_liblog_set_logger) {
-  using namespace android::base;
-  // These must be static since they're used by the liblog logger function, which only accepts
-  // lambdas without captures.  The items used by the libbase logger are explicitly not static, to
-  // ensure that lambdas with captures do work there.
-  static bool message_seen = false;
-  static std::string expected_file = Basename(__FILE__);
-  static unsigned int expected_line;
-  static std::string expected_message = "libbase test message";
-
-  auto liblog_logger_function = [](const struct __android_log_message* log_message) {
-    message_seen = true;
-    EXPECT_EQ(sizeof(__android_log_message), log_message->struct_size);
-    EXPECT_EQ(LOG_ID_DEFAULT, log_message->buffer_id);
-    EXPECT_EQ(ANDROID_LOG_WARN, log_message->priority);
-    EXPECT_STREQ(LOG_TAG, log_message->tag);
-    EXPECT_EQ(expected_file, log_message->file);
-    EXPECT_EQ(expected_line, log_message->line);
-    EXPECT_EQ(expected_message, log_message->message);
-  };
-
-  __android_log_set_logger(liblog_logger_function);
-
-  expected_line = __LINE__ + 1;
-  LOG(WARNING) << expected_message;
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_global_state, liblog_logs_with_libbase_SetLogger) {
-  using namespace android::base;
-  bool message_seen = false;
-  std::string expected_message = "libbase test message";
-
-  auto LoggerFunction = [&](LogId log_id, LogSeverity severity, const char* tag, const char* file,
-                            unsigned int line, const char* message) {
-    message_seen = true;
-    EXPECT_EQ(MAIN, log_id);
-    EXPECT_EQ(WARNING, severity);
-    EXPECT_STREQ(LOG_TAG, tag);
-    EXPECT_EQ(nullptr, file);
-    EXPECT_EQ(0U, line);
-    EXPECT_EQ(expected_message, message);
-  };
-
-  SetLogger(LoggerFunction);
-
-  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, LOG_TAG, expected_message.c_str());
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-}
-
-TEST(liblog_global_state, liblog_logs_with_liblog_set_logger) {
-  using namespace android::base;
-  // These must be static since they're used by the liblog logger function, which only accepts
-  // lambdas without captures.  The items used by the libbase logger are explicitly not static, to
-  // ensure that lambdas with captures do work there.
-  static bool message_seen = false;
-  static int expected_buffer_id = LOG_ID_MAIN;
-  static int expected_priority = ANDROID_LOG_WARN;
-  static std::string expected_message = "libbase test message";
-
-  auto liblog_logger_function = [](const struct __android_log_message* log_message) {
-    message_seen = true;
-    EXPECT_EQ(sizeof(__android_log_message), log_message->struct_size);
-    EXPECT_EQ(expected_buffer_id, log_message->buffer_id);
-    EXPECT_EQ(expected_priority, log_message->priority);
-    EXPECT_STREQ(LOG_TAG, log_message->tag);
-    EXPECT_STREQ(nullptr, log_message->file);
-    EXPECT_EQ(0U, log_message->line);
-    EXPECT_EQ(expected_message, log_message->message);
-  };
-
-  __android_log_set_logger(liblog_logger_function);
-
-  __android_log_buf_write(expected_buffer_id, expected_priority, LOG_TAG, expected_message.c_str());
-  EXPECT_TRUE(message_seen);
-}
-
-TEST(liblog_global_state, SetAborter_with_liblog) {
-  using namespace android::base;
-
-  std::string expected_message = "libbase test message";
-  static bool message_seen = false;
-  auto aborter_function = [&](const char* message) {
-    message_seen = true;
-    EXPECT_EQ(expected_message, message);
-  };
-
-  SetAborter(aborter_function);
-  LOG(FATAL) << expected_message;
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-
-  static std::string expected_message_static = "libbase test message";
-  auto liblog_aborter_function = [](const char* message) {
-    message_seen = true;
-    EXPECT_EQ(expected_message_static, message);
-  };
-  __android_log_set_aborter(liblog_aborter_function);
-  LOG(FATAL) << expected_message_static;
-  EXPECT_TRUE(message_seen);
-  message_seen = false;
-}
-
-static std::string UniqueLogTag() {
-  std::string tag = LOG_TAG;
-  tag += "-" + std::to_string(getpid());
-  return tag;
-}
-
-TEST(liblog_global_state, is_loggable_both_default) {
-  auto tag = UniqueLogTag();
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-}
-
-TEST(liblog_global_state, is_loggable_minimum_log_priority_only) {
-  auto tag = UniqueLogTag();
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  EXPECT_EQ(ANDROID_LOG_DEFAULT, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  EXPECT_EQ(ANDROID_LOG_DEBUG, __android_log_set_minimum_priority(ANDROID_LOG_WARN));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  EXPECT_EQ(android::base::WARNING, android::base::SetMinimumLogSeverity(android::base::DEBUG));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  EXPECT_EQ(android::base::DEBUG, android::base::SetMinimumLogSeverity(android::base::WARNING));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-}
-
-TEST(liblog_global_state, is_loggable_tag_log_priority_only) {
-#ifdef __ANDROID__
-  auto tag = UniqueLogTag();
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  auto log_tag_property = std::string("log.tag.") + tag;
-  ASSERT_TRUE(android::base::SetProperty(log_tag_property, "d"));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  ASSERT_TRUE(android::base::SetProperty(log_tag_property, "w"));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  ASSERT_TRUE(android::base::SetProperty(log_tag_property, ""));
-#else
-  GTEST_SKIP() << "No log tag properties on host";
-#endif
-}
-
-TEST(liblog_global_state, is_loggable_both_set) {
-#ifdef __ANDROID__
-  auto tag = UniqueLogTag();
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  // When both a tag and a minimum priority are set, we use the lower value of the two.
-
-  // tag = warning, minimum_priority = debug, expect 'debug'
-  auto log_tag_property = std::string("log.tag.") + tag;
-  ASSERT_TRUE(android::base::SetProperty(log_tag_property, "w"));
-  EXPECT_EQ(ANDROID_LOG_DEFAULT, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  // tag = warning, minimum_priority = warning, expect 'warning'
-  EXPECT_EQ(ANDROID_LOG_DEBUG, __android_log_set_minimum_priority(ANDROID_LOG_WARN));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  // tag = debug, minimum_priority = warning, expect 'debug'
-  ASSERT_TRUE(android::base::SetProperty(log_tag_property, "d"));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  // tag = debug, minimum_priority = debug, expect 'debug'
-  EXPECT_EQ(ANDROID_LOG_WARN, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
-
-  ASSERT_TRUE(android::base::SetProperty(log_tag_property, ""));
-#else
-  GTEST_SKIP() << "No log tag properties on host";
-#endif
-}
diff --git a/liblog/tests/liblog_host_test.cpp b/liblog/tests/liblog_host_test.cpp
deleted file mode 100644
index ec186d4..0000000
--- a/liblog/tests/liblog_host_test.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2019 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 <log/log.h>
-#include <private/android_logger.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <regex>
-#include <string>
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/stringprintf.h>
-#include <android-base/test_utils.h>
-#include <gtest/gtest.h>
-
-using android::base::InitLogging;
-using android::base::StderrLogger;
-using android::base::StringPrintf;
-
-static std::string MakeLogPattern(int priority, const char* tag, const char* message) {
-  static const char log_characters[] = "XXVDIWEF";
-  static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT,
-                "Mismatch in size of log_characters and values in android_LogPriority");
-  priority = priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : priority;
-  char log_char = log_characters[priority];
-
-  return StringPrintf("%s %c \\d+-\\d+ \\d+:\\d+:\\d+ \\s*\\d+ \\s*\\d+ %s", tag, log_char,
-                      message);
-}
-
-static void CheckMessage(bool expected, const std::string& output, int priority, const char* tag,
-                         const char* message) {
-  std::regex message_regex(MakeLogPattern(priority, tag, message));
-  EXPECT_EQ(expected, std::regex_search(output, message_regex)) << message;
-}
-
-static void GenerateLogContent() {
-  __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, "tag", "verbose main");
-  __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, "tag", "info main");
-  __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_ERROR, "tag", "error main");
-
-  __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, "tag", "verbose radio");
-  __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, "tag", "info radio");
-  __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, "tag", "error radio");
-
-  __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, "tag", "verbose system");
-  __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, "tag", "info system");
-  __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, "tag", "error system");
-
-  __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, "tag", "verbose crash");
-  __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_INFO, "tag", "info crash");
-  __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_ERROR, "tag", "error crash");
-}
-
-std::string GetPidString() {
-  int pid = getpid();
-  return StringPrintf("%5d", pid);
-}
-
-TEST(liblog, default_write) {
-  CapturedStderr captured_stderr;
-  InitLogging(nullptr, StderrLogger);
-
-  GenerateLogContent();
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main");
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio");
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system");
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash");
-}
-
-TEST(liblog, verbose_write) {
-  setenv("ANDROID_LOG_TAGS", "*:v", true);
-  CapturedStderr captured_stderr;
-  InitLogging(nullptr, StderrLogger);
-
-  GenerateLogContent();
-
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main");
-
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio");
-
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system");
-
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash");
-}
-
-TEST(liblog, error_write) {
-  setenv("ANDROID_LOG_TAGS", "*:e", true);
-  CapturedStderr captured_stderr;
-  InitLogging(nullptr, StderrLogger);
-
-  GenerateLogContent();
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main");
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main");
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio");
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio");
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system");
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system");
-
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash");
-  CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash");
-  CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash");
-}
-
-TEST(liblog, kernel_no_write) {
-  CapturedStderr captured_stderr;
-  InitLogging(nullptr, StderrLogger);
-  __android_log_buf_print(LOG_ID_KERNEL, ANDROID_LOG_ERROR, "tag", "kernel error");
-  EXPECT_EQ("", captured_stderr.str());
-}
-
-TEST(liblog, binary_no_write) {
-  CapturedStderr captured_stderr;
-  InitLogging(nullptr, StderrLogger);
-  __android_log_buf_print(LOG_ID_EVENTS, ANDROID_LOG_ERROR, "tag", "error events");
-  __android_log_buf_print(LOG_ID_STATS, ANDROID_LOG_ERROR, "tag", "error stats");
-  __android_log_buf_print(LOG_ID_SECURITY, ANDROID_LOG_ERROR, "tag", "error security");
-
-  __android_log_bswrite(0x12, "events");
-  __android_log_stats_bwrite(0x34, "stats", strlen("stats"));
-  __android_log_security_bswrite(0x56, "security");
-
-  EXPECT_EQ("", captured_stderr.str());
-}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
deleted file mode 100644
index c49d87b..0000000
--- a/liblog/tests/liblog_test.cpp
+++ /dev/null
@@ -1,2770 +0,0 @@
-/*
- * Copyright (C) 2013-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 <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-#include <android-base/scopeguard.h>
-#include <android-base/stringprintf.h>
-#ifdef __ANDROID__  // includes sys/properties.h which does not exist outside
-#include <cutils/properties.h>
-#endif
-#include <gtest/gtest.h>
-#include <log/log_event_list.h>
-#include <log/log_properties.h>
-#include <log/log_read.h>
-#include <log/logprint.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-using android::base::make_scope_guard;
-
-// #define ENABLE_FLAKY_TESTS
-
-// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
-// non-syscall libs. Since we are only using this in the emergency of
-// a signal to stuff a terminating code into the logs, we will spin rather
-// than try a usleep.
-#define LOG_FAILURE_RETRY(exp)                                           \
-  ({                                                                     \
-    typeof(exp) _rc;                                                     \
-    do {                                                                 \
-      _rc = (exp);                                                       \
-    } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \
-             (_rc == -EINTR) || (_rc == -EAGAIN));                       \
-    _rc;                                                                 \
-  })
-
-// std::unique_ptr doesn't let you provide a pointer to a deleter (android_logger_list_close()) if
-// the type (struct logger_list) is an incomplete type, so we create ListCloser instead.
-struct ListCloser {
-  void operator()(struct logger_list* list) { android_logger_list_close(list); }
-};
-
-// This function is meant to be used for most log tests, it does the following:
-// 1) Open the log_buffer with a blocking reader
-// 2) Write the messages via write_messages
-// 3) Set an alarm for 2 seconds as a timeout
-// 4) Read until check_message returns true, which should be used to indicate the target message
-//    is found
-// 5) Open log_buffer with a non_blocking reader and dump all messages
-// 6) Count the number of times check_messages returns true for these messages and assert it's
-//    only 1.
-template <typename FWrite, typename FCheck>
-static void RunLogTests(log_id_t log_buffer, FWrite write_messages, FCheck check_message) {
-  pid_t pid = getpid();
-
-  auto logger_list = std::unique_ptr<struct logger_list, ListCloser>{
-      android_logger_list_open(log_buffer, 0, 1000, pid)};
-  ASSERT_TRUE(logger_list);
-
-  write_messages();
-
-  alarm(2);
-  auto alarm_guard = android::base::make_scope_guard([] { alarm(0); });
-  bool found = false;
-  while (!found) {
-    log_msg log_msg;
-    ASSERT_GT(android_logger_list_read(logger_list.get(), &log_msg), 0);
-
-    ASSERT_EQ(log_buffer, log_msg.id());
-    ASSERT_EQ(pid, log_msg.entry.pid);
-
-    ASSERT_NE(nullptr, log_msg.msg());
-
-    check_message(log_msg, &found);
-  }
-
-  auto logger_list_non_block = std::unique_ptr<struct logger_list, ListCloser>{
-      android_logger_list_open(log_buffer, ANDROID_LOG_NONBLOCK, 1000, pid)};
-  ASSERT_TRUE(logger_list_non_block);
-
-  size_t count = 0;
-  while (true) {
-    log_msg log_msg;
-    auto ret = android_logger_list_read(logger_list_non_block.get(), &log_msg);
-    if (ret == -EAGAIN) {
-      break;
-    }
-    ASSERT_GT(ret, 0);
-
-    ASSERT_EQ(log_buffer, log_msg.id());
-    ASSERT_EQ(pid, log_msg.entry.pid);
-
-    ASSERT_NE(nullptr, log_msg.msg());
-
-    found = false;
-    check_message(log_msg, &found);
-    if (found) {
-      ++count;
-    }
-  }
-
-  EXPECT_EQ(1U, count);
-}
-
-TEST(liblog, __android_log_btwrite) {
-  int intBuf = 0xDEADBEEF;
-  EXPECT_LT(0,
-            __android_log_btwrite(0, EVENT_TYPE_INT, &intBuf, sizeof(intBuf)));
-  long long longBuf = 0xDEADBEEFA55A5AA5;
-  EXPECT_LT(
-      0, __android_log_btwrite(0, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf)));
-  char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
-  EXPECT_LT(0,
-            __android_log_btwrite(0, EVENT_TYPE_STRING, Buf, sizeof(Buf) - 1));
-}
-
-#if defined(__ANDROID__)
-static std::string popenToString(const std::string& command) {
-  std::string ret;
-
-  FILE* fp = popen(command.c_str(), "re");
-  if (fp) {
-    if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = "";
-    pclose(fp);
-  }
-  return ret;
-}
-
-static bool isPmsgActive() {
-  pid_t pid = getpid();
-
-  std::string myPidFds =
-      popenToString(android::base::StringPrintf("ls -l /proc/%d/fd", pid));
-  if (myPidFds.length() == 0) return true;  // guess it is?
-
-  return std::string::npos != myPidFds.find(" -> /dev/pmsg0");
-}
-
-static bool isLogdwActive() {
-  std::string logdwSignature =
-      popenToString("grep -a /dev/socket/logdw /proc/net/unix");
-  size_t beginning = logdwSignature.find(' ');
-  if (beginning == std::string::npos) return true;
-  beginning = logdwSignature.find(' ', beginning + 1);
-  if (beginning == std::string::npos) return true;
-  size_t end = logdwSignature.find(' ', beginning + 1);
-  if (end == std::string::npos) return true;
-  end = logdwSignature.find(' ', end + 1);
-  if (end == std::string::npos) return true;
-  end = logdwSignature.find(' ', end + 1);
-  if (end == std::string::npos) return true;
-  end = logdwSignature.find(' ', end + 1);
-  if (end == std::string::npos) return true;
-  std::string allLogdwEndpoints = popenToString(
-      "grep -a ' 00000002" + logdwSignature.substr(beginning, end - beginning) +
-      " ' /proc/net/unix | " +
-      "sed -n 's/.* \\([0-9][0-9]*\\)$/ -> socket:[\\1]/p'");
-  if (allLogdwEndpoints.length() == 0) return true;
-
-  // NB: allLogdwEndpoints has some false positives in it, but those
-  // strangers do not overlap with the simplistic activities inside this
-  // test suite.
-
-  pid_t pid = getpid();
-
-  std::string myPidFds =
-      popenToString(android::base::StringPrintf("ls -l /proc/%d/fd", pid));
-  if (myPidFds.length() == 0) return true;
-
-  // NB: fgrep with multiple strings is broken in Android
-  for (beginning = 0;
-       (end = allLogdwEndpoints.find('\n', beginning)) != std::string::npos;
-       beginning = end + 1) {
-    if (myPidFds.find(allLogdwEndpoints.substr(beginning, end - beginning)) !=
-        std::string::npos)
-      return true;
-  }
-  return false;
-}
-
-static bool tested__android_log_close;
-#endif
-
-TEST(liblog, __android_log_btwrite__android_logger_list_read) {
-#ifdef __ANDROID__
-  log_time ts(CLOCK_MONOTONIC);
-  log_time ts1(ts);
-
-  bool has_pstore = access("/dev/pmsg0", W_OK) == 0;
-
-  auto write_function = [&] {
-    EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-    // Check that we can close and reopen the logger
-    bool logdwActiveAfter__android_log_btwrite;
-    if (getuid() == AID_ROOT) {
-      tested__android_log_close = true;
-      if (has_pstore) {
-        bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
-        EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
-      }
-      logdwActiveAfter__android_log_btwrite = isLogdwActive();
-      EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
-    } else if (!tested__android_log_close) {
-      fprintf(stderr, "WARNING: can not test __android_log_close()\n");
-    }
-    __android_log_close();
-    if (getuid() == AID_ROOT) {
-      if (has_pstore) {
-        bool pmsgActiveAfter__android_log_close = isPmsgActive();
-        EXPECT_FALSE(pmsgActiveAfter__android_log_close);
-      }
-      bool logdwActiveAfter__android_log_close = isLogdwActive();
-      EXPECT_FALSE(logdwActiveAfter__android_log_close);
-    }
-
-    ts1 = log_time(CLOCK_MONOTONIC);
-    EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
-    if (getuid() == AID_ROOT) {
-      if (has_pstore) {
-        bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
-        EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
-      }
-      logdwActiveAfter__android_log_btwrite = isLogdwActive();
-      EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
-    }
-  };
-
-  int count = 0;
-  int second_count = 0;
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    if ((log_msg.entry.len != sizeof(android_log_event_long_t)) ||
-        (log_msg.id() != LOG_ID_EVENTS)) {
-      return;
-    }
-
-    android_log_event_long_t* eventData;
-    eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
-
-    if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
-      return;
-    }
-
-    log_time* tx = reinterpret_cast<log_time*>(&eventData->payload.data);
-    if (ts == *tx) {
-      ++count;
-    } else if (ts1 == *tx) {
-      ++second_count;
-    }
-
-    if (count == 1 && second_count == 1) {
-      count = 0;
-      second_count = 0;
-      *found = true;
-    }
-  };
-
-  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
-
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, __android_log_write__android_logger_list_read) {
-#ifdef __ANDROID__
-  pid_t pid = getpid();
-
-  struct timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld", pid, ts.tv_sec, ts.tv_nsec);
-  static const char tag[] = "liblog.__android_log_write__android_logger_list_read";
-  static const char prio = ANDROID_LOG_DEBUG;
-
-  std::string expected_message =
-      std::string(&prio, sizeof(prio)) + tag + std::string("", 1) + buf + std::string("", 1);
-
-  auto write_function = [&] { ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str())); };
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    if (log_msg.entry.len != expected_message.length()) {
-      return;
-    }
-
-    if (expected_message != std::string(log_msg.msg(), log_msg.entry.len)) {
-      return;
-    }
-
-    *found = true;
-  };
-
-  RunLogTests(LOG_ID_MAIN, write_function, check_function);
-
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-static void bswrite_test(const char* message) {
-#ifdef __ANDROID__
-  pid_t pid = getpid();
-
-  size_t num_lines = 1, size = 0, length = 0, total = 0;
-  const char* cp = message;
-  while (*cp) {
-    if (*cp == '\n') {
-      if (cp[1]) {
-        ++num_lines;
-      }
-    } else {
-      ++size;
-    }
-    ++cp;
-    ++total;
-    ++length;
-    if ((LOGGER_ENTRY_MAX_PAYLOAD - 4 - 1 - 4) <= length) {
-      break;
-    }
-  }
-  while (*cp) {
-    ++cp;
-    ++total;
-  }
-
-  auto write_function = [&] { EXPECT_LT(0, __android_log_bswrite(0, message)); };
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    if ((size_t)log_msg.entry.len != (sizeof(android_log_event_string_t) + length) ||
-        log_msg.id() != LOG_ID_EVENTS) {
-      return;
-    }
-
-    android_log_event_string_t* eventData;
-    eventData = reinterpret_cast<android_log_event_string_t*>(log_msg.msg());
-
-    if (!eventData || (eventData->type != EVENT_TYPE_STRING)) {
-      return;
-    }
-
-    size_t len = eventData->length;
-    if (len == total) {
-      *found = true;
-
-      AndroidLogFormat* logformat = android_log_format_new();
-      EXPECT_TRUE(NULL != logformat);
-      AndroidLogEntry entry;
-      char msgBuf[1024];
-      if (length != total) {
-        fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n");
-      }
-      int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
-          &log_msg.entry, &entry, nullptr, msgBuf, sizeof(msgBuf));
-      EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
-      if ((processBinaryLogBuffer == 0) || entry.message) {
-        size_t line_overhead = 20;
-        if (pid > 99999) ++line_overhead;
-        if (pid > 999999) ++line_overhead;
-        fflush(stderr);
-        if (processBinaryLogBuffer) {
-          EXPECT_GT((int)((line_overhead * num_lines) + size),
-                    android_log_printLogLine(logformat, fileno(stderr), &entry));
-        } else {
-          EXPECT_EQ((int)((line_overhead * num_lines) + size),
-                    android_log_printLogLine(logformat, fileno(stderr), &entry));
-        }
-      }
-      android_log_format_free(logformat);
-    }
-  };
-
-  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
-
-#else
-  message = NULL;
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, __android_log_bswrite_and_print) {
-  bswrite_test("Hello World");
-}
-
-TEST(liblog, __android_log_bswrite_and_print__empty_string) {
-  bswrite_test("");
-}
-
-TEST(liblog, __android_log_bswrite_and_print__newline_prefix) {
-  bswrite_test("\nHello World\n");
-}
-
-TEST(liblog, __android_log_bswrite_and_print__newline_space_prefix) {
-  bswrite_test("\n Hello World \n");
-}
-
-TEST(liblog, __android_log_bswrite_and_print__multiple_newline) {
-  bswrite_test("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten");
-}
-
-static void buf_write_test(const char* message) {
-#ifdef __ANDROID__
-  pid_t pid = getpid();
-
-  static const char tag[] = "TEST__android_log_buf_write";
-
-  auto write_function = [&] {
-    EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, tag, message));
-  };
-  size_t num_lines = 1, size = 0, length = 0;
-  const char* cp = message;
-  while (*cp) {
-    if (*cp == '\n') {
-      if (cp[1]) {
-        ++num_lines;
-      }
-    } else {
-      ++size;
-    }
-    ++length;
-    if ((LOGGER_ENTRY_MAX_PAYLOAD - 2 - sizeof(tag)) <= length) {
-      break;
-    }
-    ++cp;
-  }
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    if ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2) || log_msg.id() != LOG_ID_MAIN) {
-      return;
-    }
-
-    *found = true;
-
-    AndroidLogFormat* logformat = android_log_format_new();
-    EXPECT_TRUE(NULL != logformat);
-    AndroidLogEntry entry;
-    int processLogBuffer = android_log_processLogBuffer(&log_msg.entry, &entry);
-    EXPECT_EQ(0, processLogBuffer);
-    if (processLogBuffer == 0) {
-      size_t line_overhead = 11;
-      if (pid > 99999) ++line_overhead;
-      if (pid > 999999) ++line_overhead;
-      fflush(stderr);
-      EXPECT_EQ((int)(((line_overhead + sizeof(tag)) * num_lines) + size),
-                android_log_printLogLine(logformat, fileno(stderr), &entry));
-    }
-    android_log_format_free(logformat);
-  };
-
-  RunLogTests(LOG_ID_MAIN, write_function, check_function);
-
-#else
-  message = NULL;
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, __android_log_buf_write_and_print__empty) {
-  buf_write_test("");
-}
-
-TEST(liblog, __android_log_buf_write_and_print__newline_prefix) {
-  buf_write_test("\nHello World\n");
-}
-
-TEST(liblog, __android_log_buf_write_and_print__newline_space_prefix) {
-  buf_write_test("\n Hello World \n");
-}
-
-#ifdef ENABLE_FLAKY_TESTS
-#ifdef __ANDROID__
-static unsigned signaled;
-static log_time signal_time;
-
-/*
- *  Strictly, we are not allowed to log messages in a signal context, but we
- * do make an effort to keep the failure surface minimized, and this in-effect
- * should catch any regressions in that effort. The odds of a logged message
- * in a signal handler causing a lockup problem should be _very_ small.
- */
-static void caught_blocking_signal(int /*signum*/) {
-  unsigned long long v = 0xDEADBEEFA55A0000ULL;
-
-  v += getpid() & 0xFFFF;
-
-  ++signaled;
-  if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
-    signal_time = log_time(CLOCK_MONOTONIC);
-    signal_time.tv_sec += 2;
-  }
-
-  LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-}
-
-// Fill in current process user and system time in 10ms increments
-static void get_ticks(unsigned long long* uticks, unsigned long long* sticks) {
-  *uticks = *sticks = 0;
-
-  pid_t pid = getpid();
-
-  char buffer[512];
-  snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
-
-  FILE* fp = fopen(buffer, "re");
-  if (!fp) {
-    return;
-  }
-
-  char* cp = fgets(buffer, sizeof(buffer), fp);
-  fclose(fp);
-  if (!cp) {
-    return;
-  }
-
-  pid_t d;
-  char s[sizeof(buffer)];
-  char c;
-  long long ll;
-  unsigned long long ull;
-
-  if (15 != sscanf(buffer,
-                   "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu "
-                   "%llu %llu ",
-                   &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull,
-                   &ull, uticks, sticks)) {
-    *uticks = *sticks = 0;
-  }
-}
-#endif
-
-TEST(liblog, android_logger_list_read__cpu_signal) {
-#ifdef __ANDROID__
-  struct logger_list* logger_list;
-  unsigned long long v = 0xDEADBEEFA55A0000ULL;
-
-  pid_t pid = getpid();
-
-  v += pid & 0xFFFF;
-
-  ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 1000, pid)));
-
-  int count = 0;
-
-  int signals = 0;
-
-  unsigned long long uticks_start;
-  unsigned long long sticks_start;
-  get_ticks(&uticks_start, &sticks_start);
-
-  const unsigned alarm_time = 10;
-
-  memset(&signal_time, 0, sizeof(signal_time));
-
-  signal(SIGALRM, caught_blocking_signal);
-  alarm(alarm_time);
-
-  signaled = 0;
-
-  do {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    alarm(alarm_time);
-
-    ++count;
-
-    ASSERT_EQ(log_msg.entry.pid, pid);
-
-    if ((log_msg.entry.len != sizeof(android_log_event_long_t)) ||
-        (log_msg.id() != LOG_ID_EVENTS)) {
-      continue;
-    }
-
-    android_log_event_long_t* eventData;
-    eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
-
-    if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
-      continue;
-    }
-
-    char* cp = reinterpret_cast<char*>(&eventData->payload.data);
-    unsigned long long l = cp[0] & 0xFF;
-    l |= (unsigned long long)(cp[1] & 0xFF) << 8;
-    l |= (unsigned long long)(cp[2] & 0xFF) << 16;
-    l |= (unsigned long long)(cp[3] & 0xFF) << 24;
-    l |= (unsigned long long)(cp[4] & 0xFF) << 32;
-    l |= (unsigned long long)(cp[5] & 0xFF) << 40;
-    l |= (unsigned long long)(cp[6] & 0xFF) << 48;
-    l |= (unsigned long long)(cp[7] & 0xFF) << 56;
-
-    if (l == v) {
-      ++signals;
-      break;
-    }
-  } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
-  alarm(0);
-  signal(SIGALRM, SIG_DFL);
-
-  EXPECT_LE(1, count);
-
-  EXPECT_EQ(1, signals);
-
-  android_logger_list_close(logger_list);
-
-  unsigned long long uticks_end;
-  unsigned long long sticks_end;
-  get_ticks(&uticks_end, &sticks_end);
-
-  // Less than 1% in either user or system time, or both
-  const unsigned long long one_percent_ticks = alarm_time;
-  unsigned long long user_ticks = uticks_end - uticks_start;
-  unsigned long long system_ticks = sticks_end - sticks_start;
-  EXPECT_GT(one_percent_ticks, user_ticks);
-  EXPECT_GT(one_percent_ticks, system_ticks);
-  EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-#ifdef __ANDROID__
-/*
- *  Strictly, we are not allowed to log messages in a signal context, the
- * correct way to handle this is to ensure the messages are constructed in
- * a thread; the signal handler should only unblock the thread.
- */
-static sem_t thread_trigger;
-
-static void caught_blocking_thread(int /*signum*/) {
-  sem_post(&thread_trigger);
-}
-
-static void* running_thread(void*) {
-  unsigned long long v = 0xDEADBEAFA55A0000ULL;
-
-  v += getpid() & 0xFFFF;
-
-  struct timespec timeout;
-  clock_gettime(CLOCK_REALTIME, &timeout);
-  timeout.tv_sec += 55;
-  sem_timedwait(&thread_trigger, &timeout);
-
-  ++signaled;
-  if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
-    signal_time = log_time(CLOCK_MONOTONIC);
-    signal_time.tv_sec += 2;
-  }
-
-  LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-
-  return NULL;
-}
-
-static int start_thread() {
-  sem_init(&thread_trigger, 0, 0);
-
-  pthread_attr_t attr;
-  if (pthread_attr_init(&attr)) {
-    return -1;
-  }
-
-  struct sched_param param;
-
-  memset(&param, 0, sizeof(param));
-  pthread_attr_setschedparam(&attr, &param);
-  pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
-
-  if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
-    pthread_attr_destroy(&attr);
-    return -1;
-  }
-
-  pthread_t thread;
-  if (pthread_create(&thread, &attr, running_thread, NULL)) {
-    pthread_attr_destroy(&attr);
-    return -1;
-  }
-
-  pthread_attr_destroy(&attr);
-  return 0;
-}
-#endif
-
-TEST(liblog, android_logger_list_read__cpu_thread) {
-#ifdef __ANDROID__
-  struct logger_list* logger_list;
-  unsigned long long v = 0xDEADBEAFA55A0000ULL;
-
-  pid_t pid = getpid();
-
-  v += pid & 0xFFFF;
-
-  ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 1000, pid)));
-
-  int count = 0;
-
-  int signals = 0;
-
-  unsigned long long uticks_start;
-  unsigned long long sticks_start;
-  get_ticks(&uticks_start, &sticks_start);
-
-  const unsigned alarm_time = 10;
-
-  memset(&signal_time, 0, sizeof(signal_time));
-
-  signaled = 0;
-  EXPECT_EQ(0, start_thread());
-
-  signal(SIGALRM, caught_blocking_thread);
-  alarm(alarm_time);
-
-  do {
-    log_msg log_msg;
-    if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) {
-      break;
-    }
-
-    alarm(alarm_time);
-
-    ++count;
-
-    ASSERT_EQ(log_msg.entry.pid, pid);
-
-    if ((log_msg.entry.len != sizeof(android_log_event_long_t)) ||
-        (log_msg.id() != LOG_ID_EVENTS)) {
-      continue;
-    }
-
-    android_log_event_long_t* eventData;
-    eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
-
-    if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
-      continue;
-    }
-
-    char* cp = reinterpret_cast<char*>(&eventData->payload.data);
-    unsigned long long l = cp[0] & 0xFF;
-    l |= (unsigned long long)(cp[1] & 0xFF) << 8;
-    l |= (unsigned long long)(cp[2] & 0xFF) << 16;
-    l |= (unsigned long long)(cp[3] & 0xFF) << 24;
-    l |= (unsigned long long)(cp[4] & 0xFF) << 32;
-    l |= (unsigned long long)(cp[5] & 0xFF) << 40;
-    l |= (unsigned long long)(cp[6] & 0xFF) << 48;
-    l |= (unsigned long long)(cp[7] & 0xFF) << 56;
-
-    if (l == v) {
-      ++signals;
-      break;
-    }
-  } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
-  alarm(0);
-  signal(SIGALRM, SIG_DFL);
-
-  EXPECT_LE(1, count);
-
-  EXPECT_EQ(1, signals);
-
-  android_logger_list_close(logger_list);
-
-  unsigned long long uticks_end;
-  unsigned long long sticks_end;
-  get_ticks(&uticks_end, &sticks_end);
-
-  // Less than 1% in either user or system time, or both
-  const unsigned long long one_percent_ticks = alarm_time;
-  unsigned long long user_ticks = uticks_end - uticks_start;
-  unsigned long long system_ticks = sticks_end - sticks_start;
-  EXPECT_GT(one_percent_ticks, user_ticks);
-  EXPECT_GT(one_percent_ticks, system_ticks);
-  EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif  // ENABLE_FLAKY_TESTS
-
-static const char max_payload_buf[] =
-    "LEONATO\n\
-I learn in this letter that Don Peter of Arragon\n\
-comes this night to Messina\n\
-MESSENGER\n\
-He is very near by this: he was not three leagues off\n\
-when I left him\n\
-LEONATO\n\
-How many gentlemen have you lost in this action?\n\
-MESSENGER\n\
-But few of any sort, and none of name\n\
-LEONATO\n\
-A victory is twice itself when the achiever brings\n\
-home full numbers. I find here that Don Peter hath\n\
-bestowed much honour on a young Florentine called Claudio\n\
-MESSENGER\n\
-Much deserved on his part and equally remembered by\n\
-Don Pedro: he hath borne himself beyond the\n\
-promise of his age, doing, in the figure of a lamb,\n\
-the feats of a lion: he hath indeed better\n\
-bettered expectation than you must expect of me to\n\
-tell you how\n\
-LEONATO\n\
-He hath an uncle here in Messina will be very much\n\
-glad of it.\n\
-MESSENGER\n\
-I have already delivered him letters, and there\n\
-appears much joy in him; even so much that joy could\n\
-not show itself modest enough without a badge of\n\
-bitterness.\n\
-LEONATO\n\
-Did he break out into tears?\n\
-MESSENGER\n\
-In great measure.\n\
-LEONATO\n\
-A kind overflow of kindness: there are no faces\n\
-truer than those that are so washed. How much\n\
-better is it to weep at joy than to joy at weeping!\n\
-BEATRICE\n\
-I pray you, is Signior Mountanto returned from the\n\
-wars or no?\n\
-MESSENGER\n\
-I know none of that name, lady: there was none such\n\
-in the army of any sort.\n\
-LEONATO\n\
-What is he that you ask for, niece?\n\
-HERO\n\
-My cousin means Signior Benedick of Padua.\n\
-MESSENGER\n\
-O, he's returned; and as pleasant as ever he was.\n\
-BEATRICE\n\
-He set up his bills here in Messina and challenged\n\
-Cupid at the flight; and my uncle's fool, reading\n\
-the challenge, subscribed for Cupid, and challenged\n\
-him at the bird-bolt. I pray you, how many hath he\n\
-killed and eaten in these wars? But how many hath\n\
-he killed? for indeed I promised to eat all of his killing.\n\
-LEONATO\n\
-Faith, niece, you tax Signior Benedick too much;\n\
-but he'll be meet with you, I doubt it not.\n\
-MESSENGER\n\
-He hath done good service, lady, in these wars.\n\
-BEATRICE\n\
-You had musty victual, and he hath holp to eat it:\n\
-he is a very valiant trencherman; he hath an\n\
-excellent stomach.\n\
-MESSENGER\n\
-And a good soldier too, lady.\n\
-BEATRICE\n\
-And a good soldier to a lady: but what is he to a lord?\n\
-MESSENGER\n\
-A lord to a lord, a man to a man; stuffed with all\n\
-honourable virtues.\n\
-BEATRICE\n\
-It is so, indeed; he is no less than a stuffed man:\n\
-but for the stuffing,--well, we are all mortal.\n\
-LEONATO\n\
-You must not, sir, mistake my niece. There is a\n\
-kind of merry war betwixt Signior Benedick and her:\n\
-they never meet but there's a skirmish of wit\n\
-between them.\n\
-BEATRICE\n\
-Alas! he gets nothing by that. In our last\n\
-conflict four of his five wits went halting off, and\n\
-now is the whole man governed with one: so that if\n\
-he have wit enough to keep himself warm, let him\n\
-bear it for a difference between himself and his\n\
-horse; for it is all the wealth that he hath left,\n\
-to be known a reasonable creature. Who is his\n\
-companion now? He hath every month a new sworn brother.\n\
-MESSENGER\n\
-Is't possible?\n\
-BEATRICE\n\
-Very easily possible: he wears his faith but as\n\
-the fashion of his hat; it ever changes with the\n\
-next block.\n\
-MESSENGER\n\
-I see, lady, the gentleman is not in your books.\n\
-BEATRICE\n\
-No; an he were, I would burn my study. But, I pray\n\
-you, who is his companion? Is there no young\n\
-squarer now that will make a voyage with him to the devil?\n\
-MESSENGER\n\
-He is most in the company of the right noble Claudio.\n\
-BEATRICE\n\
-O Lord, he will hang upon him like a disease: he\n\
-is sooner caught than the pestilence, and the taker\n\
-runs presently mad. God help the noble Claudio! if\n\
-he have caught the Benedick, it will cost him a\n\
-thousand pound ere a' be cured.\n\
-MESSENGER\n\
-I will hold friends with you, lady.\n\
-BEATRICE\n\
-Do, good friend.\n\
-LEONATO\n\
-You will never run mad, niece.\n\
-BEATRICE\n\
-No, not till a hot January.\n\
-MESSENGER\n\
-Don Pedro is approached.\n\
-Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\
-\n\
-DON PEDRO\n\
-Good Signior Leonato, you are come to meet your\n\
-trouble: the fashion of the world is to avoid\n\
-cost, and you encounter it\n\
-LEONATO\n\
-Never came trouble to my house in the likeness of your grace,\n\
-for trouble being gone, comfort should remain, but\n\
-when you depart from me, sorrow abides and happiness\n\
-takes his leave.";
-
-TEST(liblog, max_payload) {
-#ifdef __ANDROID__
-  static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
-#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(max_payload_tag) - 1)
-
-  pid_t pid = getpid();
-  char tag[sizeof(max_payload_tag)];
-  memcpy(tag, max_payload_tag, sizeof(tag));
-  snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
-
-  auto write_function = [&] {
-    LOG_FAILURE_RETRY(
-        __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, max_payload_buf));
-  };
-
-  ssize_t max_len = 0;
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    char* data = log_msg.msg();
-
-    if (!data || strcmp(++data, tag)) {
-      return;
-    }
-
-    data += strlen(data) + 1;
-
-    const char* left = data;
-    const char* right = max_payload_buf;
-    while (*left && *right && (*left == *right)) {
-      ++left;
-      ++right;
-    }
-
-    if (max_len <= (left - data)) {
-      max_len = left - data + 1;
-    }
-
-    if (max_len > 512) {
-      *found = true;
-    }
-  };
-
-  RunLogTests(LOG_ID_SYSTEM, write_function, check_function);
-
-  EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, __android_log_buf_print__maxtag) {
-#ifdef __ANDROID__
-  auto write_function = [&] {
-    EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, max_payload_buf,
-                                         max_payload_buf));
-  };
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    if ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD) {
-      return;
-    }
-
-    *found = true;
-
-    AndroidLogFormat* logformat = android_log_format_new();
-    EXPECT_TRUE(NULL != logformat);
-    AndroidLogEntry entry;
-    int processLogBuffer = android_log_processLogBuffer(&log_msg.entry, &entry);
-    EXPECT_EQ(0, processLogBuffer);
-    if (processLogBuffer == 0) {
-      fflush(stderr);
-      int printLogLine =
-          android_log_printLogLine(logformat, fileno(stderr), &entry);
-      // Legacy tag truncation
-      EXPECT_LE(128, printLogLine);
-      // Measured maximum if we try to print part of the tag as message
-      EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine);
-    }
-    android_log_format_free(logformat);
-  };
-
-  RunLogTests(LOG_ID_MAIN, write_function, check_function);
-
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-// Note: This test is tautological. android_logger_list_read() calls recv() with
-// LOGGER_ENTRY_MAX_PAYLOAD as its size argument, so it's not possible for this test to read a
-// payload larger than that size.
-TEST(liblog, too_big_payload) {
-#ifdef __ANDROID__
-  pid_t pid = getpid();
-  static const char big_payload_tag[] = "TEST_big_payload_XXXX";
-  char tag[sizeof(big_payload_tag)];
-  memcpy(tag, big_payload_tag, sizeof(tag));
-  snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
-
-  std::string longString(3266519, 'x');
-  ssize_t ret;
-
-  auto write_function = [&] {
-    ret = LOG_FAILURE_RETRY(
-        __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, longString.c_str()));
-  };
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    char* data = log_msg.msg();
-
-    if (!data || strcmp(++data, tag)) {
-      return;
-    }
-
-    data += strlen(data) + 1;
-
-    const char* left = data;
-    const char* right = longString.c_str();
-    while (*left && *right && (*left == *right)) {
-      ++left;
-      ++right;
-    }
-
-    ssize_t len = left - data + 1;
-    // Check that we don't see any entries larger than the max payload.
-    EXPECT_LE(static_cast<size_t>(len), LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag));
-
-    // Once we've found our expected entry, break.
-    if (len == LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag)) {
-      *found = true;
-    }
-  };
-
-  RunLogTests(LOG_ID_SYSTEM, write_function, check_function);
-
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, dual_reader) {
-#ifdef __ANDROID__
-  static const int expected_count1 = 25;
-  static const int expected_count2 = 25;
-
-  pid_t pid = getpid();
-
-  auto logger_list1 = std::unique_ptr<struct logger_list, ListCloser>{
-      android_logger_list_open(LOG_ID_MAIN, 0, expected_count1, pid)};
-  ASSERT_TRUE(logger_list1);
-
-  auto logger_list2 = std::unique_ptr<struct logger_list, ListCloser>{
-      android_logger_list_open(LOG_ID_MAIN, 0, expected_count2, pid)};
-  ASSERT_TRUE(logger_list2);
-
-  for (int i = 25; i > 0; --i) {
-    static const char fmt[] = "dual_reader %02d";
-    char buffer[sizeof(fmt) + 8];
-    snprintf(buffer, sizeof(buffer), fmt, i);
-    LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
-                                              "liblog", buffer));
-  }
-
-  alarm(2);
-  auto alarm_guard = android::base::make_scope_guard([] { alarm(0); });
-
-  // Wait until we see all messages with the blocking reader.
-  int count1 = 0;
-  int count2 = 0;
-
-  while (count1 != expected_count2 || count2 != expected_count2) {
-    log_msg log_msg;
-    if (count1 < expected_count1) {
-      ASSERT_GT(android_logger_list_read(logger_list1.get(), &log_msg), 0);
-      count1++;
-    }
-    if (count2 < expected_count2) {
-      ASSERT_GT(android_logger_list_read(logger_list2.get(), &log_msg), 0);
-      count2++;
-    }
-  }
-
-  // Test again with the nonblocking reader.
-  auto logger_list_non_block1 = std::unique_ptr<struct logger_list, ListCloser>{
-      android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, expected_count1, pid)};
-  ASSERT_TRUE(logger_list_non_block1);
-
-  auto logger_list_non_block2 = std::unique_ptr<struct logger_list, ListCloser>{
-      android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, expected_count2, pid)};
-  ASSERT_TRUE(logger_list_non_block2);
-  count1 = 0;
-  count2 = 0;
-  bool done1 = false;
-  bool done2 = false;
-
-  while (!done1 || !done2) {
-    log_msg log_msg;
-
-    if (!done1) {
-      if (android_logger_list_read(logger_list_non_block1.get(), &log_msg) <= 0) {
-        done1 = true;
-      } else {
-        ++count1;
-      }
-    }
-
-    if (!done2) {
-      if (android_logger_list_read(logger_list_non_block2.get(), &log_msg) <= 0) {
-        done2 = true;
-      } else {
-        ++count2;
-      }
-    }
-  }
-
-  EXPECT_EQ(expected_count1, count1);
-  EXPECT_EQ(expected_count2, count2);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-static bool checkPriForTag(AndroidLogFormat* p_format, const char* tag,
-                           android_LogPriority pri) {
-  return android_log_shouldPrintLine(p_format, tag, pri) &&
-         !android_log_shouldPrintLine(p_format, tag,
-                                      (android_LogPriority)(pri - 1));
-}
-
-TEST(liblog, filterRule) {
-  static const char tag[] = "random";
-
-  AndroidLogFormat* p_format = android_log_format_new();
-
-  android_log_addFilterRule(p_format, "*:i");
-
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) ==
-              0);
-  android_log_addFilterRule(p_format, "*");
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-  android_log_addFilterRule(p_format, "*:v");
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-  android_log_addFilterRule(p_format, "*:i");
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) ==
-              0);
-
-  android_log_addFilterRule(p_format, tag);
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-  android_log_addFilterRule(p_format, "random:v");
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-  android_log_addFilterRule(p_format, "random:d");
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-  android_log_addFilterRule(p_format, "random:w");
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) ==
-              0);
-
-  android_log_addFilterRule(p_format, "crap:*");
-  EXPECT_TRUE(checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
-  EXPECT_TRUE(
-      android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
-
-  // invalid expression
-  EXPECT_TRUE(android_log_addFilterRule(p_format, "random:z") < 0);
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
-  EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) ==
-              0);
-
-  // Issue #550946
-  EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
-
-  // note trailing space
-  EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
-  EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
-
-  EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
-
-#if 0  // bitrot, seek update
-    char defaultBuffer[512];
-
-    android_log_formatLogLine(p_format,
-        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
-        123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
-
-    fprintf(stderr, "%s\n", defaultBuffer);
-#endif
-
-  android_log_format_free(p_format);
-}
-
-#ifdef ENABLE_FLAKY_TESTS
-TEST(liblog, is_loggable) {
-#ifdef __ANDROID__
-  static const char tag[] = "is_loggable";
-  static const char log_namespace[] = "persist.log.tag.";
-  static const size_t base_offset = 8; /* skip "persist." */
-  // sizeof("string") = strlen("string") + 1
-  char key[sizeof(log_namespace) + sizeof(tag) - 1];
-  char hold[4][PROP_VALUE_MAX];
-  static const struct {
-    int level;
-    char type;
-  } levels[] = {
-      {ANDROID_LOG_VERBOSE, 'v'}, {ANDROID_LOG_DEBUG, 'd'},
-      {ANDROID_LOG_INFO, 'i'},    {ANDROID_LOG_WARN, 'w'},
-      {ANDROID_LOG_ERROR, 'e'},   {ANDROID_LOG_FATAL, 'a'},
-      {ANDROID_LOG_SILENT, 's'},  {-2, 'g'},  // Illegal value, resort to default
-  };
-
-  // Set up initial test condition
-  memset(hold, 0, sizeof(hold));
-  snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
-  property_get(key, hold[0], "");
-  property_set(key, "");
-  property_get(key + base_offset, hold[1], "");
-  property_set(key + base_offset, "");
-  strcpy(key, log_namespace);
-  key[sizeof(log_namespace) - 2] = '\0';
-  property_get(key, hold[2], "");
-  property_set(key, "");
-  property_get(key, hold[3], "");
-  property_set(key + base_offset, "");
-
-  // All combinations of level and defaults
-  for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
-    if (levels[i].level == -2) {
-      continue;
-    }
-    for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
-      if (levels[j].level == -2) {
-        continue;
-      }
-      fprintf(stderr, "i=%zu j=%zu\r", i, j);
-      bool android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), levels[j].level);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1)) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), levels[j].level));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), levels[j].level));
-        }
-      }
-    }
-  }
-
-  // All combinations of level and tag and global properties
-  for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
-    if (levels[i].level == -2) {
-      continue;
-    }
-    for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
-      char buf[2];
-      buf[0] = levels[j].type;
-      buf[1] = '\0';
-
-      snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
-      fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key,
-              buf);
-      usleep(20000);
-      property_set(key, buf);
-      bool android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1) ||
-          ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      }
-      usleep(20000);
-      property_set(key, "");
-
-      fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j,
-              key + base_offset, buf);
-      property_set(key + base_offset, buf);
-      android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1) ||
-          ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      }
-      usleep(20000);
-      property_set(key + base_offset, "");
-
-      strcpy(key, log_namespace);
-      key[sizeof(log_namespace) - 2] = '\0';
-      fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key,
-              buf);
-      property_set(key, buf);
-      android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1) ||
-          ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      }
-      usleep(20000);
-      property_set(key, "");
-
-      fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j,
-              key + base_offset, buf);
-      property_set(key + base_offset, buf);
-      android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1) ||
-          ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      }
-      usleep(20000);
-      property_set(key + base_offset, "");
-    }
-  }
-
-  // All combinations of level and tag properties, but with global set to INFO
-  strcpy(key, log_namespace);
-  key[sizeof(log_namespace) - 2] = '\0';
-  usleep(20000);
-  property_set(key, "I");
-  snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
-  for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
-    if (levels[i].level == -2) {
-      continue;
-    }
-    for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
-      char buf[2];
-      buf[0] = levels[j].type;
-      buf[1] = '\0';
-
-      fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key,
-              buf);
-      usleep(20000);
-      property_set(key, buf);
-      bool android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1) ||
-          ((levels[i].level < ANDROID_LOG_INFO)  // Yes INFO
-           && (levels[j].level == -2))) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      }
-      usleep(20000);
-      property_set(key, "");
-
-      fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j,
-              key + base_offset, buf);
-      property_set(key + base_offset, buf);
-      android_log_is_loggable = __android_log_is_loggable_len(
-          levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG);
-      if ((levels[i].level < levels[j].level) || (levels[j].level == -1) ||
-          ((levels[i].level < ANDROID_LOG_INFO)  // Yes INFO
-           && (levels[j].level == -2))) {
-        if (android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_FALSE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_FALSE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      } else {
-        if (!android_log_is_loggable) {
-          fprintf(stderr, "\n");
-        }
-        EXPECT_TRUE(android_log_is_loggable);
-        for (size_t k = 10; k; --k) {
-          EXPECT_TRUE(__android_log_is_loggable_len(
-              levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG));
-        }
-      }
-      usleep(20000);
-      property_set(key + base_offset, "");
-    }
-  }
-
-  // reset parms
-  snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
-  usleep(20000);
-  property_set(key, hold[0]);
-  property_set(key + base_offset, hold[1]);
-  strcpy(key, log_namespace);
-  key[sizeof(log_namespace) - 2] = '\0';
-  property_set(key, hold[2]);
-  property_set(key + base_offset, hold[3]);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif  // ENABLE_FLAKY_TESTS
-
-#ifdef ENABLE_FLAKY_TESTS
-// Following tests the specific issues surrounding error handling wrt logd.
-// Kills logd and toss all collected data, equivalent to logcat -b all -c,
-// except we also return errors to the logging callers.
-#ifdef __ANDROID__
-// helper to liblog.enoent to count end-to-end matching logging messages.
-static int count_matching_ts(log_time ts) {
-  usleep(1000000);
-
-  pid_t pid = getpid();
-
-  struct logger_list* logger_list =
-      android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_NONBLOCK, 1000, pid);
-
-  int count = 0;
-  if (logger_list == NULL) return count;
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
-
-    if (log_msg.entry.len != sizeof(android_log_event_long_t)) continue;
-    if (log_msg.id() != LOG_ID_EVENTS) continue;
-
-    android_log_event_long_t* eventData;
-    eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
-    if (!eventData) continue;
-    if (eventData->payload.type != EVENT_TYPE_LONG) continue;
-
-    log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
-    if (ts != tx) continue;
-
-    // found event message with matching timestamp signature in payload
-    ++count;
-  }
-  android_logger_list_close(logger_list);
-
-  return count;
-}
-
-TEST(liblog, enoent) {
-#ifdef __ANDROID__
-  if (getuid() != 0) {
-    GTEST_SKIP() << "Skipping test, must be run as root.";
-    return;
-  }
-
-  log_time ts(CLOCK_MONOTONIC);
-  EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-  EXPECT_EQ(1, count_matching_ts(ts));
-
-  // This call will fail unless we are root, beware of any
-  // test prior to this one playing with setuid and causing interference.
-  // We need to run before these tests so that they do not interfere with
-  // this test.
-  //
-  // Stopping the logger can affect some other test's expectations as they
-  // count on the log buffers filled with existing content, and this
-  // effectively does a logcat -c emptying it.  So we want this test to be
-  // as near as possible to the bottom of the file.  For example
-  // liblog.android_logger_get_ is one of those tests that has no recourse
-  // and that would be adversely affected by emptying the log if it was run
-  // right after this test.
-  system("stop logd");
-  usleep(1000000);
-
-  // A clean stop like we are testing returns -ENOENT, but in the _real_
-  // world we could get -ENOTCONN or -ECONNREFUSED depending on timing.
-  // Alas we can not test these other return values; accept that they
-  // are treated equally within the open-retry logic in liblog.
-  ts = log_time(CLOCK_MONOTONIC);
-  int ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts));
-  std::string content = android::base::StringPrintf(
-      "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n",
-      ret, (ret <= 0) ? strerror(-ret) : "(content sent)");
-  EXPECT_TRUE(ret == -ENOENT || ret == -ENOTCONN || ret == -ECONNREFUSED) << content;
-  ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts));
-  content = android::base::StringPrintf(
-      "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n",
-      ret, (ret <= 0) ? strerror(-ret) : "(content sent)");
-  EXPECT_TRUE(ret == -ENOENT || ret == -ENOTCONN || ret == -ECONNREFUSED) << content;
-  EXPECT_EQ(0, count_matching_ts(ts));
-
-  system("start logd");
-  usleep(1000000);
-
-  EXPECT_EQ(0, count_matching_ts(ts));
-
-  ts = log_time(CLOCK_MONOTONIC);
-  EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-  EXPECT_EQ(1, count_matching_ts(ts));
-
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif  // __ANDROID__
-#endif  // ENABLE_FLAKY_TESTS
-
-// Below this point we run risks of setuid(AID_SYSTEM) which may affect others.
-
-#ifdef ENABLE_FLAKY_TESTS
-// Do not retest properties, and cannot log into LOG_ID_SECURITY
-TEST(liblog, __security) {
-#ifdef __ANDROID__
-  static const char persist_key[] = "persist.logd.security";
-  static const char readonly_key[] = "ro.organization_owned";
-  // A silly default value that can never be in readonly_key so
-  // that it can be determined the property is not set.
-  static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
-  char persist[PROP_VALUE_MAX];
-  char persist_hold[PROP_VALUE_MAX];
-  char readonly[PROP_VALUE_MAX];
-
-  // First part of this test requires the test itself to have the appropriate
-  // permissions. If we do not have them, we can not override them, so we
-  // bail rather than give a failing grade.
-  property_get(persist_key, persist, "");
-  fprintf(stderr, "INFO: getprop %s -> %s\n", persist_key, persist);
-  strncpy(persist_hold, persist, PROP_VALUE_MAX);
-  property_get(readonly_key, readonly, nothing_val);
-  fprintf(stderr, "INFO: getprop %s -> %s\n", readonly_key, readonly);
-
-  if (!strcmp(readonly, nothing_val)) {
-    // Lets check if we can set the value (we should not be allowed to do so)
-    EXPECT_FALSE(__android_log_security());
-    fprintf(stderr, "WARNING: setting ro.organization_owned to a domain\n");
-    static const char domain[] = "com.google.android.SecOps.DeviceOwner";
-    EXPECT_NE(0, property_set(readonly_key, domain));
-    useconds_t total_time = 0;
-    static const useconds_t seconds = 1000000;
-    static const useconds_t max_time = 5 * seconds;  // not going to happen
-    static const useconds_t rest = 20 * 1000;
-    for (; total_time < max_time; total_time += rest) {
-      usleep(rest);  // property system does not guarantee performance.
-      property_get(readonly_key, readonly, nothing_val);
-      if (!strcmp(readonly, domain)) {
-        if (total_time > rest) {
-          fprintf(stderr, "INFO: took %u.%06u seconds to set property\n",
-                  (unsigned)(total_time / seconds),
-                  (unsigned)(total_time % seconds));
-        }
-        break;
-      }
-    }
-    EXPECT_STRNE(domain, readonly);
-  }
-
-  if (!strcasecmp(readonly, "false") || !readonly[0] ||
-      !strcmp(readonly, nothing_val)) {
-    // not enough permissions to run tests surrounding persist.logd.security
-    EXPECT_FALSE(__android_log_security());
-    return;
-  }
-
-  if (!strcasecmp(persist, "true")) {
-    EXPECT_TRUE(__android_log_security());
-  } else {
-    EXPECT_FALSE(__android_log_security());
-  }
-  property_set(persist_key, "TRUE");
-  property_get(persist_key, persist, "");
-  uid_t uid = getuid();
-  gid_t gid = getgid();
-  bool perm = (gid == AID_ROOT) || (uid == AID_ROOT);
-  EXPECT_STREQ(perm ? "TRUE" : persist_hold, persist);
-  if (!strcasecmp(persist, "true")) {
-    EXPECT_TRUE(__android_log_security());
-  } else {
-    EXPECT_FALSE(__android_log_security());
-  }
-  property_set(persist_key, "FALSE");
-  property_get(persist_key, persist, "");
-  EXPECT_STREQ(perm ? "FALSE" : persist_hold, persist);
-  if (!strcasecmp(persist, "true")) {
-    EXPECT_TRUE(__android_log_security());
-  } else {
-    EXPECT_FALSE(__android_log_security());
-  }
-  property_set(persist_key, "true");
-  property_get(persist_key, persist, "");
-  EXPECT_STREQ(perm ? "true" : persist_hold, persist);
-  if (!strcasecmp(persist, "true")) {
-    EXPECT_TRUE(__android_log_security());
-  } else {
-    EXPECT_FALSE(__android_log_security());
-  }
-  property_set(persist_key, "false");
-  property_get(persist_key, persist, "");
-  EXPECT_STREQ(perm ? "false" : persist_hold, persist);
-  if (!strcasecmp(persist, "true")) {
-    EXPECT_TRUE(__android_log_security());
-  } else {
-    EXPECT_FALSE(__android_log_security());
-  }
-  property_set(persist_key, "");
-  property_get(persist_key, persist, "");
-  EXPECT_STREQ(perm ? "" : persist_hold, persist);
-  if (!strcasecmp(persist, "true")) {
-    EXPECT_TRUE(__android_log_security());
-  } else {
-    EXPECT_FALSE(__android_log_security());
-  }
-  property_set(persist_key, persist_hold);
-  property_get(persist_key, persist, "");
-  EXPECT_STREQ(persist_hold, persist);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, __security_buffer) {
-#ifdef __ANDROID__
-  struct logger_list* logger_list;
-  android_event_long_t buffer;
-
-  static const char persist_key[] = "persist.logd.security";
-  char persist[PROP_VALUE_MAX];
-  bool set_persist = false;
-  bool allow_security = false;
-
-  if (__android_log_security()) {
-    allow_security = true;
-  } else {
-    property_get(persist_key, persist, "");
-    if (strcasecmp(persist, "true")) {
-      property_set(persist_key, "TRUE");
-      if (__android_log_security()) {
-        allow_security = true;
-        set_persist = true;
-      } else {
-        property_set(persist_key, persist);
-      }
-    }
-  }
-
-  if (!allow_security) {
-    fprintf(stderr,
-            "WARNING: "
-            "security buffer disabled, bypassing end-to-end test\n");
-
-    log_time ts(CLOCK_MONOTONIC);
-
-    buffer.type = EVENT_TYPE_LONG;
-    buffer.data = *(static_cast<uint64_t*>((void*)&ts));
-
-    // expect failure!
-    ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
-
-    return;
-  }
-
-  /* Matches clientHasLogCredentials() in logd */
-  uid_t uid = getuid();
-  gid_t gid = getgid();
-  bool clientHasLogCredentials = true;
-  if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG) &&
-      (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
-    uid_t euid = geteuid();
-    if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) {
-      gid_t egid = getegid();
-      if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) {
-        int num_groups = getgroups(0, NULL);
-        if (num_groups > 0) {
-          gid_t groups[num_groups];
-          num_groups = getgroups(num_groups, groups);
-          while (num_groups > 0) {
-            if (groups[num_groups - 1] == AID_LOG) {
-              break;
-            }
-            --num_groups;
-          }
-        }
-        if (num_groups <= 0) {
-          clientHasLogCredentials = false;
-        }
-      }
-    }
-  }
-  if (!clientHasLogCredentials) {
-    fprintf(stderr,
-            "WARNING: "
-            "not in system context, bypassing end-to-end test\n");
-
-    log_time ts(CLOCK_MONOTONIC);
-
-    buffer.type = EVENT_TYPE_LONG;
-    buffer.data = *(static_cast<uint64_t*>((void*)&ts));
-
-    // expect failure!
-    ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
-
-    return;
-  }
-
-  EXPECT_EQ(0, setuid(AID_SYSTEM));  // only one that can read security buffer
-
-  uid = getuid();
-  gid = getgid();
-  pid_t pid = getpid();
-
-  ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_SECURITY, ANDROID_LOG_NONBLOCK,
-                                                              1000, pid)));
-
-  log_time ts(CLOCK_MONOTONIC);
-
-  buffer.type = EVENT_TYPE_LONG;
-  buffer.data = *(static_cast<uint64_t*>((void*)&ts));
-
-  ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
-  usleep(1000000);
-
-  int count = 0;
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    ASSERT_EQ(log_msg.entry.pid, pid);
-
-    if ((log_msg.entry.len != sizeof(android_log_event_long_t)) ||
-        (log_msg.id() != LOG_ID_SECURITY)) {
-      continue;
-    }
-
-    android_log_event_long_t* eventData;
-    eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
-
-    if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
-      continue;
-    }
-
-    log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
-    if (ts == tx) {
-      ++count;
-    }
-  }
-
-  if (set_persist) {
-    property_set(persist_key, persist);
-  }
-
-  android_logger_list_close(logger_list);
-
-  bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM);
-  if (!clientHasSecurityCredentials) {
-    fprintf(stderr,
-            "WARNING: "
-            "not system, content submitted but can not check end-to-end\n");
-  }
-  EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif  // ENABLE_FLAKY_TESTS
-
-#ifdef __ANDROID__
-static void android_errorWriteWithInfoLog_helper(int tag, const char* subtag, int uid,
-                                                 const char* payload, int data_len) {
-  auto write_function = [&] {
-    int ret = android_errorWriteWithInfoLog(tag, subtag, uid, payload, data_len);
-    ASSERT_LT(0, ret);
-  };
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    char* event_data = log_msg.msg();
-    char* original = event_data;
-
-    // Tag
-    auto* event_header = reinterpret_cast<android_event_header_t*>(event_data);
-    event_data += sizeof(android_event_header_t);
-    if (event_header->tag != tag) {
-      return;
-    }
-
-    // List type
-    auto* event_list = reinterpret_cast<android_event_list_t*>(event_data);
-    ASSERT_EQ(EVENT_TYPE_LIST, event_list->type);
-    ASSERT_EQ(3, event_list->element_count);
-    event_data += sizeof(android_event_list_t);
-
-    // Element #1: string type for subtag
-    auto* event_string_subtag = reinterpret_cast<android_event_string_t*>(event_data);
-    ASSERT_EQ(EVENT_TYPE_STRING, event_string_subtag->type);
-    int32_t subtag_len = strlen(subtag);
-    if (subtag_len > 32) {
-      subtag_len = 32;
-    }
-    ASSERT_EQ(subtag_len, event_string_subtag->length);
-    if (memcmp(subtag, &event_string_subtag->data, subtag_len)) {
-      return;
-    }
-    event_data += sizeof(android_event_string_t) + subtag_len;
-
-    // Element #2: int type for uid
-    auto* event_int_uid = reinterpret_cast<android_event_int_t*>(event_data);
-    ASSERT_EQ(EVENT_TYPE_INT, event_int_uid->type);
-    ASSERT_EQ(uid, event_int_uid->data);
-    event_data += sizeof(android_event_int_t);
-
-    // Element #3: string type for data
-    auto* event_string_data = reinterpret_cast<android_event_string_t*>(event_data);
-    ASSERT_EQ(EVENT_TYPE_STRING, event_string_data->type);
-    int32_t message_data_len = event_string_data->length;
-    if (data_len < 512) {
-      ASSERT_EQ(data_len, message_data_len);
-    }
-    if (memcmp(payload, &event_string_data->data, message_data_len) != 0) {
-      return;
-    }
-    event_data += sizeof(android_event_string_t);
-
-    if (data_len >= 512) {
-      event_data += message_data_len;
-      // 4 bytes for the tag, and max_payload_buf should be truncated.
-      ASSERT_LE(4 + 512, event_data - original);       // worst expectations
-      ASSERT_GT(4 + data_len, event_data - original);  // must be truncated
-    }
-    *found = true;
-  };
-
-  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
-}
-#endif
-
-// Make multiple tests and re-tests orthogonal to prevent falsing.
-#ifdef TEST_LOGGER
-#define UNIQUE_TAG(X) \
-  (0x12340000 + (((X) + sizeof(int) + sizeof(void*)) << 8) + TEST_LOGGER)
-#else
-#define UNIQUE_TAG(X) \
-  (0x12340000 + (((X) + sizeof(int) + sizeof(void*)) << 8) + 0xBA)
-#endif
-
-TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
-#ifdef __ANDROID__
-  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(1), "test-subtag", -1, max_payload_buf, 200);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog,
-     android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {
-#ifdef __ANDROID__
-  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(2), "test-subtag", -1, max_payload_buf,
-                                       sizeof(max_payload_buf));
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog,
-     android_errorWriteWithInfoLog__android_logger_list_read__null_data) {
-#ifdef __ANDROID__
-  int retval_android_errorWriteWithinInfoLog =
-      android_errorWriteWithInfoLog(UNIQUE_TAG(3), "test-subtag", -1, nullptr, 200);
-  ASSERT_GT(0, retval_android_errorWriteWithinInfoLog);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog,
-     android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {
-#ifdef __ANDROID__
-  android_errorWriteWithInfoLog_helper(
-      UNIQUE_TAG(4), "abcdefghijklmnopqrstuvwxyz now i know my abc", -1, max_payload_buf, 200);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, __android_log_bswrite_and_print___max) {
-  bswrite_test(max_payload_buf);
-}
-
-TEST(liblog, __android_log_buf_write_and_print__max) {
-  buf_write_test(max_payload_buf);
-}
-
-TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
-#ifdef __ANDROID__
-  int kTag = UNIQUE_TAG(5);
-  const char* kSubTag = "test-subtag";
-
-  auto write_function = [&] {
-    int retval_android_errorWriteLog = android_errorWriteLog(kTag, kSubTag);
-    ASSERT_LT(0, retval_android_errorWriteLog);
-  };
-
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    char* event_data = log_msg.msg();
-
-    // Tag
-    auto* event_header = reinterpret_cast<android_event_header_t*>(event_data);
-    event_data += sizeof(android_event_header_t);
-    if (event_header->tag != kTag) {
-      return;
-    }
-
-    // List type
-    auto* event_list = reinterpret_cast<android_event_list_t*>(event_data);
-    ASSERT_EQ(EVENT_TYPE_LIST, event_list->type);
-    ASSERT_EQ(3, event_list->element_count);
-    event_data += sizeof(android_event_list_t);
-
-    // Element #1: string type for subtag
-    auto* event_string_subtag = reinterpret_cast<android_event_string_t*>(event_data);
-    ASSERT_EQ(EVENT_TYPE_STRING, event_string_subtag->type);
-    int32_t subtag_len = strlen(kSubTag);
-    ASSERT_EQ(subtag_len, event_string_subtag->length);
-    if (memcmp(kSubTag, &event_string_subtag->data, subtag_len) == 0) {
-      *found = true;
-    }
-  };
-
-  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
-
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
-#ifdef __ANDROID__
-  EXPECT_LT(android_errorWriteLog(UNIQUE_TAG(6), nullptr), 0);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-// Do not retest logger list handling
-#ifdef __ANDROID__
-static int is_real_element(int type) {
-  return ((type == EVENT_TYPE_INT) || (type == EVENT_TYPE_LONG) ||
-          (type == EVENT_TYPE_STRING) || (type == EVENT_TYPE_FLOAT));
-}
-
-static int android_log_buffer_to_string(const char* msg, size_t len,
-                                        char* strOut, size_t strOutLen) {
-  android_log_context context = create_android_log_parser(msg, len);
-  android_log_list_element elem;
-  bool overflow = false;
-  /* Reserve 1 byte for null terminator. */
-  size_t origStrOutLen = strOutLen--;
-
-  if (!context) {
-    return -EBADF;
-  }
-
-  memset(&elem, 0, sizeof(elem));
-
-  size_t outCount;
-
-  do {
-    elem = android_log_read_next(context);
-    switch ((int)elem.type) {
-      case EVENT_TYPE_LIST:
-        if (strOutLen == 0) {
-          overflow = true;
-        } else {
-          *strOut++ = '[';
-          strOutLen--;
-        }
-        break;
-
-      case EVENT_TYPE_LIST_STOP:
-        if (strOutLen == 0) {
-          overflow = true;
-        } else {
-          *strOut++ = ']';
-          strOutLen--;
-        }
-        break;
-
-      case EVENT_TYPE_INT:
-        /*
-         * snprintf also requires room for the null terminator, which
-         * we don't care about  but we have allocated enough room for
-         * that
-         */
-        outCount = snprintf(strOut, strOutLen + 1, "%" PRId32, elem.data.int32);
-        if (outCount <= strOutLen) {
-          strOut += outCount;
-          strOutLen -= outCount;
-        } else {
-          overflow = true;
-        }
-        break;
-
-      case EVENT_TYPE_LONG:
-        /*
-         * snprintf also requires room for the null terminator, which
-         * we don't care about but we have allocated enough room for
-         * that
-         */
-        outCount = snprintf(strOut, strOutLen + 1, "%" PRId64, elem.data.int64);
-        if (outCount <= strOutLen) {
-          strOut += outCount;
-          strOutLen -= outCount;
-        } else {
-          overflow = true;
-        }
-        break;
-
-      case EVENT_TYPE_FLOAT:
-        /*
-         * snprintf also requires room for the null terminator, which
-         * we don't care about but we have allocated enough room for
-         * that
-         */
-        outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32);
-        if (outCount <= strOutLen) {
-          strOut += outCount;
-          strOutLen -= outCount;
-        } else {
-          overflow = true;
-        }
-        break;
-
-      default:
-        elem.complete = true;
-        break;
-
-      case EVENT_TYPE_UNKNOWN:
-#if 0  // Ideal purity in the test, we want to complain about UNKNOWN showing up
-            if (elem.complete) {
-                break;
-            }
-#endif
-        elem.data.string = const_cast<char*>("<unknown>");
-        elem.len = strlen(elem.data.string);
-        FALLTHROUGH_INTENDED;
-      case EVENT_TYPE_STRING:
-        if (elem.len <= strOutLen) {
-          memcpy(strOut, elem.data.string, elem.len);
-          strOut += elem.len;
-          strOutLen -= elem.len;
-        } else if (strOutLen > 0) {
-          /* copy what we can */
-          memcpy(strOut, elem.data.string, strOutLen);
-          strOut += strOutLen;
-          strOutLen = 0;
-          overflow = true;
-        }
-        break;
-    }
-
-    if (elem.complete) {
-      break;
-    }
-    /* Determine whether to put a comma or not. */
-    if (!overflow &&
-        (is_real_element(elem.type) || (elem.type == EVENT_TYPE_LIST_STOP))) {
-      android_log_list_element next = android_log_peek_next(context);
-      if (!next.complete &&
-          (is_real_element(next.type) || (next.type == EVENT_TYPE_LIST))) {
-        if (strOutLen == 0) {
-          overflow = true;
-        } else {
-          *strOut++ = ',';
-          strOutLen--;
-        }
-      }
-    }
-  } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete);
-
-  android_log_destroy(&context);
-
-  if (overflow) {
-    if (strOutLen < origStrOutLen) {
-      /* leave an indicator */
-      *(strOut - 1) = '!';
-    } else {
-      /* nothing was written at all */
-      *strOut++ = '!';
-    }
-  }
-  *strOut++ = '\0';
-
-  if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) {
-    fprintf(stderr, "Binary log entry conversion failed\n");
-    return -EINVAL;
-  }
-
-  return 0;
-}
-#endif  // __ANDROID__
-
-#ifdef __ANDROID__
-static const char* event_test_int32(uint32_t tag, size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
-
-  return "1076895760";
-}
-
-static const char* event_test_int64(uint32_t tag, size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t);
-
-  return "-9191740941672636400";
-}
-
-static const char* event_test_list_int64(uint32_t tag, size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) +
-                 sizeof(uint8_t) + sizeof(uint64_t);
-
-  return "[-9191740941672636400]";
-}
-
-static const char* event_test_simple_automagic_list(uint32_t tag,
-                                                    size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  // The convenience API where we allow a simple list to be
-  // created without explicit begin or end calls.
-  EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
-  EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) +
-                 sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) +
-                 sizeof(uint64_t);
-
-  return "[1076895760,-9191740941672636400]";
-}
-
-static const char* event_test_list_empty(uint32_t tag, size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t);
-
-  return "[]";
-}
-
-static const char* event_test_complex_nested_list(uint32_t tag,
-                                                  size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-
-  EXPECT_LE(0, android_log_write_list_begin(ctx));  // [
-  EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304));
-  EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708));
-  EXPECT_LE(0, android_log_write_string8(ctx, "Hello World"));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));  // [
-  EXPECT_LE(0, android_log_write_int32(ctx, 1));
-  EXPECT_LE(0, android_log_write_int32(ctx, 2));
-  EXPECT_LE(0, android_log_write_int32(ctx, 3));
-  EXPECT_LE(0, android_log_write_int32(ctx, 4));
-  EXPECT_LE(0, android_log_write_list_end(ctx));  // ]
-  EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708));
-  EXPECT_LE(0, android_log_write_list_end(ctx));  // ]
-
-  //
-  // This one checks for the automagic list creation because a list
-  // begin and end was missing for it! This is actually an <oops> corner
-  // case, and not the behavior we morally support. The automagic API is to
-  // allow for a simple case of a series of objects in a single list. e.g.
-  //   int32,int32,int32,string -> [int32,int32,int32,string]
-  //
-  EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH"));
-
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) +
-                 sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) +
-                 sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t) +
-                 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") -
-                 1 + sizeof(uint8_t) + sizeof(uint8_t) +
-                 4 * (sizeof(uint8_t) + sizeof(uint32_t)) + sizeof(uint8_t) +
-                 sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t) +
-                 sizeof("dlroW olleH") - 1;
-
-  return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW "
-         "olleH]";
-}
-
-static const char* event_test_7_level_prefix(uint32_t tag,
-                                             size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 1));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 2));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 3));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 4));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 5));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 6));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 7));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + 7 * (sizeof(uint8_t) + sizeof(uint8_t) +
-                                         sizeof(uint8_t) + sizeof(uint32_t));
-
-  return "[[[[[[[1],2],3],4],5],6],7]";
-}
-
-static const char* event_test_7_level_suffix(uint32_t tag,
-                                             size_t& expected_len) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
-  if (!ctx) {
-    return NULL;
-  }
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 1));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 2));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 3));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 4));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 5));
-  EXPECT_LE(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_write_int32(ctx, 6));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list_end(ctx));
-  EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  EXPECT_TRUE(NULL == ctx);
-
-  expected_len = sizeof(uint32_t) + 6 * (sizeof(uint8_t) + sizeof(uint8_t) +
-                                         sizeof(uint8_t) + sizeof(uint32_t));
-
-  return "[1,[2,[3,[4,[5,[6]]]]]]";
-}
-
-static const char* event_test_android_log_error_write(uint32_t tag,
-                                                      size_t& expected_len) {
-  EXPECT_LE(
-      0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11));
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) +
-                 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") -
-                 1 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) +
-                 sizeof(uint32_t) + sizeof("dlroW olleH") - 1;
-
-  return "[Hello World,42,dlroW olleH]";
-}
-
-static const char* event_test_android_log_error_write_null(uint32_t tag,
-                                                           size_t& expected_len) {
-  EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0));
-
-  expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) +
-                 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") -
-                 1 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) +
-                 sizeof(uint32_t) + sizeof("") - 1;
-
-  return "[Hello World,42,]";
-}
-
-// make sure all user buffers are flushed
-static void print_barrier() {
-  std::cout.flush();
-  fflush(stdout);
-  std::cerr.flush();
-  fflush(stderr);  // everything else is paranoia ...
-}
-
-static void create_android_logger(const char* (*fn)(uint32_t tag,
-                                                    size_t& expected_len)) {
-  size_t expected_len;
-  const char* expected_string;
-  auto write_function = [&] {
-    expected_string = (*fn)(1005, expected_len);
-    ASSERT_NE(nullptr, expected_string);
-  };
-
-  pid_t pid = getpid();
-  auto check_function = [&](log_msg log_msg, bool* found) {
-    if (static_cast<size_t>(log_msg.entry.len) != expected_len) {
-      return;
-    }
-
-    char* eventData = log_msg.msg();
-
-    AndroidLogFormat* logformat = android_log_format_new();
-    EXPECT_TRUE(NULL != logformat);
-    AndroidLogEntry entry;
-    char msgBuf[1024];
-    int processBinaryLogBuffer =
-        android_log_processBinaryLogBuffer(&log_msg.entry, &entry, nullptr, msgBuf, sizeof(msgBuf));
-    EXPECT_EQ(0, processBinaryLogBuffer);
-    if (processBinaryLogBuffer == 0) {
-      int line_overhead = 20;
-      if (pid > 99999) ++line_overhead;
-      if (pid > 999999) ++line_overhead;
-      print_barrier();
-      int printLogLine =
-          android_log_printLogLine(logformat, fileno(stderr), &entry);
-      print_barrier();
-      EXPECT_EQ(line_overhead + (int)strlen(expected_string), printLogLine);
-    }
-    android_log_format_free(logformat);
-
-    // test buffer reading API
-    int buffer_to_string = -1;
-    if (eventData) {
-      auto* event_header = reinterpret_cast<android_event_header_t*>(eventData);
-      eventData += sizeof(android_event_header_t);
-      snprintf(msgBuf, sizeof(msgBuf), "I/[%" PRId32 "]", event_header->tag);
-      print_barrier();
-      fprintf(stderr, "%-10s(%5u): ", msgBuf, pid);
-      memset(msgBuf, 0, sizeof(msgBuf));
-      buffer_to_string =
-          android_log_buffer_to_string(eventData, log_msg.entry.len, msgBuf, sizeof(msgBuf));
-      fprintf(stderr, "%s\n", msgBuf);
-      print_barrier();
-    }
-    EXPECT_EQ(0, buffer_to_string);
-    EXPECT_STREQ(expected_string, msgBuf);
-    *found = true;
-  };
-
-  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
-}
-#endif
-
-TEST(liblog, create_android_logger_int32) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_int32);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_int64) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_int64);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_list_int64) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_list_int64);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_simple_automagic_list) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_simple_automagic_list);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_list_empty) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_list_empty);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_complex_nested_list) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_complex_nested_list);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_7_level_prefix) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_7_level_prefix);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_7_level_suffix) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_7_level_suffix);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_android_log_error_write) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_android_log_error_write);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_android_log_error_write_null) {
-#ifdef __ANDROID__
-  create_android_logger(event_test_android_log_error_write_null);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(liblog, create_android_logger_overflow) {
-  android_log_context ctx;
-
-  EXPECT_TRUE(NULL != (ctx = create_android_logger(1005)));
-  if (ctx) {
-    for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
-      EXPECT_LE(0, android_log_write_list_begin(ctx));
-    }
-    EXPECT_GT(0, android_log_write_list_begin(ctx));
-    /* One more for good measure, must be permanently unhappy */
-    EXPECT_GT(0, android_log_write_list_begin(ctx));
-    EXPECT_LE(0, android_log_destroy(&ctx));
-    EXPECT_TRUE(NULL == ctx);
-  }
-
-  ASSERT_TRUE(NULL != (ctx = create_android_logger(1005)));
-  for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
-    EXPECT_LE(0, android_log_write_list_begin(ctx));
-    EXPECT_LE(0, android_log_write_int32(ctx, i));
-  }
-  EXPECT_GT(0, android_log_write_list_begin(ctx));
-  /* One more for good measure, must be permanently unhappy */
-  EXPECT_GT(0, android_log_write_list_begin(ctx));
-  EXPECT_LE(0, android_log_destroy(&ctx));
-  ASSERT_TRUE(NULL == ctx);
-}
-
-#ifdef ENABLE_FLAKY_TESTS
-#ifdef __ANDROID__
-#ifndef NO_PSTORE
-static const char __pmsg_file[] =
-    "/data/william-shakespeare/MuchAdoAboutNothing.txt";
-#endif /* NO_PSTORE */
-#endif
-
-TEST(liblog, __android_log_pmsg_file_write) {
-#ifdef __ANDROID__
-#ifndef NO_PSTORE
-  __android_log_close();
-  if (getuid() == AID_ROOT) {
-    tested__android_log_close = true;
-    bool pmsgActiveAfter__android_log_close = isPmsgActive();
-    bool logdwActiveAfter__android_log_close = isLogdwActive();
-    EXPECT_FALSE(pmsgActiveAfter__android_log_close);
-    EXPECT_FALSE(logdwActiveAfter__android_log_close);
-  } else if (!tested__android_log_close) {
-    fprintf(stderr, "WARNING: can not test __android_log_close()\n");
-  }
-  int return__android_log_pmsg_file_write = __android_log_pmsg_file_write(
-      LOG_ID_CRASH, ANDROID_LOG_VERBOSE, __pmsg_file, max_payload_buf,
-      sizeof(max_payload_buf));
-  EXPECT_LT(0, return__android_log_pmsg_file_write);
-  if (return__android_log_pmsg_file_write == -ENOMEM) {
-    fprintf(stderr,
-            "Kernel does not have space allocated to pmsg pstore driver "
-            "configured\n");
-  } else if (!return__android_log_pmsg_file_write) {
-    fprintf(stderr,
-            "Reboot, ensure file %s matches\n"
-            "with liblog.__android_log_msg_file_read test\n",
-            __pmsg_file);
-  }
-  bool pmsgActiveAfter__android_pmsg_file_write;
-  bool logdwActiveAfter__android_pmsg_file_write;
-  if (getuid() == AID_ROOT) {
-    pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
-    logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
-    EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write);
-    EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write);
-  }
-  EXPECT_LT(
-      0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
-                                 "TEST__android_log_pmsg_file_write", "main"));
-  if (getuid() == AID_ROOT) {
-    bool pmsgActiveAfter__android_log_buf_print = isPmsgActive();
-    bool logdwActiveAfter__android_log_buf_print = isLogdwActive();
-    EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print);
-    EXPECT_TRUE(logdwActiveAfter__android_log_buf_print);
-  }
-  EXPECT_LT(0, __android_log_pmsg_file_write(LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
-                                             __pmsg_file, max_payload_buf,
-                                             sizeof(max_payload_buf)));
-  if (getuid() == AID_ROOT) {
-    pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
-    logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
-    EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
-    EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
-  }
-#else  /* NO_PSTORE */
-  GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
-#endif /* NO_PSTORE */
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-#ifdef __ANDROID__
-#ifndef NO_PSTORE
-static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
-                         const char* buf, size_t len, void* arg) {
-  EXPECT_TRUE(NULL == arg);
-  EXPECT_EQ(LOG_ID_CRASH, logId);
-  EXPECT_EQ(ANDROID_LOG_VERBOSE, prio);
-  EXPECT_FALSE(NULL == strstr(__pmsg_file, filename));
-  EXPECT_EQ(len, sizeof(max_payload_buf));
-  EXPECT_STREQ(max_payload_buf, buf);
-
-  ++signaled;
-  if ((len != sizeof(max_payload_buf)) || strcmp(max_payload_buf, buf)) {
-    fprintf(stderr, "comparison fails on content \"%s\"\n", buf);
-  }
-  return arg || (LOG_ID_CRASH != logId) || (ANDROID_LOG_VERBOSE != prio) ||
-                 !strstr(__pmsg_file, filename) ||
-                 (len != sizeof(max_payload_buf)) ||
-                 !!strcmp(max_payload_buf, buf)
-             ? -ENOEXEC
-             : 1;
-}
-#endif /* NO_PSTORE */
-#endif
-
-TEST(liblog, __android_log_pmsg_file_read) {
-#ifdef __ANDROID__
-#ifndef NO_PSTORE
-  signaled = 0;
-
-  __android_log_close();
-  if (getuid() == AID_ROOT) {
-    tested__android_log_close = true;
-    bool pmsgActiveAfter__android_log_close = isPmsgActive();
-    bool logdwActiveAfter__android_log_close = isLogdwActive();
-    EXPECT_FALSE(pmsgActiveAfter__android_log_close);
-    EXPECT_FALSE(logdwActiveAfter__android_log_close);
-  } else if (!tested__android_log_close) {
-    fprintf(stderr, "WARNING: can not test __android_log_close()\n");
-  }
-
-  ssize_t ret = __android_log_pmsg_file_read(LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
-                                             __pmsg_file, __pmsg_fn, NULL);
-
-  if (getuid() == AID_ROOT) {
-    bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive();
-    bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive();
-    EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read);
-    EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read);
-  }
-
-  if (ret == -ENOENT) {
-    fprintf(stderr,
-            "No pre-boot results of liblog.__android_log_mesg_file_write to "
-            "compare with,\n"
-            "false positive test result.\n");
-    return;
-  }
-
-  EXPECT_LT(0, ret);
-  EXPECT_EQ(1U, signaled);
-#else  /* NO_PSTORE */
-  GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
-#endif /* NO_PSTORE */
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif  // ENABLE_FLAKY_TESTS
diff --git a/liblog/tests/log_id_test.cpp b/liblog/tests/log_id_test.cpp
deleted file mode 100644
index 9fb5a2c..0000000
--- a/liblog/tests/log_id_test.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2013-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <inttypes.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <gtest/gtest.h>
-// Test the APIs in this standalone include file
-#include <log/log_id.h>
-
-// We do not want to include <android/log.h> to acquire ANDROID_LOG_INFO for
-// include file API purity.  We do however want to allow the _option_ that
-// log/log_id.h could include this file, or related content, in the future.
-#ifndef __android_LogPriority_defined
-#define ANDROID_LOG_INFO 4
-#endif
-
-TEST(liblog, log_id) {
-  int count = 0;
-
-  for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
-    log_id_t id = static_cast<log_id_t>(i);
-    const char* name = android_log_id_to_name(id);
-    if (id != android_name_to_log_id(name)) {
-      continue;
-    }
-    ++count;
-    fprintf(stderr, "log buffer %s\r", name);
-  }
-  ASSERT_EQ(LOG_ID_MAX, count);
-}
-
-TEST(liblog, __android_log_buf_print) {
-  EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
-                                       "TEST__android_log_buf_print", "radio"));
-  usleep(1000);
-  EXPECT_LT(0,
-            __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
-                                    "TEST__android_log_buf_print", "system"));
-  usleep(1000);
-  EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
-                                       "TEST__android_log_buf_print", "main"));
-  usleep(1000);
-}
-
-TEST(liblog, __android_log_buf_write) {
-  EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
-                                       "TEST__android_log_buf_write", "radio"));
-  usleep(1000);
-  EXPECT_LT(0,
-            __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
-                                    "TEST__android_log_buf_write", "system"));
-  usleep(1000);
-  EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
-                                       "TEST__android_log_buf_write", "main"));
-  usleep(1000);
-}
-
-static void* ConcurrentPrintFn(void* arg) {
-  int ret = __android_log_buf_print(
-      LOG_ID_MAIN, ANDROID_LOG_INFO, "TEST__android_log_print",
-      "Concurrent %" PRIuPTR, reinterpret_cast<uintptr_t>(arg));
-  return reinterpret_cast<void*>(ret);
-}
-
-#define NUM_CONCURRENT 64
-#define _concurrent_name(a, n) a##__concurrent##n
-#define concurrent_name(a, n) _concurrent_name(a, n)
-
-TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
-  pthread_t t[NUM_CONCURRENT];
-  int i;
-  for (i = 0; i < NUM_CONCURRENT; i++) {
-    ASSERT_EQ(0, pthread_create(&t[i], NULL, ConcurrentPrintFn,
-                                reinterpret_cast<void*>(i)));
-  }
-  int ret = 1;
-  for (i = 0; i < NUM_CONCURRENT; i++) {
-    void* result;
-    ASSERT_EQ(0, pthread_join(t[i], &result));
-    int this_result = reinterpret_cast<uintptr_t>(result);
-    if ((0 < ret) && (ret != this_result)) {
-      ret = this_result;
-    }
-  }
-  ASSERT_LT(0, ret);
-}
diff --git a/liblog/tests/log_radio_test.cpp b/liblog/tests/log_radio_test.cpp
deleted file mode 100644
index fa1255e..0000000
--- a/liblog/tests/log_radio_test.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <gtest/gtest.h>
-// Test the APIs in this standalone include file
-#include <log/log_radio.h>
-
-TEST(liblog, RLOG) {
-  static const char content[] = "log_radio.h";
-  static const char content_false[] = "log_radio.h false";
-
-// ratelimit content to 10/s to keep away from spam filters
-// do not send identical content together to keep away from spam filters
-
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGV"
-  RLOGV(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGD"
-  RLOGD(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGI"
-  RLOGI(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGW"
-  RLOGW(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGE"
-  RLOGE(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGV"
-  RLOGV_IF(true, content);
-  usleep(100000);
-  RLOGV_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGD"
-  RLOGD_IF(true, content);
-  usleep(100000);
-  RLOGD_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGI"
-  RLOGI_IF(true, content);
-  usleep(100000);
-  RLOGI_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGW"
-  RLOGW_IF(true, content);
-  usleep(100000);
-  RLOGW_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__RLOGE"
-  RLOGE_IF(true, content);
-  usleep(100000);
-  RLOGE_IF(false, content_false);
-
-#ifdef __ANDROID__
-  // give time for content to long-path through logger
-  sleep(1);
-
-  std::string buf = android::base::StringPrintf(
-      "logcat -b radio --pid=%u -d -s"
-      " TEST__RLOGV TEST__RLOGD TEST__RLOGI TEST__RLOGW TEST__RLOGE",
-      (unsigned)getpid());
-  FILE* fp = popen(buf.c_str(), "re");
-  int count = 0;
-  int count_false = 0;
-  if (fp) {
-    if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
-    pclose(fp);
-    for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos;
-         ++pos) {
-      ++count;
-    }
-    for (size_t pos = 0;
-         (pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
-      ++count_false;
-    }
-  }
-  EXPECT_EQ(0, count_false);
-#if LOG_NDEBUG
-  ASSERT_EQ(8, count);
-#else
-  ASSERT_EQ(10, count);
-#endif
-
-#else
-  GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
-#endif
-}
diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp
deleted file mode 100644
index 7acd363..0000000
--- a/liblog/tests/log_read_test.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2013-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android/log.h>  // minimal logging API
-#include <gtest/gtest.h>
-#include <log/log_properties.h>
-// Test the APIs in this standalone include file
-#include <log/log_read.h>
-// Do not use anything in log/log_time.h despite side effects of the above.
-#include <private/android_logger.h>
-
-using android::base::GetBoolProperty;
-
-TEST(liblog, android_logger_get_) {
-#ifdef __ANDROID__
-  // This test assumes the log buffers are filled with noise from
-  // normal operations. It will fail if done immediately after a
-  // logcat -c.
-  struct logger_list* logger_list = android_logger_list_alloc(0, 0, 0);
-
-  for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
-    log_id_t id = static_cast<log_id_t>(i);
-    std::string name = android_log_id_to_name(id);
-    fprintf(stderr, "log buffer %s\r", name.c_str());
-    struct logger* logger;
-    EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
-    EXPECT_EQ(id, android_logger_get_id(logger));
-    ssize_t get_log_size = android_logger_get_log_size(logger);
-    /* security buffer is allowed to be denied */
-    if (name != "security") {
-      EXPECT_GT(get_log_size, 0);
-      // crash buffer is allowed to be empty, that is actually healthy!
-      // stats buffer is no longer in use.
-      if (name == "crash" || name == "stats") {
-        continue;
-      }
-
-      // kernel buffer is empty if ro.logd.kernel is false
-      if (name == "kernel" && !GetBoolProperty("ro.logd.kernel", false)) {
-        continue;
-      }
-
-      EXPECT_LE(0, android_logger_get_log_readable_size(logger));
-    } else {
-      EXPECT_NE(0, get_log_size);
-      if (get_log_size < 0) {
-        EXPECT_GT(0, android_logger_get_log_readable_size(logger));
-      } else {
-        EXPECT_LE(0, android_logger_get_log_readable_size(logger));
-      }
-    }
-  }
-
-  android_logger_list_close(logger_list);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
diff --git a/liblog/tests/log_system_test.cpp b/liblog/tests/log_system_test.cpp
deleted file mode 100644
index 13f026d..0000000
--- a/liblog/tests/log_system_test.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <gtest/gtest.h>
-// Test the APIs in this standalone include file
-#include <log/log_system.h>
-
-TEST(liblog, SLOG) {
-  static const char content[] = "log_system.h";
-  static const char content_false[] = "log_system.h false";
-
-// ratelimit content to 10/s to keep away from spam filters
-// do not send identical content together to keep away from spam filters
-
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGV"
-  SLOGV(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGD"
-  SLOGD(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGI"
-  SLOGI(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGW"
-  SLOGW(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGE"
-  SLOGE(content);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGV"
-  SLOGV_IF(true, content);
-  usleep(100000);
-  SLOGV_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGD"
-  SLOGD_IF(true, content);
-  usleep(100000);
-  SLOGD_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGI"
-  SLOGI_IF(true, content);
-  usleep(100000);
-  SLOGI_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGW"
-  SLOGW_IF(true, content);
-  usleep(100000);
-  SLOGW_IF(false, content_false);
-  usleep(100000);
-#undef LOG_TAG
-#define LOG_TAG "TEST__SLOGE"
-  SLOGE_IF(true, content);
-  usleep(100000);
-  SLOGE_IF(false, content_false);
-
-#ifdef __ANDROID__
-  // give time for content to long-path through logger
-  sleep(1);
-
-  std::string buf = android::base::StringPrintf(
-      "logcat -b system --pid=%u -d -s"
-      " TEST__SLOGV TEST__SLOGD TEST__SLOGI TEST__SLOGW TEST__SLOGE",
-      (unsigned)getpid());
-  FILE* fp = popen(buf.c_str(), "re");
-  int count = 0;
-  int count_false = 0;
-  if (fp) {
-    if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
-    pclose(fp);
-    for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos;
-         ++pos) {
-      ++count;
-    }
-    for (size_t pos = 0;
-         (pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
-      ++count_false;
-    }
-  }
-  EXPECT_EQ(0, count_false);
-#if LOG_NDEBUG
-  ASSERT_EQ(8, count);
-#else
-  ASSERT_EQ(10, count);
-#endif
-
-#else
-  GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
-#endif
-}
diff --git a/liblog/tests/log_time_test.cpp b/liblog/tests/log_time_test.cpp
deleted file mode 100644
index 47fe594..0000000
--- a/liblog/tests/log_time_test.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <time.h>
-
-#include <gtest/gtest.h>
-// Test the APIs in this standalone include file
-#include <log/log_time.h>
-
-TEST(liblog, log_time) {
-  struct timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  log_time tl(ts);
-
-  EXPECT_EQ(tl, ts);
-  EXPECT_GE(tl, ts);
-  EXPECT_LE(tl, ts);
-}
diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp
deleted file mode 100644
index 755898a..0000000
--- a/liblog/tests/log_wrap_test.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2013-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/chrono_utils.h>
-#include <android-base/stringprintf.h>
-#include <android/log.h>  // minimal logging API
-#include <gtest/gtest.h>
-#include <log/log_properties.h>
-#include <log/log_read.h>
-#include <log/log_time.h>
-
-#ifdef __ANDROID__
-static void read_with_wrap() {
-  // Read the last line in the log to get a starting timestamp. We're assuming
-  // the log is not empty.
-  const int mode = ANDROID_LOG_NONBLOCK;
-  struct logger_list* logger_list =
-      android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0);
-
-  ASSERT_NE(logger_list, nullptr);
-
-  log_msg log_msg;
-  int ret = android_logger_list_read(logger_list, &log_msg);
-  android_logger_list_close(logger_list);
-  ASSERT_GT(ret, 0);
-
-  log_time start(log_msg.entry.sec, log_msg.entry.nsec);
-  ASSERT_NE(start, log_time());
-
-  logger_list =
-      android_logger_list_alloc_time(mode | ANDROID_LOG_WRAP, start, 0);
-  ASSERT_NE(logger_list, nullptr);
-
-  struct logger* logger = android_logger_open(logger_list, LOG_ID_MAIN);
-  EXPECT_NE(logger, nullptr);
-  if (logger) {
-    android_logger_list_read(logger_list, &log_msg);
-  }
-
-  android_logger_list_close(logger_list);
-}
-#endif
-
-// b/64143705 confirm fixed
-TEST(liblog, wrap_mode_blocks) {
-#ifdef __ANDROID__
-  // The read call is expected to take up to 2 hours in the happy case.  There was a previous bug
-  // where it would take only 30 seconds due to an alarm() in logd_reader.cpp.  That alarm has been
-  // removed, so we check here that the read call blocks for a reasonable amount of time (5s).
-
-  struct sigaction ignore = {.sa_handler = [](int) { _exit(0); }};
-  struct sigaction old_sigaction;
-  sigaction(SIGALRM, &ignore, &old_sigaction);
-  alarm(5);
-
-  android::base::Timer timer;
-  read_with_wrap();
-
-  FAIL() << "read_with_wrap() should not return before the alarm is triggered.";
-
-  alarm(0);
-  sigaction(SIGALRM, &old_sigaction, nullptr);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
diff --git a/liblog/tests/logd_writer_test.cpp b/liblog/tests/logd_writer_test.cpp
deleted file mode 100644
index b8e4726..0000000
--- a/liblog/tests/logd_writer_test.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2020 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 <sys/un.h>
-#include <unistd.h>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-#include <gtest/gtest.h>
-
-using android::base::StringPrintf;
-using android::base::unique_fd;
-
-// logd_writer takes advantage of the fact that connect() can be called multiple times for a DGRAM
-// socket.  This tests for that behavior.
-TEST(liblog, multi_connect_dgram_socket) {
-#ifdef __ANDROID__
-  if (getuid() != 0) {
-    GTEST_SKIP() << "Skipping test, must be run as root.";
-    return;
-  }
-  auto temp_dir = TemporaryDir();
-  auto socket_path = StringPrintf("%s/test_socket", temp_dir.path);
-
-  unique_fd server_socket;
-
-  auto open_server_socket = [&] {
-    server_socket.reset(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)));
-    ASSERT_TRUE(server_socket.ok());
-
-    sockaddr_un server_sockaddr = {};
-    server_sockaddr.sun_family = AF_UNIX;
-    strlcpy(server_sockaddr.sun_path, socket_path.c_str(), sizeof(server_sockaddr.sun_path));
-    ASSERT_EQ(0,
-              TEMP_FAILURE_RETRY(bind(server_socket, reinterpret_cast<sockaddr*>(&server_sockaddr),
-                                      sizeof(server_sockaddr))));
-  };
-
-  // Open the server socket.
-  open_server_socket();
-
-  // Open the client socket.
-  auto client_socket =
-      unique_fd{TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0))};
-  ASSERT_TRUE(client_socket.ok());
-  sockaddr_un client_sockaddr = {};
-  client_sockaddr.sun_family = AF_UNIX;
-  strlcpy(client_sockaddr.sun_path, socket_path.c_str(), sizeof(client_sockaddr.sun_path));
-  ASSERT_EQ(0,
-            TEMP_FAILURE_RETRY(connect(client_socket, reinterpret_cast<sockaddr*>(&client_sockaddr),
-                                       sizeof(client_sockaddr))));
-
-  // Ensure that communication works.
-  constexpr static char kSmoke[] = "smoke test";
-  ssize_t smoke_len = sizeof(kSmoke);
-  ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(write(client_socket, kSmoke, sizeof(kSmoke))));
-  char read_buf[512];
-  ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(read(server_socket, read_buf, sizeof(read_buf))));
-  ASSERT_STREQ(kSmoke, read_buf);
-
-  // Close the server socket.
-  server_socket.reset();
-  ASSERT_EQ(0, unlink(socket_path.c_str())) << strerror(errno);
-
-  // Ensure that write() from the client returns an error since the server is closed.
-  ASSERT_EQ(-1, TEMP_FAILURE_RETRY(write(client_socket, kSmoke, sizeof(kSmoke))));
-  ASSERT_EQ(errno, ECONNREFUSED) << strerror(errno);
-
-  // Open the server socket again.
-  open_server_socket();
-
-  // Reconnect the same client socket.
-  ASSERT_EQ(0,
-            TEMP_FAILURE_RETRY(connect(client_socket, reinterpret_cast<sockaddr*>(&client_sockaddr),
-                                       sizeof(client_sockaddr))))
-      << strerror(errno);
-
-  // Ensure that communication works.
-  ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(write(client_socket, kSmoke, sizeof(kSmoke))));
-  ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(read(server_socket, read_buf, sizeof(read_buf))));
-  ASSERT_STREQ(kSmoke, read_buf);
-#else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
\ No newline at end of file
diff --git a/liblog/tests/logprint_test.cpp b/liblog/tests/logprint_test.cpp
deleted file mode 100644
index 72e53f9..0000000
--- a/liblog/tests/logprint_test.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2019 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 <log/logprint.h>
-
-#include <string>
-
-#include <gtest/gtest.h>
-
-#include <log/log_read.h>
-
-size_t convertPrintable(char* p, const char* message, size_t messageLen);
-
-TEST(liblog, convertPrintable_ascii) {
-  auto input = "easy string, output same";
-  auto output_size = convertPrintable(nullptr, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(input));
-
-  char output[output_size];
-
-  output_size = convertPrintable(output, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(input));
-  EXPECT_STREQ(input, output);
-}
-
-TEST(liblog, convertPrintable_escapes) {
-  // Note that \t is not escaped.
-  auto input = "escape\a\b\t\v\f\r\\";
-  auto expected_output = "escape\\a\\b\t\\v\\f\\r\\\\";
-  auto output_size = convertPrintable(nullptr, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(expected_output));
-
-  char output[output_size];
-
-  output_size = convertPrintable(output, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(expected_output));
-  EXPECT_STREQ(expected_output, output);
-}
-
-TEST(liblog, convertPrintable_validutf8) {
-  auto input = u8"¢ह€𐍈";
-  auto output_size = convertPrintable(nullptr, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(input));
-
-  char output[output_size];
-
-  output_size = convertPrintable(output, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(input));
-  EXPECT_STREQ(input, output);
-}
-
-TEST(liblog, convertPrintable_invalidutf8) {
-  auto input = "\x80\xC2\x01\xE0\xA4\x06\xE0\x06\xF0\x90\x8D\x06\xF0\x90\x06\xF0\x0E";
-  auto expected_output =
-      "\\x80\\xC2\\x01\\xE0\\xA4\\x06\\xE0\\x06\\xF0\\x90\\x8D\\x06\\xF0\\x90\\x06\\xF0\\x0E";
-  auto output_size = convertPrintable(nullptr, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(expected_output));
-
-  char output[output_size];
-
-  output_size = convertPrintable(output, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(expected_output));
-  EXPECT_STREQ(expected_output, output);
-}
-
-TEST(liblog, convertPrintable_mixed) {
-  auto input =
-      u8"\x80\xC2¢ह€𐍈\x01\xE0\xA4\x06¢ह€𐍈\xE0\x06\a\b\xF0\x90¢ह€𐍈\x8D\x06\xF0\t\t\x90\x06\xF0\x0E";
-  auto expected_output =
-      u8"\\x80\\xC2¢ह€𐍈\\x01\\xE0\\xA4\\x06¢ह€𐍈\\xE0\\x06\\a\\b\\xF0\\x90¢ह€𐍈\\x8D\\x06\\xF0\t\t"
-      u8"\\x90\\x06\\xF0\\x0E";
-  auto output_size = convertPrintable(nullptr, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(expected_output));
-
-  char output[output_size];
-
-  output_size = convertPrintable(output, input, strlen(input));
-  EXPECT_EQ(output_size, strlen(expected_output));
-  EXPECT_STREQ(expected_output, output);
-}
-
-TEST(liblog, log_print_different_header_size) {
-  constexpr int32_t kPid = 123;
-  constexpr uint32_t kTid = 456;
-  constexpr uint32_t kSec = 1000;
-  constexpr uint32_t kNsec = 999;
-  constexpr uint32_t kLid = LOG_ID_MAIN;
-  constexpr uint32_t kUid = 987;
-  constexpr char kPriority = ANDROID_LOG_ERROR;
-
-  auto create_buf = [](char* buf, size_t len, uint16_t hdr_size) {
-    memset(buf, 0, len);
-    logger_entry* header = reinterpret_cast<logger_entry*>(buf);
-    header->hdr_size = hdr_size;
-    header->pid = kPid;
-    header->tid = kTid;
-    header->sec = kSec;
-    header->nsec = kNsec;
-    header->lid = kLid;
-    header->uid = kUid;
-    char* message = buf + header->hdr_size;
-    uint16_t message_len = 0;
-    message[message_len++] = kPriority;
-    message[message_len++] = 'T';
-    message[message_len++] = 'a';
-    message[message_len++] = 'g';
-    message[message_len++] = '\0';
-    message[message_len++] = 'm';
-    message[message_len++] = 's';
-    message[message_len++] = 'g';
-    message[message_len++] = '!';
-    message[message_len++] = '\0';
-    header->len = message_len;
-  };
-
-  auto check_entry = [&](const AndroidLogEntry& entry) {
-    EXPECT_EQ(kSec, static_cast<uint32_t>(entry.tv_sec));
-    EXPECT_EQ(kNsec, static_cast<uint32_t>(entry.tv_nsec));
-    EXPECT_EQ(kPriority, entry.priority);
-    EXPECT_EQ(kUid, static_cast<uint32_t>(entry.uid));
-    EXPECT_EQ(kPid, entry.pid);
-    EXPECT_EQ(kTid, static_cast<uint32_t>(entry.tid));
-    EXPECT_STREQ("Tag", entry.tag);
-    EXPECT_EQ(4U, entry.tagLen);  // Apparently taglen includes the nullptr?
-    EXPECT_EQ(4U, entry.messageLen);
-    EXPECT_STREQ("msg!", entry.message);
-  };
-  alignas(logger_entry) char buf[LOGGER_ENTRY_MAX_LEN];
-  create_buf(buf, sizeof(buf), sizeof(logger_entry));
-
-  AndroidLogEntry entry_normal_size;
-  ASSERT_EQ(0,
-            android_log_processLogBuffer(reinterpret_cast<logger_entry*>(buf), &entry_normal_size));
-  check_entry(entry_normal_size);
-
-  create_buf(buf, sizeof(buf), sizeof(logger_entry) + 3);
-  AndroidLogEntry entry_odd_size;
-  ASSERT_EQ(0, android_log_processLogBuffer(reinterpret_cast<logger_entry*>(buf), &entry_odd_size));
-  check_entry(entry_odd_size);
-}
\ No newline at end of file
diff --git a/liblog/uio.h b/liblog/uio.h
deleted file mode 100644
index c85893c..0000000
--- a/liblog/uio.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#if defined(_WIN32)
-#include <stddef.h>
-struct iovec {
-  void* iov_base;
-  size_t iov_len;
-};
-#else
-#include <sys/uio.h>
-#endif
diff --git a/libprocessgroup/profiles/Android.bp b/libprocessgroup/profiles/Android.bp
index ccc6f62..c371ef7 100644
--- a/libprocessgroup/profiles/Android.bp
+++ b/libprocessgroup/profiles/Android.bp
@@ -104,8 +104,3 @@
         "vts",
     ],
 }
-
-vts_config {
-    name: "VtsProcessgroupValidateTest",
-    test_config: "vts_processgroup_validate_test.xml",
-}
diff --git a/libprocessgroup/profiles/vts_processgroup_validate_test.xml b/libprocessgroup/profiles/vts_processgroup_validate_test.xml
deleted file mode 100644
index 21d29cd..0000000
--- a/libprocessgroup/profiles/vts_processgroup_validate_test.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-<configuration description="Config for VtsProcessgroupValidateTest">
-    <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
-        <option name="abort-on-push-failure" value="false"/>
-        <option name="push-group" value="HostDrivenTest.push"/>
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-        <option name="test-module-name" value="VtsProcessgroupValidateTest"/>
-        <option name="binary-test-working-directory" value="_32bit::/data/nativetest/" />
-        <option name="binary-test-working-directory" value="_64bit::/data/nativetest64/" />
-        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_processgroup_validate_test/vts_processgroup_validate_test" />
-        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_processgroup_validate_test/vts_processgroup_validate_test" />
-        <option name="binary-test-type" value="gtest"/>
-        <option name="binary-test-disable-framework" value="false"/>
-        <option name="test-timeout" value="30s"/>
-    </test>
-</configuration>
diff --git a/libstats/push_compat/Android.bp b/libstats/push_compat/Android.bp
index a63a5b6..43ae69d 100644
--- a/libstats/push_compat/Android.bp
+++ b/libstats/push_compat/Android.bp
@@ -32,7 +32,10 @@
         "-DWRITE_TO_STATSD=1",
         "-DWRITE_TO_LOGD=0",
     ],
-    header_libs: ["libstatssocket_headers"],
+    header_libs: [
+        "libcutils_headers",
+        "libstatssocket_headers",
+    ],
     static_libs: [
         "libbase",
     ],
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 8cc780a..7770b13 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -131,7 +131,6 @@
         support_system_process: true,
     },
     defaults: ["libunwindstack_defaults"],
-
     srcs: ["DexFile.cpp"],
     cflags: ["-DDEXFILE_SUPPORT"],
     shared_libs: ["libdexfile_support"],
@@ -168,6 +167,7 @@
     defaults: ["libunwindstack_defaults"],
 
     visibility: [
+        "//external/gwp_asan",
         "//system/core/debuggerd",
         "//system/core/init",
         "//system/core/libbacktrace",
@@ -296,6 +296,8 @@
         "tests/files/offline/shared_lib_in_apk_memory_only_arm64/*",
         "tests/files/offline/shared_lib_in_apk_single_map_arm64/*",
         "tests/files/offline/signal_load_bias_arm/*",
+        "tests/files/offline/signal_fde_x86/*",
+        "tests/files/offline/signal_fde_x86_64/*",
         "tests/files/offline/straddle_arm/*",
         "tests/files/offline/straddle_arm64/*",
     ],
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index bf86e6e..ad25e80 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -37,7 +37,8 @@
 
 DwarfSection::DwarfSection(Memory* memory) : memory_(memory) {}
 
-bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
+bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished,
+                        bool* is_signal_frame) {
   // Lookup the pc in the cache.
   auto it = loc_regs_.upper_bound(pc);
   if (it == loc_regs_.end() || pc < it->second.pc_start) {
@@ -59,6 +60,8 @@
     it = loc_regs_.emplace(loc_regs.pc_end, std::move(loc_regs)).first;
   }
 
+  *is_signal_frame = it->second.cie->is_signal_frame;
+
   // Now eval the actual registers.
   return Eval(it->second.cie, process_memory, it->second, regs, finished);
 }
@@ -241,6 +244,9 @@
           return false;
         }
         break;
+      case 'S':
+        cie->is_signal_frame = true;
+        break;
     }
   }
   return true;
@@ -558,8 +564,10 @@
     cur_regs->set_pc((*cur_regs)[cie->return_address_register]);
   }
 
-  // If the pc was set to zero, consider this the final frame.
-  *finished = (cur_regs->pc() == 0) ? true : false;
+  // If the pc was set to zero, consider this the final frame. Exception: if
+  // this is the sigreturn frame, then we want to try to recover the real PC
+  // using the return address (from LR or the stack), so keep going.
+  *finished = (cur_regs->pc() == 0 && !cie->is_signal_frame) ? true : false;
 
   cur_regs->set_sp(eval_info.cfa);
 
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index 286febc..e098a58 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -188,14 +188,15 @@
 }
 
 // The relative pc is always relative to the start of the map from which it comes.
-bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) {
+bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished,
+               bool* is_signal_frame) {
   if (!valid_) {
     return false;
   }
 
   // Lock during the step which can update information in the object.
   std::lock_guard<std::mutex> guard(lock_);
-  return interface_->Step(rel_pc, regs, process_memory, finished);
+  return interface_->Step(rel_pc, regs, process_memory, finished, is_signal_frame);
 }
 
 bool Elf::IsValidElf(Memory* memory) {
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 17470fd..0188def 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -499,25 +499,27 @@
   return false;
 }
 
-bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
+bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished,
+                        bool* is_signal_frame) {
   last_error_.code = ERROR_NONE;
   last_error_.address = 0;
 
   // Try the debug_frame first since it contains the most specific unwind
   // information.
   DwarfSection* debug_frame = debug_frame_.get();
-  if (debug_frame != nullptr && debug_frame->Step(pc, regs, process_memory, finished)) {
+  if (debug_frame != nullptr &&
+      debug_frame->Step(pc, regs, process_memory, finished, is_signal_frame)) {
     return true;
   }
 
   // Try the eh_frame next.
   DwarfSection* eh_frame = eh_frame_.get();
-  if (eh_frame != nullptr && eh_frame->Step(pc, regs, process_memory, finished)) {
+  if (eh_frame != nullptr && eh_frame->Step(pc, regs, process_memory, finished, is_signal_frame)) {
     return true;
   }
 
   if (gnu_debugdata_interface_ != nullptr &&
-      gnu_debugdata_interface_->Step(pc, regs, process_memory, finished)) {
+      gnu_debugdata_interface_->Step(pc, regs, process_memory, finished, is_signal_frame)) {
     return true;
   }
 
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp
index 76f2dc8..9352a5d 100644
--- a/libunwindstack/ElfInterfaceArm.cpp
+++ b/libunwindstack/ElfInterfaceArm.cpp
@@ -100,12 +100,13 @@
   total_entries_ = ph_filesz / 8;
 }
 
-bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
+bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished,
+                           bool* is_signal_frame) {
   // Dwarf unwind information is precise about whether a pc is covered or not,
   // but arm unwind information only has ranges of pc. In order to avoid
   // incorrectly doing a bad unwind using arm unwind information for a
   // different function, always try and unwind with the dwarf information first.
-  return ElfInterface32::Step(pc, regs, process_memory, finished) ||
+  return ElfInterface32::Step(pc, regs, process_memory, finished, is_signal_frame) ||
          StepExidx(pc, regs, process_memory, finished);
 }
 
diff --git a/libunwindstack/ElfInterfaceArm.h b/libunwindstack/ElfInterfaceArm.h
index 1d71cac..fd824f8 100644
--- a/libunwindstack/ElfInterfaceArm.h
+++ b/libunwindstack/ElfInterfaceArm.h
@@ -72,7 +72,8 @@
 
   void HandleUnknownType(uint32_t type, uint64_t ph_offset, uint64_t ph_filesz) override;
 
-  bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) override;
+  bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished,
+            bool* is_signal_frame) override;
 
   bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished);
 
diff --git a/libunwindstack/LocalUnwinder.cpp b/libunwindstack/LocalUnwinder.cpp
index 05650fb..5f51a73 100644
--- a/libunwindstack/LocalUnwinder.cpp
+++ b/libunwindstack/LocalUnwinder.cpp
@@ -113,9 +113,11 @@
     step_pc -= pc_adjustment;
 
     bool finished = false;
+    bool is_signal_frame = false;
     if (elf->StepIfSignalHandler(rel_pc, regs.get(), process_memory_.get())) {
       step_pc = rel_pc;
-    } else if (!elf->Step(step_pc, regs.get(), process_memory_.get(), &finished)) {
+    } else if (!elf->Step(step_pc, regs.get(), process_memory_.get(), &finished,
+                          &is_signal_frame)) {
       finished = true;
     }
 
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 57806c1..9ffc0f7 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -27,6 +27,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 
+#include <unwindstack/DexFiles.h>
 #include <unwindstack/Elf.h>
 #include <unwindstack/JitDebug.h>
 #include <unwindstack/MapInfo.h>
@@ -34,7 +35,7 @@
 #include <unwindstack/Memory.h>
 #include <unwindstack/Unwinder.h>
 
-#include <unwindstack/DexFiles.h>
+#include "Check.h"
 
 // Use the demangler from libc++.
 extern "C" char* __cxa_demangle(const char*, char*, size_t*, int* status);
@@ -142,13 +143,11 @@
 
 void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
                       const std::vector<std::string>* map_suffixes_to_ignore) {
-  frames_.clear();
-  warnings_ = WARNING_NONE;
-  last_error_.code = ERROR_NONE;
-  last_error_.address = 0;
-  elf_from_memory_not_file_ = false;
+  CHECK(arch_ != ARCH_UNKNOWN);
+  ClearErrors();
 
-  ArchEnum arch = regs_->Arch();
+  frames_.clear();
+  elf_from_memory_not_file_ = false;
 
   bool return_address_attempt = false;
   bool adjust_pc = false;
@@ -169,7 +168,7 @@
       if (ShouldStop(map_suffixes_to_ignore, map_info->name)) {
         break;
       }
-      elf = map_info->GetElf(process_memory_, arch);
+      elf = map_info->GetElf(process_memory_, arch_);
       // If this elf is memory backed, and there is a valid file, then set
       // an indicator that we couldn't open the file.
       if (!elf_from_memory_not_file_ && map_info->memory_backed_elf && !map_info->name.empty() &&
@@ -183,7 +182,7 @@
         step_pc = rel_pc;
       }
       if (adjust_pc) {
-        pc_adjustment = GetPcAdjustment(rel_pc, elf, arch);
+        pc_adjustment = GetPcAdjustment(rel_pc, elf, arch_);
       } else {
         pc_adjustment = 0;
       }
@@ -243,18 +242,21 @@
           // some of the speculative frames.
           in_device_map = true;
         } else {
+          bool is_signal_frame = false;
           if (elf->StepIfSignalHandler(rel_pc, regs_, process_memory_.get())) {
             stepped = true;
-            if (frame != nullptr) {
-              // Need to adjust the relative pc because the signal handler
-              // pc should not be adjusted.
-              frame->rel_pc = rel_pc;
-              frame->pc += pc_adjustment;
-              step_pc = rel_pc;
-            }
-          } else if (elf->Step(step_pc, regs_, process_memory_.get(), &finished)) {
+            is_signal_frame = true;
+          } else if (elf->Step(step_pc, regs_, process_memory_.get(), &finished,
+                               &is_signal_frame)) {
             stepped = true;
           }
+          if (is_signal_frame && frame != nullptr) {
+            // Need to adjust the relative pc because the signal handler
+            // pc should not be adjusted.
+            frame->rel_pc = rel_pc;
+            frame->pc += pc_adjustment;
+            step_pc = rel_pc;
+          }
           elf->GetLastError(&last_error_);
         }
       }
@@ -311,7 +313,7 @@
 
 std::string Unwinder::FormatFrame(const FrameData& frame) const {
   std::string data;
-  if (regs_->Is32Bit()) {
+  if (ArchIs32Bit(arch_)) {
     data += android::base::StringPrintf("  #%02zu pc %08" PRIx64, frame.num, frame.rel_pc);
   } else {
     data += android::base::StringPrintf("  #%02zu pc %016" PRIx64, frame.num, frame.rel_pc);
@@ -362,23 +364,33 @@
   return FormatFrame(frames_[frame_num]);
 }
 
-void Unwinder::SetJitDebug(JitDebug* jit_debug, ArchEnum arch) {
-  jit_debug->SetArch(arch);
+void Unwinder::SetJitDebug(JitDebug* jit_debug) {
+  CHECK(arch_ != ARCH_UNKNOWN);
+  jit_debug->SetArch(arch_);
   jit_debug_ = jit_debug;
 }
 
-void Unwinder::SetDexFiles(DexFiles* dex_files, ArchEnum arch) {
-  dex_files->SetArch(arch);
+void Unwinder::SetDexFiles(DexFiles* dex_files) {
+  CHECK(arch_ != ARCH_UNKNOWN);
+  dex_files->SetArch(arch_);
   dex_files_ = dex_files;
 }
 
-bool UnwinderFromPid::Init(ArchEnum arch) {
+bool UnwinderFromPid::Init() {
+  CHECK(arch_ != ARCH_UNKNOWN);
+  if (initted_) {
+    return true;
+  }
+  initted_ = true;
+
   if (pid_ == getpid()) {
     maps_ptr_.reset(new LocalMaps());
   } else {
     maps_ptr_.reset(new RemoteMaps(pid_));
   }
   if (!maps_ptr_->Parse()) {
+    ClearErrors();
+    last_error_.code = ERROR_INVALID_MAP;
     return false;
   }
   maps_ = maps_ptr_.get();
@@ -387,16 +399,24 @@
 
   jit_debug_ptr_.reset(new JitDebug(process_memory_));
   jit_debug_ = jit_debug_ptr_.get();
-  SetJitDebug(jit_debug_, arch);
+  SetJitDebug(jit_debug_);
 #if defined(DEXFILE_SUPPORT)
   dex_files_ptr_.reset(new DexFiles(process_memory_));
   dex_files_ = dex_files_ptr_.get();
-  SetDexFiles(dex_files_, arch);
+  SetDexFiles(dex_files_);
 #endif
 
   return true;
 }
 
+void UnwinderFromPid::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
+                             const std::vector<std::string>* map_suffixes_to_ignore) {
+  if (!Init()) {
+    return;
+  }
+  Unwinder::Unwind(initial_map_names_to_skip, map_suffixes_to_ignore);
+}
+
 FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc, ArchEnum arch, Maps* maps,
                                          JitDebug* jit_debug,
                                          std::shared_ptr<Memory> process_memory,
@@ -449,8 +469,7 @@
 }
 
 FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc) {
-  return BuildFrameFromPcOnly(pc, regs_ ? regs_->Arch() : ARCH_UNKNOWN, maps_, jit_debug_,
-                              process_memory_, resolve_names_);
+  return BuildFrameFromPcOnly(pc, arch_, maps_, jit_debug_, process_memory_, resolve_names_);
 }
 
 }  // namespace unwindstack
diff --git a/libunwindstack/include/unwindstack/Arch.h b/libunwindstack/include/unwindstack/Arch.h
new file mode 100644
index 0000000..7060004
--- /dev/null
+++ b/libunwindstack/include/unwindstack/Arch.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef _LIBUNWINDSTACK_ARCH_H
+#define _LIBUNWINDSTACK_ARCH_H
+
+#include <stddef.h>
+
+namespace unwindstack {
+
+enum ArchEnum : uint8_t {
+  ARCH_UNKNOWN = 0,
+  ARCH_ARM,
+  ARCH_ARM64,
+  ARCH_X86,
+  ARCH_X86_64,
+  ARCH_MIPS,
+  ARCH_MIPS64,
+};
+
+static inline bool ArchIs32Bit(ArchEnum arch) {
+  switch (arch) {
+    case ARCH_ARM:
+    case ARCH_X86:
+    case ARCH_MIPS:
+      return true;
+    default:
+      return false;
+  }
+}
+
+}  // namespace unwindstack
+
+#endif  // _LIBUNWINDSTACK_ARCH_H
diff --git a/libunwindstack/include/unwindstack/DwarfSection.h b/libunwindstack/include/unwindstack/DwarfSection.h
index af823da..f28cf25 100644
--- a/libunwindstack/include/unwindstack/DwarfSection.h
+++ b/libunwindstack/include/unwindstack/DwarfSection.h
@@ -106,7 +106,7 @@
 
   virtual uint64_t AdjustPcFromFde(uint64_t pc) = 0;
 
-  bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished);
+  bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished, bool* is_signal_frame);
 
  protected:
   DwarfMemory memory_;
diff --git a/libunwindstack/include/unwindstack/DwarfStructs.h b/libunwindstack/include/unwindstack/DwarfStructs.h
index 4b481f0..3d8c2db 100644
--- a/libunwindstack/include/unwindstack/DwarfStructs.h
+++ b/libunwindstack/include/unwindstack/DwarfStructs.h
@@ -35,6 +35,7 @@
   uint64_t code_alignment_factor = 0;
   int64_t data_alignment_factor = 0;
   uint64_t return_address_register = 0;
+  bool is_signal_frame = false;
 };
 
 struct DwarfFde {
diff --git a/libunwindstack/include/unwindstack/Elf.h b/libunwindstack/include/unwindstack/Elf.h
index 472ed92..e15b221 100644
--- a/libunwindstack/include/unwindstack/Elf.h
+++ b/libunwindstack/include/unwindstack/Elf.h
@@ -25,6 +25,7 @@
 #include <unordered_map>
 #include <utility>
 
+#include <unwindstack/Arch.h>
 #include <unwindstack/ElfInterface.h>
 #include <unwindstack/Memory.h>
 
@@ -38,16 +39,6 @@
 struct MapInfo;
 class Regs;
 
-enum ArchEnum : uint8_t {
-  ARCH_UNKNOWN = 0,
-  ARCH_ARM,
-  ARCH_ARM64,
-  ARCH_X86,
-  ARCH_X86_64,
-  ARCH_MIPS,
-  ARCH_MIPS64,
-};
-
 class Elf {
  public:
   Elf(Memory* memory) : memory_(memory) {}
@@ -69,7 +60,8 @@
 
   bool StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory);
 
-  bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished);
+  bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished,
+            bool* is_signal_frame);
 
   ElfInterface* CreateInterfaceFromMemory(Memory* memory);
 
diff --git a/libunwindstack/include/unwindstack/ElfInterface.h b/libunwindstack/include/unwindstack/ElfInterface.h
index 0c39b23..5df7ddf 100644
--- a/libunwindstack/include/unwindstack/ElfInterface.h
+++ b/libunwindstack/include/unwindstack/ElfInterface.h
@@ -64,7 +64,8 @@
 
   virtual std::string GetBuildID() = 0;
 
-  virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished);
+  virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished,
+                    bool* is_signal_frame);
 
   virtual bool IsValidPc(uint64_t pc);
 
diff --git a/libunwindstack/include/unwindstack/Error.h b/libunwindstack/include/unwindstack/Error.h
index 66fefe7..0be4572 100644
--- a/libunwindstack/include/unwindstack/Error.h
+++ b/libunwindstack/include/unwindstack/Error.h
@@ -39,6 +39,27 @@
   ERROR_INVALID_ELF,          // Unwind in an invalid elf.
 };
 
+static inline const char* GetErrorCodeString(ErrorCode error) {
+  switch (error) {
+    case ERROR_NONE:
+      return "None";
+    case ERROR_MEMORY_INVALID:
+      return "Memory Invalid";
+    case ERROR_UNWIND_INFO:
+      return "Unwind Info";
+    case ERROR_UNSUPPORTED:
+      return "Unsupported";
+    case ERROR_INVALID_MAP:
+      return "Invalid Map";
+    case ERROR_MAX_FRAMES_EXCEEDED:
+      return "Maximum Frames Exceeded";
+    case ERROR_REPEATED_FRAME:
+      return "Repeated Frame";
+    case ERROR_INVALID_ELF:
+      return "Invalid Elf";
+  }
+}
+
 struct ErrorData {
   ErrorCode code;
   uint64_t address;  // Only valid when code is ERROR_MEMORY_INVALID.
diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h
index 5f42565..1a2a704 100644
--- a/libunwindstack/include/unwindstack/Regs.h
+++ b/libunwindstack/include/unwindstack/Regs.h
@@ -24,11 +24,12 @@
 #include <string>
 #include <vector>
 
+#include <unwindstack/Arch.h>
+
 namespace unwindstack {
 
 // Forward declarations.
 class Elf;
-enum ArchEnum : uint8_t;
 class Memory;
 
 class Regs {
@@ -52,7 +53,7 @@
 
   virtual ArchEnum Arch() = 0;
 
-  virtual bool Is32Bit() = 0;
+  bool Is32Bit() { return ArchIs32Bit(Arch()); }
 
   virtual void* RawData() = 0;
   virtual uint64_t pc() = 0;
@@ -96,8 +97,6 @@
       : Regs(total_regs, return_loc), regs_(total_regs) {}
   virtual ~RegsImpl() = default;
 
-  bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); }
-
   inline AddressType& operator[](size_t reg) { return regs_[reg]; }
 
   void* RawData() override { return regs_.data(); }
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index 3df8aad..b274c4c 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -24,6 +24,7 @@
 #include <string>
 #include <vector>
 
+#include <unwindstack/Arch.h>
 #include <unwindstack/DexFiles.h>
 #include <unwindstack/Error.h>
 #include <unwindstack/JitDebug.h>
@@ -35,7 +36,6 @@
 
 // Forward declarations.
 class Elf;
-enum ArchEnum : uint8_t;
 
 struct FrameData {
   size_t num;
@@ -64,7 +64,11 @@
 class Unwinder {
  public:
   Unwinder(size_t max_frames, Maps* maps, Regs* regs, std::shared_ptr<Memory> process_memory)
-      : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) {
+      : max_frames_(max_frames),
+        maps_(maps),
+        regs_(regs),
+        process_memory_(process_memory),
+        arch_(regs->Arch()) {
     frames_.reserve(max_frames);
   }
   Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory)
@@ -74,8 +78,8 @@
 
   virtual ~Unwinder() = default;
 
-  void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
-              const std::vector<std::string>* map_suffixes_to_ignore = nullptr);
+  virtual void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
+                      const std::vector<std::string>* map_suffixes_to_ignore = nullptr);
 
   size_t NumFrames() const { return frames_.size(); }
 
@@ -90,9 +94,14 @@
   std::string FormatFrame(size_t frame_num) const;
   std::string FormatFrame(const FrameData& frame) const;
 
-  void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);
+  void SetArch(ArchEnum arch) { arch_ = arch; };
 
-  void SetRegs(Regs* regs) { regs_ = regs; }
+  void SetJitDebug(JitDebug* jit_debug);
+
+  void SetRegs(Regs* regs) {
+    regs_ = regs;
+    arch_ = regs_ != nullptr ? regs->Arch() : ARCH_UNKNOWN;
+  }
   Maps* GetMaps() { return maps_; }
   std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; }
 
@@ -107,11 +116,12 @@
 
   void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; }
 
-  void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
+  void SetDexFiles(DexFiles* dex_files);
 
   bool elf_from_memory_not_file() { return elf_from_memory_not_file_; }
 
   ErrorCode LastErrorCode() { return last_error_.code; }
+  const char* LastErrorCodeString() { return GetErrorCodeString(last_error_.code); }
   uint64_t LastErrorAddress() { return last_error_.address; }
   uint64_t warnings() { return warnings_; }
 
@@ -126,6 +136,15 @@
 
  protected:
   Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); }
+  Unwinder(size_t max_frames, ArchEnum arch) : max_frames_(max_frames), arch_(arch) {
+    frames_.reserve(max_frames);
+  }
+
+  void ClearErrors() {
+    warnings_ = WARNING_NONE;
+    last_error_.code = ERROR_NONE;
+    last_error_.address = 0;
+  }
 
   void FillInDexFrame();
   FrameData* FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t pc_adjustment);
@@ -145,20 +164,27 @@
   bool elf_from_memory_not_file_ = false;
   ErrorData last_error_;
   uint64_t warnings_;
+  ArchEnum arch_ = ARCH_UNKNOWN;
 };
 
 class UnwinderFromPid : public Unwinder {
  public:
   UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {}
+  UnwinderFromPid(size_t max_frames, pid_t pid, ArchEnum arch)
+      : Unwinder(max_frames, arch), pid_(pid) {}
   virtual ~UnwinderFromPid() = default;
 
-  bool Init(ArchEnum arch);
+  bool Init();
+
+  void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
+              const std::vector<std::string>* map_suffixes_to_ignore = nullptr) override;
 
  private:
   pid_t pid_;
   std::unique_ptr<Maps> maps_ptr_;
   std::unique_ptr<JitDebug> jit_debug_ptr_;
   std::unique_ptr<DexFiles> dex_files_ptr_;
+  bool initted_ = false;
 };
 
 }  // namespace unwindstack
diff --git a/libunwindstack/tests/DwarfSectionTest.cpp b/libunwindstack/tests/DwarfSectionTest.cpp
index febd6d3..e5a1aed 100644
--- a/libunwindstack/tests/DwarfSectionTest.cpp
+++ b/libunwindstack/tests/DwarfSectionTest.cpp
@@ -68,7 +68,8 @@
   EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(nullptr));
 
   bool finished;
-  ASSERT_FALSE(section_->Step(0x1000, nullptr, nullptr, &finished));
+  bool is_signal_frame;
+  ASSERT_FALSE(section_->Step(0x1000, nullptr, nullptr, &finished, &is_signal_frame));
 }
 
 TEST_F(DwarfSectionTest, Step_fail_cie_null) {
@@ -79,7 +80,8 @@
   EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(&fde));
 
   bool finished;
-  ASSERT_FALSE(section_->Step(0x1000, &regs_, nullptr, &finished));
+  bool is_signal_frame;
+  ASSERT_FALSE(section_->Step(0x1000, &regs_, nullptr, &finished, &is_signal_frame));
 }
 
 TEST_F(DwarfSectionTest, Step_fail_cfa_location) {
@@ -93,7 +95,8 @@
       .WillOnce(::testing::Return(false));
 
   bool finished;
-  ASSERT_FALSE(section_->Step(0x1000, &regs_, nullptr, &finished));
+  bool is_signal_frame;
+  ASSERT_FALSE(section_->Step(0x1000, &regs_, nullptr, &finished, &is_signal_frame));
 }
 
 TEST_F(DwarfSectionTest, Step_pass) {
@@ -111,7 +114,8 @@
       .WillOnce(::testing::Return(true));
 
   bool finished;
-  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished));
+  bool is_signal_frame;
+  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished, &is_signal_frame));
 }
 
 static bool MockGetCfaLocationInfo(::testing::Unused, const DwarfFde* fde,
@@ -137,9 +141,10 @@
       .WillRepeatedly(::testing::Return(true));
 
   bool finished;
-  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished));
-  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished));
-  ASSERT_TRUE(section_->Step(0x1500, &regs_, &process, &finished));
+  bool is_signal_frame;
+  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished, &is_signal_frame));
+  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished, &is_signal_frame));
+  ASSERT_TRUE(section_->Step(0x1500, &regs_, &process, &finished, &is_signal_frame));
 }
 
 TEST_F(DwarfSectionTest, Step_cache_not_in_pc) {
@@ -157,7 +162,8 @@
       .WillRepeatedly(::testing::Return(true));
 
   bool finished;
-  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished));
+  bool is_signal_frame;
+  ASSERT_TRUE(section_->Step(0x1000, &regs_, &process, &finished, &is_signal_frame));
 
   DwarfFde fde1{};
   fde1.pc_start = 0x500;
@@ -167,8 +173,8 @@
   EXPECT_CALL(*section_, GetCfaLocationInfo(0x600, &fde1, ::testing::_, ::testing::_))
       .WillOnce(::testing::Invoke(MockGetCfaLocationInfo));
 
-  ASSERT_TRUE(section_->Step(0x600, &regs_, &process, &finished));
-  ASSERT_TRUE(section_->Step(0x700, &regs_, &process, &finished));
+  ASSERT_TRUE(section_->Step(0x600, &regs_, &process, &finished, &is_signal_frame));
+  ASSERT_TRUE(section_->Step(0x700, &regs_, &process, &finished, &is_signal_frame));
 }
 
 }  // namespace unwindstack
diff --git a/libunwindstack/tests/ElfFake.cpp b/libunwindstack/tests/ElfFake.cpp
index 3d5ddd6..b16cd53 100644
--- a/libunwindstack/tests/ElfFake.cpp
+++ b/libunwindstack/tests/ElfFake.cpp
@@ -52,7 +52,7 @@
   return true;
 }
 
-bool ElfInterfaceFake::Step(uint64_t, Regs* regs, Memory*, bool* finished) {
+bool ElfInterfaceFake::Step(uint64_t, Regs* regs, Memory*, bool* finished, bool* is_signal_frame) {
   if (steps_.empty()) {
     return false;
   }
@@ -68,6 +68,7 @@
   fake_regs->set_pc(entry.pc);
   fake_regs->set_sp(entry.sp);
   *finished = entry.finished;
+  *is_signal_frame = false;
   return true;
 }
 
diff --git a/libunwindstack/tests/ElfFake.h b/libunwindstack/tests/ElfFake.h
index 3b6cb80..abda7b8 100644
--- a/libunwindstack/tests/ElfFake.h
+++ b/libunwindstack/tests/ElfFake.h
@@ -76,7 +76,7 @@
   bool GetGlobalVariable(const std::string&, uint64_t*) override;
   std::string GetBuildID() override { return fake_build_id_; }
 
-  bool Step(uint64_t, Regs*, Memory*, bool*) override;
+  bool Step(uint64_t, Regs*, Memory*, bool*, bool*) override;
 
   void FakeSetGlobalVariable(const std::string& global, uint64_t offset) {
     globals_[global] = offset;
diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp
index f0852a4..d81edbf 100644
--- a/libunwindstack/tests/ElfTest.cpp
+++ b/libunwindstack/tests/ElfTest.cpp
@@ -138,7 +138,8 @@
   EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode());
 
   bool finished;
-  ASSERT_FALSE(elf.Step(0, nullptr, nullptr, &finished));
+  bool is_signal_frame;
+  ASSERT_FALSE(elf.Step(0, nullptr, nullptr, &finished, &is_signal_frame));
   EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode());
 }
 
@@ -327,7 +328,7 @@
   bool GetFunctionName(uint64_t, std::string*, uint64_t*) override { return false; }
   std::string GetBuildID() override { return ""; }
 
-  MOCK_METHOD(bool, Step, (uint64_t, Regs*, Memory*, bool*), (override));
+  MOCK_METHOD(bool, Step, (uint64_t, Regs*, Memory*, bool*, bool*), (override));
   MOCK_METHOD(bool, GetGlobalVariable, (const std::string&, uint64_t*), (override));
   MOCK_METHOD(bool, IsValidPc, (uint64_t), (override));
 
@@ -351,10 +352,11 @@
   MemoryFake process_memory;
 
   bool finished;
-  EXPECT_CALL(*interface, Step(0x1000, &regs, &process_memory, &finished))
+  bool is_signal_frame;
+  EXPECT_CALL(*interface, Step(0x1000, &regs, &process_memory, &finished, &is_signal_frame))
       .WillOnce(::testing::Return(true));
 
-  ASSERT_TRUE(elf.Step(0x1000, &regs, &process_memory, &finished));
+  ASSERT_TRUE(elf.Step(0x1000, &regs, &process_memory, &finished, &is_signal_frame));
 }
 
 TEST_F(ElfTest, get_global_invalid_elf) {
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index c2bd836..ab427b5 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -314,7 +314,7 @@
 
   JitDebug jit_debug(process_memory_);
   Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
-  unwinder.SetJitDebug(&jit_debug, regs_->Arch());
+  unwinder.SetJitDebug(&jit_debug);
   unwinder.Unwind();
 
   std::string frame_info(DumpFrames(unwinder));
@@ -616,7 +616,7 @@
 
   JitDebug jit_debug(process_memory_);
   Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
-  unwinder.SetJitDebug(&jit_debug, regs_->Arch());
+  unwinder.SetJitDebug(&jit_debug);
   unwinder.Unwind();
 
   std::string frame_info(DumpFrames(unwinder));
@@ -939,7 +939,7 @@
   std::unique_ptr<Regs> regs_copy(leak_data->regs->Clone());
   JitDebug jit_debug(leak_data->process_memory);
   Unwinder unwinder(128, leak_data->maps, regs_copy.get(), leak_data->process_memory);
-  unwinder.SetJitDebug(&jit_debug, regs_copy->Arch());
+  unwinder.SetJitDebug(&jit_debug);
   unwinder.Unwind();
   ASSERT_EQ(76U, unwinder.NumFrames());
 }
@@ -1062,7 +1062,7 @@
 
   JitDebug jit_debug(process_memory_);
   Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
-  unwinder.SetJitDebug(&jit_debug, regs_->Arch());
+  unwinder.SetJitDebug(&jit_debug);
   unwinder.Unwind();
 
   std::string frame_info(DumpFrames(unwinder));
@@ -1736,4 +1736,158 @@
   EXPECT_EQ(0x7ffb6c0f30U, unwinder.frames()[6].sp);
 }
 
+// This test has a libc.so where the __restore has been changed so
+// that the signal handler match does not occur and it uses the
+// fde to do the unwind.
+TEST_F(UnwindOfflineTest, signal_fde_x86) {
+  ASSERT_NO_FATAL_FAILURE(Init("signal_fde_x86/", ARCH_X86));
+
+  Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
+  unwinder.Unwind();
+
+  std::string frame_info(DumpFrames(unwinder));
+  ASSERT_EQ(20U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+  EXPECT_EQ(
+      "  #00 pc 007914d9  libunwindstack_test (SignalInnerFunction+25)\n"
+      "  #01 pc 007914fc  libunwindstack_test (SignalMiddleFunction+28)\n"
+      "  #02 pc 0079152c  libunwindstack_test (SignalOuterFunction+28)\n"
+      "  #03 pc 0079af62  libunwindstack_test (unwindstack::SignalCallerHandler(int, siginfo*, "
+      "void*)+50)\n"
+      "  #04 pc 00058fb0  libc.so (__restore)\n"
+      "  #05 pc 00000000  <unknown>\n"
+      "  #06 pc 0079161a  libunwindstack_test (InnerFunction+218)\n"
+      "  #07 pc 007923aa  libunwindstack_test (MiddleFunction+42)\n"
+      "  #08 pc 007923ea  libunwindstack_test (OuterFunction+42)\n"
+      "  #09 pc 00797444  libunwindstack_test (unwindstack::RemoteThroughSignal(int, unsigned "
+      "int)+868)\n"
+      "  #10 pc 007985b8  libunwindstack_test "
+      "(unwindstack::UnwindTest_remote_through_signal_with_invalid_func_Test::TestBody()+56)\n"
+      "  #11 pc 00817a19  libunwindstack_test\n"
+      "  #12 pc 008178c5  libunwindstack_test (testing::Test::Run()+277)\n"
+      "  #13 pc 00818d3e  libunwindstack_test (testing::TestInfo::Run()+318)\n"
+      "  #14 pc 008198b4  libunwindstack_test (testing::TestSuite::Run()+436)\n"
+      "  #15 pc 00828cb0  libunwindstack_test "
+      "(testing::internal::UnitTestImpl::RunAllTests()+1216)\n"
+      "  #16 pc 0082870f  libunwindstack_test (testing::UnitTest::Run()+367)\n"
+      "  #17 pc 0084031e  libunwindstack_test (IsolateMain+2334)\n"
+      "  #18 pc 0083f9e9  libunwindstack_test (main+41)\n"
+      "  #19 pc 00050646  libc.so (__libc_init+118)\n",
+      frame_info);
+
+  EXPECT_EQ(0x5ae0d4d9U, unwinder.frames()[0].pc);
+  EXPECT_EQ(0xecb37188U, unwinder.frames()[0].sp);
+  EXPECT_EQ(0x5ae0d4fcU, unwinder.frames()[1].pc);
+  EXPECT_EQ(0xecb37190U, unwinder.frames()[1].sp);
+  EXPECT_EQ(0x5ae0d52cU, unwinder.frames()[2].pc);
+  EXPECT_EQ(0xecb371b0U, unwinder.frames()[2].sp);
+  EXPECT_EQ(0x5ae16f62U, unwinder.frames()[3].pc);
+  EXPECT_EQ(0xecb371d0U, unwinder.frames()[3].sp);
+  EXPECT_EQ(0xec169fb0U, unwinder.frames()[4].pc);
+  EXPECT_EQ(0xecb371f0U, unwinder.frames()[4].sp);
+  EXPECT_EQ(0x0U, unwinder.frames()[5].pc);
+  EXPECT_EQ(0xffcfac6cU, unwinder.frames()[5].sp);
+  EXPECT_EQ(0x5ae0d61aU, unwinder.frames()[6].pc);
+  EXPECT_EQ(0xffcfac6cU, unwinder.frames()[6].sp);
+  EXPECT_EQ(0x5ae0e3aaU, unwinder.frames()[7].pc);
+  EXPECT_EQ(0xffcfad60U, unwinder.frames()[7].sp);
+  EXPECT_EQ(0x5ae0e3eaU, unwinder.frames()[8].pc);
+  EXPECT_EQ(0xffcfad90U, unwinder.frames()[8].sp);
+  EXPECT_EQ(0x5ae13444U, unwinder.frames()[9].pc);
+  EXPECT_EQ(0xffcfadc0U, unwinder.frames()[9].sp);
+  EXPECT_EQ(0x5ae145b8U, unwinder.frames()[10].pc);
+  EXPECT_EQ(0xffcfb020U, unwinder.frames()[10].sp);
+  EXPECT_EQ(0x5ae93a19U, unwinder.frames()[11].pc);
+  EXPECT_EQ(0xffcfb050U, unwinder.frames()[11].sp);
+  EXPECT_EQ(0x5ae938c5U, unwinder.frames()[12].pc);
+  EXPECT_EQ(0xffcfb090U, unwinder.frames()[12].sp);
+  EXPECT_EQ(0x5ae94d3eU, unwinder.frames()[13].pc);
+  EXPECT_EQ(0xffcfb0f0U, unwinder.frames()[13].sp);
+  EXPECT_EQ(0x5ae958b4U, unwinder.frames()[14].pc);
+  EXPECT_EQ(0xffcfb160U, unwinder.frames()[14].sp);
+  EXPECT_EQ(0x5aea4cb0U, unwinder.frames()[15].pc);
+  EXPECT_EQ(0xffcfb1d0U, unwinder.frames()[15].sp);
+  EXPECT_EQ(0x5aea470fU, unwinder.frames()[16].pc);
+  EXPECT_EQ(0xffcfb270U, unwinder.frames()[16].sp);
+  EXPECT_EQ(0x5aebc31eU, unwinder.frames()[17].pc);
+  EXPECT_EQ(0xffcfb2c0U, unwinder.frames()[17].sp);
+  EXPECT_EQ(0x5aebb9e9U, unwinder.frames()[18].pc);
+  EXPECT_EQ(0xffcfc3c0U, unwinder.frames()[18].sp);
+  EXPECT_EQ(0xec161646U, unwinder.frames()[19].pc);
+  EXPECT_EQ(0xffcfc3f0U, unwinder.frames()[19].sp);
+}
+
+// This test has a libc.so where the __restore_rt has been changed so
+// that the signal handler match does not occur and it uses the
+// fde to do the unwind.
+TEST_F(UnwindOfflineTest, signal_fde_x86_64) {
+  ASSERT_NO_FATAL_FAILURE(Init("signal_fde_x86_64/", ARCH_X86_64));
+
+  Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
+  unwinder.Unwind();
+
+  std::string frame_info(DumpFrames(unwinder));
+  ASSERT_EQ(18U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+  EXPECT_EQ(
+      "  #00 pc 000000000058415b  libunwindstack_test (SignalInnerFunction+11)\n"
+      "  #01 pc 0000000000584168  libunwindstack_test (SignalMiddleFunction+8)\n"
+      "  #02 pc 0000000000584178  libunwindstack_test (SignalOuterFunction+8)\n"
+      "  #03 pc 000000000058ac77  libunwindstack_test (unwindstack::SignalCallerHandler(int, "
+      "siginfo*, void*)+23)\n"
+      "  #04 pc 0000000000057d10  libc.so (__restore_rt)\n"
+      "  #05 pc 0000000000000000  <unknown>\n"
+      "  #06 pc 0000000000584244  libunwindstack_test (InnerFunction+196)\n"
+      "  #07 pc 0000000000584b44  libunwindstack_test (MiddleFunction+20)\n"
+      "  #08 pc 0000000000584b64  libunwindstack_test (OuterFunction+20)\n"
+      "  #09 pc 0000000000588457  libunwindstack_test (unwindstack::RemoteThroughSignal(int, "
+      "unsigned int)+583)\n"
+      "  #10 pc 0000000000588f67  libunwindstack_test "
+      "(unwindstack::UnwindTest_remote_through_signal_with_invalid_func_Test::TestBody()+23)\n"
+      "  #11 pc 00000000005d9c38  libunwindstack_test (testing::Test::Run()+216)\n"
+      "  #12 pc 00000000005daf9a  libunwindstack_test (testing::TestInfo::Run()+266)\n"
+      "  #13 pc 00000000005dba46  libunwindstack_test (testing::TestSuite::Run()+390)\n"
+      "  #14 pc 00000000005ea4c6  libunwindstack_test "
+      "(testing::internal::UnitTestImpl::RunAllTests()+1190)\n"
+      "  #15 pc 00000000005e9f61  libunwindstack_test (testing::UnitTest::Run()+337)\n"
+      "  #16 pc 0000000000600155  libunwindstack_test (IsolateMain+2037)\n"
+      "  #17 pc 000000000004e405  libc.so (__libc_init+101)\n",
+      frame_info);
+
+  EXPECT_EQ(0x5bb41271e15bU, unwinder.frames()[0].pc);
+  EXPECT_EQ(0x707eb5aa8320U, unwinder.frames()[0].sp);
+  EXPECT_EQ(0x5bb41271e168U, unwinder.frames()[1].pc);
+  EXPECT_EQ(0x707eb5aa8330U, unwinder.frames()[1].sp);
+  EXPECT_EQ(0x5bb41271e178U, unwinder.frames()[2].pc);
+  EXPECT_EQ(0x707eb5aa8340U, unwinder.frames()[2].sp);
+  EXPECT_EQ(0x5bb412724c77U, unwinder.frames()[3].pc);
+  EXPECT_EQ(0x707eb5aa8350U, unwinder.frames()[3].sp);
+  EXPECT_EQ(0x707eb2ca5d10U, unwinder.frames()[4].pc);
+  EXPECT_EQ(0x707eb5aa8380U, unwinder.frames()[4].sp);
+  EXPECT_EQ(0x0U, unwinder.frames()[5].pc);
+  EXPECT_EQ(0x7ffcaadde078U, unwinder.frames()[5].sp);
+  EXPECT_EQ(0x5bb41271e244U, unwinder.frames()[6].pc);
+  EXPECT_EQ(0x7ffcaadde078U, unwinder.frames()[6].sp);
+  EXPECT_EQ(0x5bb41271eb44U, unwinder.frames()[7].pc);
+  EXPECT_EQ(0x7ffcaadde1a0U, unwinder.frames()[7].sp);
+  EXPECT_EQ(0x5bb41271eb64U, unwinder.frames()[8].pc);
+  EXPECT_EQ(0x7ffcaadde1c0U, unwinder.frames()[8].sp);
+  EXPECT_EQ(0x5bb412722457U, unwinder.frames()[9].pc);
+  EXPECT_EQ(0x7ffcaadde1e0U, unwinder.frames()[9].sp);
+  EXPECT_EQ(0x5bb412722f67U, unwinder.frames()[10].pc);
+  EXPECT_EQ(0x7ffcaadde510U, unwinder.frames()[10].sp);
+  EXPECT_EQ(0x5bb412773c38U, unwinder.frames()[11].pc);
+  EXPECT_EQ(0x7ffcaadde530U, unwinder.frames()[11].sp);
+  EXPECT_EQ(0x5bb412774f9aU, unwinder.frames()[12].pc);
+  EXPECT_EQ(0x7ffcaadde560U, unwinder.frames()[12].sp);
+  EXPECT_EQ(0x5bb412775a46U, unwinder.frames()[13].pc);
+  EXPECT_EQ(0x7ffcaadde5b0U, unwinder.frames()[13].sp);
+  EXPECT_EQ(0x5bb4127844c6U, unwinder.frames()[14].pc);
+  EXPECT_EQ(0x7ffcaadde5f0U, unwinder.frames()[14].sp);
+  EXPECT_EQ(0x5bb412783f61U, unwinder.frames()[15].pc);
+  EXPECT_EQ(0x7ffcaadde6c0U, unwinder.frames()[15].sp);
+  EXPECT_EQ(0x5bb41279a155U, unwinder.frames()[16].pc);
+  EXPECT_EQ(0x7ffcaadde720U, unwinder.frames()[16].sp);
+  EXPECT_EQ(0x707eb2c9c405U, unwinder.frames()[17].pc);
+  EXPECT_EQ(0x7ffcaaddf870U, unwinder.frames()[17].sp);
+}
+
 }  // namespace unwindstack
diff --git a/libunwindstack/tests/UnwindTest.cpp b/libunwindstack/tests/UnwindTest.cpp
index f76a101..b11d213 100644
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -170,7 +170,6 @@
     unwinder.reset(new Unwinder(512, maps.get(), regs.get(), process_memory));
   } else {
     UnwinderFromPid* unwinder_from_pid = new UnwinderFromPid(512, getpid());
-    ASSERT_TRUE(unwinder_from_pid->Init(regs->Arch()));
     unwinder_from_pid->SetRegs(regs.get());
     unwinder.reset(unwinder_from_pid);
   }
@@ -283,7 +282,6 @@
   ASSERT_TRUE(regs.get() != nullptr);
 
   UnwinderFromPid unwinder(512, pid);
-  ASSERT_TRUE(unwinder.Init(regs->Arch()));
   unwinder.SetRegs(regs.get());
 
   VerifyUnwind(&unwinder, kFunctionOrder);
@@ -335,7 +333,6 @@
   ASSERT_TRUE(regs.get() != nullptr);
 
   UnwinderFromPid unwinder(512, *pid);
-  ASSERT_TRUE(unwinder.Init(regs->Arch()));
   unwinder.SetRegs(regs.get());
 
   VerifyUnwind(&unwinder, kFunctionOrder);
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 915f248..8bae242 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -1182,7 +1182,7 @@
 
   DexFiles dex_files(process_memory_);
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
-  unwinder.SetDexFiles(&dex_files, ARCH_ARM);
+  unwinder.SetDexFiles(&dex_files);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
   EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
@@ -1735,7 +1735,7 @@
   regs.FakeSetArch(ARCH_ARM);
   JitDebug jit_debug(process_memory_);
   Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
-  unwinder.SetJitDebug(&jit_debug, ARCH_ARM);
+  unwinder.SetJitDebug(&jit_debug);
 
   FrameData frame = unwinder.BuildFrameFromPcOnly(0x100310);
   EXPECT_EQ(0x10030eU, frame.pc);
@@ -1751,4 +1751,21 @@
   EXPECT_EQ(0xeU, frame.function_offset);
 }
 
+TEST_F(UnwinderTest, unwinder_from_pid_init_error) {
+  UnwinderFromPid unwinder(10, getpid());
+  ASSERT_DEATH(unwinder.Init(), "");
+}
+
+TEST_F(UnwinderTest, set_jit_debug_error) {
+  Unwinder unwinder(10, maps_.get(), process_memory_);
+  JitDebug jit_debug(process_memory_);
+  ASSERT_DEATH(unwinder.SetJitDebug(&jit_debug), "");
+}
+
+TEST_F(UnwinderTest, set_dex_files_error) {
+  Unwinder unwinder(10, maps_.get(), process_memory_);
+  DexFiles dex_files(process_memory_);
+  ASSERT_DEATH(unwinder.SetDexFiles(&dex_files), "");
+}
+
 }  // namespace unwindstack
diff --git a/libunwindstack/tests/VerifyBionicTerminationTest.cpp b/libunwindstack/tests/VerifyBionicTerminationTest.cpp
index eb2b01d..3e67dc9 100644
--- a/libunwindstack/tests/VerifyBionicTerminationTest.cpp
+++ b/libunwindstack/tests/VerifyBionicTerminationTest.cpp
@@ -94,7 +94,6 @@
   std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
 
   UnwinderFromPid unwinder(512, getpid());
-  ASSERT_TRUE(unwinder.Init(regs->Arch()));
   unwinder.SetRegs(regs.get());
 
   RegsGetLocal(regs.get());
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86/libc.so b/libunwindstack/tests/files/offline/signal_fde_x86/libc.so
new file mode 100644
index 0000000..5c882e4
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86/libc.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86/libunwindstack_test b/libunwindstack/tests/files/offline/signal_fde_x86/libunwindstack_test
new file mode 100644
index 0000000..8dcff67
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86/libunwindstack_test
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86/maps.txt b/libunwindstack/tests/files/offline/signal_fde_x86/maps.txt
new file mode 100644
index 0000000..6166a9d
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86/maps.txt
@@ -0,0 +1,4 @@
+5a67c000-5a7ba000 r--p 0 00:00 0   libunwindstack_test
+5a7ba000-5aedd000 r-xp 13d000 00:00 0   libunwindstack_test
+ec111000-ec153000 r--p 0 00:00 0   libc.so
+ec153000-ec200000 r-xp 41000 00:00 0   libc.so
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86/regs.txt b/libunwindstack/tests/files/offline/signal_fde_x86/regs.txt
new file mode 100644
index 0000000..456b212
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86/regs.txt
@@ -0,0 +1,9 @@
+eax: 5aeec4ac
+ebx: 5aeec4ac
+ecx: 0
+edx: 6b
+ebp: ecb37188
+edi: ebecda30
+esi: b
+esp: ecb37188
+eip: 5ae0d4d9
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86/stack0.data b/libunwindstack/tests/files/offline/signal_fde_x86/stack0.data
new file mode 100644
index 0000000..0bbbe22
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86/stack0.data
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86/stack1.data b/libunwindstack/tests/files/offline/signal_fde_x86/stack1.data
new file mode 100644
index 0000000..0873046
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86/stack1.data
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86_64/libc.so b/libunwindstack/tests/files/offline/signal_fde_x86_64/libc.so
new file mode 100644
index 0000000..cea7336
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86_64/libc.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86_64/libunwindstack_test b/libunwindstack/tests/files/offline/signal_fde_x86_64/libunwindstack_test
new file mode 100644
index 0000000..c48e84e
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86_64/libunwindstack_test
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86_64/maps.txt b/libunwindstack/tests/files/offline/signal_fde_x86_64/maps.txt
new file mode 100644
index 0000000..514aa71
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86_64/maps.txt
@@ -0,0 +1,4 @@
+5bb41219a000-5bb4122cd000 r--p 0 00:00 0   libunwindstack_test
+5bb4122cd000-5bb4127b9000 r-xp 132000 00:00 0   libunwindstack_test
+707eb2c4e000-707eb2c91000 r--p 0 00:00 0   libc.so
+707eb2c91000-707eb2d1b000 r-xp 42000 00:00 0   libc.so
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86_64/regs.txt b/libunwindstack/tests/files/offline/signal_fde_x86_64/regs.txt
new file mode 100644
index 0000000..8da7b4e
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86_64/regs.txt
@@ -0,0 +1,17 @@
+rax: 0
+rbx: 707d82c59c60
+rcx: 4
+rdx: 707eb5aa8380
+r8: 7ffcaadde470
+r9: 7ffcaadde478
+r10: 8
+r11: 206
+r12: 707cb2c64330
+r13: 0
+r14: 174e9096a8f
+r15: 707d52c96cb0
+rdi: b
+rsi: 707eb5aa84b0
+rbp: 707eb5aa8320
+rsp: 707eb5aa8320
+rip: 5bb41271e15b
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86_64/stack0.data b/libunwindstack/tests/files/offline/signal_fde_x86_64/stack0.data
new file mode 100644
index 0000000..e19a016
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86_64/stack0.data
Binary files differ
diff --git a/libunwindstack/tests/files/offline/signal_fde_x86_64/stack1.data b/libunwindstack/tests/files/offline/signal_fde_x86_64/stack1.data
new file mode 100644
index 0000000..3435f7c
--- /dev/null
+++ b/libunwindstack/tests/files/offline/signal_fde_x86_64/stack1.data
Binary files differ
diff --git a/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp b/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
index 9c5374a..65052b6 100644
--- a/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
+++ b/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
@@ -116,8 +116,12 @@
 
 static constexpr size_t kPageSize = 4096;
 
-static constexpr uint64_t AlignToPage(uint64_t address) {
-  return (address + kPageSize - 1) & ~(kPageSize - 1);
+static inline bool AlignToPage(uint64_t address, uint64_t* aligned_address) {
+  if (__builtin_add_overflow(address, kPageSize - 1, aligned_address)) {
+    return false;
+  }
+  *aligned_address &= ~(kPageSize - 1);
+  return true;
 }
 
 std::unique_ptr<Maps> GetMaps(FuzzedDataProvider* data_provider) {
@@ -125,8 +129,16 @@
   std::map<uint64_t, uint64_t> map_ends;
   uint8_t entry_count = data_provider->ConsumeIntegralInRange<uint8_t>(0, kMaxMapEntryCount);
   for (uint8_t i = 0; i < entry_count; i++) {
-    uint64_t start = AlignToPage(data_provider->ConsumeIntegral<uint64_t>());
-    uint64_t end = AlignToPage(data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX));
+    uint64_t start;
+    if (!AlignToPage(data_provider->ConsumeIntegral<uint64_t>(), &start)) {
+      // Overflowed.
+      continue;
+    }
+    uint64_t end;
+    if (!AlignToPage(data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX), &end)) {
+      // Overflowed.
+      continue;
+    }
     if (start == end) {
       // It's impossible to see start == end in the real world, so
       // make sure the map contains at least one page of data.
@@ -142,7 +154,11 @@
     }
     map_ends[end] = start;
 
-    uint64_t offset = AlignToPage(data_provider->ConsumeIntegral<uint64_t>());
+    uint64_t offset;
+    if (!AlignToPage(data_provider->ConsumeIntegral<uint64_t>(), &offset)) {
+      // Overflowed.
+      continue;
+    }
     std::string map_info_name = data_provider->ConsumeRandomLengthString(kMaxMapInfoNameLen);
     uint8_t flags = PROT_READ | PROT_WRITE;
 
diff --git a/libunwindstack/tests/fuzz/UnwinderFuzz.cpp b/libunwindstack/tests/fuzz/UnwinderFuzz.cpp
index 2f4986a..1600547 100644
--- a/libunwindstack/tests/fuzz/UnwinderFuzz.cpp
+++ b/libunwindstack/tests/fuzz/UnwinderFuzz.cpp
@@ -85,7 +85,7 @@
 
   // Create instance
   Unwinder unwinder(max_frames, maps.get(), regs.get(), memory);
-  unwinder.SetJitDebug(jit_debug_ptr.get(), arch);
+  unwinder.SetJitDebug(jit_debug_ptr.get());
   unwinder.SetResolveNames(data_provider.ConsumeBool());
   // Call unwind
   PerformUnwind(&data_provider, &unwinder);
diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp
index 1812e50..ae45f06 100644
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -90,11 +90,6 @@
   printf("\n");
 
   unwindstack::UnwinderFromPid unwinder(1024, pid);
-  if (!unwinder.Init(regs->Arch())) {
-    printf("Failed to init unwinder object.\n");
-    return;
-  }
-
   unwinder.SetRegs(regs);
   unwinder.Unwind();
 
diff --git a/libunwindstack/tools/unwind_for_offline.cpp b/libunwindstack/tools/unwind_for_offline.cpp
index 64b58a8..c44a121 100644
--- a/libunwindstack/tools/unwind_for_offline.cpp
+++ b/libunwindstack/tools/unwind_for_offline.cpp
@@ -248,10 +248,6 @@
   // Do an unwind so we know how much of the stack to save, and what
   // elf files are involved.
   unwindstack::UnwinderFromPid unwinder(1024, pid);
-  if (!unwinder.Init(regs->Arch())) {
-    printf("Unable to init unwinder object.\n");
-    return 1;
-  }
   unwinder.SetRegs(regs);
   uint64_t sp = regs->sp();
   unwinder.Unwind();
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 926e3d7..dd9fea0 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -269,12 +269,6 @@
 }
 
 cc_fuzz {
-    name: "libutils_fuzz_rwlock",
-    defaults: ["libutils_fuzz_defaults"],
-    srcs: ["RWLock_fuzz.cpp"],
-}
-
-cc_fuzz {
     name: "libutils_fuzz_refbase",
     defaults: ["libutils_fuzz_defaults"],
     srcs: ["RefBase_fuzz.cpp"],
diff --git a/libutils/FuzzFormatTypes.h b/libutils/FuzzFormatTypes.h
new file mode 100644
index 0000000..aa9e503
--- /dev/null
+++ b/libutils/FuzzFormatTypes.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#pragma once
+#include <string>
+
+static const std::string kFormatChars = std::string("duoxXfFeEgGaAcsp");
+static constexpr int32_t kMaxFormatFlagValue = INT16_MAX;
+enum FormatChar : uint8_t {
+    SIGNED_DECIMAL = 0,
+    UNSIGNED_DECIMAL = 1,
+    UNSIGNED_OCTAL = 2,
+    UNSIGNED_HEX_LOWER = 3,
+    UNSIGNED_HEX_UPPER = 4,
+    // Uppercase/lowercase floating point impacts 'inf', 'infinity', and 'nan'
+    FLOAT_LOWER = 5,
+    FLOAT_UPPER = 6,
+    // Upper/lower impacts the "e" in exponents.
+    EXPONENT_LOWER = 7,
+    EXPONENT_UPPER = 8,
+    // %g will use %e or %f, whichever is shortest
+    SHORT_EXP_LOWER = 9,
+    // %G will use %E or %F, whichever is shortest
+    SHORT_EXP_UPPER = 10,
+    HEX_FLOAT_LOWER = 11,
+    HEX_FLOAT_UPPER = 12,
+    CHAR = 13,
+    STRING = 14,
+    POINTER = 15,
+    // Used by libfuzzer
+    kMaxValue = POINTER
+};
+
+bool canApplyFlag(FormatChar formatChar, char modifier) {
+    if (modifier == '#') {
+        return formatChar == UNSIGNED_OCTAL || formatChar == UNSIGNED_HEX_LOWER ||
+               formatChar == UNSIGNED_HEX_UPPER || formatChar == FLOAT_LOWER ||
+               formatChar == FLOAT_UPPER || formatChar == SHORT_EXP_LOWER ||
+               formatChar == SHORT_EXP_UPPER;
+    } else if (modifier == '.') {
+        return formatChar == SIGNED_DECIMAL || formatChar == UNSIGNED_DECIMAL ||
+               formatChar == UNSIGNED_OCTAL || formatChar == UNSIGNED_HEX_LOWER ||
+               formatChar == UNSIGNED_HEX_UPPER || formatChar == FLOAT_LOWER ||
+               formatChar == FLOAT_UPPER || formatChar == SHORT_EXP_LOWER ||
+               formatChar == SHORT_EXP_UPPER || formatChar == STRING;
+    }
+    return true;
+}
diff --git a/libutils/RWLock_fuzz.cpp b/libutils/RWLock_fuzz.cpp
deleted file mode 100755
index e075905..0000000
--- a/libutils/RWLock_fuzz.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2020 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 <functional>
-
-#include "fuzzer/FuzzedDataProvider.h"
-#include "utils/RWLock.h"
-
-static constexpr int MAX_OPERATIONS = 100;
-static constexpr int MAX_NAME_LEN = 2048;
-
-static const std::vector<std::function<void(android::RWLock*)>> operations = {
-        [](android::RWLock* lock) -> void {
-            // This might return a non-zero value if already locked
-            // Either way we are definitely locked now.
-            lock->tryWriteLock();
-        },
-        [](android::RWLock* lock) -> void { lock->tryReadLock(); },
-        [](android::RWLock* lock) -> void { lock->unlock(); },
-};
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    FuzzedDataProvider dataProvider(data, size);
-    std::string nameStr = dataProvider.ConsumeRandomLengthString(MAX_NAME_LEN);
-    int type = dataProvider.ConsumeIntegral<int>();
-    android::RWLock rwLock = android::RWLock(type, nameStr.c_str());
-    std::vector<uint8_t> opsToRun = dataProvider.ConsumeRemainingBytes<uint8_t>();
-    int opsRun = 0;
-    for (auto it : opsToRun) {
-        if (opsRun++ >= MAX_OPERATIONS) {
-            break;
-        }
-        it = it % operations.size();
-        operations[it](&rwLock);
-    }
-    rwLock.unlock();
-    return 0;
-}
diff --git a/libutils/String8_fuzz.cpp b/libutils/String8_fuzz.cpp
index 2adfe98..b02683c 100644
--- a/libutils/String8_fuzz.cpp
+++ b/libutils/String8_fuzz.cpp
@@ -15,97 +15,199 @@
  */
 #include <functional>
 #include <iostream>
+#include <memory>
 
+#include "FuzzFormatTypes.h"
 #include "fuzzer/FuzzedDataProvider.h"
 #include "utils/String8.h"
 
 static constexpr int MAX_STRING_BYTES = 256;
 static constexpr uint8_t MAX_OPERATIONS = 50;
+// Interestingly, 2147483614 (INT32_MAX - 33) seems to be the max value that is handled for format
+// flags. Unfortunately we need to use a smaller value so we avoid consuming too much memory.
 
-std::vector<std::function<void(FuzzedDataProvider&, android::String8, android::String8)>>
+void fuzzFormat(FuzzedDataProvider* dataProvider, android::String8* str1, bool shouldAppend);
+std::vector<std::function<void(FuzzedDataProvider*, android::String8*, android::String8*)>>
         operations = {
-
                 // Bytes and size
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.bytes();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->bytes();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.isEmpty();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->isEmpty();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.length();
-                },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.size();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->length();
                 },
 
                 // Casing
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.toUpper();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->toUpper();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.toLower();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->toLower();
                 },
-
-                [](FuzzedDataProvider&, android::String8 str1, android::String8 str2) -> void {
-                    str1.removeAll(str2.c_str());
+                [](FuzzedDataProvider*, android::String8* str1, android::String8* str2) -> void {
+                    str1->removeAll(str2->c_str());
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8 str2) -> void {
-                    str1.compare(str2);
+                [](FuzzedDataProvider*, android::String8* str1, android::String8* str2) -> void {
+                    const android::String8& constRef(*str2);
+                    str1->compare(constRef);
                 },
 
                 // Append and format
-                [](FuzzedDataProvider&, android::String8 str1, android::String8 str2) -> void {
-                    str1.append(str2);
+                [](FuzzedDataProvider*, android::String8* str1, android::String8* str2) -> void {
+                    str1->append(str2->c_str());
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8 str2) -> void {
-                    str1.appendFormat(str1.c_str(), str2.c_str());
-                },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8 str2) -> void {
-                    str1.format(str1.c_str(), str2.c_str());
-                },
+                [](FuzzedDataProvider* dataProvider, android::String8* str1, android::String8*)
+                        -> void { fuzzFormat(dataProvider, str1, dataProvider->ConsumeBool()); },
 
                 // Find operation
-                [](FuzzedDataProvider& dataProvider, android::String8 str1,
-                   android::String8) -> void {
+                [](FuzzedDataProvider* dataProvider, android::String8* str1,
+                   android::String8* str2) -> void {
                     // We need to get a value from our fuzzer here.
-                    int start_index = dataProvider.ConsumeIntegralInRange<int>(0, str1.size());
-                    str1.find(str1.c_str(), start_index);
+                    int start_index = dataProvider->ConsumeIntegralInRange<int>(0, str1->size());
+                    str1->find(str2->c_str(), start_index);
                 },
 
                 // Path handling
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.getBasePath();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->getBasePath();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.getPathExtension();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->getPathExtension();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.getPathLeaf();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->getPathLeaf();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.getPathDir();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->getPathDir();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    str1.convertToResPath();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    str1->convertToResPath();
                 },
-                [](FuzzedDataProvider&, android::String8 str1, android::String8) -> void {
-                    android::String8 path_out_str = android::String8();
-                    str1.walkPath(&path_out_str);
-                    path_out_str.clear();
+                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
+                    std::shared_ptr<android::String8> path_out_str =
+                            std::make_shared<android::String8>();
+                    str1->walkPath(path_out_str.get());
+                    path_out_str->clear();
                 },
-                [](FuzzedDataProvider& dataProvider, android::String8 str1,
-                   android::String8) -> void {
-                    str1.setPathName(dataProvider.ConsumeBytesWithTerminator<char>(5).data());
+                [](FuzzedDataProvider* dataProvider, android::String8* str1,
+                   android::String8*) -> void {
+                    str1->setPathName(dataProvider->ConsumeBytesWithTerminator<char>(5).data());
                 },
-                [](FuzzedDataProvider& dataProvider, android::String8 str1,
-                   android::String8) -> void {
-                    str1.appendPath(dataProvider.ConsumeBytesWithTerminator<char>(5).data());
+                [](FuzzedDataProvider* dataProvider, android::String8* str1,
+                   android::String8*) -> void {
+                    str1->appendPath(dataProvider->ConsumeBytesWithTerminator<char>(5).data());
                 },
 };
 
-void callFunc(uint8_t index, FuzzedDataProvider& dataProvider, android::String8 str1,
-              android::String8 str2) {
+void fuzzFormat(FuzzedDataProvider* dataProvider, android::String8* str1, bool shouldAppend) {
+    FormatChar formatType = dataProvider->ConsumeEnum<FormatChar>();
+
+    std::string formatString("%");
+    // Width specifier
+    if (dataProvider->ConsumeBool()) {
+        // Left pad with zeroes
+        if (dataProvider->ConsumeBool()) {
+            formatString.push_back('0');
+        }
+        // Right justify (or left justify if negative)
+        int32_t justify = dataProvider->ConsumeIntegralInRange<int32_t>(-kMaxFormatFlagValue,
+                                                                        kMaxFormatFlagValue);
+        formatString += std::to_string(justify);
+    }
+
+    // The # specifier only works with o, x, X, a, A, e, E, f, F, g, and G
+    if (canApplyFlag(formatType, '#') && dataProvider->ConsumeBool()) {
+        formatString.push_back('#');
+    }
+
+    // Precision specifier
+    if (canApplyFlag(formatType, '.') && dataProvider->ConsumeBool()) {
+        formatString.push_back('.');
+        formatString +=
+                std::to_string(dataProvider->ConsumeIntegralInRange<int>(0, kMaxFormatFlagValue));
+    }
+
+    formatString.push_back(kFormatChars.at(static_cast<uint8_t>(formatType)));
+
+    switch (formatType) {
+        case SIGNED_DECIMAL: {
+            int val = dataProvider->ConsumeIntegral<int>();
+            if (shouldAppend) {
+                str1->appendFormat(formatString.c_str(), val);
+            } else {
+                str1->format(formatString.c_str(), dataProvider->ConsumeIntegral<int>());
+            }
+            break;
+        }
+
+        case UNSIGNED_DECIMAL:
+        case UNSIGNED_OCTAL:
+        case UNSIGNED_HEX_LOWER:
+        case UNSIGNED_HEX_UPPER: {
+            // Unsigned integers for u, o, x, and X
+            uint val = dataProvider->ConsumeIntegral<uint>();
+            if (shouldAppend) {
+                str1->appendFormat(formatString.c_str(), val);
+            } else {
+                str1->format(formatString.c_str(), val);
+            }
+            break;
+        }
+
+        case FLOAT_LOWER:
+        case FLOAT_UPPER:
+        case EXPONENT_LOWER:
+        case EXPONENT_UPPER:
+        case SHORT_EXP_LOWER:
+        case SHORT_EXP_UPPER:
+        case HEX_FLOAT_LOWER:
+        case HEX_FLOAT_UPPER: {
+            // Floating points for f, F, e, E, g, G, a, and A
+            float val = dataProvider->ConsumeFloatingPoint<float>();
+            if (shouldAppend) {
+                str1->appendFormat(formatString.c_str(), val);
+            } else {
+                str1->format(formatString.c_str(), val);
+            }
+            break;
+        }
+
+        case CHAR: {
+            char val = dataProvider->ConsumeIntegral<char>();
+            if (shouldAppend) {
+                str1->appendFormat(formatString.c_str(), val);
+            } else {
+                str1->format(formatString.c_str(), val);
+            }
+            break;
+        }
+
+        case STRING: {
+            std::string val = dataProvider->ConsumeRandomLengthString(MAX_STRING_BYTES);
+            if (shouldAppend) {
+                str1->appendFormat(formatString.c_str(), val.c_str());
+            } else {
+                str1->format(formatString.c_str(), val.c_str());
+            }
+            break;
+        }
+        case POINTER: {
+            uintptr_t val = dataProvider->ConsumeIntegral<uintptr_t>();
+            if (shouldAppend) {
+                str1->appendFormat(formatString.c_str(), val);
+            } else {
+                str1->format(formatString.c_str(), val);
+            }
+            break;
+        }
+    }
+}
+
+void callFunc(uint8_t index, FuzzedDataProvider* dataProvider, android::String8* str1,
+              android::String8* str2) {
     operations[index](dataProvider, str1, str2);
 }
 
@@ -120,14 +222,12 @@
     // Create UTF-8 pointers
     android::String8 str_one_utf8 = android::String8(vec.data());
     android::String8 str_two_utf8 = android::String8(vec_two.data());
-
     // Run operations against strings
     int opsRun = 0;
     while (dataProvider.remaining_bytes() > 0 && opsRun++ < MAX_OPERATIONS) {
         uint8_t op = dataProvider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
-        callFunc(op, dataProvider, str_one_utf8, str_two_utf8);
+        operations[op](&dataProvider, &str_one_utf8, &str_two_utf8);
     }
-
     // Just to be extra sure these can be freed, we're going to explicitly clear
     // them
     str_one_utf8.clear();
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 55eadb0..540dcf4 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -302,8 +302,8 @@
 }
 
 #if defined(__ANDROID__)
-namespace {
-int androidSetThreadPriorityInternal(pid_t tid, int pri, bool change_policy) {
+int androidSetThreadPriority(pid_t tid, int pri)
+{
     int rc = 0;
     int lasterr = 0;
     int curr_pri = getpriority(PRIO_PROCESS, tid);
@@ -312,19 +312,17 @@
         return rc;
     }
 
-    if (change_policy) {
-        if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-            rc = SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true) ? 0 : -1;
-        } else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) {
-            SchedPolicy policy = SP_FOREGROUND;
-            // Change to the sched policy group of the process.
-            get_sched_policy(getpid(), &policy);
-            rc = SetTaskProfiles(tid, {get_sched_policy_profile_name(policy)}, true) ? 0 : -1;
-        }
+    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+        rc = SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true) ? 0 : -1;
+    } else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) {
+        SchedPolicy policy = SP_FOREGROUND;
+        // Change to the sched policy group of the process.
+        get_sched_policy(getpid(), &policy);
+        rc = SetTaskProfiles(tid, {get_sched_policy_profile_name(policy)}, true) ? 0 : -1;
+    }
 
-        if (rc) {
-            lasterr = errno;
-        }
+    if (rc) {
+        lasterr = errno;
     }
 
     if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
@@ -335,15 +333,6 @@
 
     return rc;
 }
-}  // namespace
-
-int androidSetThreadPriority(pid_t tid, int pri) {
-    return androidSetThreadPriorityInternal(tid, pri, true);
-}
-
-int androidSetThreadPriorityAndPolicy(pid_t tid, int pri, bool change_policy) {
-    return androidSetThreadPriorityInternal(tid, pri, change_policy);
-}
 
 int androidGetThreadPriority(pid_t tid) {
     return getpriority(PRIO_PROCESS, tid);
diff --git a/libutils/include/utils/AndroidThreads.h b/libutils/include/utils/AndroidThreads.h
index cdb5442..a8d7851 100644
--- a/libutils/include/utils/AndroidThreads.h
+++ b/libutils/include/utils/AndroidThreads.h
@@ -78,13 +78,8 @@
 // should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
 // if the priority set failed, else another value if just the group set failed;
 // in either case errno is set.  Thread ID zero means current thread.
-// This is equivalent to androidSetThreadPriorityAndPolicy(tid, prio, true);
 extern int androidSetThreadPriority(pid_t tid, int prio);
 
-// Parameter "change_policy" indicates if sched policy should be changed. It needs
-// not be checked again if the change is done elsewhere like activity manager.
-extern int androidSetThreadPriorityAndPolicy(pid_t tid, int prio, bool change_policy);
-
 // Get the current priority of a particular thread. Returns one of the
 // ANDROID_PRIORITY constants or a negative result in case of error.
 extern int androidGetThreadPriority(pid_t tid);
diff --git a/logcat b/logcat
new file mode 120000
index 0000000..6c27286
--- /dev/null
+++ b/logcat
@@ -0,0 +1 @@
+../logging/logcat
\ No newline at end of file
diff --git a/logcat/Android.bp b/logcat/Android.bp
deleted file mode 100644
index 61fba59..0000000
--- a/logcat/Android.bp
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright (C) 2006 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.
-//
-
-cc_defaults {
-    name: "logcat_defaults",
-
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION=1",
-    ],
-    shared_libs: [
-        "libbase",
-        "libprocessgroup",
-    ],
-    static_libs: ["liblog"],
-    logtags: ["event.logtags"],
-}
-
-cc_binary {
-    name: "logcat",
-
-    defaults: ["logcat_defaults"],
-    srcs: [
-        "logcat.cpp",
-    ],
-}
-
-sh_binary {
-    name: "logcatd",
-    src: "logcatd",
-}
-
-sh_binary {
-    name: "logpersist.start",
-    src: "logpersist",
-    init_rc: ["logcatd.rc"],
-    required: ["logcatd"],
-    symlinks: [
-        "logpersist.stop",
-        "logpersist.cat",
-    ],
-}
diff --git a/logcat/MODULE_LICENSE_APACHE2 b/logcat/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/logcat/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/logcat/NOTICE b/logcat/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/logcat/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/logcat/OWNERS b/logcat/OWNERS
deleted file mode 100644
index babbe4d..0000000
--- a/logcat/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tomcherry@google.com
diff --git a/logcat/event.logtags b/logcat/event.logtags
deleted file mode 100644
index 93c3d6d..0000000
--- a/logcat/event.logtags
+++ /dev/null
@@ -1,159 +0,0 @@
-# The entries in this file map a sparse set of log tag numbers to tag names.
-# This is installed on the device, in /system/etc, and parsed by logcat.
-#
-# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
-# negative values alone for now.)
-#
-# Tag names are one or more ASCII letters and numbers or underscores, i.e.
-# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
-# impacts log readability, the latter makes regex searches more annoying).
-#
-# Tag numbers and names are separated by whitespace.  Blank lines and lines
-# starting with '#' are ignored.
-#
-# Optionally, after the tag names can be put a description for the value(s)
-# of the tag. Description are in the format
-#    (<name>|data type[|data unit])
-# Multiple values are separated by commas.
-#
-# The data type is a number from the following values:
-# 1: int
-# 2: long
-# 3: string
-# 4: list
-# 5: float
-#
-# The data unit is a number taken from the following list:
-# 1: Number of objects
-# 2: Number of bytes
-# 3: Number of milliseconds
-# 4: Number of allocations
-# 5: Id
-# 6: Percent
-# s: Number of seconds (monotonic time)
-# Default value for data of type int/long is 2 (bytes).
-#
-# TODO: generate ".java" and ".h" files with integer constants from this file.
-
-# These are used for testing, do not modify without updating
-# tests/framework-tests/src/android/util/EventLogFunctionalTest.java.
-# system/core/liblog/tests/liblog_benchmark.cpp
-# system/core/liblog/tests/liblog_test.cpp
-42    answer (to life the universe etc|3)
-314   pi
-2718  e
-
-# "account" is the java hash of the account name
-2720 sync (id|3),(event|1|5),(source|1|5),(account|1|5)
-
-# This event is logged when the location service uploads location data.
-2740 location_controller
-# This event is logged when someone is deciding to force a garbage collection
-2741 force_gc (reason|3)
-# This event is logged on each tickle
-2742 tickle (authority|3)
-
-# contacts aggregation: time and number of contacts.
-# count is negative for query phase, positive for merge phase
-2747 contacts_aggregation (aggregation time|2|3), (count|1|1)
-
-# Device boot timings.  We include monotonic clock values because the
-# intrinsic event log times are wall-clock.
-#
-# Runtime starts:
-3000 boot_progress_start (time|2|3)
-# ZygoteInit class preloading starts:
-3020 boot_progress_preload_start (time|2|3)
-# ZygoteInit class preloading ends:
-3030 boot_progress_preload_end (time|2|3)
-
-# Dalvik VM / ART
-20003 dvm_lock_sample (process|3),(main|1|5),(thread|3),(time|1|3),(file|3),(line|1|5),(ownerfile|3),(ownerline|1|5),(sample_percent|1|6)
-20004 art_hidden_api_access (access_method|1),(flags|1),(class|3),(member|3),(type_signature|3)
-
-75000 sqlite_mem_alarm_current (current|1|2)
-75001 sqlite_mem_alarm_max (max|1|2)
-75002 sqlite_mem_alarm_alloc_attempt (attempts|1|4)
-75003 sqlite_mem_released (Memory released|1|2)
-75004 sqlite_db_corrupt (Database file corrupt|3)
-
-50000 menu_item_selected (Menu type where 0 is options and 1 is context|1|5),(Menu item title|3)
-50001 menu_opened (Menu type where 0 is options and 1 is context|1|5)
-
-# HSM wifi state change
-# Hierarchical state class name (as defined in WifiStateTracker.java)
-# Logged on every state change in the hierarchical state machine
-50021 wifi_state_changed (wifi_state|3)
-# HSM wifi event
-# [31-16] Reserved for future use
-# [15 - 0] HSM event (as defined in WifiStateTracker.java)
-# Logged when an event is handled in a hierarchical state
-50022 wifi_event_handled (wifi_event|1|5)
-# Supplicant state change
-# [31-13] Reserved for future use
-# [8 - 0] Supplicant state (as defined in SupplicantState.java)
-# Logged when the supplicant switches to a new state
-50023 wifi_supplicant_state_changed (supplicant_state|1|5)
-
-# Database operation samples.
-# db: the filename of the database
-# sql: the executed query (without query args)
-# time: cpu time millis (not wall time), including lock acquisition
-# blocking_package: if this is on a main thread, the package name, otherwise ""
-# sample_percent: the percent likelihood this query was logged
-52000 db_sample (db|3),(sql|3),(time|1|3),(blocking_package|3),(sample_percent|1|6)
-
-# http request/response stats
-52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2)
-60000 viewroot_draw (Draw time|1|3)
-60001 viewroot_layout (Layout time|1|3)
-60002 view_build_drawing_cache (View created drawing cache|1|5)
-60003 view_use_drawing_cache (View drawn using bitmap cache|1|5)
-
-# graphics timestamp
-# 60100 - 60199 reserved for surfaceflinger
-
-# audio
-# 61000 - 61199 reserved for audioserver
-
-# input
-# 62000 - 62199 reserved for inputflinger
-
-# com.android.server.policy
-# 70000 - 70199 reserved for PhoneWindowManager and other policies
-
-# aggregation service
-70200 aggregation (aggregation time|2|3)
-70201 aggregation_test (field1|1|2),(field2|1|2),(field3|1|2),(field4|1|2),(field5|1|2)
-
-# gms refuses to register this log tag, b/30156345
-70220 gms_unknown
-
-# libc failure logging
-80100 bionic_event_memcpy_buffer_overflow (uid|1)
-80105 bionic_event_strcat_buffer_overflow (uid|1)
-80110 bionic_event_memmov_buffer_overflow (uid|1)
-80115 bionic_event_strncat_buffer_overflow (uid|1)
-80120 bionic_event_strncpy_buffer_overflow (uid|1)
-80125 bionic_event_memset_buffer_overflow (uid|1)
-80130 bionic_event_strcpy_buffer_overflow (uid|1)
-
-80200 bionic_event_strcat_integer_overflow (uid|1)
-80205 bionic_event_strncat_integer_overflow (uid|1)
-
-80300 bionic_event_resolver_old_response (uid|1)
-80305 bionic_event_resolver_wrong_server (uid|1)
-80310 bionic_event_resolver_wrong_query (uid|1)
-
-# libcore failure logging
-90100 exp_det_cert_pin_failure (certs|4)
-
-# 150000 - 160000 reserved for Android Automotive builds
-
-1397638484 snet_event_log (subtag|3) (uid|1) (message|3)
-
-# for events that go to stats log buffer
-1937006964 stats_log (atom_id|1|5),(data|4)
-
-# NOTE - the range 1000000-2000000 is reserved for partners and others who
-# want to define their own log tags without conflicting with the core platform.
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
deleted file mode 100644
index 6b7e016..0000000
--- a/logcat/logcat.cpp
+++ /dev/null
@@ -1,1212 +0,0 @@
-/*
- * Copyright (C) 2006-2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <error.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <math.h>
-#include <sched.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/cdefs.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <memory>
-#include <regex>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <android/log.h>
-#include <log/event_tag_map.h>
-#include <log/log_id.h>
-#include <log/log_read.h>
-#include <log/logprint.h>
-#include <private/android_logger.h>
-#include <processgroup/sched_policy.h>
-#include <system/thread_defs.h>
-
-#define DEFAULT_MAX_ROTATED_LOGS 4
-
-using android::base::Join;
-using android::base::ParseByteCount;
-using android::base::ParseUint;
-using android::base::Split;
-using android::base::StringPrintf;
-using android::base::WriteFully;
-
-class Logcat {
-  public:
-    int Run(int argc, char** argv);
-
-  private:
-    void RotateLogs();
-    void ProcessBuffer(struct log_msg* buf);
-    void PrintDividers(log_id_t log_id, bool print_dividers);
-    void SetupOutputAndSchedulingPolicy(bool blocking);
-    int SetLogFormat(const char* format_string);
-
-    // Used for all options
-    android::base::unique_fd output_fd_{dup(STDOUT_FILENO)};
-    std::unique_ptr<AndroidLogFormat, decltype(&android_log_format_free)> logformat_{
-            android_log_format_new(), &android_log_format_free};
-
-    // For logging to a file and log rotation
-    const char* output_file_name_ = nullptr;
-    size_t log_rotate_size_kb_ = 0;                       // 0 means "no log rotation"
-    size_t max_rotated_logs_ = DEFAULT_MAX_ROTATED_LOGS;  // 0 means "unbounded"
-    size_t out_byte_count_ = 0;
-
-    // For binary log buffers
-    int print_binary_ = 0;
-    std::unique_ptr<EventTagMap, decltype(&android_closeEventTagMap)> event_tag_map_{
-            nullptr, &android_closeEventTagMap};
-    bool has_opened_event_tag_map_ = false;
-
-    // For the related --regex, --max-count, --print
-    std::unique_ptr<std::regex> regex_;
-    size_t max_count_ = 0;  // 0 means "infinite"
-    size_t print_count_ = 0;
-    bool print_it_anyways_ = false;
-
-    // For PrintDividers()
-    log_id_t last_printed_id_ = LOG_ID_MAX;
-    bool printed_start_[LOG_ID_MAX] = {};
-
-    bool debug_ = false;
-};
-
-#ifndef F2FS_IOC_SET_PIN_FILE
-#define F2FS_IOCTL_MAGIC       0xf5
-#define F2FS_IOC_SET_PIN_FILE _IOW(F2FS_IOCTL_MAGIC, 13, __u32)
-#endif
-
-static int openLogFile(const char* pathname, size_t sizeKB) {
-    int fd = open(pathname, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP);
-    if (fd < 0) {
-        return fd;
-    }
-
-    // no need to check errors
-    __u32 set = 1;
-    ioctl(fd, F2FS_IOC_SET_PIN_FILE, &set);
-    fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, (sizeKB << 10));
-    return fd;
-}
-
-static void closeLogFile(const char* pathname) {
-    int fd = open(pathname, O_WRONLY | O_CLOEXEC);
-    if (fd == -1) {
-        return;
-    }
-
-    // no need to check errors
-    __u32 set = 0;
-    ioctl(fd, F2FS_IOC_SET_PIN_FILE, &set);
-    close(fd);
-}
-
-void Logcat::RotateLogs() {
-    // Can't rotate logs if we're not outputting to a file
-    if (!output_file_name_) return;
-
-    output_fd_.reset();
-
-    // Compute the maximum number of digits needed to count up to
-    // maxRotatedLogs in decimal.  eg:
-    // maxRotatedLogs == 30
-    //   -> log10(30) == 1.477
-    //   -> maxRotationCountDigits == 2
-    int max_rotation_count_digits =
-            max_rotated_logs_ > 0 ? (int)(floor(log10(max_rotated_logs_) + 1)) : 0;
-
-    for (int i = max_rotated_logs_; i > 0; i--) {
-        std::string file1 =
-                StringPrintf("%s.%.*d", output_file_name_, max_rotation_count_digits, i);
-
-        std::string file0;
-        if (!(i - 1)) {
-            file0 = output_file_name_;
-        } else {
-            file0 = StringPrintf("%s.%.*d", output_file_name_, max_rotation_count_digits, i - 1);
-        }
-
-        if (!file0.length() || !file1.length()) {
-            perror("while rotating log files");
-            break;
-        }
-
-        closeLogFile(file0.c_str());
-
-        int err = rename(file0.c_str(), file1.c_str());
-
-        if (err < 0 && errno != ENOENT) {
-            perror("while rotating log files");
-        }
-    }
-
-    output_fd_.reset(openLogFile(output_file_name_, log_rotate_size_kb_));
-
-    if (!output_fd_.ok()) {
-        error(EXIT_FAILURE, errno, "Couldn't open output file");
-    }
-
-    out_byte_count_ = 0;
-}
-
-void Logcat::ProcessBuffer(struct log_msg* buf) {
-    int bytesWritten = 0;
-    int err;
-    AndroidLogEntry entry;
-    char binaryMsgBuf[1024];
-
-    bool is_binary =
-            buf->id() == LOG_ID_EVENTS || buf->id() == LOG_ID_STATS || buf->id() == LOG_ID_SECURITY;
-
-    if (is_binary) {
-        if (!event_tag_map_ && !has_opened_event_tag_map_) {
-            event_tag_map_.reset(android_openEventTagMap(nullptr));
-            has_opened_event_tag_map_ = true;
-        }
-        err = android_log_processBinaryLogBuffer(&buf->entry, &entry, event_tag_map_.get(),
-                                                 binaryMsgBuf, sizeof(binaryMsgBuf));
-        // printf(">>> pri=%d len=%d msg='%s'\n",
-        //    entry.priority, entry.messageLen, entry.message);
-    } else {
-        err = android_log_processLogBuffer(&buf->entry, &entry);
-    }
-    if (err < 0 && !debug_) return;
-
-    if (android_log_shouldPrintLine(logformat_.get(), std::string(entry.tag, entry.tagLen).c_str(),
-                                    entry.priority)) {
-        bool match = !regex_ ||
-                     std::regex_search(entry.message, entry.message + entry.messageLen, *regex_);
-
-        print_count_ += match;
-        if (match || print_it_anyways_) {
-            bytesWritten = android_log_printLogLine(logformat_.get(), output_fd_.get(), &entry);
-
-            if (bytesWritten < 0) {
-                error(EXIT_FAILURE, 0, "Output error.");
-            }
-        }
-    }
-
-    out_byte_count_ += bytesWritten;
-
-    if (log_rotate_size_kb_ > 0 && (out_byte_count_ / 1024) >= log_rotate_size_kb_) {
-        RotateLogs();
-    }
-}
-
-void Logcat::PrintDividers(log_id_t log_id, bool print_dividers) {
-    if (log_id == last_printed_id_ || print_binary_) {
-        return;
-    }
-    if (!printed_start_[log_id] || print_dividers) {
-        if (dprintf(output_fd_.get(), "--------- %s %s\n",
-                    printed_start_[log_id] ? "switch to" : "beginning of",
-                    android_log_id_to_name(log_id)) < 0) {
-            error(EXIT_FAILURE, errno, "Output error");
-        }
-    }
-    last_printed_id_ = log_id;
-    printed_start_[log_id] = true;
-}
-
-void Logcat::SetupOutputAndSchedulingPolicy(bool blocking) {
-    if (!output_file_name_) return;
-
-    if (blocking) {
-        // Lower priority and set to batch scheduling if we are saving
-        // the logs into files and taking continuous content.
-        if (set_sched_policy(0, SP_BACKGROUND) < 0) {
-            fprintf(stderr, "failed to set background scheduling policy\n");
-        }
-
-        struct sched_param param = {};
-        if (sched_setscheduler((pid_t)0, SCHED_BATCH, &param) < 0) {
-            fprintf(stderr, "failed to set to batch scheduler\n");
-        }
-
-        if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
-            fprintf(stderr, "failed set to priority\n");
-        }
-    }
-
-    output_fd_.reset(openLogFile(output_file_name_, log_rotate_size_kb_));
-
-    if (!output_fd_.ok()) {
-        error(EXIT_FAILURE, errno, "Couldn't open output file");
-    }
-
-    struct stat statbuf;
-    if (fstat(output_fd_.get(), &statbuf) == -1) {
-        error(EXIT_FAILURE, errno, "Couldn't get output file stat");
-    }
-
-    if ((size_t)statbuf.st_size > SIZE_MAX || statbuf.st_size < 0) {
-        error(EXIT_FAILURE, 0, "Invalid output file stat.");
-    }
-
-    out_byte_count_ = statbuf.st_size;
-}
-
-// clang-format off
-static void show_help() {
-    const char* cmd = getprogname();
-
-    fprintf(stderr, "Usage: %s [options] [filterspecs]\n", cmd);
-
-    fprintf(stderr, R"init(
-General options:
-  -b, --buffer=<buffer>       Request alternate ring buffer(s):
-                                main system radio events crash default all
-                              Additionally, 'kernel' for userdebug and eng builds, and
-                              'security' for Device Owner installations.
-                              Multiple -b parameters or comma separated list of buffers are
-                              allowed. Buffers are interleaved.
-                              Default -b main,system,crash,kernel.
-  -L, --last                  Dump logs from prior to last reboot from pstore.
-  -c, --clear                 Clear (flush) the entire log and exit.
-                              if -f is specified, clear the specified file and its related rotated
-                              log files instead.
-                              if -L is specified, clear pstore log instead.
-  -d                          Dump the log and then exit (don't block).
-  --pid=<pid>                 Only print logs from the given pid.
-  --wrap                      Sleep for 2 hours or when buffer about to wrap whichever
-                              comes first. Improves efficiency of polling by providing
-                              an about-to-wrap wakeup.
-
-Formatting:
-  -v, --format=<format>       Sets log print format verb and adverbs, where <format> is one of:
-                                brief help long process raw tag thread threadtime time
-                              Modifying adverbs can be added:
-                                color descriptive epoch monotonic printable uid usec UTC year zone
-                              Multiple -v parameters or comma separated list of format and format
-                              modifiers are allowed.
-  -D, --dividers              Print dividers between each log buffer.
-  -B, --binary                Output the log in binary.
-
-Outfile files:
-  -f, --file=<file>           Log to file instead of stdout.
-  -r, --rotate-kbytes=<n>     Rotate log every <n> kbytes. Requires -f option.
-  -n, --rotate-count=<count>  Sets max number of rotated logs to <count>, default 4.
-  --id=<id>                   If the signature <id> for logging to file changes, then clear the
-                              associated files and continue.
-
-Logd control:
- These options send a control message to the logd daemon on device, print its return message if
- applicable, then exit. They are incompatible with -L, as these attributes do not apply to pstore.
-  -g, --buffer-size           Get the size of the ring buffers within logd.
-  -G, --buffer-size=<size>    Set size of a ring buffer in logd. May suffix with K or M.
-                              This can individually control each buffer's size with -b.
-  -S, --statistics            Output statistics.
-                              --pid can be used to provide pid specific stats.
-  -p, --prune                 Print prune rules. Each rule is specified as UID, UID/PID or /PID. A
-                              '~' prefix indicates that elements matching the rule should be pruned
-                              with higher priority otherwise they're pruned with lower priority. All
-                              other pruning activity is oldest first. Special case ~! represents an
-                              automatic pruning for the noisiest UID as determined by the current
-                              statistics.  Special case ~1000/! represents pruning of the worst PID
-                              within AID_SYSTEM when AID_SYSTEM is the noisiest UID.
-  -P, --prune='<list> ...'    Set prune rules, using same format as listed above. Must be quoted.
-
-Filtering:
-  -s                          Set default filter to silent. Equivalent to filterspec '*:S'
-  -e, --regex=<expr>          Only print lines where the log message matches <expr> where <expr> is
-                              an ECMAScript regular expression.
-  -m, --max-count=<count>     Quit after printing <count> lines. This is meant to be paired with
-                              --regex, but will work on its own.
-  --print                     This option is only applicable when --regex is set and only useful if
-                              --max-count is also provided.
-                              With --print, logcat will print all messages even if they do not
-                              match the regex. Logcat will quit after printing the max-count number
-                              of lines that match the regex.
-  -t <count>                  Print only the most recent <count> lines (implies -d).
-  -t '<time>'                 Print the lines since specified time (implies -d).
-  -T <count>                  Print only the most recent <count> lines (does not imply -d).
-  -T '<time>'                 Print the lines since specified time (not imply -d).
-                              count is pure numerical, time is 'MM-DD hh:mm:ss.mmm...'
-                              'YYYY-MM-DD hh:mm:ss.mmm...' or 'sssss.mmm...' format.
-  --uid=<uids>                Only display log messages from UIDs present in the comma separate list
-                              <uids>. No name look-up is performed, so UIDs must be provided as
-                              numeric values. This option is only useful for the 'root', 'log', and
-                              'system' users since only those users can view logs from other users.
-)init");
-
-    fprintf(stderr, "\nfilterspecs are a series of \n"
-                   "  <tag>[:priority]\n\n"
-                   "where <tag> is a log component tag (or * for all) and priority is:\n"
-                   "  V    Verbose (default for <tag>)\n"
-                   "  D    Debug (default for '*')\n"
-                   "  I    Info\n"
-                   "  W    Warn\n"
-                   "  E    Error\n"
-                   "  F    Fatal\n"
-                   "  S    Silent (suppress all output)\n"
-                   "\n'*' by itself means '*:D' and <tag> by itself means <tag>:V.\n"
-                   "If no '*' filterspec or -s on command line, all filter defaults to '*:V'.\n"
-                   "eg: '*:S <tag>' prints only <tag>, '<tag>:S' suppresses all <tag> log messages.\n"
-                   "\nIf not specified on the command line, filterspec is set from ANDROID_LOG_TAGS.\n"
-                   "\nIf not specified with -v on command line, format is set from ANDROID_PRINTF_LOG\n"
-                   "or defaults to \"threadtime\"\n\n");
-}
-
-static void show_format_help() {
-    fprintf(stderr,
-        "-v <format>, --format=<format> options:\n"
-        "  Sets log print format verb and adverbs, where <format> is:\n"
-        "    brief long process raw tag thread threadtime time\n"
-        "  and individually flagged modifying adverbs can be added:\n"
-        "    color descriptive epoch monotonic printable uid usec UTC year zone\n"
-        "\nSingle format verbs:\n"
-        "  brief      — Display priority/tag and PID of the process issuing the message.\n"
-        "  long       — Display all metadata fields, separate messages with blank lines.\n"
-        "  process    — Display PID only.\n"
-        "  raw        — Display the raw log message, with no other metadata fields.\n"
-        "  tag        — Display the priority/tag only.\n"
-        "  thread     — Display priority, PID and TID of process issuing the message.\n"
-        "  threadtime — Display the date, invocation time, priority, tag, and the PID\n"
-        "               and TID of the thread issuing the message. (the default format).\n"
-        "  time       — Display the date, invocation time, priority/tag, and PID of the\n"
-        "             process issuing the message.\n"
-        "\nAdverb modifiers can be used in combination:\n"
-        "  color       — Display in highlighted color to match priority. i.e. \x1B[39mVERBOSE\n"
-        "                \x1B[34mDEBUG \x1B[32mINFO \x1B[33mWARNING \x1B[31mERROR FATAL\x1B[0m\n"
-        "  descriptive — events logs only, descriptions from event-log-tags database.\n"
-        "  epoch       — Display time as seconds since Jan 1 1970.\n"
-        "  monotonic   — Display time as cpu seconds since last boot.\n"
-        "  printable   — Ensure that any binary logging content is escaped.\n"
-        "  uid         — If permitted, display the UID or Android ID of logged process.\n"
-        "  usec        — Display time down the microsecond precision.\n"
-        "  UTC         — Display time as UTC.\n"
-        "  year        — Add the year to the displayed time.\n"
-        "  zone        — Add the local timezone to the displayed time.\n"
-        "  \"<zone>\"    — Print using this public named timezone (experimental).\n\n"
-    );
-}
-// clang-format on
-
-int Logcat::SetLogFormat(const char* format_string) {
-    AndroidLogPrintFormat format = android_log_formatFromString(format_string);
-
-    // invalid string?
-    if (format == FORMAT_OFF) return -1;
-
-    return android_log_setPrintFormat(logformat_.get(), format);
-}
-
-static std::pair<unsigned long, const char*> format_of_size(unsigned long value) {
-    static const char multipliers[][3] = {{""}, {"Ki"}, {"Mi"}, {"Gi"}};
-    size_t i;
-    for (i = 0;
-         (i < sizeof(multipliers) / sizeof(multipliers[0])) && (value >= 1024);
-         value /= 1024, ++i)
-        ;
-    return std::make_pair(value, multipliers[i]);
-}
-
-static char* parseTime(log_time& t, const char* cp) {
-    char* ep = t.strptime(cp, "%m-%d %H:%M:%S.%q");
-    if (ep) return ep;
-    ep = t.strptime(cp, "%Y-%m-%d %H:%M:%S.%q");
-    if (ep) return ep;
-    return t.strptime(cp, "%s.%q");
-}
-
-// Find last logged line in <outputFileName>, or <outputFileName>.1
-static log_time lastLogTime(const char* outputFileName) {
-    log_time retval(log_time::EPOCH);
-    if (!outputFileName) return retval;
-
-    std::string directory;
-    const char* file = strrchr(outputFileName, '/');
-    if (!file) {
-        directory = ".";
-        file = outputFileName;
-    } else {
-        directory = std::string(outputFileName, file - outputFileName);
-        ++file;
-    }
-
-    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(directory.c_str()),
-                                            closedir);
-    if (!dir.get()) return retval;
-
-    log_time now(CLOCK_REALTIME);
-
-    size_t len = strlen(file);
-    log_time modulo(0, NS_PER_SEC);
-    struct dirent* dp;
-
-    while (!!(dp = readdir(dir.get()))) {
-        if ((dp->d_type != DT_REG) || !!strncmp(dp->d_name, file, len) ||
-            (dp->d_name[len] && ((dp->d_name[len] != '.') ||
-                                 (strtoll(dp->d_name + 1, nullptr, 10) != 1)))) {
-            continue;
-        }
-
-        std::string file_name = directory;
-        file_name += "/";
-        file_name += dp->d_name;
-        std::string file;
-        if (!android::base::ReadFileToString(file_name, &file)) continue;
-
-        bool found = false;
-        for (const auto& line : android::base::Split(file, "\n")) {
-            log_time t(log_time::EPOCH);
-            char* ep = parseTime(t, line.c_str());
-            if (!ep || (*ep != ' ')) continue;
-            // determine the time precision of the logs (eg: msec or usec)
-            for (unsigned long mod = 1UL; mod < modulo.tv_nsec; mod *= 10) {
-                if (t.tv_nsec % (mod * 10)) {
-                    modulo.tv_nsec = mod;
-                    break;
-                }
-            }
-            // We filter any times later than current as we may not have the
-            // year stored with each log entry. Also, since it is possible for
-            // entries to be recorded out of order (very rare) we select the
-            // maximum we find just in case.
-            if ((t < now) && (t > retval)) {
-                retval = t;
-                found = true;
-            }
-        }
-        // We count on the basename file to be the definitive end, so stop here.
-        if (!dp->d_name[len] && found) break;
-    }
-    if (retval == log_time::EPOCH) return retval;
-    // tail_time prints matching or higher, round up by the modulo to prevent
-    // a replay of the last entry we have just checked.
-    retval += modulo;
-    return retval;
-}
-
-void ReportErrorName(const std::string& name, bool allow_security,
-                     std::vector<std::string>* errors) {
-    if (allow_security || name != "security") {
-        errors->emplace_back(name);
-    }
-}
-
-int Logcat::Run(int argc, char** argv) {
-    bool hasSetLogFormat = false;
-    bool clearLog = false;
-    bool security_buffer_selected =
-            false;  // Do not report errors on the security buffer unless it is explicitly named.
-    bool getLogSize = false;
-    bool getPruneList = false;
-    bool printStatistics = false;
-    bool printDividers = false;
-    unsigned long setLogSize = 0;
-    const char* setPruneList = nullptr;
-    const char* setId = nullptr;
-    int mode = 0;
-    std::string forceFilters;
-    size_t tail_lines = 0;
-    log_time tail_time(log_time::EPOCH);
-    size_t pid = 0;
-    bool got_t = false;
-    unsigned id_mask = 0;
-    std::set<uid_t> uids;
-
-    if (argc == 2 && !strcmp(argv[1], "--help")) {
-        show_help();
-        return EXIT_SUCCESS;
-    }
-
-    // meant to catch comma-delimited values, but cast a wider
-    // net for stability dealing with possible mistaken inputs.
-    static const char delimiters[] = ",:; \t\n\r\f";
-
-    optind = 0;
-    while (true) {
-        int option_index = 0;
-        // list of long-argument only strings for later comparison
-        static const char pid_str[] = "pid";
-        static const char debug_str[] = "debug";
-        static const char id_str[] = "id";
-        static const char wrap_str[] = "wrap";
-        static const char print_str[] = "print";
-        static const char uid_str[] = "uid";
-        // clang-format off
-        static const struct option long_options[] = {
-          { "binary",        no_argument,       nullptr, 'B' },
-          { "buffer",        required_argument, nullptr, 'b' },
-          { "buffer-size",   optional_argument, nullptr, 'g' },
-          { "clear",         no_argument,       nullptr, 'c' },
-          { debug_str,       no_argument,       nullptr, 0 },
-          { "dividers",      no_argument,       nullptr, 'D' },
-          { "file",          required_argument, nullptr, 'f' },
-          { "format",        required_argument, nullptr, 'v' },
-          // hidden and undocumented reserved alias for --regex
-          { "grep",          required_argument, nullptr, 'e' },
-          // hidden and undocumented reserved alias for --max-count
-          { "head",          required_argument, nullptr, 'm' },
-          { "help",          no_argument,       nullptr, 'h' },
-          { id_str,          required_argument, nullptr, 0 },
-          { "last",          no_argument,       nullptr, 'L' },
-          { "max-count",     required_argument, nullptr, 'm' },
-          { pid_str,         required_argument, nullptr, 0 },
-          { print_str,       no_argument,       nullptr, 0 },
-          { "prune",         optional_argument, nullptr, 'p' },
-          { "regex",         required_argument, nullptr, 'e' },
-          { "rotate-count",  required_argument, nullptr, 'n' },
-          { "rotate-kbytes", required_argument, nullptr, 'r' },
-          { "statistics",    no_argument,       nullptr, 'S' },
-          // hidden and undocumented reserved alias for -t
-          { "tail",          required_argument, nullptr, 't' },
-          { uid_str,         required_argument, nullptr, 0 },
-          // support, but ignore and do not document, the optional argument
-          { wrap_str,        optional_argument, nullptr, 0 },
-          { nullptr,         0,                 nullptr, 0 }
-        };
-        // clang-format on
-
-        int c = getopt_long(argc, argv, ":cdDhLt:T:gG:sQf:r:n:v:b:BSpP:m:e:", long_options,
-                            &option_index);
-        if (c == -1) break;
-
-        switch (c) {
-            case 0:
-                // only long options
-                if (long_options[option_index].name == pid_str) {
-                    if (pid != 0) {
-                        error(EXIT_FAILURE, 0, "Only one --pid argument can be provided.");
-                    }
-
-                    if (!ParseUint(optarg, &pid) || pid < 1) {
-                        error(EXIT_FAILURE, 0, "%s %s out of range.",
-                              long_options[option_index].name, optarg);
-                    }
-                    break;
-                }
-                if (long_options[option_index].name == wrap_str) {
-                    mode |= ANDROID_LOG_WRAP | ANDROID_LOG_NONBLOCK;
-                    // ToDo: implement API that supports setting a wrap timeout
-                    size_t timeout = ANDROID_LOG_WRAP_DEFAULT_TIMEOUT;
-                    if (optarg && (!ParseUint(optarg, &timeout) || timeout < 1)) {
-                        error(EXIT_FAILURE, 0, "%s %s out of range.",
-                              long_options[option_index].name, optarg);
-                    }
-                    if (timeout != ANDROID_LOG_WRAP_DEFAULT_TIMEOUT) {
-                        fprintf(stderr, "WARNING: %s %u seconds, ignoring %zu\n",
-                                long_options[option_index].name, ANDROID_LOG_WRAP_DEFAULT_TIMEOUT,
-                                timeout);
-                    }
-                    break;
-                }
-                if (long_options[option_index].name == print_str) {
-                    print_it_anyways_ = true;
-                    break;
-                }
-                if (long_options[option_index].name == debug_str) {
-                    debug_ = true;
-                    break;
-                }
-                if (long_options[option_index].name == id_str) {
-                    setId = (optarg && optarg[0]) ? optarg : nullptr;
-                }
-                if (long_options[option_index].name == uid_str) {
-                    auto uid_strings = Split(optarg, delimiters);
-                    for (const auto& uid_string : uid_strings) {
-                        uid_t uid;
-                        if (!ParseUint(uid_string, &uid)) {
-                            error(EXIT_FAILURE, 0, "Unable to parse UID '%s'", uid_string.c_str());
-                        }
-                        uids.emplace(uid);
-                    }
-                    break;
-                }
-                break;
-
-            case 's':
-                // default to all silent
-                android_log_addFilterRule(logformat_.get(), "*:s");
-                break;
-
-            case 'c':
-                clearLog = true;
-                break;
-
-            case 'L':
-                mode |= ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK;
-                break;
-
-            case 'd':
-                mode |= ANDROID_LOG_NONBLOCK;
-                break;
-
-            case 't':
-                got_t = true;
-                mode |= ANDROID_LOG_NONBLOCK;
-                FALLTHROUGH_INTENDED;
-            case 'T':
-                if (strspn(optarg, "0123456789") != strlen(optarg)) {
-                    char* cp = parseTime(tail_time, optarg);
-                    if (!cp) {
-                        error(EXIT_FAILURE, 0, "-%c '%s' not in time format.", c, optarg);
-                    }
-                    if (*cp) {
-                        char ch = *cp;
-                        *cp = '\0';
-                        fprintf(stderr, "WARNING: -%c '%s' '%c%s' time truncated\n", c, optarg, ch,
-                                cp + 1);
-                        *cp = ch;
-                    }
-                } else {
-                    if (!ParseUint(optarg, &tail_lines) || tail_lines < 1) {
-                        fprintf(stderr, "WARNING: -%c %s invalid, setting to 1\n", c, optarg);
-                        tail_lines = 1;
-                    }
-                }
-                break;
-
-            case 'D':
-                printDividers = true;
-                break;
-
-            case 'e':
-                regex_.reset(new std::regex(optarg));
-                break;
-
-            case 'm': {
-                if (!ParseUint(optarg, &max_count_) || max_count_ < 1) {
-                    error(EXIT_FAILURE, 0, "-%c '%s' isn't an integer greater than zero.", c,
-                          optarg);
-                }
-            } break;
-
-            case 'g':
-                if (!optarg) {
-                    getLogSize = true;
-                    break;
-                }
-                FALLTHROUGH_INTENDED;
-
-            case 'G': {
-                if (!ParseByteCount(optarg, &setLogSize) || setLogSize < 1) {
-                    error(EXIT_FAILURE, 0, "-G must be specified as <num><multiplier>.");
-                }
-            } break;
-
-            case 'p':
-                if (!optarg) {
-                    getPruneList = true;
-                    break;
-                }
-                FALLTHROUGH_INTENDED;
-
-            case 'P':
-                setPruneList = optarg;
-                break;
-
-            case 'b':
-                for (const auto& buffer : Split(optarg, delimiters)) {
-                    if (buffer == "default") {
-                        id_mask |= (1 << LOG_ID_MAIN) | (1 << LOG_ID_SYSTEM) | (1 << LOG_ID_CRASH);
-                    } else if (buffer == "all") {
-                        id_mask = -1;
-                    } else {
-                        log_id_t log_id = android_name_to_log_id(buffer.c_str());
-                        if (log_id >= LOG_ID_MAX) {
-                            error(EXIT_FAILURE, 0, "Unknown buffer '%s' listed for -b.",
-                                  buffer.c_str());
-                        }
-                        if (log_id == LOG_ID_SECURITY) {
-                            security_buffer_selected = true;
-                        }
-                        id_mask |= (1 << log_id);
-                    }
-                }
-                break;
-
-            case 'B':
-                print_binary_ = 1;
-                break;
-
-            case 'f':
-                if ((tail_time == log_time::EPOCH) && !tail_lines) {
-                    tail_time = lastLogTime(optarg);
-                }
-                // redirect output to a file
-                output_file_name_ = optarg;
-                break;
-
-            case 'r':
-                if (!ParseUint(optarg, &log_rotate_size_kb_) || log_rotate_size_kb_ < 1) {
-                    error(EXIT_FAILURE, 0, "Invalid parameter '%s' to -r.", optarg);
-                }
-                break;
-
-            case 'n':
-                if (!ParseUint(optarg, &max_rotated_logs_) || max_rotated_logs_ < 1) {
-                    error(EXIT_FAILURE, 0, "Invalid parameter '%s' to -n.", optarg);
-                }
-                break;
-
-            case 'v':
-                if (!strcmp(optarg, "help") || !strcmp(optarg, "--help")) {
-                    show_format_help();
-                    return EXIT_SUCCESS;
-                }
-                for (const auto& arg : Split(optarg, delimiters)) {
-                    int err = SetLogFormat(arg.c_str());
-                    if (err < 0) {
-                        error(EXIT_FAILURE, 0, "Invalid parameter '%s' to -v.", arg.c_str());
-                    }
-                    if (err) hasSetLogFormat = true;
-                }
-                break;
-
-            case 'Q':
-#define LOGCAT_FILTER "androidboot.logcat="
-#define CONSOLE_PIPE_OPTION "androidboot.consolepipe="
-#define CONSOLE_OPTION "androidboot.console="
-#define QEMU_PROPERTY "ro.kernel.qemu"
-#define QEMU_CMDLINE "qemu.cmdline"
-                // This is a *hidden* option used to start a version of logcat
-                // in an emulated device only.  It basically looks for
-                // androidboot.logcat= on the kernel command line.  If
-                // something is found, it extracts a log filter and uses it to
-                // run the program. The logcat output will go to consolepipe if
-                // androiboot.consolepipe (e.g. qemu_pipe) is given, otherwise,
-                // it goes to androidboot.console (e.g. tty)
-                {
-                    // if not in emulator, exit quietly
-                    if (false == android::base::GetBoolProperty(QEMU_PROPERTY, false)) {
-                        return EXIT_SUCCESS;
-                    }
-
-                    std::string cmdline = android::base::GetProperty(QEMU_CMDLINE, "");
-                    if (cmdline.empty()) {
-                        android::base::ReadFileToString("/proc/cmdline", &cmdline);
-                    }
-
-                    const char* logcatFilter = strstr(cmdline.c_str(), LOGCAT_FILTER);
-                    // if nothing found or invalid filters, exit quietly
-                    if (!logcatFilter) {
-                        return EXIT_SUCCESS;
-                    }
-
-                    const char* p = logcatFilter + strlen(LOGCAT_FILTER);
-                    const char* q = strpbrk(p, " \t\n\r");
-                    if (!q) q = p + strlen(p);
-                    forceFilters = std::string(p, q);
-
-                    // redirect our output to the emulator console pipe or console
-                    const char* consolePipe =
-                        strstr(cmdline.c_str(), CONSOLE_PIPE_OPTION);
-                    const char* console =
-                        strstr(cmdline.c_str(), CONSOLE_OPTION);
-
-                    if (consolePipe) {
-                        p = consolePipe + strlen(CONSOLE_PIPE_OPTION);
-                    } else if (console) {
-                        p = console + strlen(CONSOLE_OPTION);
-                    } else {
-                        return EXIT_FAILURE;
-                    }
-
-                    q = strpbrk(p, " \t\n\r");
-                    int len = q ? q - p : strlen(p);
-                    std::string devname = "/dev/" + std::string(p, len);
-                    std::string pipePurpose("pipe:logcat");
-                    if (consolePipe) {
-                        // example: "qemu_pipe,pipe:logcat"
-                        // upon opening of /dev/qemu_pipe, the "pipe:logcat"
-                        // string with trailing '\0' should be written to the fd
-                        size_t pos = devname.find(',');
-                        if (pos != std::string::npos) {
-                            pipePurpose = devname.substr(pos + 1);
-                            devname = devname.substr(0, pos);
-                        }
-                    }
-
-                    fprintf(stderr, "logcat using %s\n", devname.c_str());
-
-                    int fd = open(devname.c_str(), O_WRONLY | O_CLOEXEC);
-                    if (fd < 0) {
-                        break;
-                    }
-
-                    if (consolePipe) {
-                        // need the trailing '\0'
-                        if (!WriteFully(fd, pipePurpose.c_str(), pipePurpose.size() + 1)) {
-                            close(fd);
-                            return EXIT_FAILURE;
-                        }
-                    }
-                    // close output and error channels, replace with console
-                    dup2(fd, output_fd_.get());
-                    dup2(fd, STDERR_FILENO);
-                    close(fd);
-                }
-                break;
-
-            case 'S':
-                printStatistics = true;
-                break;
-
-            case ':':
-                error(EXIT_FAILURE, 0, "Option '%s' needs an argument.", argv[optind - 1]);
-                break;
-
-            case 'h':
-                show_help();
-                show_format_help();
-                return EXIT_SUCCESS;
-
-            case '?':
-                error(EXIT_FAILURE, 0, "Unknown option '%s'.", argv[optind - 1]);
-                break;
-
-            default:
-                error(EXIT_FAILURE, 0, "Unknown getopt_long() result '%c'.", c);
-        }
-    }
-
-    if (max_count_ && got_t) {
-        error(EXIT_FAILURE, 0, "Cannot use -m (--max-count) and -t together.");
-    }
-    if (print_it_anyways_ && (!regex_ || !max_count_)) {
-        // One day it would be nice if --print -v color and --regex <expr>
-        // could play with each other and show regex highlighted content.
-        fprintf(stderr,
-                "WARNING: "
-                "--print ignored, to be used in combination with\n"
-                "         "
-                "--regex <expr> and --max-count <N>\n");
-        print_it_anyways_ = false;
-    }
-
-    // If no buffers are specified, default to using these buffers.
-    if (id_mask == 0) {
-        id_mask = (1 << LOG_ID_MAIN) | (1 << LOG_ID_SYSTEM) | (1 << LOG_ID_CRASH) |
-                  (1 << LOG_ID_KERNEL);
-    }
-
-    if (log_rotate_size_kb_ != 0 && !output_file_name_) {
-        error(EXIT_FAILURE, 0, "-r requires -f as well.");
-    }
-
-    if (setId != 0) {
-        if (!output_file_name_) {
-            error(EXIT_FAILURE, 0, "--id='%s' requires -f as well.", setId);
-        }
-
-        std::string file_name = StringPrintf("%s.id", output_file_name_);
-        std::string file;
-        bool file_ok = android::base::ReadFileToString(file_name, &file);
-        android::base::WriteStringToFile(setId, file_name, S_IRUSR | S_IWUSR,
-                                         getuid(), getgid());
-        if (!file_ok || !file.compare(setId)) setId = nullptr;
-    }
-
-    if (!hasSetLogFormat) {
-        const char* logFormat = getenv("ANDROID_PRINTF_LOG");
-
-        if (!!logFormat) {
-            for (const auto& arg : Split(logFormat, delimiters)) {
-                int err = SetLogFormat(arg.c_str());
-                // environment should not cause crash of logcat
-                if (err < 0) {
-                    fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n", arg.c_str());
-                }
-                if (err > 0) hasSetLogFormat = true;
-            }
-        }
-        if (!hasSetLogFormat) {
-            SetLogFormat("threadtime");
-        }
-    }
-
-    if (forceFilters.size()) {
-        int err = android_log_addFilterString(logformat_.get(), forceFilters.c_str());
-        if (err < 0) {
-            error(EXIT_FAILURE, 0, "Invalid filter expression in logcat args.");
-        }
-    } else if (argc == optind) {
-        // Add from environment variable
-        const char* env_tags_orig = getenv("ANDROID_LOG_TAGS");
-
-        if (!!env_tags_orig) {
-            int err = android_log_addFilterString(logformat_.get(), env_tags_orig);
-
-            if (err < 0) {
-                error(EXIT_FAILURE, 0, "Invalid filter expression in ANDROID_LOG_TAGS.");
-            }
-        }
-    } else {
-        // Add from commandline
-        for (int i = optind ; i < argc ; i++) {
-            int err = android_log_addFilterString(logformat_.get(), argv[i]);
-            if (err < 0) {
-                error(EXIT_FAILURE, 0, "Invalid filter expression '%s'.", argv[i]);
-            }
-        }
-    }
-
-    if (mode & ANDROID_LOG_PSTORE) {
-        if (output_file_name_) {
-            error(EXIT_FAILURE, 0, "-c is ambiguous with both -f and -L specified.");
-        }
-        if (setLogSize || getLogSize || printStatistics || getPruneList || setPruneList) {
-            error(EXIT_FAILURE, 0, "-L is incompatible with -g/-G, -S, and -p/-P.");
-        }
-        if (clearLog) {
-            unlink("/sys/fs/pstore/pmsg-ramoops-0");
-            return EXIT_SUCCESS;
-        }
-    }
-
-    if (output_file_name_) {
-        if (setLogSize || getLogSize || printStatistics || getPruneList || setPruneList) {
-            error(EXIT_FAILURE, 0, "-f is incompatible with -g/-G, -S, and -p/-P.");
-        }
-
-        if (clearLog || setId) {
-            int max_rotation_count_digits =
-                    max_rotated_logs_ > 0 ? (int)(floor(log10(max_rotated_logs_) + 1)) : 0;
-
-            for (int i = max_rotated_logs_; i >= 0; --i) {
-                std::string file;
-
-                if (!i) {
-                    file = output_file_name_;
-                } else {
-                    file = StringPrintf("%s.%.*d", output_file_name_, max_rotation_count_digits, i);
-                }
-
-                int err = unlink(file.c_str());
-
-                if (err < 0 && errno != ENOENT) {
-                    fprintf(stderr, "failed to delete log file '%s': %s\n", file.c_str(),
-                            strerror(errno));
-                }
-            }
-        }
-
-        if (clearLog) {
-            return EXIT_SUCCESS;
-        }
-    }
-
-    std::unique_ptr<logger_list, decltype(&android_logger_list_free)> logger_list{
-            nullptr, &android_logger_list_free};
-    if (tail_time != log_time::EPOCH) {
-        logger_list.reset(android_logger_list_alloc_time(mode, tail_time, pid));
-    } else {
-        logger_list.reset(android_logger_list_alloc(mode, tail_lines, pid));
-    }
-    // We have three orthogonal actions below to clear, set log size and
-    // get log size. All sharing the same iteration loop.
-    std::vector<std::string> open_device_failures;
-    std::vector<std::string> clear_failures;
-    std::vector<std::string> set_size_failures;
-    std::vector<std::string> get_size_failures;
-
-    for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
-        if (!(id_mask & (1 << i))) continue;
-        const char* buffer_name = android_log_id_to_name(static_cast<log_id_t>(i));
-
-        auto logger = android_logger_open(logger_list.get(), static_cast<log_id_t>(i));
-        if (logger == nullptr) {
-            ReportErrorName(buffer_name, security_buffer_selected, &open_device_failures);
-            continue;
-        }
-
-        if (clearLog) {
-            if (android_logger_clear(logger)) {
-                ReportErrorName(buffer_name, security_buffer_selected, &clear_failures);
-            }
-        }
-
-        if (setLogSize) {
-            if (android_logger_set_log_size(logger, setLogSize)) {
-                ReportErrorName(buffer_name, security_buffer_selected, &set_size_failures);
-            }
-        }
-
-        if (getLogSize) {
-            long size = android_logger_get_log_size(logger);
-            long readable = android_logger_get_log_readable_size(logger);
-            long consumed = android_logger_get_log_consumed_size(logger);
-
-            if (size < 0 || readable < 0) {
-                ReportErrorName(buffer_name, security_buffer_selected, &get_size_failures);
-            } else {
-                auto size_format = format_of_size(size);
-                auto readable_format = format_of_size(readable);
-                auto consumed_format = format_of_size(consumed);
-                std::string str = android::base::StringPrintf(
-                        "%s: ring buffer is %lu %sB (%lu %sB consumed, %lu %sB readable),"
-                        " max entry is %d B, max payload is %d B\n",
-                        buffer_name, size_format.first, size_format.second, consumed_format.first,
-                        consumed_format.second, readable_format.first, readable_format.second,
-                        (int)LOGGER_ENTRY_MAX_LEN, (int)LOGGER_ENTRY_MAX_PAYLOAD);
-                if (!WriteFully(output_fd_, str.data(), str.length())) {
-                    error(EXIT_FAILURE, errno, "Failed to write to output fd");
-                }
-            }
-        }
-    }
-
-    // report any errors in the above loop and exit
-    if (!open_device_failures.empty()) {
-        error(EXIT_FAILURE, 0, "Unable to open log device%s '%s'.",
-              open_device_failures.size() > 1 ? "s" : "", Join(open_device_failures, ",").c_str());
-    }
-    if (!clear_failures.empty()) {
-        error(EXIT_FAILURE, 0, "failed to clear the '%s' log%s.", Join(clear_failures, ",").c_str(),
-              clear_failures.size() > 1 ? "s" : "");
-    }
-    if (!set_size_failures.empty()) {
-        error(EXIT_FAILURE, 0, "failed to set the '%s' log size%s.",
-              Join(set_size_failures, ",").c_str(), set_size_failures.size() > 1 ? "s" : "");
-    }
-    if (!get_size_failures.empty()) {
-        error(EXIT_FAILURE, 0, "failed to get the readable '%s' log size%s.",
-              Join(get_size_failures, ",").c_str(), get_size_failures.size() > 1 ? "s" : "");
-    }
-
-    if (setPruneList) {
-        size_t len = strlen(setPruneList);
-        if (android_logger_set_prune_list(logger_list.get(), setPruneList, len)) {
-            error(EXIT_FAILURE, 0, "Failed to set the prune list.");
-        }
-        return EXIT_SUCCESS;
-    }
-
-    if (printStatistics || getPruneList) {
-        std::string buf(8192, '\0');
-        size_t ret_length = 0;
-        int retry = 32;
-
-        for (; retry >= 0; --retry) {
-            if (getPruneList) {
-                android_logger_get_prune_list(logger_list.get(), buf.data(), buf.size());
-            } else {
-                android_logger_get_statistics(logger_list.get(), buf.data(), buf.size());
-            }
-
-            ret_length = atol(buf.c_str());
-            if (ret_length < 3) {
-                error(EXIT_FAILURE, 0, "Failed to read data.");
-            }
-
-            if (ret_length < buf.size()) {
-                break;
-            }
-
-            buf.resize(ret_length + 1);
-        }
-
-        if (retry < 0) {
-            error(EXIT_FAILURE, 0, "Failed to read data.");
-        }
-
-        buf.resize(ret_length);
-        if (buf.back() == '\f') {
-            buf.pop_back();
-        }
-
-        // Remove the byte count prefix
-        const char* cp = buf.c_str();
-        while (isdigit(*cp)) ++cp;
-        if (*cp == '\n') ++cp;
-
-        size_t len = strlen(cp);
-        if (!WriteFully(output_fd_, cp, len)) {
-            error(EXIT_FAILURE, errno, "Failed to write to output fd");
-        }
-        return EXIT_SUCCESS;
-    }
-
-    if (getLogSize || setLogSize || clearLog) return EXIT_SUCCESS;
-
-    SetupOutputAndSchedulingPolicy(!(mode & ANDROID_LOG_NONBLOCK));
-
-    while (!max_count_ || print_count_ < max_count_) {
-        struct log_msg log_msg;
-        int ret = android_logger_list_read(logger_list.get(), &log_msg);
-        if (!ret) {
-            error(EXIT_FAILURE, 0, R"init(Unexpected EOF!
-
-This means that either the device shut down, logd crashed, or this instance of logcat was unable to read log
-messages as quickly as they were being produced.
-
-If you have enabled significant logging, look into using the -G option to increase log buffer sizes.)init");
-        }
-
-        if (ret < 0) {
-            if (ret == -EAGAIN) break;
-
-            if (ret == -EIO) {
-                error(EXIT_FAILURE, 0, "Unexpected EOF!");
-            }
-            if (ret == -EINVAL) {
-                error(EXIT_FAILURE, 0, "Unexpected length.");
-            }
-            error(EXIT_FAILURE, errno, "Logcat read failure");
-        }
-
-        if (log_msg.id() > LOG_ID_MAX) {
-            error(EXIT_FAILURE, 0, "Unexpected log id (%d) over LOG_ID_MAX (%d).", log_msg.id(),
-                  LOG_ID_MAX);
-        }
-
-        if (!uids.empty() && uids.count(log_msg.entry.uid) == 0) {
-            continue;
-        }
-
-        PrintDividers(log_msg.id(), printDividers);
-
-        if (print_binary_) {
-            if (!WriteFully(output_fd_, &log_msg, log_msg.len())) {
-                error(EXIT_FAILURE, errno, "Failed to write to output fd");
-            }
-        } else {
-            ProcessBuffer(&log_msg);
-        }
-    }
-    return EXIT_SUCCESS;
-}
-
-int main(int argc, char** argv) {
-    Logcat logcat;
-    return logcat.Run(argc, argv);
-}
diff --git a/logcat/logcatd b/logcat/logcatd
deleted file mode 100755
index 5a1415d..0000000
--- a/logcat/logcatd
+++ /dev/null
@@ -1,29 +0,0 @@
-#! /system/bin/sh
-
-# This is primarily meant to be used by logpersist.  This script is run as an init service, which
-# first reads the 'last' logcat to persistent storage with `-L` then run logcat again without
-# `-L` to read the current logcat buffers to persistent storage.
-
-# init sets the umask to 077 for forked processes. logpersist needs to create files that are group
-# readable. So relax the umask to only disallow group wx and world rwx.
-umask 037
-
-has_last="false"
-for arg in "$@"; do
-  if [ "$arg" == "-L" -o "$arg" == "--last" ]; then
-    has_last="true"
-  fi
-done
-
-if [ "$has_last" == "true" ]; then
-  logcat "$@"
-fi
-
-args_without_last=()
-for arg in "$@"; do
-  if [ "$arg" != "-L" -a "$arg" != "--last" ]; then
-    ARGS+=("$arg")
-  fi
-done
-
-exec logcat "${ARGS[@]}"
diff --git a/logcat/logcatd.rc b/logcat/logcatd.rc
deleted file mode 100644
index 64d5500..0000000
--- a/logcat/logcatd.rc
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# init scriptures for logcatd persistent logging.
-#
-# Make sure any property changes are only performed with /data mounted, after
-# post-fs-data state because otherwise behavior is undefined. The exceptions
-# are device adjustments for logcatd service properties (persist.* overrides
-# notwithstanding) for logd.logpersistd.size logd.logpersistd.rotate_kbytes and
-# logd.logpersistd.buffer.
-
-# persist to non-persistent trampolines to permit device properties can be
-# overridden when /data mounts, or during runtime.
-on property:persist.logd.logpersistd.count=*
-    # expect /init to report failure if property empty (default)
-    setprop persist.logd.logpersistd.size ${persist.logd.logpersistd.count}
-
-on property:persist.logd.logpersistd.size=*
-    setprop logd.logpersistd.size ${persist.logd.logpersistd.size}
-
-on property:persist.logd.logpersistd.rotate_kbytes=*
-    setprop logd.logpersistd.rotate_kbytes ${persist.logd.logpersistd.rotate_kbytes}
-
-on property:persist.logd.logpersistd.buffer=*
-    setprop logd.logpersistd.buffer ${persist.logd.logpersistd.buffer}
-
-on property:persist.logd.logpersistd=logcatd
-    setprop logd.logpersistd logcatd
-
-# enable, prep and start logcatd service
-on load_persist_props_action
-    setprop logd.logpersistd.enable true
-
-on property:logd.logpersistd.enable=true && property:logd.logpersistd=logcatd
-    # log group should be able to read persisted logs
-    mkdir /data/misc/logd 0750 logd log
-    start logcatd
-
-# stop logcatd service and clear data
-on property:logd.logpersistd.enable=true && property:logd.logpersistd=clear
-    setprop persist.logd.logpersistd ""
-    stop logcatd
-    # logd for clear of only our files in /data/misc/logd
-    exec - logd log -- /system/bin/logcat -c -f /data/misc/logd/logcat -n ${logd.logpersistd.size:-256}
-    setprop logd.logpersistd ""
-
-# stop logcatd service
-on property:logd.logpersistd=stop
-    setprop persist.logd.logpersistd ""
-    stop logcatd
-    setprop logd.logpersistd ""
-
-on property:logd.logpersistd.enable=false
-    stop logcatd
-
-# logcatd service
-service logcatd /system/bin/logcatd -L -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r ${logd.logpersistd.rotate_kbytes:-2048} -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
-    class late_start
-    disabled
-    # logd for write to /data/misc/logd, log group for read from log daemon
-    user logd
-    group log
-    writepid /dev/cpuset/system-background/tasks
-    oom_score_adjust -600
diff --git a/logcat/logpersist b/logcat/logpersist
deleted file mode 100755
index 05b46f0..0000000
--- a/logcat/logpersist
+++ /dev/null
@@ -1,178 +0,0 @@
-#! /system/bin/sh
-# logpersist cat, start and stop handlers
-progname="${0##*/}"
-case `getprop ro.debuggable` in
-1) ;;
-*) echo "${progname} - Permission denied"
-   exit 1
-   ;;
-esac
-
-property=persist.logd.logpersistd
-
-case `getprop ${property#persist.}.enable` in
-true) ;;
-*) echo "${progname} - Disabled"
-   exit 1
-   ;;
-esac
-
-log_uid=logd
-log_tag_property=persist.log.tag
-data=/data/misc/logd/logcat
-service=logcatd
-size_default=256
-buffer_default=all
-args="${@}"
-
-size=${size_default}
-buffer=${buffer_default}
-clear=false
-while [ ${#} -gt 0 ]; do
-  case ${1} in
-    -c|--clear) clear=true ;;
-    --size=*) size="${1#--size=}" ;;
-    --rotate-count=*) size="${1#--rotate-count=}" ;;
-    -n|--size|--rotate-count) size="${2}" ; shift ;;
-    --buffer=*) buffer="${1#--buffer=}" ;;
-    -b|--buffer) buffer="${2}" ; shift ;;
-    -h|--help|*)
-      LEAD_SPACE_="`echo ${progname%.*} | tr '[ -~]' ' '`"
-      echo "${progname%.*}.cat             - dump current ${service} logs"
-      echo "${progname%.*}.start [--size=<size_in_kb>] [--buffer=<buffers>] [--clear]"
-      echo "${LEAD_SPACE_}                 - start ${service} service"
-      echo "${progname%.*}.stop [--clear]  - stop ${service} service"
-      case ${1} in
-        -h|--help) exit 0 ;;
-        *) echo ERROR: bad argument ${@} >&2 ; exit 1 ;;
-      esac
-      ;;
-  esac
-  shift
-done
-
-if [ -z "${size}" -o "${size_default}" = "${size}" ]; then
-  unset size
-fi
-if [ -n "${size}" ] &&
-  ! ( [ 0 -lt "${size}" ] && [ 2048 -ge "${size}" ] ) >/dev/null 2>&1; then
-  echo ERROR: Invalid --size ${size} >&2
-  exit 1
-fi
-if [ -z "${buffer}" -o "${buffer_default}" = "${buffer}" ]; then
-  unset buffer
-fi
-if [ -n "${buffer}" ] && ! logcat -b ${buffer} -g >/dev/null 2>&1; then
-  echo ERROR: Invalid --buffer ${buffer} >&2
-  exit 1
-fi
-
-log_tag="`getprop ${log_tag_property}`"
-logd_logpersistd="`getprop ${property}`"
-
-case ${progname} in
-*.cat)
-  if [ -n "${size}${buffer}" -o "true" = "${clear}" ]; then
-    echo WARNING: Can not use --clear, --size or --buffer with ${progname%.*}.cat >&2
-  fi
-  su ${log_uid} ls "${data%/*}" |
-  tr -d '\r' |
-  sort -ru |
-  sed "s#^#${data%/*}/#" |
-  grep "${data}[.]*[0-9]*\$" |
-  su ${log_uid} xargs cat
-  ;;
-*.start)
-  current_buffer="`getprop ${property#persist.}.buffer`"
-  current_size="`getprop ${property#persist.}.size`"
-  if [ "${service}" = "`getprop ${property#persist.}`" ]; then
-    if [ "true" = "${clear}" ]; then
-      setprop ${property#persist.} "clear"
-    elif [ "${buffer}|${size}" != "${current_buffer}|${current_size}" ]; then
-      echo   "ERROR: Changing existing collection parameters from" >&2
-      if [ "${buffer}" != "${current_buffer}" ]; then
-        a=${current_buffer}
-        b=${buffer}
-        if [ -z "${a}" ]; then a="${default_buffer}"; fi
-        if [ -z "${b}" ]; then b="${default_buffer}"; fi
-        echo "           --buffer ${a} to ${b}" >&2
-      fi
-      if [ "${size}" != "${current_size}" ]; then
-        a=${current_size}
-        b=${size}
-        if [ -z "${a}" ]; then a="${default_size}"; fi
-        if [ -z "${b}" ]; then b="${default_size}"; fi
-        echo "           --size ${a} to ${b}" >&2
-      fi
-      echo   "       Are you sure you want to do this?" >&2
-      echo   "       Suggest add --clear to erase data and restart with new settings." >&2
-      echo   "       To blindly override and retain data, ${progname%.*}.stop first." >&2
-      exit 1
-    fi
-  elif [ "true" = "${clear}" ]; then
-    setprop ${property#persist.} "clear"
-  fi
-  if [ -n "${buffer}${current_buffer}" ]; then
-    setprop ${property}.buffer "${buffer}"
-    if [ -z "${buffer}" ]; then
-      # deal with trampoline for empty properties
-      setprop ${property#persist.}.buffer ""
-    fi
-  fi
-  if [ -n "${size}${current_size}" ]; then
-    setprop ${property}.size "${size}"
-    if [ -z "${size}" ]; then
-      # deal with trampoline for empty properties
-      setprop ${property#persist.}.size ""
-    fi
-  fi
-  while [ "clear" = "`getprop ${property#persist.}`" ]; do
-    continue
-  done
-  # Tell Settings that we are back on again if we turned logging off
-  tag="${log_tag#Settings}"
-  if [ X"${log_tag}" != X"${tag}" ]; then
-    echo "WARNING: enabling logd service" >&2
-    setprop ${log_tag_property} "${tag#,}"
-  fi
-  # ${service}.rc does the heavy lifting with the following trigger
-  setprop ${property} ${service}
-  # 20ms done, to permit process feedback check
-  sleep 1
-  getprop ${property#persist.}
-  # also generate an error return code if not found running
-  pgrep -u ${log_uid} ${service%d}
-  ;;
-*.stop)
-  if [ -n "${size}${buffer}" ]; then
-    echo "WARNING: Can not use --size or --buffer with ${progname%.*}.stop" >&2
-  fi
-  if [ "true" = "${clear}" ]; then
-    setprop ${property#persist.} "clear"
-  else
-    setprop ${property#persist.} "stop"
-  fi
-  if [ -n "`getprop ${property#persist.}.buffer`" ]; then
-    setprop ${property}.buffer ""
-    # deal with trampoline for empty properties
-    setprop ${property#persist.}.buffer ""
-  fi
-  if [ -n "`getprop ${property#persist.}.size`" ]; then
-    setprop ${property}.size ""
-    # deal with trampoline for empty properties
-    setprop ${property#persist.}.size ""
-  fi
-  while [ "clear" = "`getprop ${property#persist.}`" ]; do
-    continue
-  done
-  ;;
-*)
-  echo "ERROR: Unexpected command ${0##*/} ${args}" >&2
-  exit 1
-esac
-
-if [ X"${log_tag}" != X"`getprop ${log_tag_property}`" ] ||
-   [ X"${logd_logpersistd}" != X"`getprop ${property}`" ]; then
-  echo "WARNING: killing Settings application to pull in new values" >&2
-  am force-stop com.android.settings
-fi
diff --git a/logcat/tests/Android.bp b/logcat/tests/Android.bp
deleted file mode 100644
index ab84150..0000000
--- a/logcat/tests/Android.bp
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright (C) 2013-2014 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.
-//
-
-cc_defaults {
-    name: "logcat-tests-defaults",
-    cflags: [
-        "-fstack-protector-all",
-        "-g",
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-fno-builtin",
-    ],
-}
-
-// -----------------------------------------------------------------------------
-// Benchmarks
-// ----------------------------------------------------------------------------
-
-// Build benchmarks for the device. Run with:
-//   adb shell /data/nativetest/logcat-benchmarks/logcat-benchmarks
-cc_benchmark {
-    name: "logcat-benchmarks",
-    defaults: ["logcat-tests-defaults"],
-    srcs: ["logcat_benchmark.cpp"],
-    shared_libs: ["libbase"],
-}
-
-// -----------------------------------------------------------------------------
-// Unit tests.
-// -----------------------------------------------------------------------------
-
-// Build tests for the device (with .so). Run with:
-//   adb shell /data/nativetest/logcat-unit-tests/logcat-unit-tests
-cc_test {
-    name: "logcat-unit-tests",
-    defaults: ["logcat-tests-defaults"],
-    shared_libs: ["libbase"],
-    static_libs: ["liblog"],
-    srcs: [
-        "logcat_test.cpp",
-        "logcatd_test.cpp",
-    ],
-}
diff --git a/logcat/tests/logcat_benchmark.cpp b/logcat/tests/logcat_benchmark.cpp
deleted file mode 100644
index 8d88628..0000000
--- a/logcat/tests/logcat_benchmark.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2013-2014 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <benchmark/benchmark.h>
-
-static const char begin[] = "--------- beginning of ";
-
-static void BM_logcat_sorted_order(benchmark::State& state) {
-    FILE* fp;
-
-    if (!state.KeepRunning()) return;
-
-    fp = popen(
-        "logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
-        "r");
-    if (!fp) return;
-
-    class timestamp {
-       private:
-        int month;
-        int day;
-        int hour;
-        int minute;
-        int second;
-        int millisecond;
-        bool ok;
-
-       public:
-        void init(const char* buffer) {
-            ok = false;
-            if (buffer != NULL) {
-                ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ", &month, &day, &hour,
-                            &minute, &second, &millisecond) == 6;
-            }
-        }
-
-        explicit timestamp(const char* buffer) {
-            init(buffer);
-        }
-
-        bool operator<(timestamp& T) {
-            return !ok || !T.ok || (month < T.month) ||
-                   ((month == T.month) &&
-                    ((day < T.day) ||
-                     ((day == T.day) &&
-                      ((hour < T.hour) ||
-                       ((hour == T.hour) &&
-                        ((minute < T.minute) ||
-                         ((minute == T.minute) &&
-                          ((second < T.second) ||
-                           ((second == T.second) &&
-                            (millisecond < T.millisecond))))))))));
-        }
-
-        bool valid(void) {
-            return ok;
-        }
-    } last(NULL);
-
-    char* last_buffer = NULL;
-    char buffer[5120];
-
-    int count = 0;
-    int next_lt_last = 0;
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
-            continue;
-        }
-        if (!last.valid()) {
-            free(last_buffer);
-            last_buffer = strdup(buffer);
-            last.init(buffer);
-        }
-        timestamp next(buffer);
-        if (next < last) {
-            if (last_buffer) {
-                fprintf(stderr, "<%s", last_buffer);
-            }
-            fprintf(stderr, ">%s", buffer);
-            ++next_lt_last;
-        }
-        if (next.valid()) {
-            free(last_buffer);
-            last_buffer = strdup(buffer);
-            last.init(buffer);
-        }
-        ++count;
-    }
-    free(last_buffer);
-
-    pclose(fp);
-
-    static const int max_ok = 2;
-
-    // Allow few fails, happens with readers active
-    fprintf(stderr, "%s: %d/%d out of order entries\n",
-            (next_lt_last) ? ((next_lt_last <= max_ok) ? "WARNING" : "ERROR")
-                           : "INFO",
-            next_lt_last, count);
-
-    if (next_lt_last > max_ok) {
-        fprintf(stderr, "EXPECT_GE(max_ok=%d, next_lt_last=%d)\n", max_ok,
-                next_lt_last);
-    }
-
-    // sample statistically too small
-    if (count < 100) {
-        fprintf(stderr, "EXPECT_LT(100, count=%d)\n", count);
-    }
-
-    state.KeepRunning();
-}
-BENCHMARK(BM_logcat_sorted_order);
-
-BENCHMARK_MAIN();
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
deleted file mode 100644
index 735fd94..0000000
--- a/logcat/tests/logcat_test.cpp
+++ /dev/null
@@ -1,1772 +0,0 @@
-/*
- * Copyright (C) 2013-2014 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 <ctype.h>
-#include <dirent.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/cdefs.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <memory>
-#include <regex>
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <gtest/gtest.h>
-#include <log/event_tag_map.h>
-#include <log/log.h>
-#include <log/log_event_list.h>
-
-#ifndef logcat_executable
-#define USING_LOGCAT_EXECUTABLE_DEFAULT
-#define logcat_executable "logcat"
-#endif
-
-#define BIG_BUFFER (5 * 1024)
-
-// rest(), let the logs settle.
-//
-// logd is in a background cgroup and under extreme load can take up to
-// 3 seconds to land a log entry. Under moderate load we can do with 200ms.
-static void rest() {
-    static const useconds_t restPeriod = 200000;
-
-    usleep(restPeriod);
-}
-
-// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
-// non-syscall libs. Since we are only using this in the emergency of
-// a signal to stuff a terminating code into the logs, we will spin rather
-// than try a usleep.
-#define LOG_FAILURE_RETRY(exp)                                               \
-    ({                                                                       \
-        typeof(exp) _rc;                                                     \
-        do {                                                                 \
-            _rc = (exp);                                                     \
-        } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \
-                 (_rc == -EINTR) || (_rc == -EAGAIN));                       \
-        _rc;                                                                 \
-    })
-
-static const char begin[] = "--------- beginning of ";
-
-TEST(logcat, buckets) {
-    FILE* fp;
-
-#undef LOG_TAG
-#define LOG_TAG "inject.buckets"
-    // inject messages into radio, system, main and events buffers to
-    // ensure that we see all the begin[] bucket messages.
-    RLOGE(logcat_executable);
-    SLOGE(logcat_executable);
-    ALOGE(logcat_executable);
-    __android_log_bswrite(0, logcat_executable ".inject.buckets");
-    rest();
-
-    ASSERT_TRUE(NULL != (fp = popen(logcat_executable
-                                    " -b radio -b events -b system -b main -d 2>/dev/null",
-                                    "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int ids = 0;
-    int count = 0;
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
-            while (char* cp = strrchr(buffer, '\n')) {
-                *cp = '\0';
-            }
-            log_id_t id = android_name_to_log_id(buffer + sizeof(begin) - 1);
-            ids |= 1 << id;
-            ++count;
-        }
-    }
-
-    pclose(fp);
-
-    EXPECT_EQ(ids, 15);
-
-    EXPECT_EQ(count, 4);
-}
-
-TEST(logcat, event_tag_filter) {
-    FILE* fp;
-
-#undef LOG_TAG
-#define LOG_TAG "inject.filter"
-    // inject messages into radio, system and main buffers
-    // with our unique log tag to test logcat filter.
-    RLOGE(logcat_executable);
-    SLOGE(logcat_executable);
-    ALOGE(logcat_executable);
-    rest();
-
-    std::string command = android::base::StringPrintf(
-        logcat_executable
-        " -b radio -b system -b main --pid=%d -d -s inject.filter 2>/dev/null",
-        getpid());
-    ASSERT_TRUE(NULL != (fp = popen(command.c_str(), "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (strncmp(begin, buffer, sizeof(begin) - 1)) ++count;
-    }
-
-    pclose(fp);
-
-    // logcat, liblogcat and logcatd test instances result in the progression
-    // of 3, 6 and 9 for our counts as each round is performed.
-    EXPECT_GE(count, 3);
-    EXPECT_LE(count, 9);
-    EXPECT_EQ(count % 3, 0);
-}
-
-// If there is not enough background noise in the logs, then spam the logs to
-// permit tail checking so that the tests can progress.
-static size_t inject(ssize_t count) {
-    if (count <= 0) return 0;
-
-    static const size_t retry = 4;
-    size_t errors = retry;
-    size_t num = 0;
-    for (;;) {
-        log_time ts(CLOCK_MONOTONIC);
-        if (__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) >= 0) {
-            if (++num >= (size_t)count) {
-                // let data settle end-to-end
-                sleep(3);
-                return num;
-            }
-            errors = retry;
-            usleep(100);  // ~32 per timer tick, we are a spammer regardless
-        } else if (--errors <= 0) {
-            return num;
-        }
-    }
-    // NOTREACH
-    return num;
-}
-
-TEST(logcat, year) {
-    int count;
-    int tries = 3;  // in case run too soon after system start or buffer clear
-
-    do {
-        FILE* fp;
-
-        char needle[32];
-        time_t now;
-        time(&now);
-        struct tm* ptm;
-#if !defined(_WIN32)
-        struct tm tmBuf;
-        ptm = localtime_r(&now, &tmBuf);
-#else
-        ptm = localtime(&&now);
-#endif
-        strftime(needle, sizeof(needle), "[ %Y-", ptm);
-
-        ASSERT_TRUE(NULL !=
-                    (fp = popen(logcat_executable " -v long -v year -b all -t 3 2>/dev/null", "r")));
-
-        char buffer[BIG_BUFFER];
-
-        count = 0;
-
-        while (fgets(buffer, sizeof(buffer), fp)) {
-            if (!strncmp(buffer, needle, strlen(needle))) {
-                ++count;
-            }
-        }
-        pclose(fp);
-
-    } while ((count < 3) && --tries && inject(3 - count));
-
-    ASSERT_EQ(3, count);
-}
-
-// Return a pointer to each null terminated -v long time field.
-static char* fgetLongTime(char* buffer, size_t buflen, FILE* fp) {
-    while (fgets(buffer, buflen, fp)) {
-        char* cp = buffer;
-        if (*cp != '[') {
-            continue;
-        }
-        while (*++cp == ' ') {
-            ;
-        }
-        char* ep = cp;
-        while (isdigit(*ep)) {
-            ++ep;
-        }
-        if ((*ep != '-') && (*ep != '.')) {
-            continue;
-        }
-        // Find PID field.  Look for ': ' or ':[0-9][0-9][0-9]'
-        while (((ep = strchr(ep, ':'))) && (*++ep != ' ')) {
-            if (isdigit(ep[0]) && isdigit(ep[1]) && isdigit(ep[2])) break;
-        }
-        if (!ep) {
-            continue;
-        }
-        static const size_t pid_field_width = 7;
-        ep -= pid_field_width;
-        *ep = '\0';
-        return cp;
-    }
-    return NULL;
-}
-
-TEST(logcat, tz) {
-    int tries = 4;  // in case run too soon after system start or buffer clear
-    int count;
-
-    do {
-        FILE* fp;
-
-        ASSERT_TRUE(NULL != (fp = popen(logcat_executable
-                                        " -v long -v America/Los_Angeles -b all -t 3 2>/dev/null",
-                                        "r")));
-
-        char buffer[BIG_BUFFER];
-
-        count = 0;
-
-        while (fgetLongTime(buffer, sizeof(buffer), fp)) {
-            if (strstr(buffer, " -0700") || strstr(buffer, " -0800")) {
-                ++count;
-            } else {
-                fprintf(stderr, "ts=\"%s\"\n", buffer + 2);
-            }
-        }
-
-        pclose(fp);
-
-    } while ((count < 3) && --tries && inject(3 - count));
-
-    ASSERT_EQ(3, count);
-}
-
-TEST(logcat, ntz) {
-    FILE* fp;
-
-    ASSERT_TRUE(NULL !=
-                (fp = popen(logcat_executable
-                            " -v long -v America/Los_Angeles -v zone -b all -t 3 2>/dev/null",
-                            "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-
-    while (fgetLongTime(buffer, sizeof(buffer), fp)) {
-        if (strstr(buffer, " -0700") || strstr(buffer, " -0800")) {
-            ++count;
-        }
-    }
-
-    pclose(fp);
-
-    ASSERT_EQ(0, count);
-}
-
-static void do_tail(int num) {
-    int tries = 4;  // in case run too soon after system start or buffer clear
-    int count;
-
-    if (num > 10) ++tries;
-    if (num > 100) ++tries;
-    do {
-        char buffer[BIG_BUFFER];
-
-        snprintf(buffer, sizeof(buffer),
-                 "ANDROID_PRINTF_LOG=long logcat -b all -t %d 2>/dev/null", num);
-
-        FILE* fp;
-        ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
-
-        count = 0;
-
-        while (fgetLongTime(buffer, sizeof(buffer), fp)) {
-            ++count;
-        }
-
-        pclose(fp);
-
-    } while ((count < num) && --tries && inject(num - count));
-
-    ASSERT_EQ(num, count);
-}
-
-TEST(logcat, tail_3) {
-    do_tail(3);
-}
-
-TEST(logcat, tail_10) {
-    do_tail(10);
-}
-
-TEST(logcat, tail_100) {
-    do_tail(100);
-}
-
-TEST(logcat, tail_1000) {
-    do_tail(1000);
-}
-
-static void do_tail_time(const char* cmd) {
-    FILE* fp;
-    int count;
-    char buffer[BIG_BUFFER];
-    char* last_timestamp = NULL;
-    // Hard to predict 100% if first (overlap) or second line will match.
-    // -v nsec will in a substantial majority be the second line.
-    char* first_timestamp = NULL;
-    char* second_timestamp = NULL;
-    char* input;
-
-    int tries = 4;  // in case run too soon after system start or buffer clear
-
-    do {
-        snprintf(buffer, sizeof(buffer), "%s -t 10 2>&1", cmd);
-        ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
-        count = 0;
-
-        while ((input = fgetLongTime(buffer, sizeof(buffer), fp))) {
-            ++count;
-            if (!first_timestamp) {
-                first_timestamp = strdup(input);
-            } else if (!second_timestamp) {
-                second_timestamp = strdup(input);
-            }
-            free(last_timestamp);
-            last_timestamp = strdup(input);
-        }
-        pclose(fp);
-
-    } while ((count < 10) && --tries && inject(10 - count));
-
-    EXPECT_EQ(count, 10);  // We want _some_ history, too small, falses below
-    EXPECT_TRUE(last_timestamp != NULL);
-    EXPECT_TRUE(first_timestamp != NULL);
-    EXPECT_TRUE(second_timestamp != NULL);
-
-    snprintf(buffer, sizeof(buffer), "%s -t '%s' 2>&1", cmd, first_timestamp);
-    ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
-
-    int second_count = 0;
-    int last_timestamp_count = -1;
-
-    --count;  // One less unless we match the first_timestamp
-    bool found = false;
-    while ((input = fgetLongTime(buffer, sizeof(buffer), fp))) {
-        ++second_count;
-        // We want to highlight if we skip to the next entry.
-        // WAI, if the time in logd is *exactly*
-        // XX-XX XX:XX:XX.XXXXXX000 (usec) or XX-XX XX:XX:XX.XXX000000
-        // this can happen, but it should not happen with nsec.
-        // We can make this WAI behavior happen 1000 times less
-        // frequently if the caller does not use the -v usec flag,
-        // but always the second (always skip) if they use the
-        // (undocumented) -v nsec flag.
-        if (first_timestamp) {
-            found = !strcmp(input, first_timestamp);
-            if (found) {
-                ++count;
-                GTEST_LOG_(INFO)
-                    << "input = first(" << first_timestamp << ")\n";
-            }
-            free(first_timestamp);
-            first_timestamp = NULL;
-        }
-        if (second_timestamp) {
-            found = found || !strcmp(input, second_timestamp);
-            if (!found) {
-                GTEST_LOG_(INFO) << "input(" << input << ") != second("
-                                 << second_timestamp << ")\n";
-            }
-            free(second_timestamp);
-            second_timestamp = NULL;
-        }
-        if (!strcmp(input, last_timestamp)) {
-            last_timestamp_count = second_count;
-        }
-    }
-    pclose(fp);
-
-    EXPECT_TRUE(found);
-    if (!found) {
-        if (first_timestamp) {
-            GTEST_LOG_(INFO) << "first = " << first_timestamp << "\n";
-        }
-        if (second_timestamp) {
-            GTEST_LOG_(INFO) << "second = " << second_timestamp << "\n";
-        }
-        if (last_timestamp) {
-            GTEST_LOG_(INFO) << "last = " << last_timestamp << "\n";
-        }
-    }
-    free(last_timestamp);
-    last_timestamp = NULL;
-    free(first_timestamp);
-    free(second_timestamp);
-
-    EXPECT_TRUE(first_timestamp == NULL);
-    EXPECT_TRUE(second_timestamp == NULL);
-    EXPECT_LE(count, second_count);
-    EXPECT_LE(count, last_timestamp_count);
-}
-
-TEST(logcat, tail_time) {
-    do_tail_time(logcat_executable " -v long -v nsec -b all");
-}
-
-TEST(logcat, tail_time_epoch) {
-    do_tail_time(logcat_executable " -v long -v nsec -v epoch -b all");
-}
-
-TEST(logcat, End_to_End) {
-    pid_t pid = getpid();
-
-    log_time ts(CLOCK_MONOTONIC);
-
-    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-
-    FILE* fp;
-    ASSERT_TRUE(NULL !=
-                (fp = popen(logcat_executable " -v brief -b events -t 100 2>/dev/null", "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        int p;
-        unsigned long long t;
-
-        if ((2 != sscanf(buffer, "I/[0]     ( %d): %llu", &p, &t)) ||
-            (p != pid)) {
-            continue;
-        }
-
-        log_time* tx = reinterpret_cast<log_time*>(&t);
-        if (ts == *tx) {
-            ++count;
-        }
-    }
-
-    pclose(fp);
-
-    ASSERT_EQ(1, count);
-}
-
-TEST(logcat, End_to_End_multitude) {
-    pid_t pid = getpid();
-
-    log_time ts(CLOCK_MONOTONIC);
-
-    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-
-    FILE* fp[256];  // does this count as a multitude!
-    memset(fp, 0, sizeof(fp));
-    size_t num = 0;
-    do {
-        EXPECT_TRUE(NULL != (fp[num] = popen(logcat_executable " -v brief -b events -t 100", "r")));
-        if (!fp[num]) {
-            fprintf(stderr,
-                    "WARNING: limiting to %zu simultaneous logcat operations\n",
-                    num);
-            break;
-        }
-    } while (++num < sizeof(fp) / sizeof(fp[0]));
-
-    char buffer[BIG_BUFFER];
-
-    size_t count = 0;
-
-    for (size_t idx = 0; idx < sizeof(fp) / sizeof(fp[0]); ++idx) {
-        if (!fp[idx]) break;
-        while (fgets(buffer, sizeof(buffer), fp[idx])) {
-            int p;
-            unsigned long long t;
-
-            if ((2 != sscanf(buffer, "I/[0]     ( %d): %llu", &p, &t)) ||
-                (p != pid)) {
-                continue;
-            }
-
-            log_time* tx = reinterpret_cast<log_time*>(&t);
-            if (ts == *tx) {
-                ++count;
-            }
-        }
-
-        pclose(fp[idx]);
-    }
-
-    ASSERT_EQ(num, count);
-}
-
-static int get_groups(const char* cmd) {
-    FILE* fp;
-
-    EXPECT_TRUE(NULL != (fp = popen(cmd, "r")));
-
-    if (fp == NULL) {
-        return 0;
-    }
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        int size, consumed, readable, max, payload;
-        char size_mult[4], consumed_mult[4], readable_mult[4];
-        long full_size, full_consumed;
-
-        size = consumed = max = payload = 0;
-        // NB: crash log can be very small, not hit a Kb of consumed space
-        //     doubly lucky we are not including it.
-        EXPECT_EQ(8, sscanf(buffer,
-                            "%*s ring buffer is %d %3s (%d %3s consumed, %d %3s readable),"
-                            " max entry is %d B, max payload is %d B",
-                            &size, size_mult, &consumed, consumed_mult, &readable, readable_mult,
-                            &max, &payload))
-                << "Parse error on: " << buffer;
-        full_size = size;
-        switch (size_mult[0]) {
-            case 'G':
-                full_size *= 1024;
-                FALLTHROUGH_INTENDED;
-            case 'M':
-                full_size *= 1024;
-                FALLTHROUGH_INTENDED;
-            case 'K':
-                full_size *= 1024;
-                FALLTHROUGH_INTENDED;
-            case 'B':
-                break;
-            default:
-                ADD_FAILURE() << "Parse error on multiplier: " << size_mult;
-        }
-        full_consumed = consumed;
-        switch (consumed_mult[0]) {
-            case 'G':
-                full_consumed *= 1024;
-                FALLTHROUGH_INTENDED;
-            case 'M':
-                full_consumed *= 1024;
-                FALLTHROUGH_INTENDED;
-            case 'K':
-                full_consumed *= 1024;
-                FALLTHROUGH_INTENDED;
-            case 'B':
-                break;
-            default:
-                ADD_FAILURE() << "Parse error on multiplier: " << consumed_mult;
-        }
-        EXPECT_GT((full_size * 9) / 4, full_consumed);
-        EXPECT_GT(full_size, max);
-        EXPECT_GT(max, payload);
-
-        if ((((full_size * 9) / 4) >= full_consumed) && (full_size > max) &&
-            (max > payload)) {
-            ++count;
-        }
-    }
-
-    pclose(fp);
-
-    return count;
-}
-
-TEST(logcat, get_size) {
-    ASSERT_EQ(4, get_groups(logcat_executable
-                            " -v brief -b radio -b events -b system -b "
-                            "main -g 2>/dev/null"));
-}
-
-// duplicate test for get_size, but use comma-separated list of buffers
-TEST(logcat, multiple_buffer) {
-    ASSERT_EQ(
-        4, get_groups(logcat_executable
-                      " -v brief -b radio,events,system,main -g 2>/dev/null"));
-}
-
-TEST(logcat, bad_buffer) {
-    ASSERT_EQ(0,
-              get_groups(
-                  logcat_executable
-                  " -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
-}
-
-#ifndef logcat
-static void caught_blocking(int signum) {
-    unsigned long long v = 0xDEADBEEFA55A0000ULL;
-
-    v += getpid() & 0xFFFF;
-    if (signum == 0) ++v;
-
-    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-}
-
-TEST(logcat, blocking) {
-    FILE* fp;
-    unsigned long long v = 0xDEADBEEFA55F0000ULL;
-
-    pid_t pid = getpid();
-
-    v += pid & 0xFFFF;
-
-    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-
-    v &= 0xFFFFFFFFFFFAFFFFULL;
-
-    ASSERT_TRUE(
-        NULL !=
-        (fp = popen("( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
-                    " logcat -v brief -b events 2>&1",
-                    "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-
-    int signals = 0;
-
-    signal(SIGALRM, caught_blocking);
-    alarm(2);
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(buffer, "DONE", 4)) {
-            break;
-        }
-
-        ++count;
-
-        int p;
-        unsigned long long l;
-
-        if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l)) || (p != pid)) {
-            continue;
-        }
-
-        if (l == v) {
-            ++signals;
-            break;
-        }
-    }
-    alarm(0);
-    signal(SIGALRM, SIG_DFL);
-
-    // Generate SIGPIPE
-    fclose(fp);
-    caught_blocking(0);
-
-    pclose(fp);
-
-    EXPECT_GE(count, 2);
-
-    EXPECT_EQ(signals, 1);
-}
-
-static void caught_blocking_tail(int signum) {
-    unsigned long long v = 0xA55ADEADBEEF0000ULL;
-
-    v += getpid() & 0xFFFF;
-    if (signum == 0) ++v;
-
-    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-}
-
-TEST(logcat, blocking_tail) {
-    FILE* fp;
-    unsigned long long v = 0xA55FDEADBEEF0000ULL;
-
-    pid_t pid = getpid();
-
-    v += pid & 0xFFFF;
-
-    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-
-    v &= 0xFFFAFFFFFFFFFFFFULL;
-
-    ASSERT_TRUE(
-        NULL !=
-        (fp = popen("( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
-                    " logcat -v brief -b events -T 5 2>&1",
-                    "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-
-    int signals = 0;
-
-    signal(SIGALRM, caught_blocking_tail);
-    alarm(2);
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(buffer, "DONE", 4)) {
-            break;
-        }
-
-        ++count;
-
-        int p;
-        unsigned long long l;
-
-        if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l)) || (p != pid)) {
-            continue;
-        }
-
-        if (l == v) {
-            if (count >= 5) {
-                ++signals;
-            }
-            break;
-        }
-    }
-    alarm(0);
-    signal(SIGALRM, SIG_DFL);
-
-    // Generate SIGPIPE
-    fclose(fp);
-    caught_blocking_tail(0);
-
-    pclose(fp);
-
-    EXPECT_GE(count, 2);
-
-    EXPECT_EQ(signals, 1);
-}
-#endif
-
-// meant to be handed to ASSERT_FALSE / EXPECT_FALSE to expand the message
-static testing::AssertionResult IsFalse(int ret, const char* command) {
-    return ret ? (testing::AssertionSuccess()
-                  << "ret=" << ret << " command=\"" << command << "\"")
-               : testing::AssertionFailure();
-}
-
-TEST(logcat, logrotate) {
-    static const char form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
-    char buf[sizeof(form)];
-    ASSERT_TRUE(NULL != mkdtemp(strcpy(buf, form)));
-
-    static const char comm[] = logcat_executable
-        " -b radio -b events -b system -b main"
-        " -d -f %s/log.txt -n 7 -r 1";
-    char command[sizeof(buf) + sizeof(comm)];
-    snprintf(command, sizeof(command), comm, buf);
-
-    int ret;
-    EXPECT_FALSE(IsFalse(ret = system(command), command));
-    if (!ret) {
-        snprintf(command, sizeof(command), "ls -s %s 2>/dev/null", buf);
-
-        FILE* fp;
-        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
-        if (fp) {
-            char buffer[BIG_BUFFER];
-            int count = 0;
-
-            while (fgets(buffer, sizeof(buffer), fp)) {
-                static const char total[] = "total ";
-                int num;
-                char c;
-
-                if ((2 == sscanf(buffer, "%d log.tx%c", &num, &c)) &&
-                    (num <= 40)) {
-                    ++count;
-                } else if (strncmp(buffer, total, sizeof(total) - 1)) {
-                    fprintf(stderr, "WARNING: Parse error: %s", buffer);
-                }
-            }
-            pclose(fp);
-            if ((count != 7) && (count != 8)) {
-                fprintf(stderr, "count=%d\n", count);
-            }
-            EXPECT_TRUE(count == 7 || count == 8);
-        }
-    }
-    snprintf(command, sizeof(command), "rm -rf %s", buf);
-    EXPECT_FALSE(IsFalse(system(command), command));
-}
-
-TEST(logcat, logrotate_suffix) {
-    static const char tmp_out_dir_form[] =
-        "/data/local/tmp/logcat.logrotate.XXXXXX";
-    char tmp_out_dir[sizeof(tmp_out_dir_form)];
-    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
-
-    static const char logcat_cmd[] = logcat_executable
-        " -b radio -b events -b system -b main"
-        " -d -f %s/log.txt -n 10 -r 1";
-    char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd)];
-    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir);
-
-    int ret;
-    EXPECT_FALSE(IsFalse(ret = system(command), command));
-    if (!ret) {
-        snprintf(command, sizeof(command), "ls %s 2>/dev/null", tmp_out_dir);
-
-        FILE* fp;
-        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
-        char buffer[BIG_BUFFER];
-        int log_file_count = 0;
-
-        while (fgets(buffer, sizeof(buffer), fp)) {
-            static const char rotated_log_filename_prefix[] = "log.txt.";
-            static const size_t rotated_log_filename_prefix_len =
-                strlen(rotated_log_filename_prefix);
-            static const char log_filename[] = "log.txt";
-
-            if (!strncmp(buffer, rotated_log_filename_prefix,
-                         rotated_log_filename_prefix_len)) {
-                // Rotated file should have form log.txt.##
-                char* rotated_log_filename_suffix =
-                    buffer + rotated_log_filename_prefix_len;
-                char* endptr;
-                const long int suffix_value =
-                    strtol(rotated_log_filename_suffix, &endptr, 10);
-                EXPECT_EQ(rotated_log_filename_suffix + 2, endptr);
-                EXPECT_LE(suffix_value, 10);
-                EXPECT_GT(suffix_value, 0);
-                ++log_file_count;
-                continue;
-            }
-
-            if (!strncmp(buffer, log_filename, strlen(log_filename))) {
-                ++log_file_count;
-                continue;
-            }
-
-            fprintf(stderr, "ERROR: Unexpected file: %s", buffer);
-            ADD_FAILURE();
-        }
-        pclose(fp);
-        EXPECT_EQ(log_file_count, 11);
-    }
-    snprintf(command, sizeof(command), "rm -rf %s", tmp_out_dir);
-    EXPECT_FALSE(IsFalse(system(command), command));
-}
-
-TEST(logcat, logrotate_continue) {
-    static const char tmp_out_dir_form[] =
-        "/data/local/tmp/logcat.logrotate.XXXXXX";
-    char tmp_out_dir[sizeof(tmp_out_dir_form)];
-    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
-
-    static const char log_filename[] = "log.txt";
-    static const char logcat_cmd[] =
-        logcat_executable " -b all -v nsec -d -f %s/%s -n 256 -r 1024";
-    static const char cleanup_cmd[] = "rm -rf %s";
-    char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename)];
-    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
-
-    int ret;
-    EXPECT_FALSE(IsFalse(ret = system(command), command));
-    if (ret) {
-        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-        EXPECT_FALSE(IsFalse(system(command), command));
-        return;
-    }
-    FILE* fp;
-    snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, log_filename);
-    EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
-    if (!fp) {
-        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-        EXPECT_FALSE(IsFalse(system(command), command));
-        return;
-    }
-    char* line = NULL;
-    char* last_line =
-        NULL;  // this line is allowed to stutter, one-line overlap
-    char* second_last_line = NULL;  // should never stutter
-    char* first_line = NULL;        // help diagnose failure?
-    size_t len = 0;
-    while (getline(&line, &len, fp) != -1) {
-        if (!first_line) {
-            first_line = line;
-            line = NULL;
-            continue;
-        }
-        free(second_last_line);
-        second_last_line = last_line;
-        last_line = line;
-        line = NULL;
-    }
-    fclose(fp);
-    free(line);
-    if (second_last_line == NULL) {
-        fprintf(stderr, "No second to last line, using last, test may fail\n");
-        second_last_line = last_line;
-        last_line = NULL;
-    }
-    free(last_line);
-    EXPECT_TRUE(NULL != second_last_line);
-    if (!second_last_line) {
-        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-        EXPECT_FALSE(IsFalse(system(command), command));
-        free(first_line);
-        return;
-    }
-    // re-run the command, it should only add a few lines more content if it
-    // continues where it left off.
-    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
-    EXPECT_FALSE(IsFalse(ret = system(command), command));
-    if (ret) {
-        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-        EXPECT_FALSE(IsFalse(system(command), command));
-        free(second_last_line);
-        free(first_line);
-        return;
-    }
-    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir),
-                                                  closedir);
-    EXPECT_NE(nullptr, dir);
-    if (!dir) {
-        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-        EXPECT_FALSE(IsFalse(system(command), command));
-        free(second_last_line);
-        free(first_line);
-        return;
-    }
-    struct dirent* entry;
-    unsigned count = 0;
-    while ((entry = readdir(dir.get()))) {
-        if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
-            continue;
-        }
-        snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, entry->d_name);
-        EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
-        if (!fp) {
-            fprintf(stderr, "%s ?\n", command);
-            continue;
-        }
-        line = NULL;
-        size_t number = 0;
-        while (getline(&line, &len, fp) != -1) {
-            ++number;
-            if (!strcmp(line, second_last_line)) {
-                EXPECT_TRUE(++count <= 1);
-                fprintf(stderr, "%s(%zu):\n", entry->d_name, number);
-            }
-        }
-        fclose(fp);
-        free(line);
-        unlink(command);
-    }
-    if (count > 1) {
-        char* brk = strpbrk(second_last_line, "\r\n");
-        if (!brk) brk = second_last_line + strlen(second_last_line);
-        fprintf(stderr, "\"%.*s\" occurred %u times\n",
-                (int)(brk - second_last_line), second_last_line, count);
-        if (first_line) {
-            brk = strpbrk(first_line, "\r\n");
-            if (!brk) brk = first_line + strlen(first_line);
-            fprintf(stderr, "\"%.*s\" was first line, fault?\n",
-                    (int)(brk - first_line), first_line);
-        }
-    }
-    free(second_last_line);
-    free(first_line);
-
-    snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-    EXPECT_FALSE(IsFalse(system(command), command));
-}
-
-TEST(logcat, logrotate_clear) {
-    static const char tmp_out_dir_form[] =
-        "/data/local/tmp/logcat.logrotate.XXXXXX";
-    char tmp_out_dir[sizeof(tmp_out_dir_form)];
-    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
-
-    static const char log_filename[] = "log.txt";
-    static const unsigned num_val = 32;
-    static const char logcat_cmd[] =
-        logcat_executable " -b all -d -f %s/%s -n %d -r 1";
-    static const char clear_cmd[] = " -c";
-    static const char cleanup_cmd[] = "rm -rf %s";
-    char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) +
-                 sizeof(log_filename) + sizeof(clear_cmd) + 32];
-
-    // Run command with all data
-    {
-        snprintf(command, sizeof(command) - sizeof(clear_cmd), logcat_cmd,
-                 tmp_out_dir, log_filename, num_val);
-
-        int ret;
-        EXPECT_FALSE(IsFalse(ret = system(command), command));
-        if (ret) {
-            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-            EXPECT_FALSE(IsFalse(system(command), command));
-            return;
-        }
-        std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir),
-                                                      closedir);
-        EXPECT_NE(nullptr, dir);
-        if (!dir) {
-            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-            EXPECT_FALSE(IsFalse(system(command), command));
-            return;
-        }
-        struct dirent* entry;
-        unsigned count = 0;
-        while ((entry = readdir(dir.get()))) {
-            if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
-                continue;
-            }
-            ++count;
-        }
-        EXPECT_EQ(count, num_val + 1);
-    }
-
-    {
-        // Now with -c option tacked onto the end
-        strcat(command, clear_cmd);
-
-        int ret;
-        EXPECT_FALSE(IsFalse(ret = system(command), command));
-        if (ret) {
-            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-            EXPECT_FALSE(system(command));
-            EXPECT_FALSE(IsFalse(system(command), command));
-            return;
-        }
-        std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir),
-                                                      closedir);
-        EXPECT_NE(nullptr, dir);
-        if (!dir) {
-            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-            EXPECT_FALSE(IsFalse(system(command), command));
-            return;
-        }
-        struct dirent* entry;
-        unsigned count = 0;
-        while ((entry = readdir(dir.get()))) {
-            if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
-                continue;
-            }
-            fprintf(stderr, "Found %s/%s!!!\n", tmp_out_dir, entry->d_name);
-            ++count;
-        }
-        EXPECT_EQ(count, 0U);
-    }
-
-    snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-    EXPECT_FALSE(IsFalse(system(command), command));
-}
-
-static int logrotate_count_id(const char* logcat_cmd, const char* tmp_out_dir) {
-    static const char log_filename[] = "log.txt";
-    char command[strlen(tmp_out_dir) + strlen(logcat_cmd) +
-                 strlen(log_filename) + 32];
-
-    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
-
-    int ret = system(command);
-    if (ret) {
-        fprintf(stderr, "system(\"%s\")=%d", command, ret);
-        return -1;
-    }
-    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir),
-                                                  closedir);
-    if (!dir) {
-        fprintf(stderr, "opendir(\"%s\") failed", tmp_out_dir);
-        return -1;
-    }
-    struct dirent* entry;
-    int count = 0;
-    while ((entry = readdir(dir.get()))) {
-        if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
-            continue;
-        }
-        ++count;
-    }
-    return count;
-}
-
-TEST(logcat, logrotate_id) {
-    static const char logcat_cmd[] =
-        logcat_executable " -b all -d -f %s/%s -n 32 -r 1 --id=test";
-    static const char logcat_short_cmd[] =
-        logcat_executable " -b all -t 10 -f %s/%s -n 32 -r 1 --id=test";
-    static const char tmp_out_dir_form[] =
-        "/data/local/tmp/logcat.logrotate.XXXXXX";
-    static const char log_filename[] = "log.txt";
-    char tmp_out_dir[strlen(tmp_out_dir_form) + 1];
-    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
-
-    EXPECT_EQ(logrotate_count_id(logcat_cmd, tmp_out_dir), 34);
-    EXPECT_EQ(logrotate_count_id(logcat_short_cmd, tmp_out_dir), 34);
-
-    char id_file[strlen(tmp_out_dir_form) + strlen(log_filename) + 5];
-    snprintf(id_file, sizeof(id_file), "%s/%s.id", tmp_out_dir, log_filename);
-    if (getuid() != 0) {
-        chmod(id_file, 0);
-        EXPECT_EQ(logrotate_count_id(logcat_short_cmd, tmp_out_dir), 34);
-    }
-    unlink(id_file);
-    EXPECT_EQ(logrotate_count_id(logcat_short_cmd, tmp_out_dir), 34);
-
-    FILE* fp = fopen(id_file, "w");
-    if (fp) {
-        fprintf(fp, "not_a_test");
-        fclose(fp);
-    }
-    if (getuid() != 0) {
-        chmod(id_file,
-              0);  // API to preserve content even with signature change
-        ASSERT_EQ(34, logrotate_count_id(logcat_short_cmd, tmp_out_dir));
-        chmod(id_file, 0600);
-    }
-
-    int new_signature;
-    EXPECT_GE(
-        (new_signature = logrotate_count_id(logcat_short_cmd, tmp_out_dir)), 2);
-    EXPECT_LT(new_signature, 34);
-
-    static const char cleanup_cmd[] = "rm -rf %s";
-    char command[strlen(cleanup_cmd) + strlen(tmp_out_dir_form)];
-    snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
-    EXPECT_FALSE(IsFalse(system(command), command));
-}
-
-TEST(logcat, logrotate_nodir) {
-    // expect logcat to error out on writing content and not exit(0) for nodir
-    static const char command[] = logcat_executable
-        " -b all -d"
-        " -f /das/nein/gerfingerpoken/logcat/log.txt"
-        " -n 256 -r 1024";
-    EXPECT_FALSE(IsFalse(0 == system(command), command));
-}
-
-#ifndef logcat
-static void caught_blocking_clear(int signum) {
-    unsigned long long v = 0xDEADBEEFA55C0000ULL;
-
-    v += getpid() & 0xFFFF;
-    if (signum == 0) ++v;
-
-    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
-}
-
-TEST(logcat, blocking_clear) {
-    FILE* fp;
-    unsigned long long v = 0xDEADBEEFA55C0000ULL;
-
-    pid_t pid = getpid();
-
-    v += pid & 0xFFFF;
-
-    // This test is racey; an event occurs between clear and dump.
-    // We accept that we will get a false positive, but never a false negative.
-    ASSERT_TRUE(
-        NULL !=
-        (fp = popen("( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
-                    " logcat -b events -c 2>&1 ;"
-                    " logcat -b events -g 2>&1 ;"
-                    " logcat -v brief -b events 2>&1",
-                    "r")));
-
-    char buffer[BIG_BUFFER];
-
-    int count = 0;
-    int minus_g = 0;
-
-    int signals = 0;
-
-    signal(SIGALRM, caught_blocking_clear);
-    alarm(2);
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(buffer, "clearLog: ", strlen("clearLog: "))) {
-            fprintf(stderr, "WARNING: Test lacks permission to run :-(\n");
-            count = signals = 1;
-            break;
-        }
-        if (!strncmp(buffer, "failed to clear", strlen("failed to clear"))) {
-            fprintf(stderr, "WARNING: Test lacks permission to run :-(\n");
-            count = signals = 1;
-            break;
-        }
-
-        if (!strncmp(buffer, "DONE", 4)) {
-            break;
-        }
-
-        int size, consumed, readable, max, payload;
-        char size_mult[4], consumed_mult[4], readable_mult[4];
-        size = consumed = max = payload = 0;
-        if (8 == sscanf(buffer,
-                        "events: ring buffer is %d %3s (%d %3s consumed, %d %3s readable),"
-                        " max entry is %d B, max payload is %d B",
-                        &size, size_mult, &consumed, consumed_mult, &readable, readable_mult, &max,
-                        &payload)) {
-            long full_size = size, full_consumed = consumed;
-
-            switch (size_mult[0]) {
-                case 'G':
-                    full_size *= 1024;
-                    FALLTHROUGH_INTENDED;
-                case 'M':
-                    full_size *= 1024;
-                    FALLTHROUGH_INTENDED;
-                case 'K':
-                    full_size *= 1024;
-                    FALLTHROUGH_INTENDED;
-                case 'B':
-                    break;
-            }
-            switch (consumed_mult[0]) {
-                case 'G':
-                    full_consumed *= 1024;
-                    FALLTHROUGH_INTENDED;
-                case 'M':
-                    full_consumed *= 1024;
-                    FALLTHROUGH_INTENDED;
-                case 'K':
-                    full_consumed *= 1024;
-                    FALLTHROUGH_INTENDED;
-                case 'B':
-                    break;
-            }
-            EXPECT_GT(full_size, full_consumed);
-            EXPECT_GT(full_size, max);
-            EXPECT_GT(max, payload);
-            EXPECT_GT(max, full_consumed);
-
-            ++minus_g;
-            continue;
-        }
-
-        ++count;
-
-        int p;
-        unsigned long long l;
-
-        if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l)) || (p != pid)) {
-            continue;
-        }
-
-        if (l == v) {
-            if (count > 1) {
-                fprintf(stderr, "WARNING: Possible false positive\n");
-            }
-            ++signals;
-            break;
-        }
-    }
-    alarm(0);
-    signal(SIGALRM, SIG_DFL);
-
-    // Generate SIGPIPE
-    fclose(fp);
-    caught_blocking_clear(0);
-
-    pclose(fp);
-
-    EXPECT_GE(count, 1);
-    EXPECT_EQ(minus_g, 1);
-
-    EXPECT_EQ(signals, 1);
-}
-#endif
-
-static bool get_prune_rules(char** list) {
-    FILE* fp = popen(logcat_executable " -p 2>/dev/null", "r");
-    if (fp == NULL) {
-        fprintf(stderr, "ERROR: logcat -p 2>/dev/null\n");
-        return false;
-    }
-
-    char buffer[BIG_BUFFER];
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        char* hold = *list;
-        char* buf = buffer;
-        while (isspace(*buf)) {
-            ++buf;
-        }
-        char* end = buf + strlen(buf);
-        while (isspace(*--end) && (end >= buf)) {
-            *end = '\0';
-        }
-        if (end < buf) {
-            continue;
-        }
-        if (hold) {
-            asprintf(list, "%s %s", hold, buf);
-            free(hold);
-        } else {
-            asprintf(list, "%s", buf);
-        }
-    }
-    pclose(fp);
-    return *list != NULL;
-}
-
-static bool set_prune_rules(const char* list) {
-    char buffer[BIG_BUFFER];
-    snprintf(buffer, sizeof(buffer), logcat_executable " -P '%s' 2>&1",
-             list ? list : "");
-    FILE* fp = popen(buffer, "r");
-    if (fp == NULL) {
-        fprintf(stderr, "ERROR: %s\n", buffer);
-        return false;
-    }
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        char* buf = buffer;
-        while (isspace(*buf)) {
-            ++buf;
-        }
-        char* end = buf + strlen(buf);
-        while ((end > buf) && isspace(*--end)) {
-            *end = '\0';
-        }
-        if (end <= buf) {
-            continue;
-        }
-        fprintf(stderr, "%s\n", buf);
-        pclose(fp);
-        return false;
-    }
-    return pclose(fp) == 0;
-}
-
-TEST(logcat, prune_rules_adjust) {
-    char* list = NULL;
-    char* adjust = NULL;
-
-    get_prune_rules(&list);
-
-    static const char adjustment[] = "~! 300/20 300/25 2000 ~1000/5 ~1000/30";
-    ASSERT_EQ(true, set_prune_rules(adjustment));
-    ASSERT_EQ(true, get_prune_rules(&adjust));
-    EXPECT_STREQ(adjustment, adjust);
-    free(adjust);
-    adjust = NULL;
-
-    static const char adjustment2[] = "300/20 300/21 2000 ~1000";
-    ASSERT_EQ(true, set_prune_rules(adjustment2));
-    ASSERT_EQ(true, get_prune_rules(&adjust));
-    EXPECT_STREQ(adjustment2, adjust);
-    free(adjust);
-    adjust = NULL;
-
-    ASSERT_EQ(true, set_prune_rules(list));
-    get_prune_rules(&adjust);
-    EXPECT_STREQ(list ? list : "", adjust ? adjust : "");
-    free(adjust);
-    adjust = NULL;
-
-    free(list);
-    list = NULL;
-}
-
-TEST(logcat, regex) {
-    FILE* fp;
-    int count = 0;
-
-    char buffer[BIG_BUFFER];
-#define logcat_regex_prefix logcat_executable "_test"
-
-    snprintf(buffer, sizeof(buffer),
-             logcat_executable " --pid %d -d -e " logcat_regex_prefix "_a+b",
-             getpid());
-
-    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, logcat_regex_prefix,
-                                          logcat_regex_prefix "_ab"));
-    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, logcat_regex_prefix,
-                                          logcat_regex_prefix "_b"));
-    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, logcat_regex_prefix,
-                                          logcat_regex_prefix "_aaaab"));
-    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, logcat_regex_prefix,
-                                          logcat_regex_prefix "_aaaa"));
-    // Let the logs settle
-    rest();
-
-    ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
-            continue;
-        }
-
-        EXPECT_TRUE(strstr(buffer, logcat_regex_prefix "_") != NULL);
-
-        count++;
-    }
-
-    pclose(fp);
-
-    ASSERT_EQ(2, count);
-}
-
-TEST(logcat, maxcount) {
-    FILE* fp;
-    int count = 0;
-
-    char buffer[BIG_BUFFER];
-
-    snprintf(buffer, sizeof(buffer),
-             logcat_executable " --pid %d -d --max-count 3", getpid());
-
-    LOG_FAILURE_RETRY(
-        __android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
-    LOG_FAILURE_RETRY(
-        __android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
-    LOG_FAILURE_RETRY(
-        __android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
-    LOG_FAILURE_RETRY(
-        __android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
-
-    rest();
-
-    ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
-            continue;
-        }
-
-        count++;
-    }
-
-    pclose(fp);
-
-    ASSERT_EQ(3, count);
-}
-
-static bool End_to_End(const char* tag, const char* fmt, ...)
-#if defined(__GNUC__)
-    __attribute__((__format__(printf, 2, 3)))
-#endif
-    ;
-
-static bool End_to_End(const char* tag, const char* fmt, ...) {
-    FILE* fp = popen(logcat_executable " -v brief -b events -v descriptive -t 100 2>/dev/null", "r");
-    if (!fp) {
-        fprintf(stderr, "End_to_End: popen failed");
-        return false;
-    }
-
-    char buffer[BIG_BUFFER];
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf(buffer, sizeof(buffer), fmt, ap);
-    va_end(ap);
-
-    char* str = NULL;
-    asprintf(&str, "I/%s ( %%d):%%c%s%%c", tag, buffer);
-    std::string expect(str);
-    free(str);
-
-    int count = 0;
-    pid_t pid = getpid();
-    std::string lastMatch;
-    int maxMatch = 1;
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        char space;
-        char newline;
-        int p;
-        int ret = sscanf(buffer, expect.c_str(), &p, &space, &newline);
-        if ((ret == 3) && (p == pid) && (space == ' ') && (newline == '\n')) {
-            ++count;
-        } else if ((ret >= maxMatch) && (p == pid) && (count == 0)) {
-            lastMatch = buffer;
-            maxMatch = ret;
-        }
-    }
-
-    pclose(fp);
-
-    if ((count == 0) && (lastMatch.length() > 0)) {
-        // Help us pinpoint where things went wrong ...
-        fprintf(stderr, "Closest match for\n    %s\n  is\n    %s",
-                expect.c_str(), lastMatch.c_str());
-    } else if (count > 3) {
-        fprintf(stderr, "Too many matches (%d) for %s\n", count, expect.c_str());
-    }
-
-    // Three different known tests, we can see pollution from the others
-    return count && (count <= 3);
-}
-
-TEST(logcat, descriptive) {
-    struct tag {
-        uint32_t tagNo;
-        const char* tagStr;
-    };
-    int ret;
-
-    {
-        static const struct tag hhgtg = { 42, "answer" };
-        android_log_event_list ctx(hhgtg.tagNo);
-        static const char theAnswer[] = "what is five by seven";
-        ctx << theAnswer;
-        // crafted to rest at least once after, and rest between retries.
-        for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-        EXPECT_GE(ret, 0);
-        EXPECT_TRUE(
-            End_to_End(hhgtg.tagStr, "to life the universe etc=%s", theAnswer));
-    }
-
-    {
-        static const struct tag sync = { 2720, "sync" };
-        static const char id[] = logcat_executable ".descriptive-sync";
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << id << (int32_t)42 << (int32_t)-1 << (int32_t)0;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr,
-                                   "[id=%s,event=42,source=-1,account=0]", id));
-        }
-
-        // Partial match to description
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << id << (int32_t)43 << (int64_t)-1 << (int32_t)0;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "[id=%s,event=43,-1,0]", id));
-        }
-
-        // Negative Test of End_to_End, ensure it is working
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << id << (int32_t)44 << (int32_t)-1 << (int64_t)0;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            fprintf(stderr, "Expect a \"Closest match\" message\n");
-            EXPECT_FALSE(End_to_End(
-                sync.tagStr, "[id=%s,event=44,source=-1,account=0]", id));
-        }
-    }
-
-    {
-        static const struct tag sync = { 2747, "contacts_aggregation" };
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint64_t)30 << (int32_t)2;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(
-                End_to_End(sync.tagStr, "[aggregation time=30ms,count=2]"));
-        }
-
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint64_t)31570 << (int32_t)911;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(
-                End_to_End(sync.tagStr, "[aggregation time=31.57s,count=911]"));
-        }
-    }
-
-    {
-        static const struct tag sync = { 75000, "sqlite_mem_alarm_current" };
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint32_t)512;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "current=512B"));
-        }
-
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint32_t)3072;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "current=3KB"));
-        }
-
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint32_t)2097152;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "current=2MB"));
-        }
-
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint32_t)2097153;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "current=2097153B"));
-        }
-
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint32_t)1073741824;
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "current=1GB"));
-        }
-
-        {
-            android_log_event_list ctx(sync.tagNo);
-            ctx << (uint32_t)3221225472;  // 3MB, but on purpose overflowed
-            for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-            EXPECT_GE(ret, 0);
-            EXPECT_TRUE(End_to_End(sync.tagStr, "current=-1GB"));
-        }
-    }
-
-    {
-        static const struct tag sync = { 27501, "notification_panel_hidden" };
-        android_log_event_list ctx(sync.tagNo);
-        for (ret = -EBUSY; ret == -EBUSY; rest()) ret = ctx.write();
-        EXPECT_GE(ret, 0);
-        EXPECT_TRUE(End_to_End(sync.tagStr, ""));
-    }
-}
-
-static size_t commandOutputSize(const char* command) {
-    FILE* fp = popen(command, "r");
-    if (!fp) return 0;
-
-    std::string ret;
-    if (!android::base::ReadFdToString(fileno(fp), &ret)) return 0;
-    if (pclose(fp) != 0) return 0;
-
-    return ret.size();
-}
-
-TEST(logcat, help) {
-    size_t logcatHelpTextSize = commandOutputSize(logcat_executable " -h 2>&1");
-    EXPECT_GT(logcatHelpTextSize, 4096UL);
-    size_t logcatLastHelpTextSize =
-        commandOutputSize(logcat_executable " -L -h 2>&1");
-#ifdef USING_LOGCAT_EXECUTABLE_DEFAULT  // logcat and liblogcat
-    EXPECT_EQ(logcatHelpTextSize, logcatLastHelpTextSize);
-#else
-    // logcatd -L -h prints the help twice, as designed.
-    EXPECT_EQ(logcatHelpTextSize * 2, logcatLastHelpTextSize);
-#endif
-}
-
-TEST(logcat, invalid_buffer) {
-  FILE* fp = popen("logcat -b foo 2>&1", "r");
-  ASSERT_NE(nullptr, fp);
-  std::string output;
-  ASSERT_TRUE(android::base::ReadFdToString(fileno(fp), &output));
-  pclose(fp);
-
-  EXPECT_NE(std::string::npos, output.find("Unknown buffer 'foo'"));
-}
-
-static void SniffUid(const std::string& line, uid_t& uid) {
-    auto uid_regex = std::regex{"\\S+\\s+\\S+\\s+(\\S+).*"};
-
-    auto trimmed_line = android::base::Trim(line);
-
-    std::smatch match_results;
-    ASSERT_TRUE(std::regex_match(trimmed_line, match_results, uid_regex))
-            << "Unable to find UID in line '" << trimmed_line << "'";
-    auto uid_string = match_results[1];
-    if (!android::base::ParseUint(uid_string, &uid)) {
-        auto pwd = getpwnam(uid_string.str().c_str());
-        ASSERT_NE(nullptr, pwd) << "uid '" << uid_string << "' in line '" << trimmed_line << "'";
-        uid = pwd->pw_uid;
-    }
-}
-
-static void UidsInLog(std::optional<std::vector<uid_t>> filter_uid, std::map<uid_t, size_t>& uids) {
-    std::string command;
-    if (filter_uid) {
-        std::vector<std::string> uid_strings;
-        for (const auto& uid : *filter_uid) {
-            uid_strings.emplace_back(std::to_string(uid));
-        }
-        command = android::base::StringPrintf(logcat_executable
-                                              " -v uid -b all -d 2>/dev/null --uid=%s",
-                                              android::base::Join(uid_strings, ",").c_str());
-    } else {
-        command = logcat_executable " -v uid -b all -d 2>/dev/null";
-    }
-    auto fp = std::unique_ptr<FILE, decltype(&pclose)>(popen(command.c_str(), "r"), pclose);
-    ASSERT_NE(nullptr, fp);
-
-    char buffer[BIG_BUFFER];
-    while (fgets(buffer, sizeof(buffer), fp.get())) {
-        // Ignore dividers, e.g. '--------- beginning of radio'
-        if (android::base::StartsWith(buffer, "---------")) {
-            continue;
-        }
-        uid_t uid;
-        SniffUid(buffer, uid);
-        uids[uid]++;
-    }
-}
-
-static std::vector<uid_t> TopTwoInMap(const std::map<uid_t, size_t>& uids) {
-    std::pair<uid_t, size_t> top = {0, 0};
-    std::pair<uid_t, size_t> second = {0, 0};
-    for (const auto& [uid, count] : uids) {
-        if (count > top.second) {
-            top = second;
-            top = {uid, count};
-        } else if (count > second.second) {
-            second = {uid, count};
-        }
-    }
-    return {top.first, second.first};
-}
-
-TEST(logcat, uid_filter) {
-    std::map<uid_t, size_t> uids;
-    UidsInLog({}, uids);
-
-    ASSERT_GT(uids.size(), 2U);
-    auto top_uids = TopTwoInMap(uids);
-
-    // Test filtering with --uid=<top uid>
-    std::map<uid_t, size_t> uids_only_top;
-    std::vector<uid_t> top_uid = {top_uids[0]};
-    UidsInLog(top_uid, uids_only_top);
-
-    EXPECT_EQ(1U, uids_only_top.size());
-
-    // Test filtering with --uid=<top uid>,<2nd top uid>
-    std::map<uid_t, size_t> uids_only_top2;
-    std::vector<uid_t> top2_uids = {top_uids[0], top_uids[1]};
-    UidsInLog(top2_uids, uids_only_top2);
-
-    EXPECT_EQ(2U, uids_only_top2.size());
-}
diff --git a/logcat/tests/logcatd_test.cpp b/logcat/tests/logcatd_test.cpp
deleted file mode 100644
index bb7534e..0000000
--- a/logcat/tests/logcatd_test.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define logcat logcatd
-#define logcat_executable "logcatd"
-
-#include "logcat_test.cpp"
diff --git a/logd b/logd
new file mode 120000
index 0000000..bb2232f
--- /dev/null
+++ b/logd
@@ -0,0 +1 @@
+../logging/logd
\ No newline at end of file
diff --git a/logd/.clang-format b/logd/.clang-format
deleted file mode 120000
index 1af4f51..0000000
--- a/logd/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../.clang-format-4
\ No newline at end of file
diff --git a/logd/Android.bp b/logd/Android.bp
deleted file mode 100644
index fe22d1c..0000000
--- a/logd/Android.bp
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This is what we want to do:
-//  event_logtags = $(shell
-//    sed -n
-//        "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p"
-//        $(LOCAL_PATH)/$2/event.logtags)
-//  event_flag := $(call event_logtags,auditd)
-//  event_flag += $(call event_logtags,logd)
-//  event_flag += $(call event_logtags,tag_def)
-// so make sure we do not regret hard-coding it as follows:
-event_flag = [
-    "-DAUDITD_LOG_TAG=1003",
-    "-DCHATTY_LOG_TAG=1004",
-    "-DTAG_DEF_LOG_TAG=1005",
-    "-DLIBLOG_LOG_TAG=1006",
-]
-
-cc_defaults {
-    name: "logd_defaults",
-
-    shared_libs: [
-        "libbase",
-        "libz",
-    ],
-    static_libs: ["libzstd"],
-    cflags: [
-        "-Wextra",
-        "-Wthread-safety",
-    ] + event_flag,
-
-    lto: {
-        thin: true,
-    },
-    cpp_std: "experimental",
-}
-
-cc_library_static {
-    name: "liblogd",
-    defaults: ["logd_defaults"],
-    host_supported: true,
-    srcs: [
-        "ChattyLogBuffer.cpp",
-        "CompressionEngine.cpp",
-        "LogReaderList.cpp",
-        "LogReaderThread.cpp",
-        "LogBufferElement.cpp",
-        "LogSize.cpp",
-        "LogStatistics.cpp",
-        "LogTags.cpp",
-        "PruneList.cpp",
-        "SerializedFlushToState.cpp",
-        "SerializedLogBuffer.cpp",
-        "SerializedLogChunk.cpp",
-        "SimpleLogBuffer.cpp",
-    ],
-    static_libs: ["liblog"],
-    logtags: ["event.logtags"],
-
-    export_include_dirs: ["."],
-}
-
-cc_binary {
-    name: "logd",
-    defaults: ["logd_defaults"],
-    init_rc: ["logd.rc"],
-
-    srcs: [
-        "main.cpp",
-        "LogPermissions.cpp",
-        "CommandListener.cpp",
-        "LogListener.cpp",
-        "LogReader.cpp",
-        "LogAudit.cpp",
-        "LogKlog.cpp",
-        "libaudit.cpp",
-    ],
-
-    static_libs: [
-        "liblog",
-        "liblogd",
-    ],
-
-    shared_libs: [
-        "libsysutils",
-        "libcutils",
-        "libpackagelistparser",
-        "libprocessgroup",
-        "libcap",
-    ],
-}
-
-cc_binary {
-    name: "auditctl",
-
-    srcs: [
-        "auditctl.cpp",
-        "libaudit.cpp",
-    ],
-
-    shared_libs: ["libbase"],
-
-    cflags: [
-        "-Wextra",
-    ],
-}
-
-prebuilt_etc {
-    name: "logtagd.rc",
-    src: "logtagd.rc",
-    sub_dir: "init",
-}
-
-// -----------------------------------------------------------------------------
-// Unit tests.
-// -----------------------------------------------------------------------------
-
-cc_defaults {
-    name: "logd-unit-test-defaults",
-
-    cflags: [
-        "-fstack-protector-all",
-        "-g",
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-fno-builtin",
-    ] + event_flag,
-
-    srcs: [
-        "ChattyLogBufferTest.cpp",
-        "logd_test.cpp",
-        "LogBufferTest.cpp",
-        "SerializedLogChunkTest.cpp",
-        "SerializedFlushToStateTest.cpp",
-    ],
-
-    static_libs: [
-        "libbase",
-        "libcutils",
-        "liblog",
-        "liblogd",
-        "libselinux",
-        "libz",
-        "libzstd",
-    ],
-}
-
-// Build tests for the logger. Run with:
-//   adb shell /data/nativetest/logd-unit-tests/logd-unit-tests
-cc_test {
-    name: "logd-unit-tests",
-    host_supported: true,
-    defaults: ["logd-unit-test-defaults"],
-}
-
-cc_test {
-    name: "CtsLogdTestCases",
-    defaults: ["logd-unit-test-defaults"],
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
-    test_suites: [
-        "cts",
-        "device-tests",
-        "vts10",
-    ],
-}
-
-cc_binary {
-    name: "replay_messages",
-    defaults: ["logd_defaults"],
-    host_supported: true,
-
-    srcs: [
-        "ReplayMessages.cpp",
-    ],
-
-    static_libs: [
-        "libbase",
-        "libcutils",
-        "liblog",
-        "liblogd",
-        "libselinux",
-        "libz",
-        "libzstd",
-    ],
-}
diff --git a/logd/AndroidTest.xml b/logd/AndroidTest.xml
deleted file mode 100644
index a25dc44..0000000
--- a/logd/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-<configuration description="Config for CTS Logging Daemon test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="systems" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="cleanup" value="true" />
-        <option name="push" value="CtsLogdTestCases->/data/local/tmp/CtsLogdTestCases" />
-        <option name="append-bitness" value="true" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="CtsLogdTestCases" />
-        <option name="runtime-hint" value="65s" />
-    </test>
-</configuration>
diff --git a/logd/ChattyLogBuffer.cpp b/logd/ChattyLogBuffer.cpp
deleted file mode 100644
index fd183e4..0000000
--- a/logd/ChattyLogBuffer.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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.
- */
-// for manual checking of stale entries during ChattyLogBuffer::erase()
-//#define DEBUG_CHECK_FOR_STALE_ENTRIES
-
-#include "ChattyLogBuffer.h"
-
-#include <ctype.h>
-#include <endian.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/cdefs.h>
-#include <sys/user.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <limits>
-#include <unordered_map>
-#include <utility>
-
-#include <private/android_logger.h>
-
-#include "LogUtils.h"
-
-#ifndef __predict_false
-#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
-#endif
-
-ChattyLogBuffer::ChattyLogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
-                                 LogStatistics* stats)
-    : SimpleLogBuffer(reader_list, tags, stats), prune_(prune) {}
-
-ChattyLogBuffer::~ChattyLogBuffer() {}
-
-enum match_type { DIFFERENT, SAME, SAME_LIBLOG };
-
-static enum match_type Identical(const LogBufferElement& elem, const LogBufferElement& last) {
-    ssize_t lenl = elem.msg_len();
-    if (lenl <= 0) return DIFFERENT;  // value if this represents a chatty elem
-    ssize_t lenr = last.msg_len();
-    if (lenr <= 0) return DIFFERENT;  // value if this represents a chatty elem
-    if (elem.uid() != last.uid()) return DIFFERENT;
-    if (elem.pid() != last.pid()) return DIFFERENT;
-    if (elem.tid() != last.tid()) return DIFFERENT;
-
-    // last is more than a minute old, stop squashing identical messages
-    if (elem.realtime().nsec() > (last.realtime().nsec() + 60 * NS_PER_SEC)) return DIFFERENT;
-
-    // Identical message
-    const char* msgl = elem.msg();
-    const char* msgr = last.msg();
-    if (lenl == lenr) {
-        if (!fastcmp<memcmp>(msgl, msgr, lenl)) return SAME;
-        // liblog tagged messages (content gets summed)
-        if (elem.log_id() == LOG_ID_EVENTS && lenl == sizeof(android_log_event_int_t) &&
-            !fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_int_t) - sizeof(int32_t)) &&
-            elem.GetTag() == LIBLOG_LOG_TAG) {
-            return SAME_LIBLOG;
-        }
-    }
-
-    // audit message (except sequence number) identical?
-    if (IsBinary(last.log_id()) &&
-        lenl > static_cast<ssize_t>(sizeof(android_log_event_string_t)) &&
-        lenr > static_cast<ssize_t>(sizeof(android_log_event_string_t))) {
-        if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) - sizeof(int32_t))) {
-            return DIFFERENT;
-        }
-        msgl += sizeof(android_log_event_string_t);
-        lenl -= sizeof(android_log_event_string_t);
-        msgr += sizeof(android_log_event_string_t);
-        lenr -= sizeof(android_log_event_string_t);
-    }
-    static const char avc[] = "): avc: ";
-    const char* avcl = android::strnstr(msgl, lenl, avc);
-    if (!avcl) return DIFFERENT;
-    lenl -= avcl - msgl;
-    const char* avcr = android::strnstr(msgr, lenr, avc);
-    if (!avcr) return DIFFERENT;
-    lenr -= avcr - msgr;
-    if (lenl != lenr) return DIFFERENT;
-    if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl - strlen(avc))) {
-        return DIFFERENT;
-    }
-    return SAME;
-}
-
-void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) {
-    // b/137093665: don't coalesce security messages.
-    if (elem.log_id() == LOG_ID_SECURITY) {
-        SimpleLogBuffer::LogInternal(std::move(elem));
-        return;
-    }
-    int log_id = elem.log_id();
-
-    // Initialize last_logged_elements_ to a copy of elem if logging the first element for a log_id.
-    if (!last_logged_elements_[log_id]) {
-        last_logged_elements_[log_id].emplace(elem);
-        SimpleLogBuffer::LogInternal(std::move(elem));
-        return;
-    }
-
-    LogBufferElement& current_last = *last_logged_elements_[log_id];
-    enum match_type match = Identical(elem, current_last);
-
-    if (match == DIFFERENT) {
-        if (duplicate_elements_[log_id]) {
-            // If we previously had 3+ identical messages, log the chatty message.
-            if (duplicate_elements_[log_id]->dropped_count() > 0) {
-                SimpleLogBuffer::LogInternal(std::move(*duplicate_elements_[log_id]));
-            }
-            duplicate_elements_[log_id].reset();
-            // Log the saved copy of the last identical message seen.
-            SimpleLogBuffer::LogInternal(std::move(current_last));
-        }
-        last_logged_elements_[log_id].emplace(elem);
-        SimpleLogBuffer::LogInternal(std::move(elem));
-        return;
-    }
-
-    // 2 identical message: set duplicate_elements_ appropriately.
-    if (!duplicate_elements_[log_id]) {
-        duplicate_elements_[log_id].emplace(std::move(current_last));
-        last_logged_elements_[log_id].emplace(std::move(elem));
-        return;
-    }
-
-    // 3+ identical LIBLOG event messages: coalesce them into last_logged_elements_.
-    if (match == SAME_LIBLOG) {
-        const android_log_event_int_t* current_last_event =
-                reinterpret_cast<const android_log_event_int_t*>(current_last.msg());
-        int64_t current_last_count = current_last_event->payload.data;
-        android_log_event_int_t* elem_event =
-                reinterpret_cast<android_log_event_int_t*>(const_cast<char*>(elem.msg()));
-        int64_t elem_count = elem_event->payload.data;
-
-        int64_t total = current_last_count + elem_count;
-        if (total > std::numeric_limits<int32_t>::max()) {
-            SimpleLogBuffer::LogInternal(std::move(current_last));
-            last_logged_elements_[log_id].emplace(std::move(elem));
-            return;
-        }
-        stats()->AddTotal(current_last.log_id(), current_last.msg_len());
-        elem_event->payload.data = total;
-        last_logged_elements_[log_id].emplace(std::move(elem));
-        return;
-    }
-
-    // 3+ identical messages (not LIBLOG) messages: increase the drop count.
-    uint16_t dropped_count = duplicate_elements_[log_id]->dropped_count();
-    if (dropped_count == std::numeric_limits<uint16_t>::max()) {
-        SimpleLogBuffer::LogInternal(std::move(*duplicate_elements_[log_id]));
-        dropped_count = 0;
-    }
-    // We're dropping the current_last log so add its stats to the total.
-    stats()->AddTotal(current_last.log_id(), current_last.msg_len());
-    // Use current_last for tracking the dropped count to always use the latest timestamp.
-    current_last.SetDropped(dropped_count + 1);
-    duplicate_elements_[log_id].emplace(std::move(current_last));
-    last_logged_elements_[log_id].emplace(std::move(elem));
-}
-
-LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementCollection::iterator it,
-                                                            bool coalesce) {
-    LogBufferElement& element = *it;
-    log_id_t id = element.log_id();
-
-    // Remove iterator references in the various lists that will become stale
-    // after the element is erased from the main logging list.
-
-    {  // start of scope for found iterator
-        int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.GetTag() : element.uid();
-        LogBufferIteratorMap::iterator found = mLastWorst[id].find(key);
-        if ((found != mLastWorst[id].end()) && (it == found->second)) {
-            mLastWorst[id].erase(found);
-        }
-    }
-
-    {  // start of scope for pid found iterator
-        // element->uid() may not be AID_SYSTEM for next-best-watermark.
-        // will not assume id != LOG_ID_EVENTS or LOG_ID_SECURITY for KISS and
-        // long term code stability, find() check should be fast for those ids.
-        LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element.pid());
-        if (found != mLastWorstPidOfSystem[id].end() && it == found->second) {
-            mLastWorstPidOfSystem[id].erase(found);
-        }
-    }
-
-#ifdef DEBUG_CHECK_FOR_STALE_ENTRIES
-    LogBufferElementCollection::iterator bad = it;
-    int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->GetTag() : element->uid();
-#endif
-
-    if (coalesce) {
-        stats()->Erase(element.ToLogStatisticsElement());
-    } else {
-        stats()->Subtract(element.ToLogStatisticsElement());
-    }
-
-    it = SimpleLogBuffer::Erase(it);
-
-#ifdef DEBUG_CHECK_FOR_STALE_ENTRIES
-    log_id_for_each(i) {
-        for (auto b : mLastWorst[i]) {
-            if (bad == b.second) {
-                LOG(ERROR) << StringPrintf("stale mLastWorst[%d] key=%d mykey=%d", i, b.first, key);
-            }
-        }
-        for (auto b : mLastWorstPidOfSystem[i]) {
-            if (bad == b.second) {
-                LOG(ERROR) << StringPrintf("stale mLastWorstPidOfSystem[%d] pid=%d", i, b.first);
-            }
-        }
-    }
-#endif
-    return it;
-}
-
-// Define a temporary mechanism to report the last LogBufferElement pointer
-// for the specified uid, pid and tid. Used below to help merge-sort when
-// pruning for worst UID.
-class LogBufferElementLast {
-    typedef std::unordered_map<uint64_t, LogBufferElement*> LogBufferElementMap;
-    LogBufferElementMap map;
-
-  public:
-    bool coalesce(LogBufferElement* element, uint16_t dropped) {
-        uint64_t key = LogBufferElementKey(element->uid(), element->pid(), element->tid());
-        LogBufferElementMap::iterator it = map.find(key);
-        if (it != map.end()) {
-            LogBufferElement* found = it->second;
-            uint16_t moreDropped = found->dropped_count();
-            if ((dropped + moreDropped) > USHRT_MAX) {
-                map.erase(it);
-            } else {
-                found->SetDropped(dropped + moreDropped);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    void add(LogBufferElement* element) {
-        uint64_t key = LogBufferElementKey(element->uid(), element->pid(), element->tid());
-        map[key] = element;
-    }
-
-    void clear() { map.clear(); }
-
-    void clear(LogBufferElement* element) {
-        uint64_t current = element->realtime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
-        for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) {
-            LogBufferElement* mapElement = it->second;
-            if (mapElement->dropped_count() >= EXPIRE_THRESHOLD &&
-                current > mapElement->realtime().nsec()) {
-                it = map.erase(it);
-            } else {
-                ++it;
-            }
-        }
-    }
-
-  private:
-    uint64_t LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid) {
-        return uint64_t(uid) << 32 | uint64_t(pid) << 16 | uint64_t(tid);
-    }
-};
-
-// prune "pruneRows" of type "id" from the buffer.
-//
-// This garbage collection task is used to expire log entries. It is called to
-// remove all logs (clear), all UID logs (unprivileged clear), or every
-// 256 or 10% of the total logs (whichever is less) to prune the logs.
-//
-// First there is a prep phase where we discover the reader region lock that
-// acts as a backstop to any pruning activity to stop there and go no further.
-//
-// There are three major pruning loops that follow. All expire from the oldest
-// entries. Since there are multiple log buffers, the Android logging facility
-// will appear to drop entries 'in the middle' when looking at multiple log
-// sources and buffers. This effect is slightly more prominent when we prune
-// the worst offender by logging source. Thus the logs slowly loose content
-// and value as you move back in time. This is preferred since chatty sources
-// invariably move the logs value down faster as less chatty sources would be
-// expired in the noise.
-//
-// The first pass prunes elements that match 3 possible rules:
-// 1) A high priority prune rule, for example ~100/20, which indicates elements from UID 100 and PID
-//    20 should be pruned in this first pass.
-// 2) The default chatty pruning rule, ~!.  This rule sums the total size spent on log messages for
-//    each UID this log buffer.  If the highest sum consumes more than 12.5% of the log buffer, then
-//    these elements from that UID are pruned.
-// 3) The default AID_SYSTEM pruning rule, ~1000/!.  This rule is a special case to 2), if
-//    AID_SYSTEM is the top consumer of the log buffer, then this rule sums the total size spent on
-//    log messages for each PID in AID_SYSTEM in this log buffer and prunes elements from the PID
-//    with the highest sum.
-// This pass reevaluates the sums for rules 2) and 3) for every log message pruned. It creates
-// 'chatty' entries for the elements that it prunes and merges related chatty entries together. It
-// completes when one of three conditions have been met:
-// 1) The requested element count has been pruned.
-// 2) There are no elements that match any of these rules.
-// 3) A reader is referencing the oldest element that would match these rules.
-//
-// The second pass prunes elements starting from the beginning of the log.  It skips elements that
-// match any low priority prune rules.  It completes when one of three conditions have been met:
-// 1) The requested element count has been pruned.
-// 2) All elements except those mwatching low priority prune rules have been pruned.
-// 3) A reader is referencing the oldest element that would match these rules.
-//
-// The final pass only happens if there are any low priority prune rules and if the first two passes
-// were unable to prune the requested number of elements.  It prunes elements all starting from the
-// beginning of the log, regardless of if they match any low priority prune rules.
-//
-// If the requested number of logs was unable to be pruned, KickReader() is called to mitigate the
-// situation before the next call to Prune() and the function returns false.  Otherwise, if the
-// requested number of logs or all logs present in the buffer are pruned, in the case of Clear(),
-// it returns true.
-bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
-    LogReaderThread* oldest = nullptr;
-    bool clearAll = pruneRows == ULONG_MAX;
-
-    auto reader_threads_lock = std::lock_guard{reader_list()->reader_threads_lock()};
-
-    // Region locked?
-    for (const auto& reader_thread : reader_list()->reader_threads()) {
-        if (!reader_thread->IsWatching(id)) {
-            continue;
-        }
-        if (!oldest || oldest->start() > reader_thread->start() ||
-            (oldest->start() == reader_thread->start() &&
-             reader_thread->deadline().time_since_epoch().count() != 0)) {
-            oldest = reader_thread.get();
-        }
-    }
-
-    LogBufferElementCollection::iterator it;
-
-    if (__predict_false(caller_uid != AID_ROOT)) {  // unlikely
-        // Only here if clear all request from non system source, so chatty
-        // filter logistics is not required.
-        it = GetOldest(id);
-        while (it != logs().end()) {
-            LogBufferElement& element = *it;
-
-            if (element.log_id() != id || element.uid() != caller_uid) {
-                ++it;
-                continue;
-            }
-
-            if (oldest && oldest->start() <= element.sequence()) {
-                KickReader(oldest, id, pruneRows);
-                return false;
-            }
-
-            it = Erase(it);
-            if (--pruneRows == 0) {
-                return true;
-            }
-        }
-        return true;
-    }
-
-    // First prune pass.
-    bool check_high_priority = id != LOG_ID_SECURITY && prune_->HasHighPriorityPruneRules();
-    while (!clearAll && (pruneRows > 0)) {
-        // recalculate the worst offender on every batched pass
-        int worst = -1;  // not valid for uid() or getKey()
-        size_t worst_sizes = 0;
-        size_t second_worst_sizes = 0;
-        pid_t worstPid = 0;  // POSIX guarantees PID != 0
-
-        if (worstUidEnabledForLogid(id) && prune_->worst_uid_enabled()) {
-            // Calculate threshold as 12.5% of available storage
-            size_t threshold = max_size(id) / 8;
-
-            if (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) {
-                stats()->WorstTwoTags(threshold, &worst, &worst_sizes, &second_worst_sizes);
-                // per-pid filter for AID_SYSTEM sources is too complex
-            } else {
-                stats()->WorstTwoUids(id, threshold, &worst, &worst_sizes, &second_worst_sizes);
-
-                if (worst == AID_SYSTEM && prune_->worst_pid_of_system_enabled()) {
-                    stats()->WorstTwoSystemPids(id, worst_sizes, &worstPid, &second_worst_sizes);
-                }
-            }
-        }
-
-        // skip if we have neither a worst UID or high priority prune rules
-        if (worst == -1 && !check_high_priority) {
-            break;
-        }
-
-        bool kick = false;
-        bool leading = true;  // true if starting from the oldest log entry, false if starting from
-                              // a specific chatty entry.
-        // Perform at least one mandatory garbage collection cycle in following
-        // - clear leading chatty tags
-        // - coalesce chatty tags
-        // - check age-out of preserved logs
-        bool gc = pruneRows <= 1;
-        if (!gc && (worst != -1)) {
-            {  // begin scope for worst found iterator
-                LogBufferIteratorMap::iterator found = mLastWorst[id].find(worst);
-                if (found != mLastWorst[id].end() && found->second != logs().end()) {
-                    leading = false;
-                    it = found->second;
-                }
-            }
-            if (worstPid) {  // begin scope for pid worst found iterator
-                // FYI: worstPid only set if !LOG_ID_EVENTS and
-                //      !LOG_ID_SECURITY, not going to make that assumption ...
-                LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(worstPid);
-                if (found != mLastWorstPidOfSystem[id].end() && found->second != logs().end()) {
-                    leading = false;
-                    it = found->second;
-                }
-            }
-        }
-        if (leading) {
-            it = GetOldest(id);
-        }
-        static const log_time too_old{EXPIRE_HOUR_THRESHOLD * 60 * 60, 0};
-        LogBufferElementCollection::iterator lastt;
-        lastt = logs().end();
-        --lastt;
-        LogBufferElementLast last;
-        while (it != logs().end()) {
-            LogBufferElement& element = *it;
-
-            if (oldest && oldest->start() <= element.sequence()) {
-                // Do not let chatty eliding trigger any reader mitigation
-                break;
-            }
-
-            if (element.log_id() != id) {
-                ++it;
-                continue;
-            }
-            // below this point element->log_id() == id
-
-            uint16_t dropped = element.dropped_count();
-
-            // remove any leading drops
-            if (leading && dropped) {
-                it = Erase(it);
-                continue;
-            }
-
-            if (dropped && last.coalesce(&element, dropped)) {
-                it = Erase(it, true);
-                continue;
-            }
-
-            int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.GetTag()
-                                                                     : element.uid();
-
-            if (check_high_priority && prune_->IsHighPriority(&element)) {
-                last.clear(&element);
-                it = Erase(it);
-                if (dropped) {
-                    continue;
-                }
-
-                pruneRows--;
-                if (pruneRows == 0) {
-                    break;
-                }
-
-                if (key == worst) {
-                    kick = true;
-                    if (worst_sizes < second_worst_sizes) {
-                        break;
-                    }
-                    worst_sizes -= element.msg_len();
-                }
-                continue;
-            }
-
-            if (element.realtime() < (lastt->realtime() - too_old) ||
-                element.realtime() > lastt->realtime()) {
-                break;
-            }
-
-            if (dropped) {
-                last.add(&element);
-                if (worstPid && ((!gc && element.pid() == worstPid) ||
-                                 mLastWorstPidOfSystem[id].find(element.pid()) ==
-                                         mLastWorstPidOfSystem[id].end())) {
-                    // element->uid() may not be AID_SYSTEM, next best
-                    // watermark if current one empty. id is not LOG_ID_EVENTS
-                    // or LOG_ID_SECURITY because of worstPid check.
-                    mLastWorstPidOfSystem[id][element.pid()] = it;
-                }
-                if ((!gc && !worstPid && (key == worst)) ||
-                    (mLastWorst[id].find(key) == mLastWorst[id].end())) {
-                    mLastWorst[id][key] = it;
-                }
-                ++it;
-                continue;
-            }
-
-            if (key != worst || (worstPid && element.pid() != worstPid)) {
-                leading = false;
-                last.clear(&element);
-                ++it;
-                continue;
-            }
-            // key == worst below here
-            // If worstPid set, then element->pid() == worstPid below here
-
-            pruneRows--;
-            if (pruneRows == 0) {
-                break;
-            }
-
-            kick = true;
-
-            uint16_t len = element.msg_len();
-
-            // do not create any leading drops
-            if (leading) {
-                it = Erase(it);
-            } else {
-                stats()->Drop(element.ToLogStatisticsElement());
-                element.SetDropped(1);
-                if (last.coalesce(&element, 1)) {
-                    it = Erase(it, true);
-                } else {
-                    last.add(&element);
-                    if (worstPid && (!gc || mLastWorstPidOfSystem[id].find(worstPid) ==
-                                                    mLastWorstPidOfSystem[id].end())) {
-                        // element->uid() may not be AID_SYSTEM, next best
-                        // watermark if current one empty. id is not
-                        // LOG_ID_EVENTS or LOG_ID_SECURITY because of worstPid.
-                        mLastWorstPidOfSystem[id][worstPid] = it;
-                    }
-                    if ((!gc && !worstPid) || mLastWorst[id].find(worst) == mLastWorst[id].end()) {
-                        mLastWorst[id][worst] = it;
-                    }
-                    ++it;
-                }
-            }
-            if (worst_sizes < second_worst_sizes) {
-                break;
-            }
-            worst_sizes -= len;
-        }
-        last.clear();
-
-        if (!kick || !prune_->worst_uid_enabled()) {
-            break;  // the following loop will ask bad clients to skip/drop
-        }
-    }
-
-    // Second prune pass.
-    bool skipped_low_priority_prune = false;
-    bool check_low_priority =
-            id != LOG_ID_SECURITY && prune_->HasLowPriorityPruneRules() && !clearAll;
-    it = GetOldest(id);
-    while (pruneRows > 0 && it != logs().end()) {
-        LogBufferElement& element = *it;
-
-        if (element.log_id() != id) {
-            it++;
-            continue;
-        }
-
-        if (oldest && oldest->start() <= element.sequence()) {
-            if (!skipped_low_priority_prune) KickReader(oldest, id, pruneRows);
-            break;
-        }
-
-        if (check_low_priority && !element.dropped_count() && prune_->IsLowPriority(&element)) {
-            skipped_low_priority_prune = true;
-            it++;
-            continue;
-        }
-
-        it = Erase(it);
-        pruneRows--;
-    }
-
-    // Third prune pass.
-    if (skipped_low_priority_prune && pruneRows > 0) {
-        it = GetOldest(id);
-        while (it != logs().end() && pruneRows > 0) {
-            LogBufferElement& element = *it;
-
-            if (element.log_id() != id) {
-                ++it;
-                continue;
-            }
-
-            if (oldest && oldest->start() <= element.sequence()) {
-                KickReader(oldest, id, pruneRows);
-                break;
-            }
-
-            it = Erase(it);
-            pruneRows--;
-        }
-    }
-
-    return pruneRows == 0 || it == logs().end();
-}
diff --git a/logd/ChattyLogBuffer.h b/logd/ChattyLogBuffer.h
deleted file mode 100644
index b4d3a2f..0000000
--- a/logd/ChattyLogBuffer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <list>
-#include <optional>
-#include <string>
-
-#include <android-base/thread_annotations.h>
-#include <android/log.h>
-#include <private/android_filesystem_config.h>
-
-#include "LogBuffer.h"
-#include "LogBufferElement.h"
-#include "LogReaderList.h"
-#include "LogReaderThread.h"
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "LogWriter.h"
-#include "PruneList.h"
-#include "SimpleLogBuffer.h"
-#include "rwlock.h"
-
-typedef std::list<LogBufferElement> LogBufferElementCollection;
-
-class ChattyLogBuffer : public SimpleLogBuffer {
-    // watermark of any worst/chatty uid processing
-    typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap;
-    LogBufferIteratorMap mLastWorst[LOG_ID_MAX] GUARDED_BY(lock_);
-    // watermark of any worst/chatty pid of system processing
-    typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> LogBufferPidIteratorMap;
-    LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX] GUARDED_BY(lock_);
-
-  public:
-    ChattyLogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
-                    LogStatistics* stats);
-    ~ChattyLogBuffer();
-
-  protected:
-    bool Prune(log_id_t id, unsigned long pruneRows, uid_t uid) REQUIRES(lock_) override;
-    void LogInternal(LogBufferElement&& elem) REQUIRES(lock_) override;
-
-  private:
-    LogBufferElementCollection::iterator Erase(LogBufferElementCollection::iterator it,
-                                               bool coalesce = false) REQUIRES(lock_);
-
-    PruneList* prune_;
-
-    // This always contains a copy of the last message logged, for deduplication.
-    std::optional<LogBufferElement> last_logged_elements_[LOG_ID_MAX] GUARDED_BY(lock_);
-    // This contains an element if duplicate messages are seen.
-    // Its `dropped` count is `duplicates seen - 1`.
-    std::optional<LogBufferElement> duplicate_elements_[LOG_ID_MAX] GUARDED_BY(lock_);
-};
diff --git a/logd/ChattyLogBufferTest.cpp b/logd/ChattyLogBufferTest.cpp
deleted file mode 100644
index 3d9005a..0000000
--- a/logd/ChattyLogBufferTest.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2020 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 "LogBufferTest.h"
-
-class ChattyLogBufferTest : public LogBufferTest {};
-
-TEST_P(ChattyLogBufferTest, deduplication_simple) {
-    auto make_message = [&](uint32_t sec, const char* tag, const char* msg,
-                            bool regex = false) -> LogMessage {
-        logger_entry entry = {
-                .pid = 1, .tid = 1, .sec = sec, .nsec = 1, .lid = LOG_ID_MAIN, .uid = 0};
-        std::string message;
-        message.push_back(ANDROID_LOG_INFO);
-        message.append(tag);
-        message.push_back('\0');
-        message.append(msg);
-        message.push_back('\0');
-        return {entry, message, regex};
-    };
-
-    // clang-format off
-    std::vector<LogMessage> log_messages = {
-            make_message(0, "test_tag", "duplicate"),
-            make_message(1, "test_tag", "duplicate"),
-            make_message(2, "test_tag", "not_same"),
-            make_message(3, "test_tag", "duplicate"),
-            make_message(4, "test_tag", "duplicate"),
-            make_message(5, "test_tag", "not_same"),
-            make_message(6, "test_tag", "duplicate"),
-            make_message(7, "test_tag", "duplicate"),
-            make_message(8, "test_tag", "duplicate"),
-            make_message(9, "test_tag", "not_same"),
-            make_message(10, "test_tag", "duplicate"),
-            make_message(11, "test_tag", "duplicate"),
-            make_message(12, "test_tag", "duplicate"),
-            make_message(13, "test_tag", "duplicate"),
-            make_message(14, "test_tag", "duplicate"),
-            make_message(15, "test_tag", "duplicate"),
-            make_message(16, "test_tag", "not_same"),
-            make_message(100, "test_tag", "duplicate"),
-            make_message(200, "test_tag", "duplicate"),
-            make_message(300, "test_tag", "duplicate"),
-    };
-    // clang-format on
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, nullptr));
-    std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, kLogMaskAll);
-    EXPECT_TRUE(log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr));
-
-    std::vector<LogMessage> expected_log_messages = {
-            make_message(0, "test_tag", "duplicate"),
-            make_message(1, "test_tag", "duplicate"),
-            make_message(2, "test_tag", "not_same"),
-            make_message(3, "test_tag", "duplicate"),
-            make_message(4, "test_tag", "duplicate"),
-            make_message(5, "test_tag", "not_same"),
-            // 3 duplicate logs together print the first, a 1 count chatty message, then the last.
-            make_message(6, "test_tag", "duplicate"),
-            make_message(7, "chatty", "uid=0\\([^\\)]+\\) [^ ]+ identical 1 line", true),
-            make_message(8, "test_tag", "duplicate"),
-            make_message(9, "test_tag", "not_same"),
-            // 6 duplicate logs together print the first, a 4 count chatty message, then the last.
-            make_message(10, "test_tag", "duplicate"),
-            make_message(14, "chatty", "uid=0\\([^\\)]+\\) [^ ]+ identical 4 lines", true),
-            make_message(15, "test_tag", "duplicate"),
-            make_message(16, "test_tag", "not_same"),
-            // duplicate logs > 1 minute apart are not deduplicated.
-            make_message(100, "test_tag", "duplicate"),
-            make_message(200, "test_tag", "duplicate"),
-            make_message(300, "test_tag", "duplicate"),
-    };
-    FixupMessages(&expected_log_messages);
-    CompareLogMessages(expected_log_messages, read_log_messages);
-};
-
-TEST_P(ChattyLogBufferTest, deduplication_overflow) {
-    auto make_message = [&](uint32_t sec, const char* tag, const char* msg,
-                            bool regex = false) -> LogMessage {
-        logger_entry entry = {
-                .pid = 1, .tid = 1, .sec = sec, .nsec = 1, .lid = LOG_ID_MAIN, .uid = 0};
-        std::string message;
-        message.push_back(ANDROID_LOG_INFO);
-        message.append(tag);
-        message.push_back('\0');
-        message.append(msg);
-        message.push_back('\0');
-        return {entry, message, regex};
-    };
-
-    uint32_t sec = 0;
-    std::vector<LogMessage> log_messages = {
-            make_message(sec++, "test_tag", "normal"),
-    };
-    size_t expired_per_chatty_message = std::numeric_limits<uint16_t>::max();
-    for (size_t i = 0; i < expired_per_chatty_message + 3; ++i) {
-        log_messages.emplace_back(make_message(sec++, "test_tag", "duplicate"));
-    }
-    log_messages.emplace_back(make_message(sec++, "test_tag", "normal"));
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, nullptr));
-    std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, kLogMaskAll);
-    EXPECT_TRUE(log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr));
-
-    std::vector<LogMessage> expected_log_messages = {
-            make_message(0, "test_tag", "normal"),
-            make_message(1, "test_tag", "duplicate"),
-            make_message(expired_per_chatty_message + 1, "chatty",
-                         "uid=0\\([^\\)]+\\) [^ ]+ identical 65535 lines", true),
-            make_message(expired_per_chatty_message + 2, "chatty",
-                         "uid=0\\([^\\)]+\\) [^ ]+ identical 1 line", true),
-            make_message(expired_per_chatty_message + 3, "test_tag", "duplicate"),
-            make_message(expired_per_chatty_message + 4, "test_tag", "normal"),
-    };
-    FixupMessages(&expected_log_messages);
-    CompareLogMessages(expected_log_messages, read_log_messages);
-}
-
-TEST_P(ChattyLogBufferTest, deduplication_liblog) {
-    auto make_message = [&](uint32_t sec, int32_t tag, int32_t count) -> LogMessage {
-        logger_entry entry = {
-                .pid = 1, .tid = 1, .sec = sec, .nsec = 1, .lid = LOG_ID_EVENTS, .uid = 0};
-        android_log_event_int_t liblog_event = {
-                .header.tag = tag, .payload.type = EVENT_TYPE_INT, .payload.data = count};
-        return {entry, std::string(reinterpret_cast<char*>(&liblog_event), sizeof(liblog_event)),
-                false};
-    };
-
-    // LIBLOG_LOG_TAG
-    std::vector<LogMessage> log_messages = {
-            make_message(0, 1234, 1),
-            make_message(1, LIBLOG_LOG_TAG, 3),
-            make_message(2, 1234, 2),
-            make_message(3, LIBLOG_LOG_TAG, 3),
-            make_message(4, LIBLOG_LOG_TAG, 4),
-            make_message(5, 1234, 223),
-            make_message(6, LIBLOG_LOG_TAG, 2),
-            make_message(7, LIBLOG_LOG_TAG, 3),
-            make_message(8, LIBLOG_LOG_TAG, 4),
-            make_message(9, 1234, 227),
-            make_message(10, LIBLOG_LOG_TAG, 1),
-            make_message(11, LIBLOG_LOG_TAG, 3),
-            make_message(12, LIBLOG_LOG_TAG, 2),
-            make_message(13, LIBLOG_LOG_TAG, 3),
-            make_message(14, LIBLOG_LOG_TAG, 5),
-            make_message(15, 1234, 227),
-            make_message(16, LIBLOG_LOG_TAG, 2),
-            make_message(17, LIBLOG_LOG_TAG, std::numeric_limits<int32_t>::max()),
-            make_message(18, LIBLOG_LOG_TAG, 3),
-            make_message(19, LIBLOG_LOG_TAG, 5),
-            make_message(20, 1234, 227),
-    };
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, nullptr));
-    std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, kLogMaskAll);
-    EXPECT_TRUE(log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr));
-
-    std::vector<LogMessage> expected_log_messages = {
-            make_message(0, 1234, 1),
-            make_message(1, LIBLOG_LOG_TAG, 3),
-            make_message(2, 1234, 2),
-            make_message(3, LIBLOG_LOG_TAG, 3),
-            make_message(4, LIBLOG_LOG_TAG, 4),
-            make_message(5, 1234, 223),
-            // More than 2 liblog events (3 here), sum their value into the third message.
-            make_message(6, LIBLOG_LOG_TAG, 2),
-            make_message(8, LIBLOG_LOG_TAG, 7),
-            make_message(9, 1234, 227),
-            // More than 2 liblog events (5 here), sum their value into the third message.
-            make_message(10, LIBLOG_LOG_TAG, 1),
-            make_message(14, LIBLOG_LOG_TAG, 13),
-            make_message(15, 1234, 227),
-            // int32_t max is the max for a chatty message, beyond that we must use new messages.
-            make_message(16, LIBLOG_LOG_TAG, 2),
-            make_message(17, LIBLOG_LOG_TAG, std::numeric_limits<int32_t>::max()),
-            make_message(19, LIBLOG_LOG_TAG, 8),
-            make_message(20, 1234, 227),
-    };
-    FixupMessages(&expected_log_messages);
-    CompareLogMessages(expected_log_messages, read_log_messages);
-};
-
-TEST_P(ChattyLogBufferTest, no_leading_chatty_simple) {
-    auto make_message = [&](uint32_t sec, int32_t pid, uint32_t uid, uint32_t lid, const char* tag,
-                            const char* msg, bool regex = false) -> LogMessage {
-        logger_entry entry = {.pid = pid, .tid = 1, .sec = sec, .nsec = 1, .lid = lid, .uid = uid};
-        std::string message;
-        message.push_back(ANDROID_LOG_INFO);
-        message.append(tag);
-        message.push_back('\0');
-        message.append(msg);
-        message.push_back('\0');
-        return {entry, message, regex};
-    };
-
-    // clang-format off
-    std::vector<LogMessage> log_messages = {
-            make_message(1, 1, 1, LOG_ID_MAIN, "test_tag", "duplicate1"),
-            make_message(2, 2, 2, LOG_ID_SYSTEM, "test_tag", "duplicate2"),
-            make_message(3, 2, 2, LOG_ID_SYSTEM, "test_tag", "duplicate2"),
-            make_message(4, 2, 2, LOG_ID_SYSTEM, "test_tag", "duplicate2"),
-            make_message(6, 2, 2, LOG_ID_SYSTEM, "test_tag", "not duplicate2"),
-            make_message(7, 1, 1, LOG_ID_MAIN, "test_tag", "duplicate1"),
-            make_message(8, 1, 1, LOG_ID_MAIN, "test_tag", "duplicate1"),
-            make_message(9, 1, 1, LOG_ID_MAIN, "test_tag", "duplicate1"),
-            make_message(10, 1, 1, LOG_ID_MAIN, "test_tag", "not duplicate1"),
-    };
-    // clang-format on
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    // After logging log_messages, the below is what should be in the buffer:
-    // PID=1, LOG_ID_MAIN duplicate1
-    // [1] PID=2, LOG_ID_SYSTEM duplicate2
-    // PID=2, LOG_ID_SYSTEM chatty drop
-    // PID=2, LOG_ID_SYSTEM duplicate2
-    // PID=2, LOG_ID_SYSTEM not duplicate2
-    // [2] PID=1, LOG_ID_MAIN chatty drop
-    // [3] PID=1, LOG_ID_MAIN duplicate1
-    // PID=1, LOG_ID_MAIN not duplicate1
-
-    // We then read from the 2nd sequence number, starting from log message [1], but filtering out
-    // everything but PID=1, which results in us starting with log message [2], which is a chatty
-    // drop.  Code prior to this test case would erroneously print it.  The intended behavior that
-    // this test checks prints logs starting from log message [3].
-
-    // clang-format off
-    std::vector<LogMessage> expected_log_messages = {
-            make_message(9, 1, 1, LOG_ID_MAIN, "test_tag", "duplicate1"),
-            make_message(10, 1, 1, LOG_ID_MAIN, "test_tag", "not duplicate1"),
-    };
-    FixupMessages(&expected_log_messages);
-    // clang-format on
-
-    std::vector<LogMessage> read_log_messages;
-    bool released = false;
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released));
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true,
-                                    0, ~0, 1, {}, 2, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    while (!released) {
-        usleep(5000);
-    }
-
-    CompareLogMessages(expected_log_messages, read_log_messages);
-}
-
-TEST_P(ChattyLogBufferTest, no_leading_chatty_tail) {
-    auto make_message = [&](uint32_t sec, const char* tag, const char* msg,
-                            bool regex = false) -> LogMessage {
-        logger_entry entry = {
-                .pid = 1, .tid = 1, .sec = sec, .nsec = 1, .lid = LOG_ID_MAIN, .uid = 0};
-        std::string message;
-        message.push_back(ANDROID_LOG_INFO);
-        message.append(tag);
-        message.push_back('\0');
-        message.append(msg);
-        message.push_back('\0');
-        return {entry, message, regex};
-    };
-
-    // clang-format off
-    std::vector<LogMessage> log_messages = {
-            make_message(1, "test_tag", "duplicate"),
-            make_message(2, "test_tag", "duplicate"),
-            make_message(3, "test_tag", "duplicate"),
-            make_message(4, "test_tag", "not_duplicate"),
-    };
-    // clang-format on
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    // After logging log_messages, the below is what should be in the buffer:
-    // "duplicate"
-    // chatty
-    // "duplicate"
-    // "not duplicate"
-
-    // We then read the tail 3 messages expecting there to not be a chatty message, meaning that we
-    // should only see the last two messages.
-
-    // clang-format off
-    std::vector<LogMessage> expected_log_messages = {
-            make_message(3, "test_tag", "duplicate"),
-            make_message(4, "test_tag", "not_duplicate"),
-    };
-    FixupMessages(&expected_log_messages);
-    // clang-format on
-
-    std::vector<LogMessage> read_log_messages;
-    bool released = false;
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released));
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true,
-                                    3, ~0, 0, {}, 1, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    while (!released) {
-        usleep(5000);
-    }
-
-    CompareLogMessages(expected_log_messages, read_log_messages);
-}
-
-INSTANTIATE_TEST_CASE_P(ChattyLogBufferTests, ChattyLogBufferTest, testing::Values("chatty"));
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
deleted file mode 100644
index 0ba1621..0000000
--- a/logd/CommandListener.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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 "CommandListener.h"
-
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <string>
-
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <cutils/sockets.h>
-#include <log/log_properties.h>
-#include <private/android_filesystem_config.h>
-#include <sysutils/SocketClient.h>
-
-#include "LogPermissions.h"
-
-CommandListener::CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune,
-                                 LogStatistics* stats)
-    : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags), prune_(prune), stats_(stats) {
-    registerCmd(new ClearCmd(this));
-    registerCmd(new GetBufSizeCmd(this));
-    registerCmd(new SetBufSizeCmd(this));
-    registerCmd(new GetBufSizeReadableCmd(this));
-    registerCmd(new GetBufSizeUsedCmd(this));
-    registerCmd(new GetStatisticsCmd(this));
-    registerCmd(new SetPruneListCmd(this));
-    registerCmd(new GetPruneListCmd(this));
-    registerCmd(new GetEventTagCmd(this));
-    registerCmd(new ReinitCmd(this));
-    registerCmd(new ExitCmd(this));
-}
-
-static void setname() {
-    static bool name_set;
-    if (!name_set) {
-        prctl(PR_SET_NAME, "logd.control");
-        name_set = true;
-    }
-}
-
-template <typename F>
-static int LogIdCommand(SocketClient* cli, int argc, char** argv, F&& function) {
-    setname();
-    if (argc < 2) {
-        cli->sendMsg("Missing Argument");
-        return 0;
-    }
-
-    int log_id;
-    if (!android::base::ParseInt(argv[1], &log_id, static_cast<int>(LOG_ID_MAIN),
-                                 static_cast<int>(LOG_ID_KERNEL))) {
-        cli->sendMsg("Range Error");
-        return 0;
-    }
-
-    function(static_cast<log_id_t>(log_id));
-    return 0;
-}
-
-int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    uid_t uid = cli->getUid();
-    if (clientHasLogCredentials(cli)) {
-        uid = AID_ROOT;
-    }
-
-    return LogIdCommand(cli, argc, argv, [&](log_id_t id) {
-        cli->sendMsg(buf()->Clear(id, uid) ? "success" : "busy");
-    });
-}
-
-template <typename F>
-static int LogSizeCommand(SocketClient* cli, int argc, char** argv, F&& size_function) {
-    return LogIdCommand(cli, argc, argv, [&](log_id_t log_id) {
-        cli->sendMsg(std::to_string(size_function(log_id)).c_str());
-    });
-}
-
-int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    return LogSizeCommand(cli, argc, argv, [this](log_id_t id) { return buf()->GetSize(id); });
-}
-
-int CommandListener::GetBufSizeReadableCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    return LogSizeCommand(cli, argc, argv,
-                          [this](log_id_t id) { return stats()->SizeReadable(id); });
-}
-
-int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    return LogSizeCommand(cli, argc, argv, [this](log_id_t id) { return stats()->Sizes(id); });
-}
-
-int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
-                                               char** argv) {
-    if (!clientHasLogCredentials(cli)) {
-        cli->sendMsg("Permission Denied");
-        return 0;
-    }
-
-    if (argc < 3) {
-        cli->sendMsg("Missing Argument");
-        return 0;
-    }
-    size_t size = atol(argv[2]);
-
-    return LogIdCommand(cli, argc, argv, [&](log_id_t log_id) {
-        cli->sendMsg(buf()->SetSize(log_id, size) ? "success" : "busy");
-    });
-}
-
-// This returns a string with a length prefix with the format <length>\n<data>\n\f.  The length
-// prefix includes the length of the prefix itself.
-static std::string PackageString(const std::string& str) {
-    size_t overhead_length = 3;  // \n \n \f.
-
-    // Number of digits needed to represent length(str + overhead_length).
-    size_t str_size_digits = 1 + static_cast<size_t>(log10(str.size() + overhead_length));
-    // Number of digits needed to represent the total size.
-    size_t total_size_digits =
-            1 + static_cast<size_t>(log10(str.size() + overhead_length + str_size_digits));
-
-    // If adding the size prefix causes a new digit to be required to represent the new total
-    // size, add it to the 'overhead_length'.  This can only happen once, since each new digit
-    // allows for 10x the previous size to be recorded.
-    if (total_size_digits != str_size_digits) {
-        overhead_length++;
-    }
-
-    size_t total_size = str.size() + overhead_length + str_size_digits;
-    return android::base::StringPrintf("%zu\n%s\n\f", total_size, str.c_str());
-}
-
-int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    setname();
-    uid_t uid = cli->getUid();
-    if (clientHasLogCredentials(cli)) {
-        uid = AID_ROOT;
-    }
-
-    unsigned int logMask = -1;
-    pid_t pid = 0;
-    if (argc > 1) {
-        logMask = 0;
-        for (int i = 1; i < argc; ++i) {
-            static const char _pid[] = "pid=";
-            if (!strncmp(argv[i], _pid, sizeof(_pid) - 1)) {
-                pid = atol(argv[i] + sizeof(_pid) - 1);
-                if (pid == 0) {
-                    cli->sendMsg("PID Error");
-                    return 0;
-                }
-                continue;
-            }
-
-            int id = atoi(argv[i]);
-            if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
-                cli->sendMsg("Range Error");
-                return 0;
-            }
-            logMask |= 1 << id;
-        }
-    }
-
-    cli->sendMsg(PackageString(stats()->Format(uid, pid, logMask)).c_str());
-    return 0;
-}
-
-int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli, int, char**) {
-    setname();
-    cli->sendMsg(PackageString(prune()->Format()).c_str());
-    return 0;
-}
-
-int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    setname();
-    if (!clientHasLogCredentials(cli)) {
-        cli->sendMsg("Permission Denied");
-        return 0;
-    }
-
-    std::string str;
-    for (int i = 1; i < argc; ++i) {
-        if (str.length()) {
-            str += " ";
-        }
-        str += argv[i];
-    }
-
-    if (!prune()->Init(str.c_str())) {
-        cli->sendMsg("Invalid");
-        return 0;
-    }
-
-    cli->sendMsg("success");
-    return 0;
-}
-
-int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc, char** argv) {
-    setname();
-    uid_t uid = cli->getUid();
-    if (clientHasLogCredentials(cli)) {
-        uid = AID_ROOT;
-    }
-
-    const char* name = nullptr;
-    const char* format = nullptr;
-    const char* id = nullptr;
-    for (int i = 1; i < argc; ++i) {
-        static const char _name[] = "name=";
-        if (!strncmp(argv[i], _name, strlen(_name))) {
-            name = argv[i] + strlen(_name);
-            continue;
-        }
-
-        static const char _format[] = "format=";
-        if (!strncmp(argv[i], _format, strlen(_format))) {
-            format = argv[i] + strlen(_format);
-            continue;
-        }
-
-        static const char _id[] = "id=";
-        if (!strncmp(argv[i], _id, strlen(_id))) {
-            id = argv[i] + strlen(_id);
-            continue;
-        }
-    }
-
-    if (id) {
-        if (format || name) {
-            cli->sendMsg("can not mix id= with either format= or name=");
-            return 0;
-        }
-        cli->sendMsg(PackageString(tags()->formatEntry(atoi(id), uid)).c_str());
-        return 0;
-    }
-
-    cli->sendMsg(PackageString(tags()->formatGetEventTag(uid, name, format)).c_str());
-
-    return 0;
-}
-
-int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int, char**) {
-    setname();
-
-    LOG(INFO) << "logd reinit";
-    buf()->Init();
-    prune()->Init(nullptr);
-
-    // This only works on userdebug and eng devices to re-read the
-    // /data/misc/logd/event-log-tags file right after /data is mounted.
-    // The operation is near to boot and should only happen once.  There
-    // are races associated with its use since it can trigger a Rebuild
-    // of the file, but that is a can-not-happen since the file was not
-    // read yet.  More dangerous if called later, but if all is well it
-    // should just skip over everything and not write any new entries.
-    if (__android_log_is_debuggable()) {
-        tags()->ReadFileEventLogTags(tags()->debug_event_log_tags);
-    }
-
-    cli->sendMsg("success");
-
-    return 0;
-}
-
-int CommandListener::ExitCmd::runCommand(SocketClient* cli, int, char**) {
-    setname();
-
-    cli->sendMsg("success");
-    parent_->release(cli);
-
-    return 0;
-}
-
-int CommandListener::getLogSocket() {
-    static const char socketName[] = "logd";
-    int sock = android_get_control_socket(socketName);
-
-    if (sock < 0) {
-        sock = socket_local_server(
-            socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
-    }
-
-    return sock;
-}
diff --git a/logd/CommandListener.h b/logd/CommandListener.h
deleted file mode 100644
index 8e12634..0000000
--- a/logd/CommandListener.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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.
- */
-
-#pragma once
-
-#include <sysutils/FrameworkCommand.h>
-#include <sysutils/FrameworkListener.h>
-
-#include "LogBuffer.h"
-#include "LogListener.h"
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "PruneList.h"
-
-class CommandListener : public FrameworkListener {
-  public:
-    CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune, LogStatistics* log_statistics);
-    virtual ~CommandListener() {}
-
-  private:
-    static int getLogSocket();
-
-    LogBuffer* buf_;
-    LogTags* tags_;
-    PruneList* prune_;
-    LogStatistics* stats_;
-
-#define LogCmd(name, command_string)                                \
-    class name##Cmd : public FrameworkCommand {                     \
-      public:                                                       \
-        explicit name##Cmd(CommandListener* parent)                 \
-            : FrameworkCommand(#command_string), parent_(parent) {} \
-        virtual ~name##Cmd() {}                                     \
-        int runCommand(SocketClient* c, int argc, char** argv);     \
-                                                                    \
-      private:                                                      \
-        LogBuffer* buf() const { return parent_->buf_; }            \
-        LogTags* tags() const { return parent_->tags_; }            \
-        PruneList* prune() const { return parent_->prune_; }        \
-        LogStatistics* stats() const { return parent_->stats_; }    \
-        CommandListener* parent_;                                   \
-    }
-
-    LogCmd(Clear, clear);
-    LogCmd(GetBufSize, getLogSize);
-    LogCmd(SetBufSize, setLogSize);
-    LogCmd(GetBufSizeReadable, getLogSizeReadable);
-    LogCmd(GetBufSizeUsed, getLogSizeUsed);
-    LogCmd(GetStatistics, getStatistics);
-    LogCmd(GetPruneList, getPruneList);
-    LogCmd(SetPruneList, setPruneList);
-    LogCmd(GetEventTag, getEventTag);
-    LogCmd(Reinit, reinit);
-    LogCmd(Exit, EXIT);
-#undef LogCmd
-};
diff --git a/logd/CompressionEngine.cpp b/logd/CompressionEngine.cpp
deleted file mode 100644
index da2628c..0000000
--- a/logd/CompressionEngine.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2020 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 "CompressionEngine.h"
-
-#include <limits>
-
-#include <android-base/logging.h>
-#include <zlib.h>
-#include <zstd.h>
-
-CompressionEngine& CompressionEngine::GetInstance() {
-    static CompressionEngine* engine = new ZstdCompressionEngine();
-    return *engine;
-}
-
-bool ZlibCompressionEngine::Compress(SerializedData& in, size_t data_length, SerializedData& out) {
-    z_stream strm;
-    strm.zalloc = Z_NULL;
-    strm.zfree = Z_NULL;
-    strm.opaque = Z_NULL;
-    int ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
-    if (ret != Z_OK) {
-        LOG(FATAL) << "deflateInit() failed";
-    }
-
-    CHECK_LE(data_length, in.size());
-    CHECK_LE(in.size(), std::numeric_limits<uint32_t>::max());
-    uint32_t deflate_bound = deflateBound(&strm, in.size());
-
-    out.Resize(deflate_bound);
-
-    strm.avail_in = data_length;
-    strm.next_in = in.data();
-    strm.avail_out = out.size();
-    strm.next_out = out.data();
-    ret = deflate(&strm, Z_FINISH);
-    CHECK_EQ(ret, Z_STREAM_END);
-
-    uint32_t compressed_size = strm.total_out;
-    deflateEnd(&strm);
-
-    out.Resize(compressed_size);
-
-    return true;
-}
-
-bool ZlibCompressionEngine::Decompress(SerializedData& in, SerializedData& out) {
-    z_stream strm;
-    strm.zalloc = Z_NULL;
-    strm.zfree = Z_NULL;
-    strm.opaque = Z_NULL;
-    strm.avail_in = in.size();
-    strm.next_in = in.data();
-    strm.avail_out = out.size();
-    strm.next_out = out.data();
-
-    inflateInit(&strm);
-    int ret = inflate(&strm, Z_NO_FLUSH);
-
-    CHECK_EQ(strm.avail_in, 0U);
-    CHECK_EQ(strm.avail_out, 0U);
-    CHECK_EQ(ret, Z_STREAM_END);
-    inflateEnd(&strm);
-
-    return true;
-}
-
-bool ZstdCompressionEngine::Compress(SerializedData& in, size_t data_length, SerializedData& out) {
-    CHECK_LE(data_length, in.size());
-
-    size_t compress_bound = ZSTD_compressBound(data_length);
-    out.Resize(compress_bound);
-
-    size_t out_size = ZSTD_compress(out.data(), out.size(), in.data(), data_length, 1);
-    if (ZSTD_isError(out_size)) {
-        LOG(FATAL) << "ZSTD_compress failed: " << ZSTD_getErrorName(out_size);
-    }
-    out.Resize(out_size);
-
-    return true;
-}
-
-bool ZstdCompressionEngine::Decompress(SerializedData& in, SerializedData& out) {
-    size_t result = ZSTD_decompress(out.data(), out.size(), in.data(), in.size());
-    if (ZSTD_isError(result)) {
-        LOG(FATAL) << "ZSTD_decompress failed: " << ZSTD_getErrorName(result);
-    }
-    CHECK_EQ(result, out.size());
-    return true;
-}
diff --git a/logd/CompressionEngine.h b/logd/CompressionEngine.h
deleted file mode 100644
index 0f760ed..0000000
--- a/logd/CompressionEngine.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <memory>
-
-#include "SerializedData.h"
-
-class CompressionEngine {
-  public:
-    static CompressionEngine& GetInstance();
-
-    virtual ~CompressionEngine(){};
-
-    virtual bool Compress(SerializedData& in, size_t data_length, SerializedData& out) = 0;
-    // Decompress the contents of `in` into `out`.  `out.size()` must be set to the decompressed
-    // size of the contents.
-    virtual bool Decompress(SerializedData& in, SerializedData& out) = 0;
-};
-
-class ZlibCompressionEngine : public CompressionEngine {
-  public:
-    bool Compress(SerializedData& in, size_t data_length, SerializedData& out) override;
-    bool Decompress(SerializedData& in, SerializedData& out) override;
-};
-
-class ZstdCompressionEngine : public CompressionEngine {
-  public:
-    bool Compress(SerializedData& in, size_t data_length, SerializedData& out) override;
-    bool Decompress(SerializedData& in, SerializedData& out) override;
-};
\ No newline at end of file
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
deleted file mode 100644
index 0e17476..0000000
--- a/logd/LogAudit.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2014 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 "LogAudit.h"
-
-#include <ctype.h>
-#include <endian.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/uio.h>
-#include <syslog.h>
-
-#include <fstream>
-#include <sstream>
-
-#include <android-base/macros.h>
-#include <android-base/properties.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include "LogKlog.h"
-#include "LogUtils.h"
-#include "libaudit.h"
-
-using android::base::GetBoolProperty;
-
-#define KMSG_PRIORITY(PRI)                               \
-    '<', '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) / 10, \
-        '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) % 10, '>'
-
-LogAudit::LogAudit(LogBuffer* buf, int fdDmesg, LogStatistics* stats)
-    : SocketListener(getLogSocket(), false),
-      logbuf(buf),
-      fdDmesg(fdDmesg),
-      main(GetBoolProperty("ro.logd.auditd.main", true)),
-      events(GetBoolProperty("ro.logd.auditd.events", true)),
-      initialized(false),
-      stats_(stats) {
-    static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO),
-                                           'l',
-                                           'o',
-                                           'g',
-                                           'd',
-                                           '.',
-                                           'a',
-                                           'u',
-                                           'd',
-                                           'i',
-                                           't',
-                                           'd',
-                                           ':',
-                                           ' ',
-                                           's',
-                                           't',
-                                           'a',
-                                           'r',
-                                           't',
-                                           '\n' };
-    write(fdDmesg, auditd_message, sizeof(auditd_message));
-}
-
-bool LogAudit::onDataAvailable(SocketClient* cli) {
-    if (!initialized) {
-        prctl(PR_SET_NAME, "logd.auditd");
-        initialized = true;
-    }
-
-    struct audit_message rep;
-
-    rep.nlh.nlmsg_type = 0;
-    rep.nlh.nlmsg_len = 0;
-    rep.data[0] = '\0';
-
-    if (audit_get_reply(cli->getSocket(), &rep, GET_REPLY_BLOCKING, 0) < 0) {
-        SLOGE("Failed on audit_get_reply with error: %s", strerror(errno));
-        return false;
-    }
-
-    logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data);
-
-    return true;
-}
-
-static inline bool hasMetadata(char* str, int str_len) {
-    // need to check and see if str already contains bug metadata from
-    // possibility of stuttering if log audit crashes and then reloads kernel
-    // messages. Kernel denials that contain metadata will either end in
-    // "b/[0-9]+$" or "b/[0-9]+  duplicate messages suppressed$" which will put
-    // a '/' character at either 9 or 39 indices away from the end of the str.
-    return str_len >= 39 &&
-           (str[str_len - 9] == '/' || str[str_len - 39] == '/');
-}
-
-std::map<std::string, std::string> LogAudit::populateDenialMap() {
-    std::ifstream bug_file("/vendor/etc/selinux/selinux_denial_metadata");
-    std::string line;
-    // allocate a map for the static map pointer in auditParse to keep track of,
-    // this function only runs once
-    std::map<std::string, std::string> denial_to_bug;
-    if (bug_file.good()) {
-        std::string scontext;
-        std::string tcontext;
-        std::string tclass;
-        std::string bug_num;
-        while (std::getline(bug_file, line)) {
-            std::stringstream split_line(line);
-            split_line >> scontext >> tcontext >> tclass >> bug_num;
-            denial_to_bug.emplace(scontext + tcontext + tclass, bug_num);
-        }
-    }
-    return denial_to_bug;
-}
-
-std::string LogAudit::denialParse(const std::string& denial, char terminator,
-                                  const std::string& search_term) {
-    size_t start_index = denial.find(search_term);
-    if (start_index != std::string::npos) {
-        start_index += search_term.length();
-        return denial.substr(
-            start_index, denial.find(terminator, start_index) - start_index);
-    }
-    return "";
-}
-
-void LogAudit::auditParse(const std::string& string, uid_t uid,
-                          std::string* bug_num) {
-    static std::map<std::string, std::string> denial_to_bug =
-        populateDenialMap();
-    std::string scontext = denialParse(string, ':', "scontext=u:object_r:");
-    std::string tcontext = denialParse(string, ':', "tcontext=u:object_r:");
-    std::string tclass = denialParse(string, ' ', "tclass=");
-    if (scontext.empty()) {
-        scontext = denialParse(string, ':', "scontext=u:r:");
-    }
-    if (tcontext.empty()) {
-        tcontext = denialParse(string, ':', "tcontext=u:r:");
-    }
-    auto search = denial_to_bug.find(scontext + tcontext + tclass);
-    if (search != denial_to_bug.end()) {
-        bug_num->assign(" " + search->second);
-    } else {
-        bug_num->assign("");
-    }
-
-    // Ensure the uid name is not null before passing it to the bug string.
-    if (uid >= AID_APP_START && uid <= AID_APP_END) {
-        char* uidname = android::uidToName(uid);
-        if (uidname) {
-            bug_num->append(" app=");
-            bug_num->append(uidname);
-            free(uidname);
-        }
-    }
-}
-
-int LogAudit::logPrint(const char* fmt, ...) {
-    if (fmt == nullptr) {
-        return -EINVAL;
-    }
-
-    va_list args;
-
-    char* str = nullptr;
-    va_start(args, fmt);
-    int rc = vasprintf(&str, fmt, args);
-    va_end(args);
-
-    if (rc < 0) {
-        return rc;
-    }
-    char* cp;
-    // Work around kernels missing
-    // https://github.com/torvalds/linux/commit/b8f89caafeb55fba75b74bea25adc4e4cd91be67
-    // Such kernels improperly add newlines inside audit messages.
-    while ((cp = strchr(str, '\n'))) {
-        *cp = ' ';
-    }
-
-    while ((cp = strstr(str, "  "))) {
-        memmove(cp, cp + 1, strlen(cp + 1) + 1);
-    }
-    pid_t pid = getpid();
-    pid_t tid = gettid();
-    uid_t uid = AID_LOGD;
-    static const char pid_str[] = " pid=";
-    char* pidptr = strstr(str, pid_str);
-    if (pidptr && isdigit(pidptr[sizeof(pid_str) - 1])) {
-        cp = pidptr + sizeof(pid_str) - 1;
-        pid = 0;
-        while (isdigit(*cp)) {
-            pid = (pid * 10) + (*cp - '0');
-            ++cp;
-        }
-        tid = pid;
-        uid = stats_->PidToUid(pid);
-        memmove(pidptr, cp, strlen(cp) + 1);
-    }
-
-    bool info = strstr(str, " permissive=1") || strstr(str, " policy loaded ");
-    static std::string denial_metadata;
-    if ((fdDmesg >= 0) && initialized) {
-        struct iovec iov[4];
-        static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) };
-        static const char log_warning[] = { KMSG_PRIORITY(LOG_WARNING) };
-        static const char newline[] = "\n";
-
-        auditParse(str, uid, &denial_metadata);
-        iov[0].iov_base = info ? const_cast<char*>(log_info) : const_cast<char*>(log_warning);
-        iov[0].iov_len = info ? sizeof(log_info) : sizeof(log_warning);
-        iov[1].iov_base = str;
-        iov[1].iov_len = strlen(str);
-        iov[2].iov_base = const_cast<char*>(denial_metadata.c_str());
-        iov[2].iov_len = denial_metadata.length();
-        iov[3].iov_base = const_cast<char*>(newline);
-        iov[3].iov_len = strlen(newline);
-
-        writev(fdDmesg, iov, arraysize(iov));
-    }
-
-    if (!main && !events) {
-        free(str);
-        return 0;
-    }
-
-    log_time now(log_time::EPOCH);
-
-    static const char audit_str[] = " audit(";
-    char* timeptr = strstr(str, audit_str);
-    if (timeptr && ((cp = now.strptime(timeptr + sizeof(audit_str) - 1, "%s.%q"))) &&
-        (*cp == ':')) {
-        memcpy(timeptr + sizeof(audit_str) - 1, "0.0", 3);
-        memmove(timeptr + sizeof(audit_str) - 1 + 3, cp, strlen(cp) + 1);
-    } else {
-        now = log_time(CLOCK_REALTIME);
-    }
-
-    // log to events
-
-    size_t str_len = strnlen(str, LOGGER_ENTRY_MAX_PAYLOAD);
-    if (((fdDmesg < 0) || !initialized) && !hasMetadata(str, str_len))
-        auditParse(str, uid, &denial_metadata);
-    str_len = (str_len + denial_metadata.length() <= LOGGER_ENTRY_MAX_PAYLOAD)
-                  ? str_len + denial_metadata.length()
-                  : LOGGER_ENTRY_MAX_PAYLOAD;
-    size_t message_len = str_len + sizeof(android_log_event_string_t);
-
-    unsigned int notify = 0;
-
-    if (events) {  // begin scope for event buffer
-        uint32_t buffer[(message_len + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
-
-        android_log_event_string_t* event =
-            reinterpret_cast<android_log_event_string_t*>(buffer);
-        event->header.tag = htole32(AUDITD_LOG_TAG);
-        event->type = EVENT_TYPE_STRING;
-        event->length = htole32(str_len);
-        memcpy(event->data, str, str_len - denial_metadata.length());
-        memcpy(event->data + str_len - denial_metadata.length(),
-               denial_metadata.c_str(), denial_metadata.length());
-
-        rc = logbuf->Log(LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
-                         (message_len <= UINT16_MAX) ? (uint16_t)message_len : UINT16_MAX);
-        if (rc >= 0) {
-            notify |= 1 << LOG_ID_EVENTS;
-        }
-        // end scope for event buffer
-    }
-
-    // log to main
-
-    static const char comm_str[] = " comm=\"";
-    const char* comm = strstr(str, comm_str);
-    const char* estr = str + strlen(str);
-    const char* commfree = nullptr;
-    if (comm) {
-        estr = comm;
-        comm += sizeof(comm_str) - 1;
-    } else if (pid == getpid()) {
-        pid = tid;
-        comm = "auditd";
-    } else {
-        comm = commfree = stats_->PidToName(pid);
-        if (!comm) {
-            comm = "unknown";
-        }
-    }
-
-    const char* ecomm = strchr(comm, '"');
-    if (ecomm) {
-        ++ecomm;
-        str_len = ecomm - comm;
-    } else {
-        str_len = strlen(comm) + 1;
-        ecomm = "";
-    }
-    size_t prefix_len = estr - str;
-    if (prefix_len > LOGGER_ENTRY_MAX_PAYLOAD) {
-        prefix_len = LOGGER_ENTRY_MAX_PAYLOAD;
-    }
-    size_t suffix_len = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - prefix_len);
-    message_len =
-        str_len + prefix_len + suffix_len + denial_metadata.length() + 2;
-
-    if (main) {  // begin scope for main buffer
-        char newstr[message_len];
-
-        *newstr = info ? ANDROID_LOG_INFO : ANDROID_LOG_WARN;
-        strlcpy(newstr + 1, comm, str_len);
-        strncpy(newstr + 1 + str_len, str, prefix_len);
-        strncpy(newstr + 1 + str_len + prefix_len, ecomm, suffix_len);
-        strncpy(newstr + 1 + str_len + prefix_len + suffix_len,
-                denial_metadata.c_str(), denial_metadata.length());
-
-        rc = logbuf->Log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
-                         (message_len <= UINT16_MAX) ? (uint16_t)message_len : UINT16_MAX);
-
-        if (rc >= 0) {
-            notify |= 1 << LOG_ID_MAIN;
-        }
-        // end scope for main buffer
-    }
-
-    free(const_cast<char*>(commfree));
-    free(str);
-
-    if (notify) {
-        if (rc < 0) {
-            rc = message_len;
-        }
-    }
-
-    return rc;
-}
-
-int LogAudit::log(char* buf, size_t len) {
-    char* audit = strstr(buf, " audit(");
-    if (!audit || (audit >= &buf[len])) {
-        return 0;
-    }
-
-    *audit = '\0';
-
-    int rc;
-    char* type = strstr(buf, "type=");
-    if (type && (type < &buf[len])) {
-        rc = logPrint("%s %s", type, audit + 1);
-    } else {
-        rc = logPrint("%s", audit + 1);
-    }
-    *audit = ' ';
-    return rc;
-}
-
-int LogAudit::getLogSocket() {
-    int fd = audit_open();
-    if (fd < 0) {
-        return fd;
-    }
-    if (audit_setup(fd, getpid()) < 0) {
-        audit_close(fd);
-        fd = -1;
-    }
-    return fd;
-}
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
deleted file mode 100644
index 181920e..0000000
--- a/logd/LogAudit.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma once
-
-#include <map>
-
-#include <sysutils/SocketListener.h>
-
-#include "LogBuffer.h"
-#include "LogStatistics.h"
-
-class LogAudit : public SocketListener {
-    LogBuffer* logbuf;
-    int fdDmesg;  // fdDmesg >= 0 is functionally bool dmesg
-    bool main;
-    bool events;
-    bool initialized;
-
-  public:
-    LogAudit(LogBuffer* buf, int fdDmesg, LogStatistics* stats);
-    int log(char* buf, size_t len);
-
-  protected:
-    virtual bool onDataAvailable(SocketClient* cli);
-
-  private:
-    static int getLogSocket();
-    std::map<std::string, std::string> populateDenialMap();
-    std::string denialParse(const std::string& denial, char terminator,
-                            const std::string& search_term);
-    void auditParse(const std::string& string, uid_t uid, std::string* bug_num);
-    int logPrint(const char* fmt, ...)
-        __attribute__((__format__(__printf__, 2, 3)));
-
-    LogStatistics* stats_;
-};
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
deleted file mode 100644
index a98c4b9..0000000
--- a/logd/LogBuffer.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <functional>
-
-#include <log/log.h>
-#include <log/log_read.h>
-
-#include "LogWriter.h"
-
-// A mask to represent which log buffers a reader is watching, values are (1 << LOG_ID_MAIN), etc.
-using LogMask = uint32_t;
-constexpr uint32_t kLogMaskAll = 0xFFFFFFFF;
-
-// State that a LogBuffer may want to persist across calls to FlushTo().
-class FlushToState {
-  public:
-    FlushToState(uint64_t start, LogMask log_mask) : start_(start), log_mask_(log_mask) {}
-    virtual ~FlushToState() {}
-
-    uint64_t start() const { return start_; }
-    void set_start(uint64_t start) { start_ = start; }
-
-    LogMask log_mask() const { return log_mask_; }
-
-  private:
-    uint64_t start_;
-    LogMask log_mask_;
-};
-
-// Enum for the return values of the `filter` function passed to FlushTo().
-enum class FilterResult {
-    kSkip,
-    kStop,
-    kWrite,
-};
-
-class LogBuffer {
-  public:
-    virtual ~LogBuffer() {}
-
-    virtual void Init() = 0;
-
-    virtual int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                    const char* msg, uint16_t len) = 0;
-
-    virtual std::unique_ptr<FlushToState> CreateFlushToState(uint64_t start, LogMask log_mask) = 0;
-    virtual bool FlushTo(
-            LogWriter* writer, FlushToState& state,
-            const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
-                                             log_time realtime)>& filter) = 0;
-
-    virtual bool Clear(log_id_t id, uid_t uid) = 0;
-    virtual size_t GetSize(log_id_t id) = 0;
-    virtual bool SetSize(log_id_t id, size_t size) = 0;
-
-    virtual uint64_t sequence() const = 0;
-};
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
deleted file mode 100644
index 26affa8..0000000
--- a/logd/LogBufferElement.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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 "LogBufferElement.h"
-
-#include <ctype.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <log/log_read.h>
-#include <private/android_logger.h>
-
-#include "LogStatistics.h"
-#include "LogUtils.h"
-
-LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
-                                   pid_t tid, uint64_t sequence, const char* msg, uint16_t len)
-    : uid_(uid),
-      pid_(pid),
-      tid_(tid),
-      sequence_(sequence),
-      realtime_(realtime),
-      msg_len_(len),
-      log_id_(log_id),
-      dropped_(false) {
-    msg_ = new char[len];
-    memcpy(msg_, msg, len);
-}
-
-LogBufferElement::LogBufferElement(const LogBufferElement& elem)
-    : uid_(elem.uid_),
-      pid_(elem.pid_),
-      tid_(elem.tid_),
-      sequence_(elem.sequence_),
-      realtime_(elem.realtime_),
-      msg_len_(elem.msg_len_),
-      log_id_(elem.log_id_),
-      dropped_(elem.dropped_) {
-    if (dropped_) {
-        tag_ = elem.GetTag();
-    } else {
-        msg_ = new char[msg_len_];
-        memcpy(msg_, elem.msg_, msg_len_);
-    }
-}
-
-LogBufferElement::LogBufferElement(LogBufferElement&& elem) noexcept
-    : uid_(elem.uid_),
-      pid_(elem.pid_),
-      tid_(elem.tid_),
-      sequence_(elem.sequence_),
-      realtime_(elem.realtime_),
-      msg_len_(elem.msg_len_),
-      log_id_(elem.log_id_),
-      dropped_(elem.dropped_) {
-    if (dropped_) {
-        tag_ = elem.GetTag();
-    } else {
-        msg_ = elem.msg_;
-        elem.msg_ = nullptr;
-    }
-}
-
-LogBufferElement::~LogBufferElement() {
-    if (!dropped_) {
-        delete[] msg_;
-    }
-}
-
-uint32_t LogBufferElement::GetTag() const {
-    // Binary buffers have no tag.
-    if (!IsBinary(log_id())) {
-        return 0;
-    }
-
-    // Dropped messages store the tag in place of msg_.
-    if (dropped_) {
-        return tag_;
-    }
-
-    return MsgToTag(msg(), msg_len());
-}
-
-LogStatisticsElement LogBufferElement::ToLogStatisticsElement() const {
-    // Estimate the size of this element in the parent std::list<> by adding two void*'s
-    // corresponding to the next/prev pointers and aligning to 64 bit.
-    uint16_t element_in_list_size =
-            (sizeof(*this) + 2 * sizeof(void*) + sizeof(uint64_t) - 1) & -sizeof(uint64_t);
-    return LogStatisticsElement{
-            .uid = uid(),
-            .pid = pid(),
-            .tid = tid(),
-            .tag = GetTag(),
-            .realtime = realtime(),
-            .msg = msg(),
-            .msg_len = msg_len(),
-            .dropped_count = dropped_count(),
-            .log_id = log_id(),
-            .total_len = static_cast<uint16_t>(element_in_list_size + msg_len()),
-    };
-}
-
-uint16_t LogBufferElement::SetDropped(uint16_t value) {
-    if (dropped_) {
-        return dropped_count_ = value;
-    }
-
-    // The tag information is saved in msg_ data, which is in a union with tag_, used after dropped_
-    // is set to true. Therefore we save the tag value aside, delete msg_, then set tag_ to the tag
-    // value in its place.
-    auto old_tag = GetTag();
-    delete[] msg_;
-    msg_ = nullptr;
-
-    tag_ = old_tag;
-    dropped_ = true;
-    return dropped_count_ = value;
-}
-
-// caller must own and free character string
-char* android::tidToName(pid_t tid) {
-    char* retval = nullptr;
-    char buffer[256];
-    snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid);
-    int fd = open(buffer, O_RDONLY | O_CLOEXEC);
-    if (fd >= 0) {
-        ssize_t ret = read(fd, buffer, sizeof(buffer));
-        if (ret >= (ssize_t)sizeof(buffer)) {
-            ret = sizeof(buffer) - 1;
-        }
-        while ((ret > 0) && isspace(buffer[ret - 1])) {
-            --ret;
-        }
-        if (ret > 0) {
-            buffer[ret] = '\0';
-            retval = strdup(buffer);
-        }
-        close(fd);
-    }
-
-    // if nothing for comm, check out cmdline
-    char* name = android::pidToName(tid);
-    if (!retval) {
-        retval = name;
-        name = nullptr;
-    }
-
-    // check if comm is truncated, see if cmdline has full representation
-    if (name) {
-        // impossible for retval to be NULL if name not NULL
-        size_t retval_len = strlen(retval);
-        size_t name_len = strlen(name);
-        // KISS: ToDo: Only checks prefix truncated, not suffix, or both
-        if ((retval_len < name_len) &&
-            !fastcmp<strcmp>(retval, name + name_len - retval_len)) {
-            free(retval);
-            retval = name;
-        } else {
-            free(name);
-        }
-    }
-    return retval;
-}
-
-// assumption: msg_ == NULL
-size_t LogBufferElement::PopulateDroppedMessage(char*& buffer, LogStatistics* stats,
-                                                bool lastSame) {
-    static const char tag[] = "chatty";
-
-    if (!__android_log_is_loggable_len(ANDROID_LOG_INFO, tag, strlen(tag),
-                                       ANDROID_LOG_VERBOSE)) {
-        return 0;
-    }
-
-    static const char format_uid[] = "uid=%u%s%s %s %u line%s";
-    const char* name = stats->UidToName(uid_);
-    const char* commName = android::tidToName(tid_);
-    if (!commName && (tid_ != pid_)) {
-        commName = android::tidToName(pid_);
-    }
-    if (!commName) {
-        commName = stats->PidToName(pid_);
-    }
-    if (name && name[0] && commName && (name[0] == commName[0])) {
-        size_t len = strlen(name + 1);
-        if (!strncmp(name + 1, commName + 1, len)) {
-            if (commName[len + 1] == '\0') {
-                free(const_cast<char*>(commName));
-                commName = nullptr;
-            } else {
-                free(const_cast<char*>(name));
-                name = nullptr;
-            }
-        }
-    }
-    if (name) {
-        char* buf = nullptr;
-        int result = asprintf(&buf, "(%s)", name);
-        if (result != -1) {
-            free(const_cast<char*>(name));
-            name = buf;
-        }
-    }
-    if (commName) {
-        char* buf = nullptr;
-        int result = asprintf(&buf, " %s", commName);
-        if (result != -1) {
-            free(const_cast<char*>(commName));
-            commName = buf;
-        }
-    }
-    // identical to below to calculate the buffer size required
-    const char* type = lastSame ? "identical" : "expire";
-    size_t len = snprintf(nullptr, 0, format_uid, uid_, name ? name : "", commName ? commName : "",
-                          type, dropped_count(), (dropped_count() > 1) ? "s" : "");
-
-    size_t hdrLen;
-    if (IsBinary(log_id())) {
-        hdrLen = sizeof(android_log_event_string_t);
-    } else {
-        hdrLen = 1 + sizeof(tag);
-    }
-
-    buffer = static_cast<char*>(calloc(1, hdrLen + len + 1));
-    if (!buffer) {
-        free(const_cast<char*>(name));
-        free(const_cast<char*>(commName));
-        return 0;
-    }
-
-    size_t retval = hdrLen + len;
-    if (IsBinary(log_id())) {
-        android_log_event_string_t* event =
-            reinterpret_cast<android_log_event_string_t*>(buffer);
-
-        event->header.tag = htole32(CHATTY_LOG_TAG);
-        event->type = EVENT_TYPE_STRING;
-        event->length = htole32(len);
-    } else {
-        ++retval;
-        buffer[0] = ANDROID_LOG_INFO;
-        strcpy(buffer + 1, tag);
-    }
-
-    snprintf(buffer + hdrLen, len + 1, format_uid, uid_, name ? name : "", commName ? commName : "",
-             type, dropped_count(), (dropped_count() > 1) ? "s" : "");
-    free(const_cast<char*>(name));
-    free(const_cast<char*>(commName));
-
-    return retval;
-}
-
-bool LogBufferElement::FlushTo(LogWriter* writer, LogStatistics* stats, bool lastSame) {
-    struct logger_entry entry = {};
-
-    entry.hdr_size = sizeof(struct logger_entry);
-    entry.lid = log_id_;
-    entry.pid = pid_;
-    entry.tid = tid_;
-    entry.uid = uid_;
-    entry.sec = realtime_.tv_sec;
-    entry.nsec = realtime_.tv_nsec;
-
-    char* buffer = nullptr;
-    const char* msg;
-    if (dropped_) {
-        entry.len = PopulateDroppedMessage(buffer, stats, lastSame);
-        if (!entry.len) return true;
-        msg = buffer;
-    } else {
-        msg = msg_;
-        entry.len = msg_len_;
-    }
-
-    bool retval = writer->Write(entry, msg);
-
-    if (buffer) free(buffer);
-
-    return retval;
-}
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
deleted file mode 100644
index b263ca5..0000000
--- a/logd/LogBufferElement.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include <log/log.h>
-
-#include "LogWriter.h"
-
-#include "LogStatistics.h"
-
-#define EXPIRE_HOUR_THRESHOLD 24  // Only expire chatty UID logs to preserve
-                                  // non-chatty UIDs less than this age in hours
-#define EXPIRE_THRESHOLD 10       // A smaller expire count is considered too
-                                  // chatty for the temporal expire messages
-#define EXPIRE_RATELIMIT 10  // maximum rate in seconds to report expiration
-
-class __attribute__((packed)) LogBufferElement {
-  public:
-    LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                     uint64_t sequence, const char* msg, uint16_t len);
-    LogBufferElement(const LogBufferElement& elem);
-    LogBufferElement(LogBufferElement&& elem) noexcept;
-    ~LogBufferElement();
-
-    uint32_t GetTag() const;
-    uint16_t SetDropped(uint16_t value);
-
-    bool FlushTo(LogWriter* writer, LogStatistics* parent, bool lastSame);
-
-    LogStatisticsElement ToLogStatisticsElement() const;
-
-    log_id_t log_id() const { return static_cast<log_id_t>(log_id_); }
-    uid_t uid() const { return uid_; }
-    pid_t pid() const { return pid_; }
-    pid_t tid() const { return tid_; }
-    uint16_t msg_len() const { return dropped_ ? 0 : msg_len_; }
-    const char* msg() const { return dropped_ ? nullptr : msg_; }
-    uint64_t sequence() const { return sequence_; }
-    log_time realtime() const { return realtime_; }
-    uint16_t dropped_count() const { return dropped_ ? dropped_count_ : 0; }
-
-  private:
-    // assumption: mDropped == true
-    size_t PopulateDroppedMessage(char*& buffer, LogStatistics* parent, bool lastSame);
-
-    // sized to match reality of incoming log packets
-    const uint32_t uid_;
-    const uint32_t pid_;
-    const uint32_t tid_;
-    uint64_t sequence_;
-    log_time realtime_;
-    union {
-        char* msg_;    // mDropped == false
-        int32_t tag_;  // mDropped == true
-    };
-    union {
-        const uint16_t msg_len_;  // mDropped == false
-        uint16_t dropped_count_;  // mDropped == true
-    };
-    const uint8_t log_id_;
-    bool dropped_;
-};
diff --git a/logd/LogBufferTest.cpp b/logd/LogBufferTest.cpp
deleted file mode 100644
index 1911105..0000000
--- a/logd/LogBufferTest.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2020 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 "LogBufferTest.h"
-
-#include <unistd.h>
-
-#include <limits>
-#include <memory>
-#include <regex>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "LogBuffer.h"
-#include "LogReaderThread.h"
-#include "LogWriter.h"
-
-using android::base::Join;
-using android::base::Split;
-using android::base::StringPrintf;
-
-char* android::uidToName(uid_t) {
-    return nullptr;
-}
-
-static std::vector<std::string> CompareLoggerEntries(const logger_entry& expected,
-                                                     const logger_entry& result, bool ignore_len) {
-    std::vector<std::string> errors;
-    if (!ignore_len && expected.len != result.len) {
-        errors.emplace_back(
-                StringPrintf("len: expected %" PRIu16 " vs %" PRIu16, expected.len, result.len));
-    }
-    if (expected.hdr_size != result.hdr_size) {
-        errors.emplace_back(StringPrintf("hdr_size: %" PRIu16 " vs %" PRIu16, expected.hdr_size,
-                                         result.hdr_size));
-    }
-    if (expected.pid != result.pid) {
-        errors.emplace_back(
-                StringPrintf("pid: expected %" PRIi32 " vs %" PRIi32, expected.pid, result.pid));
-    }
-    if (expected.tid != result.tid) {
-        errors.emplace_back(
-                StringPrintf("tid: expected %" PRIu32 " vs %" PRIu32, expected.tid, result.tid));
-    }
-    if (expected.sec != result.sec) {
-        errors.emplace_back(
-                StringPrintf("sec: expected %" PRIu32 " vs %" PRIu32, expected.sec, result.sec));
-    }
-    if (expected.nsec != result.nsec) {
-        errors.emplace_back(
-                StringPrintf("nsec: expected %" PRIu32 " vs %" PRIu32, expected.nsec, result.nsec));
-    }
-    if (expected.lid != result.lid) {
-        errors.emplace_back(
-                StringPrintf("lid: expected %" PRIu32 " vs %" PRIu32, expected.lid, result.lid));
-    }
-    if (expected.uid != result.uid) {
-        errors.emplace_back(
-                StringPrintf("uid: expected %" PRIu32 " vs %" PRIu32, expected.uid, result.uid));
-    }
-    return errors;
-}
-
-static std::string MakePrintable(std::string in) {
-    if (in.size() > 80) {
-        in = in.substr(0, 80) + "...";
-    }
-    std::string result;
-    for (const char c : in) {
-        if (isprint(c)) {
-            result.push_back(c);
-        } else {
-            result.append(StringPrintf("\\%02x", static_cast<int>(c) & 0xFF));
-        }
-    }
-    return result;
-}
-
-static std::string CompareMessages(const std::string& expected, const std::string& result) {
-    if (expected == result) {
-        return {};
-    }
-    size_t diff_index = 0;
-    for (; diff_index < std::min(expected.size(), result.size()); ++diff_index) {
-        if (expected[diff_index] != result[diff_index]) {
-            break;
-        }
-    }
-
-    if (diff_index < 80) {
-        auto expected_short = MakePrintable(expected);
-        auto result_short = MakePrintable(result);
-        return StringPrintf("msg: expected '%s' vs '%s'", expected_short.c_str(),
-                            result_short.c_str());
-    }
-
-    auto expected_short = MakePrintable(expected.substr(diff_index));
-    auto result_short = MakePrintable(result.substr(diff_index));
-    return StringPrintf("msg: index %zu: expected '%s' vs '%s'", diff_index, expected_short.c_str(),
-                        result_short.c_str());
-}
-
-static std::string CompareRegexMessages(const std::string& expected, const std::string& result) {
-    auto expected_pieces = Split(expected, std::string("\0", 1));
-    auto result_pieces = Split(result, std::string("\0", 1));
-
-    if (expected_pieces.size() != 3 || result_pieces.size() != 3) {
-        return StringPrintf(
-                "msg: should have 3 null delimited strings found %d in expected, %d in result: "
-                "'%s' vs '%s'",
-                static_cast<int>(expected_pieces.size()), static_cast<int>(result_pieces.size()),
-                MakePrintable(expected).c_str(), MakePrintable(result).c_str());
-    }
-    if (expected_pieces[0] != result_pieces[0]) {
-        return StringPrintf("msg: tag/priority mismatch expected '%s' vs '%s'",
-                            MakePrintable(expected_pieces[0]).c_str(),
-                            MakePrintable(result_pieces[0]).c_str());
-    }
-    std::regex expected_tag_regex(expected_pieces[1]);
-    if (!std::regex_search(result_pieces[1], expected_tag_regex)) {
-        return StringPrintf("msg: message regex mismatch expected '%s' vs '%s'",
-                            MakePrintable(expected_pieces[1]).c_str(),
-                            MakePrintable(result_pieces[1]).c_str());
-    }
-    if (expected_pieces[2] != result_pieces[2]) {
-        return StringPrintf("msg: nothing expected after final null character '%s' vs '%s'",
-                            MakePrintable(expected_pieces[2]).c_str(),
-                            MakePrintable(result_pieces[2]).c_str());
-    }
-    return {};
-}
-
-void CompareLogMessages(const std::vector<LogMessage>& expected,
-                        const std::vector<LogMessage>& result) {
-    EXPECT_EQ(expected.size(), result.size());
-    size_t end = std::min(expected.size(), result.size());
-    size_t num_errors = 0;
-    for (size_t i = 0; i < end; ++i) {
-        auto errors =
-                CompareLoggerEntries(expected[i].entry, result[i].entry, expected[i].regex_compare);
-        auto msg_error = expected[i].regex_compare
-                                 ? CompareRegexMessages(expected[i].message, result[i].message)
-                                 : CompareMessages(expected[i].message, result[i].message);
-        if (!msg_error.empty()) {
-            errors.emplace_back(msg_error);
-        }
-        if (!errors.empty()) {
-            GTEST_LOG_(ERROR) << "Mismatch log message " << i << "\n" << Join(errors, "\n");
-            ++num_errors;
-        }
-    }
-    EXPECT_EQ(0U, num_errors);
-}
-
-void FixupMessages(std::vector<LogMessage>* messages) {
-    for (auto& [entry, message, _] : *messages) {
-        entry.hdr_size = sizeof(logger_entry);
-        entry.len = message.size();
-    }
-}
-
-TEST_P(LogBufferTest, smoke) {
-    std::vector<LogMessage> log_messages = {
-            {{
-                     .pid = 1,
-                     .tid = 1,
-                     .sec = 1234,
-                     .nsec = 323001,
-                     .lid = LOG_ID_MAIN,
-                     .uid = 0,
-             },
-             "smoke test"},
-    };
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, nullptr));
-    std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, kLogMaskAll);
-    EXPECT_TRUE(log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr));
-    EXPECT_EQ(2ULL, flush_to_state->start());
-    CompareLogMessages(log_messages, read_log_messages);
-}
-
-TEST_P(LogBufferTest, smoke_with_reader_thread) {
-    std::vector<LogMessage> log_messages = {
-            {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
-             "first"},
-            {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
-             "second"},
-            {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_KERNEL, .uid = 0},
-             "third"},
-            {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20004, .lid = LOG_ID_MAIN, .uid = 0},
-             "fourth"},
-            {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20005, .lid = LOG_ID_RADIO, .uid = 0},
-             "fifth"},
-            {{.pid = 2, .tid = 2, .sec = 10000, .nsec = 20006, .lid = LOG_ID_RADIO, .uid = 0},
-             "sixth"},
-            {{.pid = 3, .tid = 2, .sec = 10000, .nsec = 20007, .lid = LOG_ID_RADIO, .uid = 0},
-             "seventh"},
-            {{.pid = 4, .tid = 2, .sec = 10000, .nsec = 20008, .lid = LOG_ID_MAIN, .uid = 0},
-             "eighth"},
-            {{.pid = 5, .tid = 2, .sec = 10000, .nsec = 20009, .lid = LOG_ID_CRASH, .uid = 0},
-             "nineth"},
-            {{.pid = 6, .tid = 2, .sec = 10000, .nsec = 20011, .lid = LOG_ID_MAIN, .uid = 0},
-             "tenth"},
-    };
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    bool released = false;
-
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released));
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true,
-                                    0, kLogMaskAll, 0, {}, 1, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    while (!released) {
-        usleep(5000);
-    }
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        EXPECT_EQ(0U, reader_list_.reader_threads().size());
-    }
-    CompareLogMessages(log_messages, read_log_messages);
-}
-
-// Generate random messages, set the 'sec' parameter explicit though, to be able to track the
-// expected order of messages.
-LogMessage GenerateRandomLogMessage(uint32_t sec) {
-    auto rand_uint32 = [](int max) -> uint32_t { return rand() % max; };
-    logger_entry entry = {
-            .hdr_size = sizeof(logger_entry),
-            .pid = rand() % 5000,
-            .tid = rand_uint32(5000),
-            .sec = sec,
-            .nsec = rand_uint32(NS_PER_SEC),
-            .lid = rand_uint32(LOG_ID_STATS),
-            .uid = rand_uint32(100000),
-    };
-
-    // See comment in ChattyLogBuffer::Log() for why this is disallowed.
-    if (entry.nsec % 1000 == 0) {
-        ++entry.nsec;
-    }
-
-    if (entry.lid == LOG_ID_EVENTS) {
-        entry.lid = LOG_ID_KERNEL;
-    }
-
-    std::string message;
-    char priority = ANDROID_LOG_INFO + rand() % 2;
-    message.push_back(priority);
-
-    int tag_length = 2 + rand() % 10;
-    for (int i = 0; i < tag_length; ++i) {
-        message.push_back('a' + rand() % 26);
-    }
-    message.push_back('\0');
-
-    int msg_length = 2 + rand() % 1000;
-    for (int i = 0; i < msg_length; ++i) {
-        message.push_back('a' + rand() % 26);
-    }
-    message.push_back('\0');
-
-    entry.len = message.size();
-
-    return {entry, message};
-}
-
-TEST_P(LogBufferTest, random_messages) {
-    srand(1);
-    std::vector<LogMessage> log_messages;
-    for (size_t i = 0; i < 1000; ++i) {
-        log_messages.emplace_back(GenerateRandomLogMessage(i));
-    }
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    bool released = false;
-
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released));
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true,
-                                    0, kLogMaskAll, 0, {}, 1, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    while (!released) {
-        usleep(5000);
-    }
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        EXPECT_EQ(0U, reader_list_.reader_threads().size());
-    }
-    CompareLogMessages(log_messages, read_log_messages);
-}
-
-TEST_P(LogBufferTest, read_last_sequence) {
-    std::vector<LogMessage> log_messages = {
-            {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
-             "first"},
-            {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
-             "second"},
-            {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
-             "third"},
-    };
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    bool released = false;
-
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released));
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true,
-                                    0, kLogMaskAll, 0, {}, 3, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    while (!released) {
-        usleep(5000);
-    }
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        EXPECT_EQ(0U, reader_list_.reader_threads().size());
-    }
-    std::vector<LogMessage> expected_log_messages = {log_messages.back()};
-    CompareLogMessages(expected_log_messages, read_log_messages);
-}
-
-TEST_P(LogBufferTest, clear_logs) {
-    // Log 3 initial logs.
-    std::vector<LogMessage> log_messages = {
-            {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
-             "first"},
-            {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
-             "second"},
-            {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
-             "third"},
-    };
-    FixupMessages(&log_messages);
-    LogMessages(log_messages);
-
-    std::vector<LogMessage> read_log_messages;
-    bool released = false;
-
-    // Connect a blocking reader.
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released));
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), false,
-                                    0, kLogMaskAll, 0, {}, 1, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    // Wait up to 250ms for the reader to read the first 3 logs.
-    constexpr int kMaxRetryCount = 50;
-    int count = 0;
-    for (; count < kMaxRetryCount; ++count) {
-        usleep(5000);
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        if (reader_list_.reader_threads().back()->start() == 4) {
-            break;
-        }
-    }
-    ASSERT_LT(count, kMaxRetryCount);
-
-    // Clear the log buffer.
-    log_buffer_->Clear(LOG_ID_MAIN, 0);
-
-    // Log 3 more logs.
-    std::vector<LogMessage> after_clear_messages = {
-            {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
-             "4th"},
-            {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
-             "5th"},
-            {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
-             "6th"},
-    };
-    FixupMessages(&after_clear_messages);
-    LogMessages(after_clear_messages);
-
-    // Wait up to 250ms for the reader to read the 3 additional logs.
-    for (count = 0; count < kMaxRetryCount; ++count) {
-        usleep(5000);
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        if (reader_list_.reader_threads().back()->start() == 7) {
-            break;
-        }
-    }
-    ASSERT_LT(count, kMaxRetryCount);
-
-    // Release the reader, wait for it to get the signal then check that it has been deleted.
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        reader_list_.reader_threads().back()->release_Locked();
-    }
-    while (!released) {
-        usleep(5000);
-    }
-    {
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        EXPECT_EQ(0U, reader_list_.reader_threads().size());
-    }
-
-    // Check that we have read all 6 messages.
-    std::vector<LogMessage> expected_log_messages = log_messages;
-    expected_log_messages.insert(expected_log_messages.end(), after_clear_messages.begin(),
-                                 after_clear_messages.end());
-    CompareLogMessages(expected_log_messages, read_log_messages);
-
-    // Finally, call FlushTo and ensure that only the 3 logs after the clear remain in the buffer.
-    std::vector<LogMessage> read_log_messages_after_clear;
-    std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages_after_clear, nullptr));
-    std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, kLogMaskAll);
-    EXPECT_TRUE(log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr));
-    EXPECT_EQ(7ULL, flush_to_state->start());
-    CompareLogMessages(after_clear_messages, read_log_messages_after_clear);
-}
-
-INSTANTIATE_TEST_CASE_P(LogBufferTests, LogBufferTest,
-                        testing::Values("chatty", "serialized", "simple"));
diff --git a/logd/LogBufferTest.h b/logd/LogBufferTest.h
deleted file mode 100644
index eeeb980..0000000
--- a/logd/LogBufferTest.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "ChattyLogBuffer.h"
-#include "LogReaderList.h"
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "PruneList.h"
-#include "SerializedLogBuffer.h"
-#include "SimpleLogBuffer.h"
-
-struct LogMessage {
-    logger_entry entry;
-    std::string message;
-    bool regex_compare = false;  // Only set for expected messages, when true 'message' should be
-                                 // interpretted as a regex.
-};
-
-// Compares the ordered list of expected and result, causing a test failure with appropriate
-// information on failure.
-void CompareLogMessages(const std::vector<LogMessage>& expected,
-                        const std::vector<LogMessage>& result);
-// Sets hdr_size and len parameters appropriately.
-void FixupMessages(std::vector<LogMessage>* messages);
-
-class TestWriter : public LogWriter {
-  public:
-    TestWriter(std::vector<LogMessage>* msgs, bool* released)
-        : LogWriter(0, true), msgs_(msgs), released_(released) {}
-    bool Write(const logger_entry& entry, const char* message) override {
-        msgs_->emplace_back(LogMessage{entry, std::string(message, entry.len), false});
-        return true;
-    }
-
-    void Release() {
-        if (released_) *released_ = true;
-    }
-
-    std::string name() const override { return "test_writer"; }
-
-  private:
-    std::vector<LogMessage>* msgs_;
-    bool* released_;
-};
-
-class LogBufferTest : public testing::TestWithParam<std::string> {
-  protected:
-    void SetUp() override {
-        if (GetParam() == "chatty") {
-            log_buffer_.reset(new ChattyLogBuffer(&reader_list_, &tags_, &prune_, &stats_));
-        } else if (GetParam() == "serialized") {
-            log_buffer_.reset(new SerializedLogBuffer(&reader_list_, &tags_, &stats_));
-        } else if (GetParam() == "simple") {
-            log_buffer_.reset(new SimpleLogBuffer(&reader_list_, &tags_, &stats_));
-        } else {
-            FAIL() << "Unknown buffer type selected for test";
-        }
-
-        log_id_for_each(i) { log_buffer_->SetSize(i, 1024 * 1024); }
-    }
-
-    void LogMessages(const std::vector<LogMessage>& messages) {
-        for (auto& [entry, message, _] : messages) {
-            log_buffer_->Log(static_cast<log_id_t>(entry.lid), log_time(entry.sec, entry.nsec),
-                             entry.uid, entry.pid, entry.tid, message.c_str(), message.size());
-        }
-    }
-
-    LogReaderList reader_list_;
-    LogTags tags_;
-    PruneList prune_;
-    LogStatistics stats_{false, true};
-    std::unique_ptr<LogBuffer> log_buffer_;
-};
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
deleted file mode 100644
index d6c7d25..0000000
--- a/logd/LogKlog.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * Copyright (C) 2014 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 "LogKlog.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/uio.h>
-#include <syslog.h>
-
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include "LogBuffer.h"
-
-#define KMSG_PRIORITY(PRI) \
-    '<', '0' + (LOG_SYSLOG | (PRI)) / 10, '0' + (LOG_SYSLOG | (PRI)) % 10, '>'
-
-static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' };
-
-// List of the _only_ needles we supply here to android::strnstr
-static const char suspendStr[] = "PM: suspend entry ";
-static const char resumeStr[] = "PM: suspend exit ";
-static const char suspendedStr[] = "Suspended for ";
-static const char healthdStr[] = "healthd";
-static const char batteryStr[] = ": battery ";
-static const char auditStr[] = " audit(";
-static const char klogdStr[] = "logd.klogd: ";
-
-// Parsing is hard
-
-// called if we see a '<', s is the next character, returns pointer after '>'
-static char* is_prio(char* s, ssize_t len) {
-    if ((len <= 0) || !isdigit(*s++)) return nullptr;
-    --len;
-    static const size_t max_prio_len = (len < 4) ? len : 4;
-    size_t priolen = 0;
-    char c;
-    while (((c = *s++)) && (++priolen <= max_prio_len)) {
-        if (!isdigit(c)) return ((c == '>') && (*s == '[')) ? s : nullptr;
-    }
-    return nullptr;
-}
-
-// called if we see a '[', s is the next character, returns pointer after ']'
-static char* is_timestamp(char* s, ssize_t len) {
-    while ((len > 0) && (*s == ' ')) {
-        ++s;
-        --len;
-    }
-    if ((len <= 0) || !isdigit(*s++)) return nullptr;
-    --len;
-    bool first_period = true;
-    char c;
-    while ((len > 0) && ((c = *s++))) {
-        --len;
-        if ((c == '.') && first_period) {
-            first_period = false;
-        } else if (!isdigit(c)) {
-            return ((c == ']') && !first_period && (*s == ' ')) ? s : nullptr;
-        }
-    }
-    return nullptr;
-}
-
-// Like strtok_r with "\r\n" except that we look for log signatures (regex)
-//  \(\(<[0-9]\{1,4\}>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[]
-//  *[0-9]+[.][0-9]+[]] \)
-// and split if we see a second one without a newline.
-// We allow nuls in content, monitoring the overall length and sub-length of
-// the discovered tokens.
-
-#define SIGNATURE_MASK 0xF0
-// <digit> following ('0' to '9' masked with ~SIGNATURE_MASK) added to signature
-#define LESS_THAN_SIG SIGNATURE_MASK
-#define OPEN_BRACKET_SIG ((SIGNATURE_MASK << 1) & SIGNATURE_MASK)
-// space is one more than <digit> of 9
-#define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10))
-
-char* android::log_strntok_r(char* s, ssize_t& len, char*& last,
-                             ssize_t& sublen) {
-    sublen = 0;
-    if (len <= 0) return nullptr;
-    if (!s) {
-        if (!(s = last)) return nullptr;
-        // fixup for log signature split <,
-        // LESS_THAN_SIG + <digit>
-        if ((*s & SIGNATURE_MASK) == LESS_THAN_SIG) {
-            *s = (*s & ~SIGNATURE_MASK) + '0';
-            *--s = '<';
-            ++len;
-        }
-        // fixup for log signature split [,
-        // OPEN_BRACKET_SPACE is space, OPEN_BRACKET_SIG + <digit>
-        if ((*s & SIGNATURE_MASK) == OPEN_BRACKET_SIG) {
-            *s = (*s == OPEN_BRACKET_SPACE) ? ' ' : (*s & ~SIGNATURE_MASK) + '0';
-            *--s = '[';
-            ++len;
-        }
-    }
-
-    while ((len > 0) && ((*s == '\r') || (*s == '\n'))) {
-        ++s;
-        --len;
-    }
-
-    if (len <= 0) return last = nullptr;
-    char *peek, *tok = s;
-
-    for (;;) {
-        if (len <= 0) {
-            last = nullptr;
-            return tok;
-        }
-        char c = *s++;
-        --len;
-        ssize_t adjust;
-        switch (c) {
-            case '\r':
-            case '\n':
-                s[-1] = '\0';
-                last = s;
-                return tok;
-
-            case '<':
-                peek = is_prio(s, len);
-                if (!peek) break;
-                if (s != (tok + 1)) {  // not first?
-                    s[-1] = '\0';
-                    *s &= ~SIGNATURE_MASK;
-                    *s |= LESS_THAN_SIG;  // signature for '<'
-                    last = s;
-                    return tok;
-                }
-                adjust = peek - s;
-                if (adjust > len) {
-                    adjust = len;
-                }
-                sublen += adjust;
-                len -= adjust;
-                s = peek;
-                if ((*s == '[') && ((peek = is_timestamp(s + 1, len - 1)))) {
-                    adjust = peek - s;
-                    if (adjust > len) {
-                        adjust = len;
-                    }
-                    sublen += adjust;
-                    len -= adjust;
-                    s = peek;
-                }
-                break;
-
-            case '[':
-                peek = is_timestamp(s, len);
-                if (!peek) break;
-                if (s != (tok + 1)) {  // not first?
-                    s[-1] = '\0';
-                    if (*s == ' ') {
-                        *s = OPEN_BRACKET_SPACE;
-                    } else {
-                        *s &= ~SIGNATURE_MASK;
-                        *s |= OPEN_BRACKET_SIG;  // signature for '['
-                    }
-                    last = s;
-                    return tok;
-                }
-                adjust = peek - s;
-                if (adjust > len) {
-                    adjust = len;
-                }
-                sublen += adjust;
-                len -= adjust;
-                s = peek;
-                break;
-        }
-        ++sublen;
-    }
-    // NOTREACHED
-}
-
-log_time LogKlog::correction = (log_time(CLOCK_REALTIME) < log_time(CLOCK_MONOTONIC))
-                                       ? log_time(log_time::EPOCH)
-                                       : (log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC));
-
-LogKlog::LogKlog(LogBuffer* buf, int fdWrite, int fdRead, bool auditd, LogStatistics* stats)
-    : SocketListener(fdRead, false),
-      logbuf(buf),
-      signature(CLOCK_MONOTONIC),
-      initialized(false),
-      enableLogging(true),
-      auditd(auditd),
-      stats_(stats) {
-    static const char klogd_message[] = "%s%s%" PRIu64 "\n";
-    char buffer[strlen(priority_message) + strlen(klogdStr) +
-                strlen(klogd_message) + 20];
-    snprintf(buffer, sizeof(buffer), klogd_message, priority_message, klogdStr,
-             signature.nsec());
-    write(fdWrite, buffer, strlen(buffer));
-}
-
-bool LogKlog::onDataAvailable(SocketClient* cli) {
-    if (!initialized) {
-        prctl(PR_SET_NAME, "logd.klogd");
-        initialized = true;
-        enableLogging = false;
-    }
-
-    char buffer[LOGGER_ENTRY_MAX_PAYLOAD];
-    ssize_t len = 0;
-
-    for (;;) {
-        ssize_t retval = 0;
-        if (len < (ssize_t)(sizeof(buffer) - 1)) {
-            retval =
-                read(cli->getSocket(), buffer + len, sizeof(buffer) - 1 - len);
-        }
-        if ((retval == 0) && (len <= 0)) {
-            break;
-        }
-        if (retval < 0) {
-            return false;
-        }
-        len += retval;
-        bool full = len == (sizeof(buffer) - 1);
-        char* ep = buffer + len;
-        *ep = '\0';
-        ssize_t sublen;
-        for (char *ptr = nullptr, *tok = buffer;
-             !!(tok = android::log_strntok_r(tok, len, ptr, sublen));
-             tok = nullptr) {
-            if (((tok + sublen) >= ep) && (retval != 0) && full) {
-                if (sublen > 0) memmove(buffer, tok, sublen);
-                len = sublen;
-                break;
-            }
-            if ((sublen > 0) && *tok) {
-                log(tok, sublen);
-            }
-        }
-    }
-
-    return true;
-}
-
-void LogKlog::calculateCorrection(const log_time& monotonic,
-                                  const char* real_string, ssize_t len) {
-    static const char real_format[] = "%Y-%m-%d %H:%M:%S.%09q UTC";
-    if (len < (ssize_t)(strlen(real_format) + 5)) return;
-
-    log_time real(log_time::EPOCH);
-    const char* ep = real.strptime(real_string, real_format);
-    if (!ep || (ep > &real_string[len]) || (real > log_time(CLOCK_REALTIME))) {
-        return;
-    }
-    // kernel report UTC, log_time::strptime is localtime from calendar.
-    // Bionic and liblog strptime does not support %z or %Z to pick up
-    // timezone so we are calculating our own correction.
-    time_t now = real.tv_sec;
-    struct tm tm;
-    memset(&tm, 0, sizeof(tm));
-    tm.tm_isdst = -1;
-    localtime_r(&now, &tm);
-    if ((tm.tm_gmtoff < 0) && ((-tm.tm_gmtoff) > (long)real.tv_sec)) {
-        real = log_time(log_time::EPOCH);
-    } else {
-        real.tv_sec += tm.tm_gmtoff;
-    }
-    if (monotonic > real) {
-        correction = log_time(log_time::EPOCH);
-    } else {
-        correction = real - monotonic;
-    }
-}
-
-log_time LogKlog::sniffTime(const char*& buf, ssize_t len, bool reverse) {
-    log_time now(log_time::EPOCH);
-    if (len <= 0) return now;
-
-    const char* cp = nullptr;
-    if ((len > 10) && (*buf == '[')) {
-        cp = now.strptime(buf, "[ %s.%q]");  // can index beyond buffer bounds
-        if (cp && (cp > &buf[len - 1])) cp = nullptr;
-    }
-    if (cp) {
-        len -= cp - buf;
-        if ((len > 0) && isspace(*cp)) {
-            ++cp;
-            --len;
-        }
-        buf = cp;
-
-        const char* b;
-        if (((b = android::strnstr(cp, len, suspendStr))) &&
-            (((b += strlen(suspendStr)) - cp) < len)) {
-            len -= b - cp;
-            calculateCorrection(now, b, len);
-        } else if (((b = android::strnstr(cp, len, resumeStr))) &&
-                   (((b += strlen(resumeStr)) - cp) < len)) {
-            len -= b - cp;
-            calculateCorrection(now, b, len);
-        } else if (((b = android::strnstr(cp, len, healthdStr))) &&
-                   (((b += strlen(healthdStr)) - cp) < len) &&
-                   ((b = android::strnstr(b, len -= b - cp, batteryStr))) &&
-                   (((b += strlen(batteryStr)) - cp) < len)) {
-            // NB: healthd is roughly 150us late, so we use it instead to
-            //     trigger a check for ntp-induced or hardware clock drift.
-            log_time real(CLOCK_REALTIME);
-            log_time mono(CLOCK_MONOTONIC);
-            correction = (real < mono) ? log_time(log_time::EPOCH) : (real - mono);
-        } else if (((b = android::strnstr(cp, len, suspendedStr))) &&
-                   (((b += strlen(suspendStr)) - cp) < len)) {
-            len -= b - cp;
-            log_time real(log_time::EPOCH);
-            char* endp;
-            real.tv_sec = strtol(b, &endp, 10);
-            if ((*endp == '.') && ((endp - b) < len)) {
-                unsigned long multiplier = NS_PER_SEC;
-                real.tv_nsec = 0;
-                len -= endp - b;
-                while (--len && isdigit(*++endp) && (multiplier /= 10)) {
-                    real.tv_nsec += (*endp - '0') * multiplier;
-                }
-                if (reverse) {
-                    if (real > correction) {
-                        correction = log_time(log_time::EPOCH);
-                    } else {
-                        correction -= real;
-                    }
-                } else {
-                    correction += real;
-                }
-            }
-        }
-
-        convertMonotonicToReal(now);
-    } else {
-        now = log_time(CLOCK_REALTIME);
-    }
-    return now;
-}
-
-pid_t LogKlog::sniffPid(const char*& buf, ssize_t len) {
-    if (len <= 0) return 0;
-
-    const char* cp = buf;
-    // sscanf does a strlen, let's check if the string is not nul terminated.
-    // pseudo out-of-bounds access since we always have an extra char on buffer.
-    if (((ssize_t)strnlen(cp, len) == len) && cp[len]) {
-        return 0;
-    }
-    // HTC kernels with modified printk "c0   1648 "
-    if ((len > 9) && (cp[0] == 'c') && isdigit(cp[1]) &&
-        (isdigit(cp[2]) || (cp[2] == ' ')) && (cp[3] == ' ')) {
-        bool gotDigit = false;
-        int i;
-        for (i = 4; i < 9; ++i) {
-            if (isdigit(cp[i])) {
-                gotDigit = true;
-            } else if (gotDigit || (cp[i] != ' ')) {
-                break;
-            }
-        }
-        if ((i == 9) && (cp[i] == ' ')) {
-            int pid = 0;
-            char placeholder;
-            if (sscanf(cp + 4, "%d%c", &pid, &placeholder) == 2) {
-                buf = cp + 10;  // skip-it-all
-                return pid;
-            }
-        }
-    }
-    while (len) {
-        // Mediatek kernels with modified printk
-        if (*cp == '[') {
-            int pid = 0;
-            char placeholder;
-            if (sscanf(cp, "[%d:%*[a-z_./0-9:A-Z]]%c", &pid, &placeholder) == 2) {
-                return pid;
-            }
-            break;  // Only the first one
-        }
-        ++cp;
-        --len;
-    }
-    return 0;
-}
-
-// kernel log prefix, convert to a kernel log priority number
-static int parseKernelPrio(const char*& buf, ssize_t len) {
-    int pri = LOG_USER | LOG_INFO;
-    const char* cp = buf;
-    if ((len > 0) && (*cp == '<')) {
-        pri = 0;
-        while (--len && isdigit(*++cp)) {
-            pri = (pri * 10) + *cp - '0';
-        }
-        if ((len > 0) && (*cp == '>')) {
-            ++cp;
-        } else {
-            cp = buf;
-            pri = LOG_USER | LOG_INFO;
-        }
-        buf = cp;
-    }
-    return pri;
-}
-
-// Convert kernel log priority number into an Android Logger priority number
-static int convertKernelPrioToAndroidPrio(int pri) {
-    switch (pri & LOG_PRIMASK) {
-        case LOG_EMERG:
-        case LOG_ALERT:
-        case LOG_CRIT:
-            return ANDROID_LOG_FATAL;
-
-        case LOG_ERR:
-            return ANDROID_LOG_ERROR;
-
-        case LOG_WARNING:
-            return ANDROID_LOG_WARN;
-
-        default:
-        case LOG_NOTICE:
-        case LOG_INFO:
-            break;
-
-        case LOG_DEBUG:
-            return ANDROID_LOG_DEBUG;
-    }
-
-    return ANDROID_LOG_INFO;
-}
-
-static const char* strnrchr(const char* s, ssize_t len, char c) {
-    const char* save = nullptr;
-    for (; len > 0; ++s, len--) {
-        if (*s == c) {
-            save = s;
-        }
-    }
-    return save;
-}
-
-//
-// log a message into the kernel log buffer
-//
-// Filter rules to parse <PRI> <TIME> <tag> and <message> in order for
-// them to appear correct in the logcat output:
-//
-// LOG_KERN (0):
-// <PRI>[<TIME>] <tag> ":" <message>
-// <PRI>[<TIME>] <tag> <tag> ":" <message>
-// <PRI>[<TIME>] <tag> <tag>_work ":" <message>
-// <PRI>[<TIME>] <tag> '<tag>.<num>' ":" <message>
-// <PRI>[<TIME>] <tag> '<tag><num>' ":" <message>
-// <PRI>[<TIME>] <tag>_host '<tag>.<num>' ":" <message>
-// (unimplemented) <PRI>[<TIME>] <tag> '<num>.<tag>' ":" <message>
-// <PRI>[<TIME>] "[INFO]"<tag> : <message>
-// <PRI>[<TIME>] "------------[ cut here ]------------"   (?)
-// <PRI>[<TIME>] "---[ end trace 3225a3070ca3e4ac ]---"   (?)
-// LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
-// LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_FTP:
-// <PRI+TAG>[<TIME>] (see sys/syslog.h)
-// Observe:
-//  Minimum tag length = 3   NB: drops things like r5:c00bbadf, but allow PM:
-//  Maximum tag words = 2
-//  Maximum tag length = 16  NB: we are thinking of how ugly logcat can get.
-//  Not a Tag if there is no message content.
-//  leading additional spaces means no tag, inherit last tag.
-//  Not a Tag if <tag>: is "ERROR:", "WARNING:", "INFO:" or "CPU:"
-// Drop:
-//  empty messages
-//  messages with ' audit(' in them if auditd is running
-//  logd.klogd:
-// return -1 if message logd.klogd: <signature>
-//
-int LogKlog::log(const char* buf, ssize_t len) {
-    if (auditd && android::strnstr(buf, len, auditStr)) {
-        return 0;
-    }
-
-    const char* p = buf;
-    int pri = parseKernelPrio(p, len);
-
-    log_time now = sniffTime(p, len - (p - buf), false);
-
-    // sniff for start marker
-    const char* start = android::strnstr(p, len - (p - buf), klogdStr);
-    if (start) {
-        uint64_t sig = strtoll(start + strlen(klogdStr), nullptr, 10);
-        if (sig == signature.nsec()) {
-            if (initialized) {
-                enableLogging = true;
-            } else {
-                enableLogging = false;
-            }
-            return -1;
-        }
-        return 0;
-    }
-
-    if (!enableLogging) {
-        return 0;
-    }
-
-    // Parse pid, tid and uid
-    const pid_t pid = sniffPid(p, len - (p - buf));
-    const pid_t tid = pid;
-    uid_t uid = AID_ROOT;
-    if (pid) {
-        uid = stats_->PidToUid(pid);
-    }
-
-    // Parse (rules at top) to pull out a tag from the incoming kernel message.
-    // Some may view the following as an ugly heuristic, the desire is to
-    // beautify the kernel logs into an Android Logging format; the goal is
-    // admirable but costly.
-    while ((p < &buf[len]) && (isspace(*p) || !*p)) {
-        ++p;
-    }
-    if (p >= &buf[len]) {  // timestamp, no content
-        return 0;
-    }
-    start = p;
-    const char* tag = "";
-    const char* etag = tag;
-    ssize_t taglen = len - (p - buf);
-    const char* bt = p;
-
-    static const char infoBrace[] = "[INFO]";
-    static const ssize_t infoBraceLen = strlen(infoBrace);
-    if ((taglen >= infoBraceLen) &&
-        !fastcmp<strncmp>(p, infoBrace, infoBraceLen)) {
-        // <PRI>[<TIME>] "[INFO]"<tag> ":" message
-        bt = p + infoBraceLen;
-        taglen -= infoBraceLen;
-    }
-
-    const char* et;
-    for (et = bt; (taglen > 0) && *et && (*et != ':') && !isspace(*et);
-         ++et, --taglen) {
-        // skip ':' within [ ... ]
-        if (*et == '[') {
-            while ((taglen > 0) && *et && *et != ']') {
-                ++et;
-                --taglen;
-            }
-            if (taglen <= 0) {
-                break;
-            }
-        }
-    }
-    const char* cp;
-    for (cp = et; (taglen > 0) && isspace(*cp); ++cp, --taglen) {
-    }
-
-    // Validate tag
-    ssize_t size = et - bt;
-    if ((taglen > 0) && (size > 0)) {
-        if (*cp == ':') {
-            // ToDo: handle case insensitive colon separated logging stutter:
-            //       <tag> : <tag>: ...
-
-            // One Word
-            tag = bt;
-            etag = et;
-            p = cp + 1;
-        } else if ((taglen > size) && (tolower(*bt) == tolower(*cp))) {
-            // clean up any tag stutter
-            if (!fastcmp<strncasecmp>(bt + 1, cp + 1, size - 1)) {  // no match
-                // <PRI>[<TIME>] <tag> <tag> : message
-                // <PRI>[<TIME>] <tag> <tag>: message
-                // <PRI>[<TIME>] <tag> '<tag>.<num>' : message
-                // <PRI>[<TIME>] <tag> '<tag><num>' : message
-                // <PRI>[<TIME>] <tag> '<tag><stuff>' : message
-                const char* b = cp;
-                cp += size;
-                taglen -= size;
-                while ((--taglen > 0) && !isspace(*++cp) && (*cp != ':')) {
-                }
-                const char* e;
-                for (e = cp; (taglen > 0) && isspace(*cp); ++cp, --taglen) {
-                }
-                if ((taglen > 0) && (*cp == ':')) {
-                    tag = b;
-                    etag = e;
-                    p = cp + 1;
-                }
-            } else {
-                // what about <PRI>[<TIME>] <tag>_host '<tag><stuff>' : message
-                static const char host[] = "_host";
-                static const ssize_t hostlen = strlen(host);
-                if ((size > hostlen) &&
-                    !fastcmp<strncmp>(bt + size - hostlen, host, hostlen) &&
-                    !fastcmp<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) {
-                    const char* b = cp;
-                    cp += size - hostlen;
-                    taglen -= size - hostlen;
-                    if (*cp == '.') {
-                        while ((--taglen > 0) && !isspace(*++cp) &&
-                               (*cp != ':')) {
-                        }
-                        const char* e;
-                        for (e = cp; (taglen > 0) && isspace(*cp);
-                             ++cp, --taglen) {
-                        }
-                        if ((taglen > 0) && (*cp == ':')) {
-                            tag = b;
-                            etag = e;
-                            p = cp + 1;
-                        }
-                    }
-                } else {
-                    goto twoWord;
-                }
-            }
-        } else {
-        // <PRI>[<TIME>] <tag> <stuff>' : message
-        twoWord:
-            while ((--taglen > 0) && !isspace(*++cp) && (*cp != ':')) {
-            }
-            const char* e;
-            for (e = cp; (taglen > 0) && isspace(*cp); ++cp, --taglen) {
-            }
-            // Two words
-            if ((taglen > 0) && (*cp == ':')) {
-                tag = bt;
-                etag = e;
-                p = cp + 1;
-            }
-        }
-    }  // else no tag
-
-    static const char cpu[] = "CPU";
-    static const ssize_t cpuLen = strlen(cpu);
-    static const char warning[] = "WARNING";
-    static const ssize_t warningLen = strlen(warning);
-    static const char error[] = "ERROR";
-    static const ssize_t errorLen = strlen(error);
-    static const char info[] = "INFO";
-    static const ssize_t infoLen = strlen(info);
-
-    size = etag - tag;
-    if ((size <= 1) ||
-        // register names like x9
-        ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1]))) ||
-        // register names like x18 but not driver names like en0
-        ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2]))) ||
-        // ignore
-        ((size == cpuLen) && !fastcmp<strncmp>(tag, cpu, cpuLen)) ||
-        ((size == warningLen) && !fastcmp<strncasecmp>(tag, warning, warningLen)) ||
-        ((size == errorLen) && !fastcmp<strncasecmp>(tag, error, errorLen)) ||
-        ((size == infoLen) && !fastcmp<strncasecmp>(tag, info, infoLen))) {
-        p = start;
-        etag = tag = "";
-    }
-
-    // Suppress additional stutter in tag:
-    //   eg: [143:healthd]healthd -> [143:healthd]
-    taglen = etag - tag;
-    // Mediatek-special printk induced stutter
-    const char* mp = strnrchr(tag, taglen, ']');
-    if (mp && (++mp < etag)) {
-        ssize_t s = etag - mp;
-        if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) {
-            taglen = mp - tag;
-        }
-    }
-    // Deal with sloppy and simplistic harmless p = cp + 1 etc above.
-    if (len < (p - buf)) {
-        p = &buf[len];
-    }
-    // skip leading space
-    while ((p < &buf[len]) && (isspace(*p) || !*p)) {
-        ++p;
-    }
-    // truncate trailing space or nuls
-    ssize_t b = len - (p - buf);
-    while ((b > 0) && (isspace(p[b - 1]) || !p[b - 1])) {
-        --b;
-    }
-    // trick ... allow tag with empty content to be logged. log() drops empty
-    if ((b <= 0) && (taglen > 0)) {
-        p = " ";
-        b = 1;
-    }
-    // This shouldn't happen, but clamp the size if it does.
-    if (b > LOGGER_ENTRY_MAX_PAYLOAD) {
-        b = LOGGER_ENTRY_MAX_PAYLOAD;
-    }
-    if (taglen > LOGGER_ENTRY_MAX_PAYLOAD) {
-        taglen = LOGGER_ENTRY_MAX_PAYLOAD;
-    }
-    // calculate buffer copy requirements
-    ssize_t n = 1 + taglen + 1 + b + 1;
-    // Extra checks for likely impossible cases.
-    if ((taglen > n) || (b > n) || (n > (ssize_t)USHRT_MAX) || (n <= 0)) {
-        return -EINVAL;
-    }
-
-    // Careful.
-    // We are using the stack to house the log buffer for speed reasons.
-    // If we malloc'd this buffer, we could get away without n's USHRT_MAX
-    // test above, but we would then required a max(n, USHRT_MAX) as
-    // truncating length argument to logbuf->log() below. Gain is protection
-    // against stack corruption and speedup, loss is truncated long-line content.
-    char newstr[n];
-    char* np = newstr;
-
-    // Convert priority into single-byte Android logger priority
-    *np = convertKernelPrioToAndroidPrio(pri);
-    ++np;
-
-    // Copy parsed tag following priority
-    memcpy(np, tag, taglen);
-    np += taglen;
-    *np = '\0';
-    ++np;
-
-    // Copy main message to the remainder
-    memcpy(np, p, b);
-    np[b] = '\0';
-
-    {
-        // Watch out for singular race conditions with timezone causing near
-        // integer quarter-hour jumps in the time and compensate accordingly.
-        // Entries will be temporal within near_seconds * 2. b/21868540
-        static uint32_t vote_time[3];
-        vote_time[2] = vote_time[1];
-        vote_time[1] = vote_time[0];
-        vote_time[0] = now.tv_sec;
-
-        if (vote_time[1] && vote_time[2]) {
-            static const unsigned near_seconds = 10;
-            static const unsigned timezones_seconds = 900;
-            int diff0 = (vote_time[0] - vote_time[1]) / near_seconds;
-            unsigned abs0 = (diff0 < 0) ? -diff0 : diff0;
-            int diff1 = (vote_time[1] - vote_time[2]) / near_seconds;
-            unsigned abs1 = (diff1 < 0) ? -diff1 : diff1;
-            if ((abs1 <= 1) &&  // last two were in agreement on timezone
-                ((abs0 + 1) % (timezones_seconds / near_seconds)) <= 2) {
-                abs0 = (abs0 + 1) / (timezones_seconds / near_seconds) *
-                       timezones_seconds;
-                now.tv_sec -= (diff0 < 0) ? -abs0 : abs0;
-            }
-        }
-    }
-
-    // Log message
-    int rc = logbuf->Log(LOG_ID_KERNEL, now, uid, pid, tid, newstr, (uint16_t)n);
-
-    return rc;
-}
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
deleted file mode 100644
index 56e0452..0000000
--- a/logd/LogKlog.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma once
-
-#include <private/android_logger.h>
-#include <sysutils/SocketListener.h>
-
-#include "LogBuffer.h"
-#include "LogStatistics.h"
-
-class LogKlog : public SocketListener {
-    LogBuffer* logbuf;
-    const log_time signature;
-    // Set once thread is started, separates KLOG_ACTION_READ_ALL
-    // and KLOG_ACTION_READ phases.
-    bool initialized;
-    // Used during each of the above phases to control logging.
-    bool enableLogging;
-    // set if we are also running auditd, to filter out audit reports from
-    // our copy of the kernel log
-    bool auditd;
-
-    static log_time correction;
-
-  public:
-    LogKlog(LogBuffer* buf, int fdWrite, int fdRead, bool auditd, LogStatistics* stats);
-    int log(const char* buf, ssize_t len);
-
-    static void convertMonotonicToReal(log_time& real) { real += correction; }
-
-  protected:
-    log_time sniffTime(const char*& buf, ssize_t len, bool reverse);
-    pid_t sniffPid(const char*& buf, ssize_t len);
-    void calculateCorrection(const log_time& monotonic, const char* real_string, ssize_t len);
-    virtual bool onDataAvailable(SocketClient* cli);
-
-  private:
-    LogStatistics* stats_;
-};
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
deleted file mode 100644
index a6ab50b..0000000
--- a/logd/LogListener.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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 <limits.h>
-#include <sys/cdefs.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <thread>
-
-#include <cutils/sockets.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include "LogBuffer.h"
-#include "LogListener.h"
-#include "LogPermissions.h"
-
-LogListener::LogListener(LogBuffer* buf) : socket_(GetLogSocket()), logbuf_(buf) {}
-
-bool LogListener::StartListener() {
-    if (socket_ <= 0) {
-        return false;
-    }
-    auto thread = std::thread(&LogListener::ThreadFunction, this);
-    thread.detach();
-    return true;
-}
-
-void LogListener::ThreadFunction() {
-    prctl(PR_SET_NAME, "logd.writer");
-
-    while (true) {
-        HandleData();
-    }
-}
-
-void LogListener::HandleData() {
-    // + 1 to ensure null terminator if MAX_PAYLOAD buffer is received
-    __attribute__((uninitialized)) char
-            buffer[sizeof(android_log_header_t) + LOGGER_ENTRY_MAX_PAYLOAD + 1];
-    struct iovec iov = {buffer, sizeof(buffer) - 1};
-
-    alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
-    struct msghdr hdr = {
-        nullptr, 0, &iov, 1, control, sizeof(control), 0,
-    };
-
-    // To clear the entire buffer is secure/safe, but this contributes to 1.68%
-    // overhead under logging load. We are safe because we check counts, but
-    // still need to clear null terminator
-    // memset(buffer, 0, sizeof(buffer));
-    ssize_t n = recvmsg(socket_, &hdr, 0);
-    if (n <= (ssize_t)(sizeof(android_log_header_t))) {
-        return;
-    }
-
-    buffer[n] = 0;
-
-    struct ucred* cred = nullptr;
-
-    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
-    while (cmsg != nullptr) {
-        if (cmsg->cmsg_level == SOL_SOCKET &&
-            cmsg->cmsg_type == SCM_CREDENTIALS) {
-            cred = (struct ucred*)CMSG_DATA(cmsg);
-            break;
-        }
-        cmsg = CMSG_NXTHDR(&hdr, cmsg);
-    }
-
-    if (cred == nullptr) {
-        return;
-    }
-
-    if (cred->uid == AID_LOGD) {
-        // ignore log messages we send to ourself.
-        // Such log messages are often generated by libraries we depend on
-        // which use standard Android logging.
-        return;
-    }
-
-    android_log_header_t* header =
-        reinterpret_cast<android_log_header_t*>(buffer);
-    log_id_t logId = static_cast<log_id_t>(header->id);
-    if (/* logId < LOG_ID_MIN || */ logId >= LOG_ID_MAX ||
-        logId == LOG_ID_KERNEL) {
-        return;
-    }
-
-    if ((logId == LOG_ID_SECURITY) &&
-        (!__android_log_security() ||
-         !clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) {
-        return;
-    }
-
-    char* msg = ((char*)buffer) + sizeof(android_log_header_t);
-    n -= sizeof(android_log_header_t);
-
-    // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
-    // truncated message to the logs.
-
-    logbuf_->Log(logId, header->realtime, cred->uid, cred->pid, header->tid, msg,
-                 ((size_t)n <= UINT16_MAX) ? (uint16_t)n : UINT16_MAX);
-}
-
-int LogListener::GetLogSocket() {
-    static const char socketName[] = "logdw";
-    int sock = android_get_control_socket(socketName);
-
-    if (sock < 0) {  // logd started up in init.sh
-        sock = socket_local_server(
-            socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
-
-        int on = 1;
-        if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
-            return -1;
-        }
-    }
-    return sock;
-}
diff --git a/logd/LogListener.h b/logd/LogListener.h
deleted file mode 100644
index 566af5b..0000000
--- a/logd/LogListener.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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.
- */
-
-#pragma once
-
-#include "LogBuffer.h"
-
-class LogListener {
-  public:
-    explicit LogListener(LogBuffer* buf);
-    bool StartListener();
-
-  private:
-    void ThreadFunction();
-    void HandleData();
-    static int GetLogSocket();
-
-    int socket_;
-    LogBuffer* logbuf_;
-};
diff --git a/logd/LogPermissions.cpp b/logd/LogPermissions.cpp
deleted file mode 100644
index 3fd0ea1..0000000
--- a/logd/LogPermissions.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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 "LogPermissions.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <private/android_filesystem_config.h>
-
-// gets a list of supplementary group IDs associated with
-// the socket peer.  This is implemented by opening
-// /proc/PID/status and look for the "Group:" line.
-//
-// This function introduces races especially since status
-// can change 'shape' while reading, the net result is err
-// on lack of permission.
-//
-// Race-free alternative is to introduce pairs of sockets
-// and threads for each command and reading, one each that
-// has open permissions, and one that has restricted
-// permissions.
-
-static bool groupIsLog(char* buf) {
-    char* ptr;
-    static const char ws[] = " \n";
-
-    for (buf = strtok_r(buf, ws, &ptr); buf; buf = strtok_r(nullptr, ws, &ptr)) {
-        errno = 0;
-        gid_t Gid = strtol(buf, nullptr, 10);
-        if (errno != 0) {
-            return false;
-        }
-        if (Gid == AID_LOG) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) {
-    if ((uid == AID_ROOT) || (uid == AID_SYSTEM) || (uid == AID_LOG)) {
-        return true;
-    }
-
-    if ((gid == AID_ROOT) || (gid == AID_SYSTEM) || (gid == AID_LOG)) {
-        return true;
-    }
-
-    // FYI We will typically be here for 'adb logcat'
-    char filename[256];
-    snprintf(filename, sizeof(filename), "/proc/%u/status", pid);
-
-    bool ret;
-    bool foundLog = false;
-    bool foundGid = false;
-    bool foundUid = false;
-
-    //
-    // Reading /proc/<pid>/status is rife with race conditions. All of /proc
-    // suffers from this and its use should be minimized. However, we have no
-    // choice.
-    //
-    // Notably the content from one 4KB page to the next 4KB page can be from a
-    // change in shape even if we are gracious enough to attempt to read
-    // atomically. getline can not even guarantee a page read is not split up
-    // and in effect can read from different vintages of the content.
-    //
-    // We are finding out in the field that a 'logcat -c' via adb occasionally
-    // is returned with permission denied when we did only one pass and thus
-    // breaking scripts. For security we still err on denying access if in
-    // doubt, but we expect the falses  should be reduced significantly as
-    // three times is a charm.
-    //
-    for (int retry = 3; !(ret = foundGid && foundUid && foundLog) && retry;
-         --retry) {
-        FILE* file = fopen(filename, "re");
-        if (!file) {
-            continue;
-        }
-
-        char* line = nullptr;
-        size_t len = 0;
-        while (getline(&line, &len, file) > 0) {
-            static const char groups_string[] = "Groups:\t";
-            static const char uid_string[] = "Uid:\t";
-            static const char gid_string[] = "Gid:\t";
-
-            if (strncmp(groups_string, line, sizeof(groups_string) - 1) == 0) {
-                if (groupIsLog(line + sizeof(groups_string) - 1)) {
-                    foundLog = true;
-                }
-            } else if (strncmp(uid_string, line, sizeof(uid_string) - 1) == 0) {
-                uid_t u[4] = { (uid_t)-1, (uid_t)-1, (uid_t)-1, (uid_t)-1 };
-
-                sscanf(line + sizeof(uid_string) - 1, "%u\t%u\t%u\t%u", &u[0],
-                       &u[1], &u[2], &u[3]);
-
-                // Protect against PID reuse by checking that UID is the same
-                if ((uid == u[0]) && (uid == u[1]) && (uid == u[2]) &&
-                    (uid == u[3])) {
-                    foundUid = true;
-                }
-            } else if (strncmp(gid_string, line, sizeof(gid_string) - 1) == 0) {
-                gid_t g[4] = { (gid_t)-1, (gid_t)-1, (gid_t)-1, (gid_t)-1 };
-
-                sscanf(line + sizeof(gid_string) - 1, "%u\t%u\t%u\t%u", &g[0],
-                       &g[1], &g[2], &g[3]);
-
-                // Protect against PID reuse by checking that GID is the same
-                if ((gid == g[0]) && (gid == g[1]) && (gid == g[2]) &&
-                    (gid == g[3])) {
-                    foundGid = true;
-                }
-            }
-        }
-        free(line);
-        fclose(file);
-    }
-
-    return ret;
-}
-
-bool clientHasLogCredentials(SocketClient* cli) {
-    return clientHasLogCredentials(cli->getUid(), cli->getGid(), cli->getPid());
-}
diff --git a/logd/LogPermissions.h b/logd/LogPermissions.h
deleted file mode 100644
index 3130db5..0000000
--- a/logd/LogPermissions.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <sysutils/SocketClient.h>
-
-bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid);
-bool clientHasLogCredentials(SocketClient* cli);
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
deleted file mode 100644
index 6c97693..0000000
--- a/logd/LogReader.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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 <ctype.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <chrono>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <cutils/sockets.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include "LogBuffer.h"
-#include "LogBufferElement.h"
-#include "LogPermissions.h"
-#include "LogReader.h"
-#include "LogUtils.h"
-#include "LogWriter.h"
-
-static bool CanReadSecurityLogs(SocketClient* client) {
-    return client->getUid() == AID_SYSTEM || client->getGid() == AID_SYSTEM;
-}
-
-static std::string SocketClientToName(SocketClient* client) {
-    return android::base::StringPrintf("pid %d, fd %d", client->getPid(), client->getSocket());
-}
-
-class SocketLogWriter : public LogWriter {
-  public:
-    SocketLogWriter(LogReader* reader, SocketClient* client, bool privileged)
-        : LogWriter(client->getUid(), privileged), reader_(reader), client_(client) {}
-
-    bool Write(const logger_entry& entry, const char* msg) override {
-        struct iovec iovec[2];
-        iovec[0].iov_base = const_cast<logger_entry*>(&entry);
-        iovec[0].iov_len = entry.hdr_size;
-        iovec[1].iov_base = const_cast<char*>(msg);
-        iovec[1].iov_len = entry.len;
-
-        return client_->sendDatav(iovec, 1 + (entry.len != 0)) == 0;
-    }
-
-    void Release() override {
-        reader_->release(client_);
-        client_->decRef();
-    }
-
-    void Shutdown() override { shutdown(client_->getSocket(), SHUT_RDWR); }
-
-    std::string name() const override { return SocketClientToName(client_); }
-
-  private:
-    LogReader* reader_;
-    SocketClient* client_;
-};
-
-LogReader::LogReader(LogBuffer* logbuf, LogReaderList* reader_list)
-    : SocketListener(getLogSocket(), true), log_buffer_(logbuf), reader_list_(reader_list) {}
-
-// Note returning false will release the SocketClient instance.
-bool LogReader::onDataAvailable(SocketClient* cli) {
-    static bool name_set;
-    if (!name_set) {
-        prctl(PR_SET_NAME, "logd.reader");
-        name_set = true;
-    }
-
-    char buffer[255];
-
-    int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1);
-    if (len <= 0) {
-        DoSocketDelete(cli);
-        return false;
-    }
-    buffer[len] = '\0';
-
-    // Clients are only allowed to send one command, disconnect them if they send another.
-    if (DoSocketDelete(cli)) {
-        return false;
-    }
-
-    unsigned long tail = 0;
-    static const char _tail[] = " tail=";
-    char* cp = strstr(buffer, _tail);
-    if (cp) {
-        tail = atol(cp + sizeof(_tail) - 1);
-    }
-
-    log_time start(log_time::EPOCH);
-    static const char _start[] = " start=";
-    cp = strstr(buffer, _start);
-    if (cp) {
-        // Parse errors will result in current time
-        start.strptime(cp + sizeof(_start) - 1, "%s.%q");
-    }
-
-    std::chrono::steady_clock::time_point deadline = {};
-    static const char _timeout[] = " timeout=";
-    cp = strstr(buffer, _timeout);
-    if (cp) {
-        long timeout_seconds = atol(cp + sizeof(_timeout) - 1);
-        deadline = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);
-    }
-
-    unsigned int logMask = -1;
-    static const char _logIds[] = " lids=";
-    cp = strstr(buffer, _logIds);
-    if (cp) {
-        logMask = 0;
-        cp += sizeof(_logIds) - 1;
-        while (*cp != '\0') {
-            int val = 0;
-            while (isdigit(*cp)) {
-                val = val * 10 + *cp - '0';
-                ++cp;
-            }
-            logMask |= 1 << val;
-            if (*cp != ',') {
-                break;
-            }
-            ++cp;
-        }
-    }
-
-    pid_t pid = 0;
-    static const char _pid[] = " pid=";
-    cp = strstr(buffer, _pid);
-    if (cp) {
-        pid = atol(cp + sizeof(_pid) - 1);
-    }
-
-    bool nonBlock = false;
-    if (!fastcmp<strncmp>(buffer, "dumpAndClose", 12)) {
-        // Allow writer to get some cycles, and wait for pending notifications
-        sched_yield();
-        reader_list_->reader_threads_lock().lock();
-        reader_list_->reader_threads_lock().unlock();
-        sched_yield();
-        nonBlock = true;
-    }
-
-    bool privileged = clientHasLogCredentials(cli);
-    bool can_read_security = CanReadSecurityLogs(cli);
-    if (!can_read_security) {
-        logMask &= ~(1 << LOG_ID_SECURITY);
-    }
-
-    std::unique_ptr<LogWriter> socket_log_writer(new SocketLogWriter(this, cli, privileged));
-
-    uint64_t sequence = 1;
-    // Convert realtime to sequence number
-    if (start != log_time::EPOCH) {
-        bool start_time_set = false;
-        uint64_t last = sequence;
-        auto log_find_start = [pid, start, &sequence, &start_time_set, &last](
-                                      log_id_t, pid_t element_pid, uint64_t element_sequence,
-                                      log_time element_realtime) -> FilterResult {
-            if (pid && pid != element_pid) {
-                return FilterResult::kSkip;
-            }
-            if (start == element_realtime) {
-                sequence = element_sequence;
-                start_time_set = true;
-                return FilterResult::kStop;
-            } else {
-                if (start < element_realtime) {
-                    sequence = last;
-                    start_time_set = true;
-                    return FilterResult::kStop;
-                }
-                last = element_sequence;
-            }
-            return FilterResult::kSkip;
-        };
-        auto flush_to_state = log_buffer_->CreateFlushToState(sequence, logMask);
-        log_buffer_->FlushTo(socket_log_writer.get(), *flush_to_state, log_find_start);
-
-        if (!start_time_set) {
-            if (nonBlock) {
-                return false;
-            }
-            sequence = log_buffer_->sequence();
-        }
-    }
-
-    LOG(INFO) << android::base::StringPrintf(
-            "logdr: UID=%d GID=%d PID=%d %c tail=%lu logMask=%x pid=%d "
-            "start=%" PRIu64 "ns deadline=%" PRIi64 "ns",
-            cli->getUid(), cli->getGid(), cli->getPid(), nonBlock ? 'n' : 'b', tail, logMask,
-            (int)pid, start.nsec(), static_cast<int64_t>(deadline.time_since_epoch().count()));
-
-    if (start == log_time::EPOCH) {
-        deadline = {};
-    }
-
-    auto lock = std::lock_guard{reader_list_->reader_threads_lock()};
-    auto entry = std::make_unique<LogReaderThread>(log_buffer_, reader_list_,
-                                                   std::move(socket_log_writer), nonBlock, tail,
-                                                   logMask, pid, start, sequence, deadline);
-    // release client and entry reference counts once done
-    cli->incRef();
-    reader_list_->reader_threads().emplace_front(std::move(entry));
-
-    // Set acceptable upper limit to wait for slow reader processing b/27242723
-    struct timeval t = { LOGD_SNDTIMEO, 0 };
-    setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&t,
-               sizeof(t));
-
-    return true;
-}
-
-bool LogReader::DoSocketDelete(SocketClient* cli) {
-    auto cli_name = SocketClientToName(cli);
-    auto lock = std::lock_guard{reader_list_->reader_threads_lock()};
-    for (const auto& reader : reader_list_->reader_threads()) {
-        if (reader->name() == cli_name) {
-            reader->release_Locked();
-            return true;
-        }
-    }
-    return false;
-}
-
-int LogReader::getLogSocket() {
-    static const char socketName[] = "logdr";
-    int sock = android_get_control_socket(socketName);
-
-    if (sock < 0) {
-        sock = socket_local_server(
-            socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
-    }
-
-    return sock;
-}
diff --git a/logd/LogReader.h b/logd/LogReader.h
deleted file mode 100644
index a4e52c4..0000000
--- a/logd/LogReader.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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.
- */
-
-#pragma once
-
-#include <sysutils/SocketListener.h>
-
-#include "LogBuffer.h"
-#include "LogReaderList.h"
-#include "LogReaderThread.h"
-
-class LogReader : public SocketListener {
-  public:
-    explicit LogReader(LogBuffer* logbuf, LogReaderList* reader_list);
-
-  protected:
-    virtual bool onDataAvailable(SocketClient* cli);
-
-  private:
-    static int getLogSocket();
-
-    bool DoSocketDelete(SocketClient* cli);
-
-    LogBuffer* log_buffer_;
-    LogReaderList* reader_list_;
-};
diff --git a/logd/LogReaderList.cpp b/logd/LogReaderList.cpp
deleted file mode 100644
index 32ba291..0000000
--- a/logd/LogReaderList.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 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 "LogReaderList.h"
-
-// When we are notified a new log entry is available, inform
-// listening sockets who are watching this entry's log id.
-void LogReaderList::NotifyNewLog(LogMask log_mask) const {
-    auto lock = std::lock_guard{reader_threads_lock_};
-
-    for (const auto& entry : reader_threads_) {
-        if (!entry->IsWatchingMultiple(log_mask)) {
-            continue;
-        }
-        if (entry->deadline().time_since_epoch().count() != 0) {
-            continue;
-        }
-        entry->triggerReader_Locked();
-    }
-}
diff --git a/logd/LogReaderList.h b/logd/LogReaderList.h
deleted file mode 100644
index 594716a..0000000
--- a/logd/LogReaderList.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <list>
-#include <memory>
-#include <mutex>
-
-#include "LogBuffer.h"
-#include "LogReaderThread.h"
-
-class LogReaderList {
-  public:
-    void NotifyNewLog(LogMask log_mask) const;
-
-    std::list<std::unique_ptr<LogReaderThread>>& reader_threads() { return reader_threads_; }
-    std::mutex& reader_threads_lock() { return reader_threads_lock_; }
-
-  private:
-    std::list<std::unique_ptr<LogReaderThread>> reader_threads_;
-    mutable std::mutex reader_threads_lock_;
-};
\ No newline at end of file
diff --git a/logd/LogReaderThread.cpp b/logd/LogReaderThread.cpp
deleted file mode 100644
index 4a8be01..0000000
--- a/logd/LogReaderThread.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2014 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 "LogReaderThread.h"
-
-#include <errno.h>
-#include <string.h>
-#include <sys/prctl.h>
-
-#include <thread>
-
-#include "LogBuffer.h"
-#include "LogReaderList.h"
-
-LogReaderThread::LogReaderThread(LogBuffer* log_buffer, LogReaderList* reader_list,
-                                 std::unique_ptr<LogWriter> writer, bool non_block,
-                                 unsigned long tail, LogMask log_mask, pid_t pid,
-                                 log_time start_time, uint64_t start,
-                                 std::chrono::steady_clock::time_point deadline)
-    : log_buffer_(log_buffer),
-      reader_list_(reader_list),
-      writer_(std::move(writer)),
-      pid_(pid),
-      tail_(tail),
-      count_(0),
-      index_(0),
-      start_time_(start_time),
-      deadline_(deadline),
-      non_block_(non_block) {
-    cleanSkip_Locked();
-    flush_to_state_ = log_buffer_->CreateFlushToState(start, log_mask);
-    auto thread = std::thread{&LogReaderThread::ThreadFunction, this};
-    thread.detach();
-}
-
-void LogReaderThread::ThreadFunction() {
-    prctl(PR_SET_NAME, "logd.reader.per");
-
-    auto lock = std::unique_lock{reader_list_->reader_threads_lock()};
-
-    while (!release_) {
-        if (deadline_.time_since_epoch().count() != 0) {
-            if (thread_triggered_condition_.wait_until(lock, deadline_) ==
-                std::cv_status::timeout) {
-                deadline_ = {};
-            }
-            if (release_) {
-                break;
-            }
-        }
-
-        lock.unlock();
-
-        if (tail_) {
-            auto first_pass_state = log_buffer_->CreateFlushToState(flush_to_state_->start(),
-                                                                    flush_to_state_->log_mask());
-            log_buffer_->FlushTo(
-                    writer_.get(), *first_pass_state,
-                    [this](log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime) {
-                        return FilterFirstPass(log_id, pid, sequence, realtime);
-                    });
-        }
-        bool flush_success = log_buffer_->FlushTo(
-                writer_.get(), *flush_to_state_,
-                [this](log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime) {
-                    return FilterSecondPass(log_id, pid, sequence, realtime);
-                });
-
-        // We only ignore entries before the original start time for the first flushTo(), if we
-        // get entries after this first flush before the original start time, then the client
-        // wouldn't have seen them.
-        // Note: this is still racy and may skip out of order events that came in since the last
-        // time the client disconnected and then reconnected with the new start time.  The long term
-        // solution here is that clients must request events since a specific sequence number.
-        start_time_.tv_sec = 0;
-        start_time_.tv_nsec = 0;
-
-        lock.lock();
-
-        if (!flush_success) {
-            break;
-        }
-
-        if (non_block_ || release_) {
-            break;
-        }
-
-        cleanSkip_Locked();
-
-        if (deadline_.time_since_epoch().count() == 0) {
-            thread_triggered_condition_.wait(lock);
-        }
-    }
-
-    writer_->Release();
-
-    auto& log_reader_threads = reader_list_->reader_threads();
-    auto it = std::find_if(log_reader_threads.begin(), log_reader_threads.end(),
-                           [this](const auto& other) { return other.get() == this; });
-
-    if (it != log_reader_threads.end()) {
-        log_reader_threads.erase(it);
-    }
-}
-
-// A first pass to count the number of elements
-FilterResult LogReaderThread::FilterFirstPass(log_id_t, pid_t pid, uint64_t, log_time realtime) {
-    auto lock = std::lock_guard{reader_list_->reader_threads_lock()};
-
-    if ((!pid_ || pid_ == pid) && (start_time_ == log_time::EPOCH || start_time_ <= realtime)) {
-        ++count_;
-    }
-
-    return FilterResult::kSkip;
-}
-
-// A second pass to send the selected elements
-FilterResult LogReaderThread::FilterSecondPass(log_id_t log_id, pid_t pid, uint64_t,
-                                               log_time realtime) {
-    auto lock = std::lock_guard{reader_list_->reader_threads_lock()};
-
-    if (skip_ahead_[log_id]) {
-        skip_ahead_[log_id]--;
-        return FilterResult::kSkip;
-    }
-
-    // Truncate to close race between first and second pass
-    if (non_block_ && tail_ && index_ >= count_) {
-        return FilterResult::kStop;
-    }
-
-    if (pid_ && pid_ != pid) {
-        return FilterResult::kSkip;
-    }
-
-    if (start_time_ != log_time::EPOCH && realtime <= start_time_) {
-        return FilterResult::kSkip;
-    }
-
-    if (release_) {
-        return FilterResult::kStop;
-    }
-
-    if (!tail_) {
-        goto ok;
-    }
-
-    ++index_;
-
-    if (count_ > tail_ && index_ <= (count_ - tail_)) {
-        return FilterResult::kSkip;
-    }
-
-    if (!non_block_) {
-        tail_ = 0;
-    }
-
-ok:
-    if (!skip_ahead_[log_id]) {
-        return FilterResult::kWrite;
-    }
-    return FilterResult::kSkip;
-}
-
-void LogReaderThread::cleanSkip_Locked(void) {
-    memset(skip_ahead_, 0, sizeof(skip_ahead_));
-}
diff --git a/logd/LogReaderThread.h b/logd/LogReaderThread.h
deleted file mode 100644
index 20624f2..0000000
--- a/logd/LogReaderThread.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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.
- */
-
-#pragma once
-
-#include <pthread.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include <chrono>
-#include <condition_variable>
-#include <list>
-#include <memory>
-
-#include <log/log.h>
-
-#include "LogBuffer.h"
-#include "LogWriter.h"
-
-class LogReaderList;
-
-class LogReaderThread {
-  public:
-    LogReaderThread(LogBuffer* log_buffer, LogReaderList* reader_list,
-                    std::unique_ptr<LogWriter> writer, bool non_block, unsigned long tail,
-                    LogMask log_mask, pid_t pid, log_time start_time, uint64_t sequence,
-                    std::chrono::steady_clock::time_point deadline);
-    void triggerReader_Locked() { thread_triggered_condition_.notify_all(); }
-
-    void triggerSkip_Locked(log_id_t id, unsigned int skip) { skip_ahead_[id] = skip; }
-    void cleanSkip_Locked();
-
-    void release_Locked() {
-        // gracefully shut down the socket.
-        writer_->Shutdown();
-        release_ = true;
-        thread_triggered_condition_.notify_all();
-    }
-
-    bool IsWatching(log_id_t id) const { return flush_to_state_->log_mask() & (1 << id); }
-    bool IsWatchingMultiple(LogMask log_mask) const {
-        return flush_to_state_->log_mask() & log_mask;
-    }
-
-    std::string name() const { return writer_->name(); }
-    uint64_t start() const { return flush_to_state_->start(); }
-    std::chrono::steady_clock::time_point deadline() const { return deadline_; }
-    FlushToState& flush_to_state() { return *flush_to_state_; }
-
-  private:
-    void ThreadFunction();
-    // flushTo filter callbacks
-    FilterResult FilterFirstPass(log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime);
-    FilterResult FilterSecondPass(log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime);
-
-    std::condition_variable thread_triggered_condition_;
-    LogBuffer* log_buffer_;
-    LogReaderList* reader_list_;
-    std::unique_ptr<LogWriter> writer_;
-
-    // Set to true to cause the thread to end and the LogReaderThread to delete itself.
-    bool release_ = false;
-
-    // If set to non-zero, only pids equal to this are read by the reader.
-    const pid_t pid_;
-    // When a reader is referencing (via start_) old elements in the log buffer, and the log
-    // buffer's size grows past its memory limit, the log buffer may request the reader to skip
-    // ahead a specified number of logs.
-    unsigned int skip_ahead_[LOG_ID_MAX];
-    // LogBuffer::FlushTo() needs to store state across subsequent calls.
-    std::unique_ptr<FlushToState> flush_to_state_;
-
-    // These next three variables are used for reading only the most recent lines aka `adb logcat
-    // -t` / `adb logcat -T`.
-    // tail_ is the number of most recent lines to print.
-    unsigned long tail_;
-    // count_ is the result of a first pass through the log buffer to determine how many total
-    // messages there are.
-    unsigned long count_;
-    // index_ is used along with count_ to only start sending lines once index_ > (count_ - tail_)
-    // and to disconnect the reader (if it is dumpAndClose, `adb logcat -t`), when index_ >= count_.
-    unsigned long index_;
-
-    // When a reader requests logs starting from a given timestamp, its stored here for the first
-    // pass, such that logs before this time stamp that are accumulated in the buffer are ignored.
-    log_time start_time_;
-    // CLOCK_MONOTONIC based deadline used for log wrapping.  If this deadline expires before logs
-    // wrap, then wake up and send the logs to the reader anyway.
-    std::chrono::steady_clock::time_point deadline_;
-    // If this reader is 'dumpAndClose' and will disconnect once it has read its intended logs.
-    const bool non_block_;
-};
diff --git a/logd/LogSize.cpp b/logd/LogSize.cpp
deleted file mode 100644
index fe829ba..0000000
--- a/logd/LogSize.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2020 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 <LogSize.h>
-
-#include <array>
-#include <optional>
-#include <string>
-
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-
-bool IsValidBufferSize(size_t value) {
-    return kLogBufferMinSize <= value && value <= kLogBufferMaxSize;
-}
-
-static std::optional<size_t> GetBufferSizeProperty(const std::string& key) {
-    std::string value = android::base::GetProperty(key, "");
-    if (value.empty()) {
-        return {};
-    }
-
-    uint32_t size;
-    if (!android::base::ParseByteCount(value, &size)) {
-        return {};
-    }
-
-    if (!IsValidBufferSize(size)) {
-        return {};
-    }
-
-    return size;
-}
-
-size_t GetBufferSizeFromProperties(log_id_t log_id) {
-    std::string buffer_name = android_log_id_to_name(log_id);
-    std::array<std::string, 4> properties = {
-            "persist.logd.size." + buffer_name,
-            "ro.logd.size." + buffer_name,
-            "persist.logd.size",
-            "ro.logd.size",
-    };
-
-    for (const auto& property : properties) {
-        if (auto size = GetBufferSizeProperty(property)) {
-            return *size;
-        }
-    }
-
-    if (android::base::GetBoolProperty("ro.config.low_ram", false)) {
-        return kLogBufferMinSize;
-    }
-
-    return kDefaultLogBufferSize;
-}
diff --git a/logd/LogSize.h b/logd/LogSize.h
deleted file mode 100644
index d5716ff..0000000
--- a/logd/LogSize.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2020 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.
- */
-
-#pragma once
-
-#include <stddef.h>
-
-#include <log/log.h>
-
-static constexpr size_t kDefaultLogBufferSize = 256 * 1024;
-static constexpr size_t kLogBufferMinSize = 64 * 1024;
-static constexpr size_t kLogBufferMaxSize = 256 * 1024 * 1024;
-
-bool IsValidBufferSize(size_t value);
-
-// This returns the buffer size as set in system properties for use in LogBuffer::Init().
-// Note that `logcat -G` calls LogBuffer::SetSize(), which configures log buffer sizes without
-// setting these properties, so this function should never be used except for LogBuffer::Init().
-// LogBuffer::GetSize() should be used instead within logd.  Other processes can use
-// android_logger_get_log_size() or `logcat -g` to query the actual allotted buffer size.
-size_t GetBufferSizeFromProperties(log_id_t log_id);
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
deleted file mode 100644
index 87069b3..0000000
--- a/logd/LogStatistics.cpp
+++ /dev/null
@@ -1,1071 +0,0 @@
-/*
- * Copyright (C) 2014 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 "LogStatistics.h"
-
-#include <ctype.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <list>
-#include <vector>
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <private/android_logger.h>
-
-#include "LogBufferElement.h"
-
-static const uint64_t hourSec = 60 * 60;
-static const uint64_t monthSec = 31 * 24 * hourSec;
-
-std::atomic<size_t> LogStatistics::SizesTotal;
-
-static std::string TagNameKey(const LogStatisticsElement& element) {
-    if (IsBinary(element.log_id)) {
-        uint32_t tag = element.tag;
-        if (tag) {
-            const char* cp = android::tagToName(tag);
-            if (cp) {
-                return std::string(cp);
-            }
-        }
-        return android::base::StringPrintf("[%" PRIu32 "]", tag);
-    }
-    const char* msg = element.msg;
-    if (!msg) {
-        return "chatty";
-    }
-    ++msg;
-    uint16_t len = element.msg_len;
-    len = (len <= 1) ? 0 : strnlen(msg, len - 1);
-    if (!len) {
-        return "<NULL>";
-    }
-    return std::string(msg, len);
-}
-
-LogStatistics::LogStatistics(bool enable_statistics, bool track_total_size,
-                             std::optional<log_time> start_time)
-    : enable(enable_statistics), track_total_size_(track_total_size) {
-    log_time now(CLOCK_REALTIME);
-    log_id_for_each(id) {
-        mSizes[id] = 0;
-        mElements[id] = 0;
-        mDroppedElements[id] = 0;
-        mSizesTotal[id] = 0;
-        mElementsTotal[id] = 0;
-        if (start_time) {
-            mOldest[id] = *start_time;
-            mNewest[id] = *start_time;
-        } else {
-            mOldest[id] = now;
-            mNewest[id] = now;
-        }
-        mNewestDropped[id] = now;
-    }
-}
-
-namespace android {
-
-size_t sizesTotal() {
-    return LogStatistics::sizesTotal();
-}
-
-// caller must own and free character string
-char* pidToName(pid_t pid) {
-    char* retval = nullptr;
-    if (pid == 0) {  // special case from auditd/klogd for kernel
-        retval = strdup("logd");
-    } else {
-        char buffer[512];
-        snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
-        int fd = open(buffer, O_RDONLY | O_CLOEXEC);
-        if (fd >= 0) {
-            ssize_t ret = read(fd, buffer, sizeof(buffer));
-            if (ret > 0) {
-                buffer[sizeof(buffer) - 1] = '\0';
-                // frameworks intermediate state
-                if (fastcmp<strcmp>(buffer, "<pre-initialized>")) {
-                    retval = strdup(buffer);
-                }
-            }
-            close(fd);
-        }
-    }
-    return retval;
-}
-}
-
-void LogStatistics::AddTotal(log_id_t log_id, uint16_t size) {
-    auto lock = std::lock_guard{lock_};
-
-    mSizesTotal[log_id] += size;
-    SizesTotal += size;
-    ++mElementsTotal[log_id];
-}
-
-void LogStatistics::Add(LogStatisticsElement element) {
-    auto lock = std::lock_guard{lock_};
-
-    if (!track_total_size_) {
-        element.total_len = element.msg_len;
-    }
-
-    log_id_t log_id = element.log_id;
-    uint16_t size = element.total_len;
-    mSizes[log_id] += size;
-    ++mElements[log_id];
-
-    // When caller adding a chatty entry, they will have already
-    // called add() and subtract() for each entry as they are
-    // evaluated and trimmed, thus recording size and number of
-    // elements, but we must recognize the manufactured dropped
-    // entry as not contributing to the lifetime totals.
-    if (element.dropped_count) {
-        ++mDroppedElements[log_id];
-    } else {
-        mSizesTotal[log_id] += size;
-        SizesTotal += size;
-        ++mElementsTotal[log_id];
-    }
-
-    log_time stamp(element.realtime);
-    if (mNewest[log_id] < stamp) {
-        // A major time update invalidates the statistics :-(
-        log_time diff = stamp - mNewest[log_id];
-        mNewest[log_id] = stamp;
-
-        if (diff.tv_sec > hourSec) {
-            // approximate Do-Your-Best fixup
-            diff += mOldest[log_id];
-            if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) {
-                diff = stamp;
-            }
-            if (diff <= stamp) {
-                mOldest[log_id] = diff;
-                if (mNewestDropped[log_id] < diff) {
-                    mNewestDropped[log_id] = diff;
-                }
-            }
-        }
-    }
-
-    if (log_id == LOG_ID_KERNEL) {
-        return;
-    }
-
-    uidTable[log_id].Add(element.uid, element);
-    if (element.uid == AID_SYSTEM) {
-        pidSystemTable[log_id].Add(element.pid, element);
-    }
-
-    if (!enable) {
-        return;
-    }
-
-    pidTable.Add(element.pid, element);
-    tidTable.Add(element.tid, element);
-
-    uint32_t tag = element.tag;
-    if (tag) {
-        if (log_id == LOG_ID_SECURITY) {
-            securityTagTable.Add(tag, element);
-        } else {
-            tagTable.Add(tag, element);
-        }
-    }
-
-    if (!element.dropped_count) {
-        tagNameTable.Add(TagNameKey(element), element);
-    }
-}
-
-void LogStatistics::Subtract(LogStatisticsElement element) {
-    auto lock = std::lock_guard{lock_};
-
-    if (!track_total_size_) {
-        element.total_len = element.msg_len;
-    }
-
-    log_id_t log_id = element.log_id;
-    uint16_t size = element.total_len;
-    mSizes[log_id] -= size;
-    --mElements[log_id];
-    if (element.dropped_count) {
-        --mDroppedElements[log_id];
-    }
-
-    if (mOldest[log_id] < element.realtime) {
-        mOldest[log_id] = element.realtime;
-    }
-
-    if (log_id == LOG_ID_KERNEL) {
-        return;
-    }
-
-    uidTable[log_id].Subtract(element.uid, element);
-    if (element.uid == AID_SYSTEM) {
-        pidSystemTable[log_id].Subtract(element.pid, element);
-    }
-
-    if (!enable) {
-        return;
-    }
-
-    pidTable.Subtract(element.pid, element);
-    tidTable.Subtract(element.tid, element);
-
-    uint32_t tag = element.tag;
-    if (tag) {
-        if (log_id == LOG_ID_SECURITY) {
-            securityTagTable.Subtract(tag, element);
-        } else {
-            tagTable.Subtract(tag, element);
-        }
-    }
-
-    if (!element.dropped_count) {
-        tagNameTable.Subtract(TagNameKey(element), element);
-    }
-}
-
-// Atomically set an entry to drop
-// entry->setDropped(1) must follow this call, caller should do this explicitly.
-void LogStatistics::Drop(LogStatisticsElement element) {
-    CHECK_EQ(element.dropped_count, 0U);
-
-    auto lock = std::lock_guard{lock_};
-    log_id_t log_id = element.log_id;
-    uint16_t size = element.msg_len;
-    mSizes[log_id] -= size;
-    ++mDroppedElements[log_id];
-
-    if (mNewestDropped[log_id] < element.realtime) {
-        mNewestDropped[log_id] = element.realtime;
-    }
-
-    uidTable[log_id].Drop(element.uid, element);
-    if (element.uid == AID_SYSTEM) {
-        pidSystemTable[log_id].Drop(element.pid, element);
-    }
-
-    if (!enable) {
-        return;
-    }
-
-    pidTable.Drop(element.pid, element);
-    tidTable.Drop(element.tid, element);
-
-    uint32_t tag = element.tag;
-    if (tag) {
-        if (log_id == LOG_ID_SECURITY) {
-            securityTagTable.Drop(tag, element);
-        } else {
-            tagTable.Drop(tag, element);
-        }
-    }
-
-    tagNameTable.Subtract(TagNameKey(element), element);
-}
-
-void LogStatistics::Erase(LogStatisticsElement element) {
-    CHECK_GT(element.dropped_count, 0U);
-    CHECK_EQ(element.msg_len, 0U);
-
-    auto lock = std::lock_guard{lock_};
-
-    if (!track_total_size_) {
-        element.total_len = 0;
-    }
-
-    log_id_t log_id = element.log_id;
-    --mElements[log_id];
-    --mDroppedElements[log_id];
-    mSizes[log_id] -= element.total_len;
-
-    uidTable[log_id].Erase(element.uid, element);
-    if (element.uid == AID_SYSTEM) {
-        pidSystemTable[log_id].Erase(element.pid, element);
-    }
-
-    if (!enable) {
-        return;
-    }
-
-    pidTable.Erase(element.pid, element);
-    tidTable.Erase(element.tid, element);
-
-    uint32_t tag = element.tag;
-    if (tag) {
-        if (log_id == LOG_ID_SECURITY) {
-            securityTagTable.Erase(tag, element);
-        } else {
-            tagTable.Erase(tag, element);
-        }
-    }
-}
-
-const char* LogStatistics::UidToName(uid_t uid) const {
-    auto lock = std::lock_guard{lock_};
-    return UidToNameLocked(uid);
-}
-
-// caller must own and free character string
-const char* LogStatistics::UidToNameLocked(uid_t uid) const {
-    // Local hard coded favourites
-    if (uid == AID_LOGD) {
-        return strdup("auditd");
-    }
-
-    // Android system
-    if (uid < AID_APP) {
-        // in bionic, thread safe as long as we copy the results
-        struct passwd* pwd = getpwuid(uid);
-        if (pwd) {
-            return strdup(pwd->pw_name);
-        }
-    }
-
-    // Parse /data/system/packages.list
-    uid_t userId = uid % AID_USER_OFFSET;
-    const char* name = android::uidToName(userId);
-    if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
-        name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
-    }
-    if (name) {
-        return name;
-    }
-
-    // Android application
-    if (uid >= AID_APP) {
-        struct passwd* pwd = getpwuid(uid);
-        if (pwd) {
-            return strdup(pwd->pw_name);
-        }
-    }
-
-    // report uid -> pid(s) -> pidToName if unique
-    for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end();
-         ++it) {
-        const PidEntry& entry = it->second;
-
-        if (entry.uid() == uid) {
-            const char* nameTmp = entry.name();
-
-            if (nameTmp) {
-                if (!name) {
-                    name = strdup(nameTmp);
-                } else if (fastcmp<strcmp>(name, nameTmp)) {
-                    free(const_cast<char*>(name));
-                    name = nullptr;
-                    break;
-                }
-            }
-        }
-    }
-
-    // No one
-    return name;
-}
-
-template <typename TKey, typename TEntry>
-void LogStatistics::WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& table, size_t threshold,
-                                          int* worst, size_t* worst_sizes,
-                                          size_t* second_worst_sizes) const {
-    std::array<const TKey*, 2> max_keys;
-    std::array<const TEntry*, 2> max_entries;
-    table.MaxEntries(AID_ROOT, 0, max_keys, max_entries);
-    if (max_entries[0] == nullptr || max_entries[1] == nullptr) {
-        return;
-    }
-    *worst_sizes = max_entries[0]->getSizes();
-    // b/24782000: Allow time horizon to extend roughly tenfold, assume average entry length is
-    // 100 characters.
-    if (*worst_sizes > threshold && *worst_sizes > (10 * max_entries[0]->dropped_count())) {
-        *worst = *max_keys[0];
-        *second_worst_sizes = max_entries[1]->getSizes();
-        if (*second_worst_sizes < threshold) {
-            *second_worst_sizes = threshold;
-        }
-    }
-}
-
-void LogStatistics::WorstTwoUids(log_id id, size_t threshold, int* worst, size_t* worst_sizes,
-                                 size_t* second_worst_sizes) const {
-    auto lock = std::lock_guard{lock_};
-    WorstTwoWithThreshold(uidTable[id], threshold, worst, worst_sizes, second_worst_sizes);
-}
-
-void LogStatistics::WorstTwoTags(size_t threshold, int* worst, size_t* worst_sizes,
-                                 size_t* second_worst_sizes) const {
-    auto lock = std::lock_guard{lock_};
-    WorstTwoWithThreshold(tagTable, threshold, worst, worst_sizes, second_worst_sizes);
-}
-
-void LogStatistics::WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* worst,
-                                       size_t* second_worst_sizes) const {
-    auto lock = std::lock_guard{lock_};
-    std::array<const pid_t*, 2> max_keys;
-    std::array<const PidEntry*, 2> max_entries;
-    pidSystemTable[id].MaxEntries(AID_SYSTEM, 0, max_keys, max_entries);
-    if (max_entries[0] == nullptr || max_entries[1] == nullptr) {
-        return;
-    }
-
-    *worst = *max_keys[0];
-    *second_worst_sizes = worst_uid_sizes - max_entries[0]->getSizes() + max_entries[1]->getSizes();
-}
-
-// Prune at most 10% of the log entries or maxPrune, whichever is less.
-bool LogStatistics::ShouldPrune(log_id id, unsigned long max_size,
-                                unsigned long* prune_rows) const {
-    static constexpr size_t kMinPrune = 4;
-    static constexpr size_t kMaxPrune = 256;
-
-    auto lock = std::lock_guard{lock_};
-    size_t sizes = mSizes[id];
-    if (sizes <= max_size) {
-        return false;
-    }
-    size_t size_over = sizes - ((max_size * 9) / 10);
-    size_t elements = mElements[id] - mDroppedElements[id];
-    size_t min_elements = elements / 100;
-    if (min_elements < kMinPrune) {
-        min_elements = kMinPrune;
-    }
-    *prune_rows = elements * size_over / sizes;
-    if (*prune_rows < min_elements) {
-        *prune_rows = min_elements;
-    }
-    if (*prune_rows > kMaxPrune) {
-        *prune_rows = kMaxPrune;
-    }
-
-    return true;
-}
-
-std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const {
-    bool isprune = worstUidEnabledForLogid(id);
-    return formatLine(android::base::StringPrintf(name.c_str(),
-                                                  android_log_id_to_name(id)),
-                      std::string("Size"),
-                      std::string(isprune ? "+/-  Pruned" : "")) +
-           formatLine(std::string("UID   PACKAGE"), std::string("BYTES"),
-                      std::string(isprune ? "NUM" : ""));
-}
-
-// Helper to truncate name, if too long, and add name dressings
-void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name, std::string& size,
-                              size_t nameLen) const {
-    const char* allocNameTmp = nullptr;
-    if (!nameTmp) nameTmp = allocNameTmp = UidToNameLocked(uid);
-    if (nameTmp) {
-        size_t lenSpace = std::max(nameLen - name.length(), (size_t)1);
-        size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
-                     lenSpace - 2;
-        size_t lenNameTmp = strlen(nameTmp);
-        while ((len < lenNameTmp) && (lenSpace > 1)) {
-            ++len;
-            --lenSpace;
-        }
-        name += android::base::StringPrintf("%*s", (int)lenSpace, "");
-        if (len < lenNameTmp) {
-            name += "...";
-            nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
-        }
-        name += nameTmp;
-        free(const_cast<char*>(allocNameTmp));
-    }
-}
-
-std::string UidEntry::format(const LogStatistics& stat, log_id_t id, uid_t uid) const
-        REQUIRES(stat.lock_) {
-    std::string name = android::base::StringPrintf("%u", uid);
-    std::string size = android::base::StringPrintf("%zu", getSizes());
-
-    stat.FormatTmp(nullptr, uid, name, size, 6);
-
-    std::string pruned = "";
-    if (worstUidEnabledForLogid(id)) {
-        size_t totalDropped = 0;
-        for (LogStatistics::uidTable_t::const_iterator it =
-                 stat.uidTable[id].begin();
-             it != stat.uidTable[id].end(); ++it) {
-            totalDropped += it->second.dropped_count();
-        }
-        size_t sizes = stat.mSizes[id];
-        size_t totalSize = stat.mSizesTotal[id];
-        size_t totalElements = stat.mElementsTotal[id];
-        float totalVirtualSize =
-            (float)sizes + (float)totalDropped * totalSize / totalElements;
-        size_t entrySize = getSizes();
-        float virtualEntrySize = entrySize;
-        int realPermille = virtualEntrySize * 1000.0 / sizes;
-        size_t dropped = dropped_count();
-        if (dropped) {
-            pruned = android::base::StringPrintf("%zu", dropped);
-            virtualEntrySize += (float)dropped * totalSize / totalElements;
-        }
-        int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize;
-        int permille =
-            (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1);
-        if ((permille < -1) || (1 < permille)) {
-            std::string change;
-            const char* units = "%";
-            const char* prefix = (permille > 0) ? "+" : "";
-
-            if (permille > 999) {
-                permille = (permille + 1000) / 100;  // Now tenths fold
-                units = "X";
-                prefix = "";
-            }
-            if ((-99 < permille) && (permille < 99)) {
-                change = android::base::StringPrintf(
-                    "%s%d.%u%s", prefix, permille / 10,
-                    ((permille < 0) ? (-permille % 10) : (permille % 10)),
-                    units);
-            } else {
-                change = android::base::StringPrintf(
-                    "%s%d%s", prefix, (permille + 5) / 10, units);
-            }
-            ssize_t spaces = EntryBase::PRUNED_LEN - 2 - pruned.length() - change.length();
-            if ((spaces <= 0) && pruned.length()) {
-                spaces = 1;
-            }
-            if (spaces > 0) {
-                change += android::base::StringPrintf("%*s", (int)spaces, "");
-            }
-            pruned = change + pruned;
-        }
-    }
-
-    std::string output = formatLine(name, size, pruned);
-
-    if (uid != AID_SYSTEM) {
-        return output;
-    }
-
-    static const size_t maximum_sorted_entries = 32;
-    std::array<const pid_t*, maximum_sorted_entries> sorted_pids;
-    std::array<const PidEntry*, maximum_sorted_entries> sorted_entries;
-    stat.pidSystemTable[id].MaxEntries(uid, 0, sorted_pids, sorted_entries);
-
-    std::string byPid;
-    size_t index;
-    bool hasDropped = false;
-    for (index = 0; index < maximum_sorted_entries; ++index) {
-        const PidEntry* entry = sorted_entries[index];
-        if (!entry) {
-            break;
-        }
-        if (entry->getSizes() <= (getSizes() / 100)) {
-            break;
-        }
-        if (entry->dropped_count()) {
-            hasDropped = true;
-        }
-        byPid += entry->format(stat, id, *sorted_pids[index]);
-    }
-    if (index > 1) {  // print this only if interesting
-        std::string ditto("\" ");
-        output += formatLine(std::string("  PID/UID   COMMAND LINE"), ditto,
-                             hasDropped ? ditto : std::string(""));
-        output += byPid;
-    }
-
-    return output;
-}
-
-std::string PidEntry::formatHeader(const std::string& name,
-                                   log_id_t /* id */) const {
-    return formatLine(name, std::string("Size"), std::string("Pruned")) +
-           formatLine(std::string("  PID/UID   COMMAND LINE"),
-                      std::string("BYTES"), std::string("NUM"));
-}
-
-std::string PidEntry::format(const LogStatistics& stat, log_id_t, pid_t pid) const
-        REQUIRES(stat.lock_) {
-    std::string name = android::base::StringPrintf("%5u/%u", pid, uid_);
-    std::string size = android::base::StringPrintf("%zu", getSizes());
-
-    stat.FormatTmp(name_, uid_, name, size, 12);
-
-    std::string pruned = "";
-    size_t dropped = dropped_count();
-    if (dropped) {
-        pruned = android::base::StringPrintf("%zu", dropped);
-    }
-
-    return formatLine(name, size, pruned);
-}
-
-std::string TidEntry::formatHeader(const std::string& name,
-                                   log_id_t /* id */) const {
-    return formatLine(name, std::string("Size"), std::string("Pruned")) +
-           formatLine(std::string("  TID/UID   COMM"), std::string("BYTES"),
-                      std::string("NUM"));
-}
-
-std::string TidEntry::format(const LogStatistics& stat, log_id_t, pid_t tid) const
-        REQUIRES(stat.lock_) {
-    std::string name = android::base::StringPrintf("%5u/%u", tid, uid_);
-    std::string size = android::base::StringPrintf("%zu", getSizes());
-
-    stat.FormatTmp(name_, uid_, name, size, 12);
-
-    std::string pruned = "";
-    size_t dropped = dropped_count();
-    if (dropped) {
-        pruned = android::base::StringPrintf("%zu", dropped);
-    }
-
-    return formatLine(name, size, pruned);
-}
-
-std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
-    bool isprune = worstUidEnabledForLogid(id);
-    return formatLine(name, std::string("Size"),
-                      std::string(isprune ? "Prune" : "")) +
-           formatLine(std::string("    TAG/UID   TAGNAME"),
-                      std::string("BYTES"), std::string(isprune ? "NUM" : ""));
-}
-
-std::string TagEntry::format(const LogStatistics&, log_id_t, uint32_t) const {
-    std::string name;
-    if (uid_ == (uid_t)-1) {
-        name = android::base::StringPrintf("%7u", key());
-    } else {
-        name = android::base::StringPrintf("%7u/%u", key(), uid_);
-    }
-    const char* nameTmp = this->name();
-    if (nameTmp) {
-        name += android::base::StringPrintf(
-            "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp);
-    }
-
-    std::string size = android::base::StringPrintf("%zu", getSizes());
-
-    std::string pruned = "";
-    size_t dropped = dropped_count();
-    if (dropped) {
-        pruned = android::base::StringPrintf("%zu", dropped);
-    }
-
-    return formatLine(name, size, pruned);
-}
-
-std::string TagNameEntry::formatHeader(const std::string& name,
-                                       log_id_t /* id */) const {
-    return formatLine(name, std::string("Size"), std::string("")) +
-           formatLine(std::string("  TID/PID/UID   LOG_TAG NAME"),
-                      std::string("BYTES"), std::string(""));
-}
-
-std::string TagNameEntry::format(const LogStatistics&, log_id_t,
-                                 const std::string& key_name) const {
-    std::string name;
-    std::string pidstr;
-    if (pid_ != (pid_t)-1) {
-        pidstr = android::base::StringPrintf("%u", pid_);
-        if (tid_ != (pid_t)-1 && tid_ != pid_) pidstr = "/" + pidstr;
-    }
-    int len = 9 - pidstr.length();
-    if (len < 0) len = 0;
-    if (tid_ == (pid_t)-1 || tid_ == pid_) {
-        name = android::base::StringPrintf("%*s", len, "");
-    } else {
-        name = android::base::StringPrintf("%*u", len, tid_);
-    }
-    name += pidstr;
-    if (uid_ != (uid_t)-1) {
-        name += android::base::StringPrintf("/%u", uid_);
-    }
-
-    std::string size = android::base::StringPrintf("%zu", getSizes());
-
-    const char* nameTmp = key_name.data();
-    if (nameTmp) {
-        size_t lenSpace = std::max(16 - name.length(), (size_t)1);
-        size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
-                     lenSpace - 2;
-        size_t lenNameTmp = strlen(nameTmp);
-        while ((len < lenNameTmp) && (lenSpace > 1)) {
-            ++len;
-            --lenSpace;
-        }
-        name += android::base::StringPrintf("%*s", (int)lenSpace, "");
-        if (len < lenNameTmp) {
-            name += "...";
-            nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
-        }
-        name += nameTmp;
-    }
-
-    std::string pruned = "";
-
-    return formatLine(name, size, pruned);
-}
-
-static std::string formatMsec(uint64_t val) {
-    static const unsigned subsecDigits = 3;
-    static const uint64_t sec = MS_PER_SEC;
-
-    static const uint64_t minute = 60 * sec;
-    static const uint64_t hour = 60 * minute;
-    static const uint64_t day = 24 * hour;
-
-    std::string output;
-    if (val < sec) return output;
-
-    if (val >= day) {
-        output = android::base::StringPrintf("%" PRIu64 "d ", val / day);
-        val = (val % day) + day;
-    }
-    if (val >= minute) {
-        if (val >= hour) {
-            output += android::base::StringPrintf("%" PRIu64 ":",
-                                                  (val / hour) % (day / hour));
-        }
-        output += android::base::StringPrintf(
-            (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
-            (val / minute) % (hour / minute));
-    }
-    output +=
-        android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64,
-                                    (val / sec) % (minute / sec));
-    val %= sec;
-    unsigned digits = subsecDigits;
-    while (digits && ((val % 10) == 0)) {
-        val /= 10;
-        --digits;
-    }
-    if (digits) {
-        output += android::base::StringPrintf(".%0*" PRIu64, digits, val);
-    }
-    return output;
-}
-
-template <typename TKey, typename TEntry>
-std::string LogStatistics::FormatTable(const LogHashtable<TKey, TEntry>& table, uid_t uid,
-                                       pid_t pid, const std::string& name, log_id_t id) const
-        REQUIRES(lock_) {
-    static const size_t maximum_sorted_entries = 32;
-    std::string output;
-    std::array<const TKey*, maximum_sorted_entries> sorted_keys;
-    std::array<const TEntry*, maximum_sorted_entries> sorted_entries;
-    table.MaxEntries(uid, pid, sorted_keys, sorted_entries);
-    bool header_printed = false;
-    for (size_t index = 0; index < maximum_sorted_entries; ++index) {
-        const TEntry* entry = sorted_entries[index];
-        if (!entry) {
-            break;
-        }
-        if (entry->getSizes() <= (sorted_entries[0]->getSizes() / 100)) {
-            break;
-        }
-        if (!header_printed) {
-            output += "\n\n";
-            output += entry->formatHeader(name, id);
-            header_printed = true;
-        }
-        output += entry->format(*this, id, *sorted_keys[index]);
-    }
-    return output;
-}
-
-std::string LogStatistics::ReportInteresting() const {
-    auto lock = std::lock_guard{lock_};
-
-    std::vector<std::string> items;
-
-    log_id_for_each(i) { items.emplace_back(std::to_string(mElements[i])); }
-
-    log_id_for_each(i) { items.emplace_back(std::to_string(mSizes[i])); }
-
-    log_id_for_each(i) {
-        items.emplace_back(std::to_string(overhead_[i] ? *overhead_[i] : mSizes[i]));
-    }
-
-    log_id_for_each(i) {
-        uint64_t oldest = mOldest[i].msec() / 1000;
-        uint64_t newest = mNewest[i].msec() / 1000;
-
-        int span = newest - oldest;
-
-        items.emplace_back(std::to_string(span));
-    }
-
-    return android::base::Join(items, ",");
-}
-
-std::string LogStatistics::Format(uid_t uid, pid_t pid, unsigned int logMask) const {
-    auto lock = std::lock_guard{lock_};
-
-    static const uint16_t spaces_total = 19;
-
-    // Report on total logging, current and for all time
-
-    std::string output = "size/num";
-    size_t oldLength;
-    int16_t spaces = 1;
-
-    log_id_for_each(id) {
-        if (!(logMask & (1 << id))) continue;
-        oldLength = output.length();
-        if (spaces < 0) spaces = 0;
-        output += android::base::StringPrintf("%*s%s", spaces, "",
-                                              android_log_id_to_name(id));
-        spaces += spaces_total + oldLength - output.length();
-    }
-    if (spaces < 0) spaces = 0;
-    output += android::base::StringPrintf("%*sTotal", spaces, "");
-
-    static const char TotalStr[] = "\nTotal";
-    spaces = 10 - strlen(TotalStr);
-    output += TotalStr;
-
-    size_t totalSize = 0;
-    size_t totalEls = 0;
-    log_id_for_each(id) {
-        if (!(logMask & (1 << id))) continue;
-        oldLength = output.length();
-        if (spaces < 0) spaces = 0;
-        size_t szs = mSizesTotal[id];
-        totalSize += szs;
-        size_t els = mElementsTotal[id];
-        totalEls += els;
-        output +=
-            android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
-        spaces += spaces_total + oldLength - output.length();
-    }
-    if (spaces < 0) spaces = 0;
-    output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
-                                          totalEls);
-
-    static const char NowStr[] = "\nNow";
-    spaces = 10 - strlen(NowStr);
-    output += NowStr;
-
-    totalSize = 0;
-    totalEls = 0;
-    log_id_for_each(id) {
-        if (!(logMask & (1 << id))) continue;
-
-        size_t els = mElements[id];
-        if (els) {
-            oldLength = output.length();
-            if (spaces < 0) spaces = 0;
-            size_t szs = mSizes[id];
-            totalSize += szs;
-            totalEls += els;
-            output +=
-                android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
-            spaces -= output.length() - oldLength;
-        }
-        spaces += spaces_total;
-    }
-    if (spaces < 0) spaces = 0;
-    output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
-                                          totalEls);
-
-    static const char SpanStr[] = "\nLogspan";
-    spaces = 10 - strlen(SpanStr);
-    output += SpanStr;
-
-    // Total reports the greater of the individual maximum time span, or the
-    // validated minimum start and maximum end time span if it makes sense.
-    uint64_t minTime = UINT64_MAX;
-    uint64_t maxTime = 0;
-    uint64_t maxSpan = 0;
-    totalSize = 0;
-
-    log_id_for_each(id) {
-        if (!(logMask & (1 << id))) continue;
-
-        // validity checking
-        uint64_t oldest = mOldest[id].msec();
-        uint64_t newest = mNewest[id].msec();
-        if (newest <= oldest) {
-            spaces += spaces_total;
-            continue;
-        }
-
-        uint64_t span = newest - oldest;
-        if (span > (monthSec * MS_PER_SEC)) {
-            spaces += spaces_total;
-            continue;
-        }
-
-        // total span
-        if (minTime > oldest) minTime = oldest;
-        if (maxTime < newest) maxTime = newest;
-        if (span > maxSpan) maxSpan = span;
-        totalSize += span;
-
-        uint64_t dropped = mNewestDropped[id].msec();
-        if (dropped < oldest) dropped = oldest;
-        if (dropped > newest) dropped = newest;
-
-        oldLength = output.length();
-        output += android::base::StringPrintf("%*s%s", spaces, "",
-                                              formatMsec(span).c_str());
-        unsigned permille = ((newest - dropped) * 1000 + (span / 2)) / span;
-        if ((permille > 1) && (permille < 999)) {
-            output += android::base::StringPrintf("(%u", permille / 10);
-            permille %= 10;
-            if (permille) {
-                output += android::base::StringPrintf(".%u", permille);
-            }
-            output += android::base::StringPrintf("%%)");
-        }
-        spaces -= output.length() - oldLength;
-        spaces += spaces_total;
-    }
-    if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) &&
-        (maxTime > maxSpan)) {
-        maxSpan = maxTime;
-    }
-    if (spaces < 0) spaces = 0;
-    output += android::base::StringPrintf("%*s%s", spaces, "",
-                                          formatMsec(maxSpan).c_str());
-
-    static const char OverheadStr[] = "\nOverhead";
-    spaces = 10 - strlen(OverheadStr);
-    output += OverheadStr;
-
-    totalSize = 0;
-    log_id_for_each(id) {
-        if (!(logMask & (1 << id))) continue;
-
-        size_t els = mElements[id];
-        if (els) {
-            oldLength = output.length();
-            if (spaces < 0) spaces = 0;
-            size_t szs = 0;
-            if (overhead_[id]) {
-                szs = *overhead_[id];
-            } else if (track_total_size_) {
-                szs = mSizes[id];
-            } else {
-                // Legacy fallback for Chatty without track_total_size_
-                // Estimate the size of this element in the parent std::list<> by adding two void*'s
-                // corresponding to the next/prev pointers and aligning to 64 bit.
-                static const size_t overhead =
-                        (sizeof(LogBufferElement) + 2 * sizeof(void*) + sizeof(uint64_t) - 1) &
-                        -sizeof(uint64_t);
-                szs = mSizes[id] + els * overhead;
-            }
-            totalSize += szs;
-            output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
-            spaces -= output.length() - oldLength;
-        }
-        spaces += spaces_total;
-    }
-    totalSize += sizeOf();
-    if (spaces < 0) spaces = 0;
-    output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
-
-    // Report on Chattiest
-
-    std::string name;
-
-    // Chattiest by application (UID)
-    log_id_for_each(id) {
-        if (!(logMask & (1 << id))) continue;
-
-        name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:"
-                                 : "Logging for your UID in %s log buffer:";
-        output += FormatTable(uidTable[id], uid, pid, name, id);
-    }
-
-    if (enable) {
-        name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:"
-                                           : "Logging for this PID:";
-        output += FormatTable(pidTable, uid, pid, name);
-        name = "Chattiest TIDs";
-        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
-        name += ":";
-        output += FormatTable(tidTable, uid, pid, name);
-    }
-
-    if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
-        name = "Chattiest events log buffer TAGs";
-        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
-        name += ":";
-        output += FormatTable(tagTable, uid, pid, name, LOG_ID_EVENTS);
-    }
-
-    if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
-        name = "Chattiest security log buffer TAGs";
-        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
-        name += ":";
-        output += FormatTable(securityTagTable, uid, pid, name, LOG_ID_SECURITY);
-    }
-
-    if (enable) {
-        name = "Chattiest TAGs";
-        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
-        name += ":";
-        output += FormatTable(tagNameTable, uid, pid, name);
-    }
-
-    return output;
-}
-
-namespace android {
-
-uid_t pidToUid(pid_t pid) {
-    char buffer[512];
-    snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
-    FILE* fp = fopen(buffer, "re");
-    if (fp) {
-        while (fgets(buffer, sizeof(buffer), fp)) {
-            int uid = AID_LOGD;
-            char space = 0;
-            if ((sscanf(buffer, "Uid: %d%c", &uid, &space) == 2) &&
-                isspace(space)) {
-                fclose(fp);
-                return uid;
-            }
-        }
-        fclose(fp);
-    }
-    return AID_LOGD;  // associate this with the logger
-}
-}
-
-uid_t LogStatistics::PidToUid(pid_t pid) {
-    auto lock = std::lock_guard{lock_};
-    return pidTable.Add(pid)->second.uid();
-}
-
-// caller must free character string
-const char* LogStatistics::PidToName(pid_t pid) const {
-    auto lock = std::lock_guard{lock_};
-    // An inconvenient truth ... getName() can alter the object
-    pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
-    const char* name = writablePidTable.Add(pid)->second.name();
-    if (!name) {
-        return nullptr;
-    }
-    return strdup(name);
-}
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
deleted file mode 100644
index faf9283..0000000
--- a/logd/LogStatistics.h
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma once
-
-#include <ctype.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <algorithm>  // std::max
-#include <array>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-#include <android/log.h>
-#include <log/log_time.h>
-#include <private/android_filesystem_config.h>
-#include <utils/FastStrcmp.h>
-
-#include "LogUtils.h"
-
-#define log_id_for_each(i) \
-    for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t)((i) + 1))
-
-class LogStatistics;
-class UidEntry;
-class PidEntry;
-
-struct LogStatisticsElement {
-    uid_t uid;
-    pid_t pid;
-    pid_t tid;
-    uint32_t tag;
-    log_time realtime;
-    const char* msg;
-    uint16_t msg_len;
-    uint16_t dropped_count;
-    log_id_t log_id;
-    uint16_t total_len;
-};
-
-template <typename TKey, typename TEntry>
-class LogHashtable {
-    std::unordered_map<TKey, TEntry> map;
-
-    size_t bucket_size() const {
-        size_t count = 0;
-        for (size_t idx = 0; idx < map.bucket_count(); ++idx) {
-            size_t bucket_size = map.bucket_size(idx);
-            if (bucket_size == 0) bucket_size = 1;
-            count += bucket_size;
-        }
-        float load_factor = map.max_load_factor();
-        if (load_factor < 1.0) return count;
-        return count * load_factor;
-    }
-
-    static const size_t unordered_map_per_entry_overhead = sizeof(void*);
-    static const size_t unordered_map_bucket_overhead = sizeof(void*);
-
-  public:
-    size_t size() const {
-        return map.size();
-    }
-
-    // Estimate unordered_map memory usage.
-    size_t sizeOf() const {
-        return sizeof(*this) +
-               (size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) +
-               (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead);
-    }
-
-    typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
-    typedef
-        typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
-
-    // Returns a sorted array of up to len highest entries sorted by size.  If fewer than len
-    // entries are found, their positions are set to nullptr.
-    template <size_t len>
-    void MaxEntries(uid_t uid, pid_t pid, std::array<const TKey*, len>& out_keys,
-                    std::array<const TEntry*, len>& out_entries) const {
-        out_keys.fill(nullptr);
-        out_entries.fill(nullptr);
-        for (const auto& [key, entry] : map) {
-            uid_t entry_uid = 0;
-            if constexpr (std::is_same_v<TEntry, UidEntry>) {
-                entry_uid = key;
-            } else {
-                entry_uid = entry.uid();
-            }
-            if (uid != AID_ROOT && uid != entry_uid) {
-                continue;
-            }
-            pid_t entry_pid = 0;
-            if constexpr (std::is_same_v<TEntry, PidEntry>) {
-                entry_pid = key;
-            } else {
-                entry_pid = entry.pid();
-            }
-            if (pid && entry_pid && pid != entry_pid) {
-                continue;
-            }
-
-            size_t sizes = entry.getSizes();
-            ssize_t index = len - 1;
-            while ((!out_entries[index] || sizes > out_entries[index]->getSizes()) && --index >= 0)
-                ;
-            if (++index < (ssize_t)len) {
-                size_t num = len - index - 1;
-                if (num) {
-                    memmove(&out_keys[index + 1], &out_keys[index], num * sizeof(const TKey*));
-                    memmove(&out_entries[index + 1], &out_entries[index],
-                            num * sizeof(const TEntry*));
-                }
-                out_keys[index] = &key;
-                out_entries[index] = &entry;
-            }
-        }
-    }
-
-    iterator Add(const TKey& key, const LogStatisticsElement& element) {
-        iterator it = map.find(key);
-        if (it == map.end()) {
-            it = map.insert(std::make_pair(key, TEntry(element))).first;
-        } else {
-            it->second.Add(element);
-        }
-        return it;
-    }
-
-    iterator Add(const TKey& key) {
-        iterator it = map.find(key);
-        if (it == map.end()) {
-            it = map.insert(std::make_pair(key, TEntry(key))).first;
-        } else {
-            it->second.Add(key);
-        }
-        return it;
-    }
-
-    void Subtract(const TKey& key, const LogStatisticsElement& element) {
-        iterator it = map.find(key);
-        if (it != map.end() && it->second.Subtract(element)) {
-            map.erase(it);
-        }
-    }
-
-    void Drop(const TKey& key, const LogStatisticsElement& element) {
-        iterator it = map.find(key);
-        if (it != map.end()) {
-            it->second.Drop(element);
-        }
-    }
-
-    void Erase(const TKey& key, const LogStatisticsElement& element) {
-        iterator it = map.find(key);
-        if (it != map.end()) {
-            it->second.Erase(element);
-        }
-    }
-
-    iterator begin() { return map.begin(); }
-    const_iterator begin() const { return map.begin(); }
-    iterator end() { return map.end(); }
-    const_iterator end() const { return map.end(); }
-};
-
-class EntryBase {
-  public:
-    EntryBase() : size_(0) {}
-    explicit EntryBase(const LogStatisticsElement& element) : size_(element.total_len) {}
-
-    size_t getSizes() const { return size_; }
-
-    void Add(const LogStatisticsElement& element) { size_ += element.total_len; }
-    bool Subtract(const LogStatisticsElement& element) {
-        size_ -= element.total_len;
-        return size_ == 0;
-    }
-    void Drop(const LogStatisticsElement& element) { size_ -= element.msg_len; }
-    void Erase(const LogStatisticsElement& element) { size_ -= element.total_len; }
-
-    static constexpr size_t PRUNED_LEN = 14;
-    static constexpr size_t TOTAL_LEN = 80;
-
-    static std::string formatLine(const std::string& name,
-                                  const std::string& size,
-                                  const std::string& pruned) {
-        ssize_t drop_len = std::max(pruned.length() + 1, PRUNED_LEN);
-        ssize_t size_len = std::max(size.length() + 1, TOTAL_LEN - name.length() - drop_len - 1);
-
-        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";
-    }
-
-  private:
-    size_t size_;
-};
-
-class EntryBaseDropped : public EntryBase {
-  public:
-    EntryBaseDropped() : dropped_(0) {}
-    explicit EntryBaseDropped(const LogStatisticsElement& element)
-        : EntryBase(element), dropped_(element.dropped_count) {}
-
-    size_t dropped_count() const { return dropped_; }
-
-    void Add(const LogStatisticsElement& element) {
-        dropped_ += element.dropped_count;
-        EntryBase::Add(element);
-    }
-    bool Subtract(const LogStatisticsElement& element) {
-        dropped_ -= element.dropped_count;
-        return EntryBase::Subtract(element) && dropped_ == 0;
-    }
-    void Drop(const LogStatisticsElement& element) {
-        dropped_ += 1;
-        EntryBase::Drop(element);
-    }
-
-  private:
-    size_t dropped_;
-};
-
-class UidEntry : public EntryBaseDropped {
-  public:
-    explicit UidEntry(const LogStatisticsElement& element)
-        : EntryBaseDropped(element), pid_(element.pid) {}
-
-    pid_t pid() const { return pid_; }
-
-    void Add(const LogStatisticsElement& element) {
-        if (pid_ != element.pid) {
-            pid_ = -1;
-        }
-        EntryBaseDropped::Add(element);
-    }
-
-    std::string formatHeader(const std::string& name, log_id_t id) const;
-    std::string format(const LogStatistics& stat, log_id_t id, uid_t uid) const;
-
-  private:
-    pid_t pid_;
-};
-
-namespace android {
-uid_t pidToUid(pid_t pid);
-}
-
-class PidEntry : public EntryBaseDropped {
-  public:
-    explicit PidEntry(pid_t pid)
-        : EntryBaseDropped(),
-          uid_(android::pidToUid(pid)),
-          name_(android::pidToName(pid)) {}
-    explicit PidEntry(const LogStatisticsElement& element)
-        : EntryBaseDropped(element), uid_(element.uid), name_(android::pidToName(element.pid)) {}
-    PidEntry(const PidEntry& element)
-        : EntryBaseDropped(element),
-          uid_(element.uid_),
-          name_(element.name_ ? strdup(element.name_) : nullptr) {}
-    ~PidEntry() { free(name_); }
-
-    uid_t uid() const { return uid_; }
-    const char* name() const { return name_; }
-
-    void Add(pid_t new_pid) {
-        if (name_ && !fastcmp<strncmp>(name_, "zygote", 6)) {
-            free(name_);
-            name_ = nullptr;
-        }
-        if (!name_) {
-            name_ = android::pidToName(new_pid);
-        }
-    }
-
-    void Add(const LogStatisticsElement& element) {
-        uid_t incoming_uid = element.uid;
-        if (uid() != incoming_uid) {
-            uid_ = incoming_uid;
-            free(name_);
-            name_ = android::pidToName(element.pid);
-        } else {
-            Add(element.pid);
-        }
-        EntryBaseDropped::Add(element);
-    }
-
-    std::string formatHeader(const std::string& name, log_id_t id) const;
-    std::string format(const LogStatistics& stat, log_id_t id, pid_t pid) const;
-
-  private:
-    uid_t uid_;
-    char* name_;
-};
-
-class TidEntry : public EntryBaseDropped {
-  public:
-    TidEntry(pid_t tid, pid_t pid)
-        : EntryBaseDropped(),
-          pid_(pid),
-          uid_(android::pidToUid(tid)),
-          name_(android::tidToName(tid)) {}
-    explicit TidEntry(const LogStatisticsElement& element)
-        : EntryBaseDropped(element),
-          pid_(element.pid),
-          uid_(element.uid),
-          name_(android::tidToName(element.tid)) {}
-    TidEntry(const TidEntry& element)
-        : EntryBaseDropped(element),
-          pid_(element.pid_),
-          uid_(element.uid_),
-          name_(element.name_ ? strdup(element.name_) : nullptr) {}
-    ~TidEntry() { free(name_); }
-
-    pid_t pid() const { return pid_; }
-    uid_t uid() const { return uid_; }
-    const char* name() const { return name_; }
-
-    void Add(pid_t incomingTid) {
-        if (name_ && !fastcmp<strncmp>(name_, "zygote", 6)) {
-            free(name_);
-            name_ = nullptr;
-        }
-        if (!name_) {
-            name_ = android::tidToName(incomingTid);
-        }
-    }
-
-    void Add(const LogStatisticsElement& element) {
-        uid_t incoming_uid = element.uid;
-        pid_t incoming_pid = element.pid;
-        if (uid() != incoming_uid || pid() != incoming_pid) {
-            uid_ = incoming_uid;
-            pid_ = incoming_pid;
-            free(name_);
-            name_ = android::tidToName(element.tid);
-        } else {
-            Add(element.tid);
-        }
-        EntryBaseDropped::Add(element);
-    }
-
-    std::string formatHeader(const std::string& name, log_id_t id) const;
-    std::string format(const LogStatistics& stat, log_id_t id, pid_t pid) const;
-
-  private:
-    pid_t pid_;
-    uid_t uid_;
-    char* name_;
-};
-
-class TagEntry : public EntryBaseDropped {
-  public:
-    explicit TagEntry(const LogStatisticsElement& element)
-        : EntryBaseDropped(element), tag_(element.tag), pid_(element.pid), uid_(element.uid) {}
-
-    uint32_t key() const { return tag_; }
-    pid_t pid() const { return pid_; }
-    uid_t uid() const { return uid_; }
-    const char* name() const { return android::tagToName(tag_); }
-
-    void Add(const LogStatisticsElement& element) {
-        if (uid_ != element.uid) {
-            uid_ = -1;
-        }
-        if (pid_ != element.pid) {
-            pid_ = -1;
-        }
-        EntryBaseDropped::Add(element);
-    }
-
-    std::string formatHeader(const std::string& name, log_id_t id) const;
-    std::string format(const LogStatistics& stat, log_id_t id, uint32_t) const;
-
-  private:
-    const uint32_t tag_;
-    pid_t pid_;
-    uid_t uid_;
-};
-
-class TagNameEntry : public EntryBase {
-  public:
-    explicit TagNameEntry(const LogStatisticsElement& element)
-        : EntryBase(element), tid_(element.tid), pid_(element.pid), uid_(element.uid) {}
-
-    pid_t tid() const { return tid_; }
-    pid_t pid() const { return pid_; }
-    uid_t uid() const { return uid_; }
-
-    void Add(const LogStatisticsElement& element) {
-        if (uid_ != element.uid) {
-            uid_ = -1;
-        }
-        if (pid_ != element.pid) {
-            pid_ = -1;
-        }
-        if (tid_ != element.tid) {
-            tid_ = -1;
-        }
-        EntryBase::Add(element);
-    }
-
-    std::string formatHeader(const std::string& name, log_id_t id) const;
-    std::string format(const LogStatistics& stat, log_id_t id, const std::string& key_name) const;
-
-  private:
-    pid_t tid_;
-    pid_t pid_;
-    uid_t uid_;
-};
-
-class LogStatistics {
-    friend UidEntry;
-    friend PidEntry;
-    friend TidEntry;
-
-    size_t mSizes[LOG_ID_MAX] GUARDED_BY(lock_);
-    size_t mElements[LOG_ID_MAX] GUARDED_BY(lock_);
-    size_t mDroppedElements[LOG_ID_MAX] GUARDED_BY(lock_);
-    size_t mSizesTotal[LOG_ID_MAX] GUARDED_BY(lock_);
-    size_t mElementsTotal[LOG_ID_MAX] GUARDED_BY(lock_);
-    log_time mOldest[LOG_ID_MAX] GUARDED_BY(lock_);
-    log_time mNewest[LOG_ID_MAX] GUARDED_BY(lock_);
-    log_time mNewestDropped[LOG_ID_MAX] GUARDED_BY(lock_);
-    static std::atomic<size_t> SizesTotal;
-    bool enable;
-
-    // uid to size list
-    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
-    uidTable_t uidTable[LOG_ID_MAX] GUARDED_BY(lock_);
-
-    // pid of system to size list
-    typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t;
-    pidSystemTable_t pidSystemTable[LOG_ID_MAX] GUARDED_BY(lock_);
-
-    // pid to uid list
-    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
-    pidTable_t pidTable GUARDED_BY(lock_);
-
-    // tid to uid list
-    typedef LogHashtable<pid_t, TidEntry> tidTable_t;
-    tidTable_t tidTable GUARDED_BY(lock_);
-
-    // tag list
-    typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
-    tagTable_t tagTable GUARDED_BY(lock_);
-
-    // security tag list
-    tagTable_t securityTagTable GUARDED_BY(lock_);
-
-    // global tag list
-    typedef LogHashtable<std::string, TagNameEntry> tagNameTable_t;
-    tagNameTable_t tagNameTable;
-
-    size_t sizeOf() const REQUIRES(lock_) {
-        size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() +
-                      tagTable.sizeOf() + securityTagTable.sizeOf() +
-                      tagNameTable.sizeOf() +
-                      (pidTable.size() * sizeof(pidTable_t::iterator)) +
-                      (tagTable.size() * sizeof(tagTable_t::iterator));
-        for (const auto& it : pidTable) {
-            const char* name = it.second.name();
-            if (name) size += strlen(name) + 1;
-        }
-        for (const auto& it : tidTable) {
-            const char* name = it.second.name();
-            if (name) size += strlen(name) + 1;
-        }
-        for (const auto& it : tagNameTable) {
-            size += sizeof(std::string);
-            size_t len = it.first.size();
-            // Account for short string optimization: if the string's length is <= 22 bytes for 64
-            // bit or <= 10 bytes for 32 bit, then there is no additional allocation.
-            if ((sizeof(std::string) == 24 && len > 22) ||
-                (sizeof(std::string) != 24 && len > 10)) {
-                size += len;
-            }
-        }
-        log_id_for_each(id) {
-            size += uidTable[id].sizeOf();
-            size += uidTable[id].size() * sizeof(uidTable_t::iterator);
-            size += pidSystemTable[id].sizeOf();
-            size += pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator);
-        }
-        return size;
-    }
-
-  public:
-    LogStatistics(bool enable_statistics, bool track_total_size,
-                  std::optional<log_time> start_time = {});
-
-    void AddTotal(log_id_t log_id, uint16_t size) EXCLUDES(lock_);
-
-    // Add is for adding an element to the log buffer.  It may be a chatty element in the case of
-    // log deduplication.  Add the total size of the element to statistics.
-    void Add(LogStatisticsElement entry) EXCLUDES(lock_);
-    // Subtract is for removing an element from the log buffer.  It may be a chatty element.
-    // Subtract the total size of the element from statistics.
-    void Subtract(LogStatisticsElement entry) EXCLUDES(lock_);
-    // Drop is for converting a normal element into a chatty element. entry->setDropped(1) must
-    // follow this call.  Subtract only msg_len from statistics, since a chatty element will remain.
-    void Drop(LogStatisticsElement entry) EXCLUDES(lock_);
-    // Erase is for coalescing two chatty elements into one.  Erase() is called on the element that
-    // is removed from the log buffer.  Subtract the total size of the element, which is by
-    // definition only the size of the LogBufferElement + list overhead for chatty elements.
-    void Erase(LogStatisticsElement element) EXCLUDES(lock_);
-
-    void WorstTwoUids(log_id id, size_t threshold, int* worst, size_t* worst_sizes,
-                      size_t* second_worst_sizes) const EXCLUDES(lock_);
-    void WorstTwoTags(size_t threshold, int* worst, size_t* worst_sizes,
-                      size_t* second_worst_sizes) const EXCLUDES(lock_);
-    void WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* worst,
-                            size_t* second_worst_sizes) const EXCLUDES(lock_);
-
-    bool ShouldPrune(log_id id, unsigned long max_size, unsigned long* prune_rows) const
-            EXCLUDES(lock_);
-
-    // Return the consumed size of the given buffer.
-    size_t Sizes(log_id_t id) const EXCLUDES(lock_) {
-        auto lock = std::lock_guard{lock_};
-        if (overhead_[id]) {
-            return *overhead_[id];
-        }
-        return mSizes[id];
-    }
-
-    // Return the uncompressed size of the contents of the given buffer.
-    size_t SizeReadable(log_id_t id) const EXCLUDES(lock_) {
-        auto lock = std::lock_guard{lock_};
-        return mSizes[id];
-    }
-
-    // TODO: Get rid of this entirely.
-    static size_t sizesTotal() {
-        return SizesTotal;
-    }
-
-    std::string ReportInteresting() const EXCLUDES(lock_);
-    std::string Format(uid_t uid, pid_t pid, unsigned int logMask) const EXCLUDES(lock_);
-
-    const char* PidToName(pid_t pid) const EXCLUDES(lock_);
-    uid_t PidToUid(pid_t pid) EXCLUDES(lock_);
-    const char* UidToName(uid_t uid) const EXCLUDES(lock_);
-
-    void set_overhead(log_id_t id, size_t size) {
-        auto lock = std::lock_guard{lock_};
-        overhead_[id] = size;
-    }
-
-  private:
-    template <typename TKey, typename TEntry>
-    void WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& table, size_t threshold,
-                               int* worst, size_t* worst_sizes, size_t* second_worst_sizes) const;
-    template <typename TKey, typename TEntry>
-    std::string FormatTable(const LogHashtable<TKey, TEntry>& table, uid_t uid, pid_t pid,
-                            const std::string& name = std::string(""),
-                            log_id_t id = LOG_ID_MAX) const REQUIRES(lock_);
-    void FormatTmp(const char* nameTmp, uid_t uid, std::string& name, std::string& size,
-                   size_t nameLen) const REQUIRES(lock_);
-    const char* UidToNameLocked(uid_t uid) const REQUIRES(lock_);
-
-    mutable std::mutex lock_;
-    bool track_total_size_;
-
-    std::optional<size_t> overhead_[LOG_ID_MAX] GUARDED_BY(lock_);
-};
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
deleted file mode 100644
index 6ab3b48..0000000
--- a/logd/LogTags.cpp
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/scopeguard.h>
-#include <android-base/stringprintf.h>
-#include <android-base/threads.h>
-#include <log/log_event_list.h>
-#include <log/log_properties.h>
-#include <log/log_read.h>
-#include <private/android_filesystem_config.h>
-
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "LogUtils.h"
-
-using android::base::make_scope_guard;
-
-static LogTags* logtags;
-
-const char LogTags::system_event_log_tags[] = "/system/etc/event-log-tags";
-const char LogTags::dynamic_event_log_tags[] = "/dev/event-log-tags";
-// Only for debug
-const char LogTags::debug_event_log_tags[] = "/data/misc/logd/event-log-tags";
-
-// Sniff for first uid=%d in utf8z comment string
-static uid_t sniffUid(const char* comment, const char* endp) {
-    if (!comment) return AID_ROOT;
-
-    if (*comment == '#') ++comment;
-    while ((comment < endp) && (*comment != '\n') && isspace(*comment))
-        ++comment;
-    static const char uid_str[] = "uid=";
-    if (((comment + strlen(uid_str)) >= endp) ||
-        fastcmp<strncmp>(comment, uid_str, strlen(uid_str)) ||
-        !isdigit(comment[strlen(uid_str)]))
-        return AID_ROOT;
-    char* cp;
-    unsigned long Uid = strtoul(comment + 4, &cp, 10);
-    if ((cp > endp) || (Uid >= INT_MAX)) return AID_ROOT;
-
-    return Uid;
-}
-
-// Checks for file corruption, and report false if there was no need
-// to rebuild the referenced file.  Failure to rebuild is only logged,
-// does not cause a return value of false.
-bool LogTags::RebuildFileEventLogTags(const char* filename, bool warn) {
-    int fd;
-
-    {
-        android::RWLock::AutoRLock readLock(rwlock);
-
-        if (tag2total.begin() == tag2total.end()) {
-            return false;
-        }
-
-        file2watermark_const_iterator iwater = file2watermark.find(filename);
-        if (iwater == file2watermark.end()) {
-            return false;
-        }
-
-        struct stat sb;
-        if (!stat(filename, &sb) && ((size_t)sb.st_size >= iwater->second)) {
-            return false;
-        }
-
-        // dump what we already know back into the file?
-        fd = TEMP_FAILURE_RETRY(open(
-            filename, O_WRONLY | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY));
-        if (fd >= 0) {
-            time_t now = time(nullptr);
-            struct tm tm;
-            localtime_r(&now, &tm);
-            char timebuf[20];
-            strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", &tm);
-            android::base::WriteStringToFd(
-                android::base::StringPrintf(
-                    "# Rebuilt %.20s, content owned by logd\n", timebuf),
-                fd);
-            for (const auto& it : tag2total) {
-                android::base::WriteStringToFd(
-                    formatEntry_locked(it.first, AID_ROOT), fd);
-            }
-            close(fd);
-        }
-    }
-
-    if (warn) {
-        if (fd < 0) {
-            LOG(ERROR) << filename << " failed to rebuild";
-        } else {
-            LOG(ERROR) << filename << " missing, damaged or truncated; rebuilt";
-        }
-    }
-
-    if (fd >= 0) {
-        android::RWLock::AutoWLock writeLock(rwlock);
-
-        struct stat sb;
-        if (!stat(filename, &sb)) file2watermark[filename] = sb.st_size;
-    }
-
-    return true;
-}
-
-void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name,
-                              const std::string& Format, const char* source,
-                              bool warn) {
-    std::string Key = Name;
-    if (Format.length()) Key += "+" + Format;
-
-    bool update = !source || !!strcmp(source, system_event_log_tags);
-    bool newOne;
-
-    {
-        android::RWLock::AutoWLock writeLock(rwlock);
-
-        tag2total_const_iterator itot = tag2total.find(tag);
-
-        // unlikely except for dupes, or updates to uid list (more later)
-        if (itot != tag2total.end()) update = false;
-
-        newOne = tag2name.find(tag) == tag2name.end();
-        key2tag[Key] = tag;
-
-        if (Format.length()) {
-            if (key2tag.find(Name) == key2tag.end()) {
-                key2tag[Name] = tag;
-            }
-            tag2format[tag] = Format;
-        }
-        tag2name[tag] = Name;
-
-        tag2uid_const_iterator ut = tag2uid.find(tag);
-        if (ut != tag2uid.end()) {
-            if (uid == AID_ROOT) {
-                tag2uid.erase(ut);
-                update = true;
-            } else if (ut->second.find(uid) == ut->second.end()) {
-                const_cast<uid_list&>(ut->second).emplace(uid);
-                update = true;
-            }
-        } else if (newOne && (uid != AID_ROOT)) {
-            tag2uid[tag].emplace(uid);
-            update = true;
-        }
-
-        // updatePersist -> trigger output on modified
-        // content, reset tag2total if available
-        if (update && (itot != tag2total.end())) tag2total[tag] = 0;
-    }
-
-    if (update) {
-        WritePersistEventLogTags(tag, uid, source);
-    } else if (warn && !newOne && source) {
-        // For the files, we want to report dupes.
-        LOG(DEBUG) << "Multiple tag " << tag << " " << Name << " " << Format << " " << source;
-    }
-}
-
-// Read the event log tags file, and build up our internal database
-void LogTags::ReadFileEventLogTags(const char* filename, bool warn) {
-    bool etc = !strcmp(filename, system_event_log_tags);
-
-    if (!etc) {
-        RebuildFileEventLogTags(filename, warn);
-    }
-    std::string content;
-    if (android::base::ReadFileToString(filename, &content)) {
-        char* cp = (char*)content.c_str();
-        char* endp = cp + content.length();
-
-        {
-            android::RWLock::AutoRLock writeLock(rwlock);
-
-            file2watermark[filename] = content.length();
-        }
-
-        char* lineStart = cp;
-        while (cp < endp) {
-            if (*cp == '\n') {
-                lineStart = cp;
-            } else if (lineStart) {
-                if (*cp == '#') {
-                    /* comment; just scan to end */
-                    lineStart = nullptr;
-                } else if (isdigit(*cp)) {
-                    unsigned long Tag = strtoul(cp, &cp, 10);
-                    if (warn && (Tag > emptyTag)) {
-                        LOG(WARNING) << "tag too large " << Tag;
-                    }
-                    while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp;
-                    if (cp >= endp) break;
-                    if (*cp == '\n') continue;
-                    const char* name = cp;
-                    /* Determine whether it is a valid tag name [a-zA-Z0-9_] */
-                    bool hasAlpha = false;
-                    while ((cp < endp) && (isalnum(*cp) || (*cp == '_'))) {
-                        if (!isdigit(*cp)) hasAlpha = true;
-                        ++cp;
-                    }
-                    std::string Name(name, cp - name);
-#ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT
-                    static const size_t maximum_official_tag_name_size = 24;
-                    if (warn && (Name.length() > maximum_official_tag_name_size)) {
-                        LOG(WARNING) << "tag name too long " << Name;
-                    }
-#endif
-                    if (hasAlpha &&
-                        ((cp >= endp) || (*cp == '#') || isspace(*cp))) {
-                        if (Tag > emptyTag) {
-                            if (*cp != '\n') lineStart = nullptr;
-                            continue;
-                        }
-                        while ((cp < endp) && (*cp != '\n') && isspace(*cp))
-                            ++cp;
-                        const char* format = cp;
-                        uid_t uid = AID_ROOT;
-                        while ((cp < endp) && (*cp != '\n')) {
-                            if (*cp == '#') {
-                                uid = sniffUid(cp, endp);
-                                lineStart = nullptr;
-                                break;
-                            }
-                            ++cp;
-                        }
-                        while ((cp > format) && isspace(cp[-1])) {
-                            --cp;
-                            lineStart = nullptr;
-                        }
-                        std::string Format(format, cp - format);
-
-                        AddEventLogTags((uint32_t)Tag, uid, Name, Format,
-                                        filename, warn);
-                    } else {
-                        if (warn) {
-                            LOG(ERROR) << android::base::StringPrintf("tag name invalid %.*s",
-                                                                      (int)(cp - name + 1), name);
-                        }
-                        lineStart = nullptr;
-                    }
-                } else if (!isspace(*cp)) {
-                    break;
-                }
-            }
-            cp++;
-        }
-    } else if (warn) {
-#ifdef __ANDROID__
-        LOG(ERROR) << "Cannot read " << filename;
-#endif
-    }
-}
-
-// Extract a 4-byte value from a byte stream.
-static inline uint32_t get4LE(const char* msg) {
-    const uint8_t* src = reinterpret_cast<const uint8_t*>(msg);
-    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
-}
-
-// Additional persistent sources for invented log tags.  Read the
-// special pmsg event for log tags, and build up our internal
-// database with any found.
-void LogTags::ReadPersistEventLogTags() {
-    struct logger_list* logger_list =
-            android_logger_list_alloc(ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, 0, (pid_t)0);
-    if (!logger_list) return;
-
-    struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS);
-    struct logger* s = android_logger_open(logger_list, LOG_ID_SECURITY);
-    if (!e && !s) {
-        android_logger_list_free(logger_list);
-        return;
-    }
-
-    for (;;) {
-        struct log_msg log_msg;
-        int ret = android_logger_list_read(logger_list, &log_msg);
-        if (ret <= 0) break;
-
-        const char* msg = log_msg.msg();
-        if (!msg) continue;
-        if (log_msg.entry.len <= sizeof(uint32_t)) continue;
-        uint32_t Tag = get4LE(msg);
-        if (Tag != TAG_DEF_LOG_TAG) continue;
-        uid_t uid = log_msg.entry.uid;
-
-        std::string Name;
-        std::string Format;
-        android_log_list_element elem;
-        {
-            auto ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
-                                                 log_msg.entry.len - sizeof(uint32_t));
-            auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
-            elem = android_log_read_next(ctx);
-            if (elem.type != EVENT_TYPE_LIST) {
-                continue;
-            }
-            elem = android_log_read_next(ctx);
-            if (elem.type != EVENT_TYPE_INT) {
-                continue;
-            }
-            Tag = elem.data.int32;
-            elem = android_log_read_next(ctx);
-            if (elem.type != EVENT_TYPE_STRING) {
-                continue;
-            }
-            Name = std::string(elem.data.string, elem.len);
-            elem = android_log_read_next(ctx);
-            if (elem.type != EVENT_TYPE_STRING) {
-                continue;
-            }
-            Format = std::string(elem.data.string, elem.len);
-            elem = android_log_read_next(ctx);
-        }
-        if ((elem.type != EVENT_TYPE_LIST_STOP) || !elem.complete) continue;
-
-        AddEventLogTags(Tag, uid, Name, Format);
-    }
-    android_logger_list_free(logger_list);
-}
-
-LogTags::LogTags() {
-    ReadFileEventLogTags(system_event_log_tags);
-    // Following will likely fail on boot, but is required if logd restarts
-    ReadFileEventLogTags(dynamic_event_log_tags, false);
-    if (__android_log_is_debuggable()) {
-        ReadFileEventLogTags(debug_event_log_tags, false);
-    }
-    ReadPersistEventLogTags();
-
-    logtags = this;
-}
-
-// Converts an event tag into a name
-const char* LogTags::tagToName(uint32_t tag) const {
-    tag2name_const_iterator it;
-
-    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
-
-    it = tag2name.find(tag);
-    if ((it == tag2name.end()) || (it->second.length() == 0)) return nullptr;
-
-    return it->second.c_str();
-}
-
-// Prototype in LogUtils.h allowing external access to our database.
-//
-// This must be a pure reader to our database, as everything else is
-// guaranteed single-threaded except this access point which is
-// asynchonous and can be multithreaded and thus rentrant.  The
-// object's rwlock is only used to guarantee atomic access to the
-// unordered_map to prevent corruption, with a requirement to be a
-// low chance of contention for this call.  If we end up changing
-// this algorithm resulting in write, then we should use a different
-// lock than the object's rwlock to protect groups of associated
-// actions.
-const char* android::tagToName(uint32_t tag) {
-    LogTags* me = logtags;
-
-    if (!me) return nullptr;
-    me->WritePmsgEventLogTags(tag);
-    return me->tagToName(tag);
-}
-
-// converts an event tag into a format
-const char* LogTags::tagToFormat(uint32_t tag) const {
-    tag2format_const_iterator iform;
-
-    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
-
-    iform = tag2format.find(tag);
-    if (iform == tag2format.end()) return nullptr;
-
-    return iform->second.c_str();
-}
-
-// converts a name into an event tag
-uint32_t LogTags::nameToTag(const char* name) const {
-    uint32_t ret = emptyTag;
-
-    // Bug: Only works for a single entry, we can have multiple entries,
-    // one for each format, so we find first entry recorded, or entry with
-    // no format associated with it.
-
-    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
-
-    key2tag_const_iterator ik = key2tag.find(std::string(name));
-    if (ik != key2tag.end()) ret = ik->second;
-
-    return ret;
-}
-
-// Caller must perform locks, can be under reader (for pre-check) or
-// writer lock.  We use this call to invent a new deterministically
-// random tag, unique is cleared if no conflicts.  If format is NULL,
-// we are in readonly mode.
-uint32_t LogTags::nameToTag_locked(const std::string& name, const char* format,
-                                   bool& unique) {
-    key2tag_const_iterator ik;
-
-    bool write = format != nullptr;
-    unique = write;
-
-    if (!write) {
-        // Bug: Only works for a single entry, we can have multiple entries,
-        // one for each format, so we find first entry recorded, or entry with
-        // no format associated with it.
-        ik = key2tag.find(name);
-        if (ik == key2tag.end()) return emptyTag;
-        return ik->second;
-    }
-
-    std::string Key(name);
-    if (*format) Key += std::string("+") + format;
-
-    ik = key2tag.find(Key);
-    if (ik != key2tag.end()) {
-        unique = false;
-        return ik->second;
-    }
-
-    size_t Hash = key2tag.hash_function()(Key);
-    uint32_t Tag = Hash;
-    // This sets an upper limit on the conflics we are allowed to deal with.
-    for (unsigned i = 0; i < 256;) {
-        tag2name_const_iterator it = tag2name.find(Tag);
-        if (it == tag2name.end()) return Tag;
-        std::string localKey(it->second);
-        tag2format_const_iterator iform = tag2format.find(Tag);
-        if ((iform == tag2format.end()) && iform->second.length()) {
-            localKey += "+" + iform->second;
-        }
-        unique = !!it->second.compare(localKey);
-        if (!unique) return Tag;  // unlikely except in a race
-
-        ++i;
-        // Algorithm to convert hash to next tag
-        if (i < 32) {
-            Tag = (Hash >> i);
-            // size_t is 32 bits, or upper word zero, rotate
-            if ((sizeof(Hash) <= 4) || ((Hash & (uint64_t(-1LL) << 32)) == 0)) {
-                Tag |= Hash << (32 - i);
-            }
-        } else {
-            Tag = Hash + i - 31;
-        }
-    }
-    return emptyTag;
-}
-
-static int openFile(const char* name, int mode, bool warning) {
-    int fd = TEMP_FAILURE_RETRY(open(name, mode));
-    if (fd < 0 && warning) {
-        PLOG(ERROR) << "Failed to open " << name;
-    }
-    return fd;
-}
-
-void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) {
-    android::RWLock::AutoRLock readLock(rwlock);
-
-    tag2total_const_iterator itot = tag2total.find(tag);
-    if (itot == tag2total.end()) return;  // source is a static entry
-
-    size_t lastTotal = itot->second;
-
-    // Every 16K (half the smallest configurable pmsg buffer size) record
-    static const size_t rate_to_pmsg = 16 * 1024;
-    if (lastTotal && (LogStatistics::sizesTotal() - lastTotal) < rate_to_pmsg) {
-        return;
-    }
-
-    static int pmsg_fd = -1;
-    if (pmsg_fd < 0) {
-        pmsg_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
-        // unlikely, but deal with partners with borken pmsg
-        if (pmsg_fd < 0) return;
-    }
-
-    std::string Name = tag2name[tag];
-    tag2format_const_iterator iform = tag2format.find(tag);
-    std::string Format = (iform != tag2format.end()) ? iform->second : "";
-
-    auto ctx = create_android_logger(TAG_DEF_LOG_TAG);
-    auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
-    if (android_log_write_int32(ctx, static_cast<int32_t>(tag) < 0) ||
-        android_log_write_string8_len(ctx, Name.c_str(), Name.size()) < 0 ||
-        android_log_write_string8_len(ctx, Format.c_str(), Format.size()) < 0) {
-        return;
-    }
-
-    const char* cp = nullptr;
-    ssize_t len = android_log_write_list_buffer(ctx, &cp);
-
-    if (len <= 0 || cp == nullptr) {
-        return;
-    }
-
-    std::string buffer(cp, len);
-
-    /*
-     *  struct {
-     *      // what we provide to pstore
-     *      android_pmsg_log_header_t pmsgHeader;
-     *      // what we provide to file
-     *      android_log_header_t header;
-     *      // caller provides
-     *      union {
-     *          struct {
-     *              char     prio;
-     *              char     payload[];
-     *          } string;
-     *          struct {
-     *              uint32_t tag
-     *              char     payload[];
-     *          } binary;
-     *      };
-     *  };
-     */
-
-    struct timespec ts;
-    clock_gettime(CLOCK_REALTIME, &ts);
-
-    android_log_header_t header = {
-            .id = LOG_ID_EVENTS,
-            .tid = static_cast<uint16_t>(android::base::GetThreadId()),
-            .realtime.tv_sec = static_cast<uint32_t>(ts.tv_sec),
-            .realtime.tv_nsec = static_cast<uint32_t>(ts.tv_nsec),
-    };
-
-    uint32_t outTag = TAG_DEF_LOG_TAG;
-    outTag = get4LE((const char*)&outTag);
-
-    android_pmsg_log_header_t pmsgHeader = {
-        .magic = LOGGER_MAGIC,
-        .len = (uint16_t)(sizeof(pmsgHeader) + sizeof(header) + sizeof(outTag) +
-                          buffer.length()),
-        .uid = (uint16_t)AID_ROOT,
-        .pid = (uint16_t)getpid(),
-    };
-
-    struct iovec Vec[] = { { (unsigned char*)&pmsgHeader, sizeof(pmsgHeader) },
-                           { (unsigned char*)&header, sizeof(header) },
-                           { (unsigned char*)&outTag, sizeof(outTag) },
-                           { (unsigned char*)const_cast<char*>(buffer.data()),
-                             buffer.length() } };
-
-    tag2uid_const_iterator ut = tag2uid.find(tag);
-    if (ut == tag2uid.end()) {
-        TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
-    } else if (uid != AID_ROOT) {
-        pmsgHeader.uid = (uint16_t)uid;
-        TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
-    } else {
-        for (auto& it : ut->second) {
-            pmsgHeader.uid = (uint16_t)it;
-            TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
-        }
-    }
-}
-
-void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) {
-    static const int mode =
-        O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY;
-
-    int fd = openFile(dynamic_event_log_tags, mode, true);
-    if (fd < 0) return;
-
-    android::RWLock::AutoWLock writeLock(rwlock);
-
-    std::string ret = formatEntry_locked(tag, uid, false);
-    android::base::WriteStringToFd(ret, fd);
-    close(fd);
-
-    size_t size = 0;
-    file2watermark_const_iterator iwater;
-
-    iwater = file2watermark.find(dynamic_event_log_tags);
-    if (iwater != file2watermark.end()) size = iwater->second;
-
-    file2watermark[dynamic_event_log_tags] = size + ret.length();
-}
-
-void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) {
-    static const int mode =
-        O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY;
-
-    static bool one = true;
-    int fd = openFile(debug_event_log_tags, mode, one);
-    one = fd >= 0;
-    if (!one) return;
-
-    android::RWLock::AutoWLock writeLock(rwlock);
-
-    std::string ret = formatEntry_locked(tag, uid, false);
-    android::base::WriteStringToFd(ret, fd);
-    close(fd);
-
-    size_t size = 0;
-    file2watermark_const_iterator iwater;
-
-    iwater = file2watermark.find(debug_event_log_tags);
-    if (iwater != file2watermark.end()) size = iwater->second;
-
-    file2watermark[debug_event_log_tags] = size + ret.length();
-}
-
-// How we maintain some runtime or reboot stickiness
-void LogTags::WritePersistEventLogTags(uint32_t tag, uid_t uid,
-                                       const char* source) {
-    // very unlikely
-    bool etc = source && !strcmp(source, system_event_log_tags);
-    if (etc) return;
-
-    bool dynamic = source && !strcmp(source, dynamic_event_log_tags);
-    bool debug = (!dynamic && source && !strcmp(source, debug_event_log_tags)) ||
-                 !__android_log_is_debuggable();
-
-    WritePmsgEventLogTags(tag, uid);
-
-    size_t lastTotal = 0;
-    {
-        android::RWLock::AutoRLock readLock(rwlock);
-
-        tag2total_const_iterator itot = tag2total.find(tag);
-        if (itot != tag2total.end()) lastTotal = itot->second;
-    }
-
-    if (lastTotal == 0) {  // denotes first time for this one
-        if (!dynamic || !RebuildFileEventLogTags(dynamic_event_log_tags)) {
-            WriteDynamicEventLogTags(tag, uid);
-        }
-
-        if (!debug && !RebuildFileEventLogTags(debug_event_log_tags)) {
-            WriteDebugEventLogTags(tag, uid);
-        }
-    }
-
-    lastTotal = LogStatistics::sizesTotal();
-    if (!lastTotal) ++lastTotal;
-
-    // record totals for next watermark.
-    android::RWLock::AutoWLock writeLock(rwlock);
-    tag2total[tag] = lastTotal;
-}
-
-// nameToTag converts a name into an event tag. If format is NULL, then we
-// are in readonly mode.
-uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) {
-    std::string Name = std::string(name);
-    bool write = format != nullptr;
-    bool updateUid = uid != AID_ROOT;
-    bool updateFormat = format && *format;
-    bool unique;
-    uint32_t Tag;
-
-    {
-        android::RWLock::AutoRLock readLock(rwlock);
-
-        Tag = nameToTag_locked(Name, format, unique);
-        if (updateUid && (Tag != emptyTag) && !unique) {
-            tag2uid_const_iterator ut = tag2uid.find(Tag);
-            if (updateUid) {
-                if ((ut != tag2uid.end()) &&
-                    (ut->second.find(uid) == ut->second.end())) {
-                    unique = write;  // write passthrough to update uid counts
-                    if (!write) Tag = emptyTag;  // deny read access
-                }
-            } else {
-                unique = write && (ut != tag2uid.end());
-            }
-        }
-    }
-
-    if (Tag == emptyTag) return Tag;
-    WritePmsgEventLogTags(Tag, uid);  // record references periodically
-    if (!unique) return Tag;
-
-    bool updateWrite = false;
-    bool updateTag;
-
-    // Special case of AddEventLogTags, checks per-uid counter which makes
-    // no sense there, and is also optimized somewhat to reduce write times.
-    {
-        android::RWLock::AutoWLock writeLock(rwlock);
-
-        // double check after switch from read lock to write lock for Tag
-        updateTag = tag2name.find(Tag) == tag2name.end();
-        // unlikely, either update, race inviting conflict or multiple uids
-        if (!updateTag) {
-            Tag = nameToTag_locked(Name, format, unique);
-            if (Tag == emptyTag) return Tag;
-            // is it multiple uid's setting this value
-            if (!unique) {
-                tag2uid_const_iterator ut = tag2uid.find(Tag);
-                if (updateUid) {
-                    // Add it to the uid list
-                    if ((ut == tag2uid.end()) ||
-                        (ut->second.find(uid) != ut->second.end())) {
-                        return Tag;
-                    }
-                    const_cast<uid_list&>(ut->second).emplace(uid);
-                    updateWrite = true;
-                } else {
-                    if (ut == tag2uid.end()) return Tag;
-                    // (system) adding a global one, erase the uid list
-                    tag2uid.erase(ut);
-                    updateWrite = true;
-                }
-            }
-        }
-
-        // Update section
-        size_t count;
-        if (updateUid) {
-            count = 0;
-            uid2count_const_iterator ci = uid2count.find(uid);
-            if (ci != uid2count.end()) {
-                count = ci->second;
-                if (count >= max_per_uid) {
-                    if (!updateWrite) return emptyTag;
-                    // If we are added to the per-Uid perms, leak the Tag
-                    // if it already exists.
-                    updateUid = false;
-                    updateTag = false;
-                    updateFormat = false;
-                }
-            }
-        }
-
-        // updateWrite -> trigger output on modified content, reset tag2total
-        //    also sets static to dynamic entries if they are alterred,
-        //    only occurs if they have a uid, and runtime adds another uid.
-        if (updateWrite) tag2total[Tag] = 0;
-
-        if (updateTag) {
-            // mark as a dynamic entry, but do not upset current total counter
-            tag2total_const_iterator itot = tag2total.find(Tag);
-            if (itot == tag2total.end()) tag2total[Tag] = 0;
-
-            if (*format) {
-                key2tag[Name + "+" + format] = Tag;
-                if (key2tag.find(Name) == key2tag.end()) key2tag[Name] = Tag;
-            } else {
-                key2tag[Name] = Tag;
-            }
-            tag2name[Tag] = Name;
-        }
-        if (updateFormat) tag2format[Tag] = format;
-
-        if (updateUid) {
-            tag2uid[Tag].emplace(uid);
-            uid2count[uid] = count + 1;
-        }
-    }
-
-    if (updateTag || updateFormat || updateWrite) {
-        WritePersistEventLogTags(Tag, uid);
-    }
-
-    return Tag;
-}
-
-std::string LogTags::formatEntry(uint32_t tag, uid_t uid, const char* name,
-                                 const char* format) {
-    if (!format || !format[0]) {
-        return android::base::StringPrintf("%" PRIu32 "\t%s\n", tag, name);
-    }
-    size_t len = (strlen(name) + 7) / 8;
-    static const char tabs[] = "\t\t\t";
-    if (len > strlen(tabs)) len = strlen(tabs);
-    std::string Uid;
-    if (uid != AID_ROOT) Uid = android::base::StringPrintf(" # uid=%u", uid);
-    return android::base::StringPrintf("%" PRIu32 "\t%s%s\t%s%s\n", tag, name,
-                                       &tabs[len], format, Uid.c_str());
-}
-
-std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid,
-                                        bool authenticate) {
-    const char* name = tag2name[tag].c_str();
-
-    const char* format = "";
-    tag2format_const_iterator iform = tag2format.find(tag);
-    if (iform != tag2format.end()) format = iform->second.c_str();
-
-    // Access permission test, do not report dynamic entries
-    // that do not belong to us.
-    tag2uid_const_iterator ut = tag2uid.find(tag);
-    if (ut == tag2uid.end()) {
-        return formatEntry(tag, AID_ROOT, name, format);
-    }
-    if (uid != AID_ROOT) {
-        if (authenticate && (ut->second.find(uid) == ut->second.end())) {
-            return std::string("");
-        }
-        return formatEntry(tag, uid, name, format);
-    }
-
-    // Show all, one for each registered uid (we are group root)
-    std::string ret;
-    for (auto& it : ut->second) {
-        ret += formatEntry(tag, it, name, format);
-    }
-    return ret;
-}
-
-std::string LogTags::formatEntry(uint32_t tag, uid_t uid) {
-    android::RWLock::AutoRLock readLock(rwlock);
-    return formatEntry_locked(tag, uid);
-}
-
-std::string LogTags::formatGetEventTag(uid_t uid, const char* name,
-                                       const char* format) {
-    bool all = name && (name[0] == '*') && !name[1];
-    bool list = !name || all;
-    std::string ret;
-
-    if (!list) {
-        // switch to read entry only if format == "*"
-        if (format && (format[0] == '*') && !format[1]) format = nullptr;
-
-        // WAI: for null format, only works for a single entry, we can have
-        // multiple entries, one for each format, so we find first entry
-        // recorded, or entry with no format associated with it.
-        // We may desire to print all that match the name, but we did not
-        // add a mapping table for that and the cost is too high.
-        uint32_t tag = nameToTag(uid, name, format);
-        if (tag == emptyTag) return std::string("-1 ESRCH");
-        if (uid == AID_ROOT) {
-            android::RWLock::AutoRLock readLock(rwlock);
-
-            // first uid in list so as to manufacture an accurate reference
-            tag2uid_const_iterator ut = tag2uid.find(tag);
-            if ((ut != tag2uid.end()) &&
-                (ut->second.begin() != ut->second.end())) {
-                uid = *(ut->second.begin());
-            }
-        }
-        ret = formatEntry(tag, uid, name, format ?: tagToFormat(tag));
-        if (!ret.length()) return std::string("-1 ESRCH");
-        return ret;
-    }
-
-    android::RWLock::AutoRLock readLock(rwlock);
-    if (all) {
-        // everything under the sun
-        for (const auto& it : tag2name) {
-            ret += formatEntry_locked(it.first, uid);
-        }
-    } else {
-        // set entries are dynamic
-        for (const auto& it : tag2total) {
-            ret += formatEntry_locked(it.first, uid);
-        }
-    }
-    return ret;
-}
diff --git a/logd/LogTags.h b/logd/LogTags.h
deleted file mode 100644
index cce700c..0000000
--- a/logd/LogTags.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-
-#include <private/android_filesystem_config.h>
-#include <utils/RWLock.h>
-
-class LogTags {
-    // This lock protects all the unordered_map accesses below.  It
-    // is a reader/writer lock so that contentions are kept to a
-    // minimum since writes are rare, even administratably when
-    // reads are extended.  Resist the temptation to use the writer
-    // lock to protect anything outside the following unordered_maps
-    // as that would increase the reader contentions.  Use a separate
-    // mutex to protect the other entities.
-    android::RWLock rwlock;
-
-    // key is Name + "+" + Format
-    std::unordered_map<std::string, uint32_t> key2tag;
-    typedef std::unordered_map<std::string, uint32_t>::const_iterator
-        key2tag_const_iterator;
-
-    // Allows us to manage access permissions based on uid registrants
-    // Global entries are specifically erased.
-    typedef std::unordered_set<uid_t> uid_list;
-    std::unordered_map<uint32_t, uid_list> tag2uid;
-    typedef std::unordered_map<uint32_t, uid_list>::const_iterator
-        tag2uid_const_iterator;
-
-    std::unordered_map<uint32_t, std::string> tag2name;
-    typedef std::unordered_map<uint32_t, std::string>::const_iterator
-        tag2name_const_iterator;
-
-    std::unordered_map<uint32_t, std::string> tag2format;
-    typedef std::unordered_map<uint32_t, std::string>::const_iterator
-        tag2format_const_iterator;
-
-    static const size_t max_per_uid = 256;  // Put a cap on the tags per uid
-    std::unordered_map<uid_t, size_t> uid2count;
-    typedef std::unordered_map<uid_t, size_t>::const_iterator
-        uid2count_const_iterator;
-
-    // Dynamic entries are assigned
-    std::unordered_map<uint32_t, size_t> tag2total;
-    typedef std::unordered_map<uint32_t, size_t>::const_iterator
-        tag2total_const_iterator;
-
-    // emplace unique tag
-    uint32_t nameToTag(uid_t uid, const char* name, const char* format);
-    // find unique or associated tag
-    uint32_t nameToTag_locked(const std::string& name, const char* format,
-                              bool& unique);
-
-    // Record expected file watermarks to detect corruption.
-    std::unordered_map<std::string, size_t> file2watermark;
-    typedef std::unordered_map<std::string, size_t>::const_iterator
-        file2watermark_const_iterator;
-
-    void ReadPersistEventLogTags();
-
-    // format helpers
-    // format a single entry, does not need object data
-    static std::string formatEntry(uint32_t tag, uid_t uid, const char* name,
-                                   const char* format);
-    // caller locks, database lookup, authenticate against uid
-    std::string formatEntry_locked(uint32_t tag, uid_t uid,
-                                   bool authenticate = true);
-
-    bool RebuildFileEventLogTags(const char* filename, bool warn = true);
-
-    void AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name,
-                         const std::string& Format, const char* source = nullptr,
-                         bool warn = false);
-
-    void WriteDynamicEventLogTags(uint32_t tag, uid_t uid);
-    void WriteDebugEventLogTags(uint32_t tag, uid_t uid);
-    // push tag details to persistent storage
-    void WritePersistEventLogTags(uint32_t tag, uid_t uid = AID_ROOT,
-                                  const char* source = nullptr);
-
-    static const uint32_t emptyTag = uint32_t(-1);
-
-   public:
-    static const char system_event_log_tags[];
-    static const char dynamic_event_log_tags[];
-    // Only for userdebug and eng
-    static const char debug_event_log_tags[];
-
-    LogTags();
-
-    void WritePmsgEventLogTags(uint32_t tag, uid_t uid = AID_ROOT);
-    void ReadFileEventLogTags(const char* filename, bool warn = true);
-
-    // reverse lookup from tag
-    const char* tagToName(uint32_t tag) const;
-    const char* tagToFormat(uint32_t tag) const;
-    std::string formatEntry(uint32_t tag, uid_t uid);
-    // find associated tag
-    uint32_t nameToTag(const char* name) const;
-
-    // emplace tag if necessary, provide event-log-tag formated output in string
-    std::string formatGetEventTag(uid_t uid, const char* name,
-                                  const char* format);
-};
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
deleted file mode 100644
index c0f62d3..0000000
--- a/logd/LogUtils.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012-2015 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.
- */
-
-#pragma once
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include <private/android_logger.h>
-#include <utils/FastStrcmp.h>
-
-// Hijack this header as a common include file used by most all sources
-// to report some utilities defined here and there.
-
-#define LOGD_SNDTIMEO 32
-
-namespace android {
-
-// Furnished in main.cpp. Caller must own and free returned value
-char* uidToName(uid_t uid);
-
-// Caller must own and free returned value
-char* pidToName(pid_t pid);
-char* tidToName(pid_t tid);
-
-// Furnished in LogTags.cpp. Thread safe.
-const char* tagToName(uint32_t tag);
-
-// Furnished by LogKlog.cpp
-char* log_strntok_r(char* s, ssize_t& len, char*& saveptr, ssize_t& sublen);
-
-// needle should reference a string longer than 1 character
-static inline const char* strnstr(const char* s, ssize_t len,
-                                  const char* needle) {
-    if (len <= 0) return nullptr;
-
-    const char c = *needle++;
-    const size_t needleLen = strlen(needle);
-    do {
-        do {
-            if (len <= (ssize_t)needleLen) return nullptr;
-            --len;
-        } while (*s++ != c);
-    } while (fastcmp<memcmp>(s, needle, needleLen));
-    s--;
-    return s;
-}
-}
-
-// Returns true if the log buffer is meant for binary logs.
-static inline bool IsBinary(log_id_t log_id) {
-    return log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS || log_id == LOG_ID_SECURITY;
-}
-
-// Returns the numeric log tag for binary log messages.
-static inline uint32_t MsgToTag(const char* msg, uint16_t msg_len) {
-    if (msg_len < sizeof(android_event_header_t)) {
-        return 0;
-    }
-
-    return reinterpret_cast<const android_event_header_t*>(msg)->tag;
-}
-
-static inline bool worstUidEnabledForLogid(log_id_t id) {
-    return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) ||
-           (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS);
-}
diff --git a/logd/LogWriter.h b/logd/LogWriter.h
deleted file mode 100644
index d43c604..0000000
--- a/logd/LogWriter.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <string>
-
-#include <log/log_read.h>
-
-// An interface for writing logs to a reader.
-class LogWriter {
-  public:
-    LogWriter(uid_t uid, bool privileged) : uid_(uid), privileged_(privileged) {}
-    virtual ~LogWriter() {}
-
-    virtual bool Write(const logger_entry& entry, const char* msg) = 0;
-    virtual void Shutdown() {}
-    virtual void Release() {}
-
-    virtual std::string name() const = 0;
-    uid_t uid() const { return uid_; }
-
-    bool privileged() const { return privileged_; }
-
-  private:
-    uid_t uid_;
-
-    // If this writer sees logs from all UIDs or only its own UID.  See clientHasLogCredentials().
-    bool privileged_;
-};
\ No newline at end of file
diff --git a/logd/OWNERS b/logd/OWNERS
deleted file mode 100644
index 2394e32..0000000
--- a/logd/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-cferris@google.com
-tomcherry@google.com
diff --git a/logd/PruneList.cpp b/logd/PruneList.cpp
deleted file mode 100644
index c3859f3..0000000
--- a/logd/PruneList.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2014 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 "PruneList.h"
-
-#include <ctype.h>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-bool Prune::Matches(LogBufferElement* element) const {
-    return (uid_ == UID_ALL || uid_ == element->uid()) &&
-           (pid_ == PID_ALL || pid_ == element->pid());
-}
-
-std::string Prune::Format() const {
-    if (uid_ != UID_ALL) {
-        if (pid_ != PID_ALL) {
-            return android::base::StringPrintf("%u/%u", uid_, pid_);
-        }
-        return android::base::StringPrintf("%u", uid_);
-    }
-    if (pid_ != PID_ALL) {
-        return android::base::StringPrintf("/%u", pid_);
-    }
-    // NB: pid_ == PID_ALL can not happen if uid_ == UID_ALL
-    return std::string("/");
-}
-
-PruneList::PruneList() {
-    Init(nullptr);
-}
-
-bool PruneList::Init(const char* str) {
-    high_priority_prune_.clear();
-    low_priority_prune_.clear();
-
-    // default here means take ro.logd.filter, persist.logd.filter then internal default in order.
-    if (str && !strcmp(str, "default")) {
-        str = nullptr;
-    }
-    if (str && !strcmp(str, "disable")) {
-        str = "";
-    }
-
-    std::string filter;
-
-    if (str) {
-        filter = str;
-    } else {
-        filter = android::base::GetProperty("ro.logd.filter", "default");
-        auto persist_filter = android::base::GetProperty("persist.logd.filter", "default");
-        // default here means take ro.logd.filter
-        if (persist_filter != "default") {
-            filter = persist_filter;
-        }
-    }
-
-    // default here means take internal default.
-    if (filter == "default") {
-        filter = "~! ~1000/!";
-    }
-    if (filter == "disable") {
-        filter = "";
-    }
-
-    worst_uid_enabled_ = false;
-    worst_pid_of_system_enabled_ = false;
-
-    for (str = filter.c_str(); *str; ++str) {
-        if (isspace(*str)) {
-            continue;
-        }
-
-        std::list<Prune>* list;
-        if (*str == '~' || *str == '!') {  // ~ supported, ! undocumented
-            ++str;
-            // special case, prune the worst UID of those using at least 1/8th of the buffer.
-            if (*str == '!') {
-                worst_uid_enabled_ = true;
-                ++str;
-                if (!*str) {
-                    break;
-                }
-                if (!isspace(*str)) {
-                    LOG(ERROR) << "Nothing expected after '~!', but found '" << str << "'";
-                    return false;
-                }
-                continue;
-            }
-            // special case, translated to worst PID of System at priority
-            static const char WORST_SYSTEM_PID[] = "1000/!";
-            if (!strncmp(str, WORST_SYSTEM_PID, sizeof(WORST_SYSTEM_PID) - 1)) {
-                worst_pid_of_system_enabled_ = true;
-                str += sizeof(WORST_SYSTEM_PID) - 1;
-                if (!*str) {
-                    break;
-                }
-                if (!isspace(*str)) {
-                    LOG(ERROR) << "Nothing expected after '~1000/!', but found '" << str << "'";
-                    return false;
-                }
-                continue;
-            }
-            if (!*str) {
-                LOG(ERROR) << "Expected UID or PID after '~', but found nothing";
-                return false;
-            }
-            list = &high_priority_prune_;
-        } else {
-            list = &low_priority_prune_;
-        }
-
-        uid_t uid = Prune::UID_ALL;
-        if (isdigit(*str)) {
-            uid = 0;
-            do {
-                uid = uid * 10 + *str++ - '0';
-            } while (isdigit(*str));
-        }
-
-        pid_t pid = Prune::PID_ALL;
-        if (*str == '/') {
-            ++str;
-            if (isdigit(*str)) {
-                pid = 0;
-                do {
-                    pid = pid * 10 + *str++ - '0';
-                } while (isdigit(*str));
-            }
-        }
-
-        if (uid == Prune::UID_ALL && pid == Prune::PID_ALL) {
-            LOG(ERROR) << "Expected UID/PID combination, but found none";
-            return false;
-        }
-
-        if (*str && !isspace(*str)) {
-            LOG(ERROR) << "Nothing expected after UID/PID combination, but found '" << str << "'";
-            return false;
-        }
-
-        list->emplace_back(uid, pid);
-        if (!*str) {
-            break;
-        }
-    }
-
-    return true;
-}
-
-std::string PruneList::Format() const {
-    std::vector<std::string> prune_rules;
-
-    if (worst_uid_enabled_) {
-        prune_rules.emplace_back("~!");
-    }
-    if (worst_pid_of_system_enabled_) {
-        prune_rules.emplace_back("~1000/!");
-    }
-    for (const auto& rule : low_priority_prune_) {
-        prune_rules.emplace_back(rule.Format());
-    }
-    for (const auto& rule : high_priority_prune_) {
-        prune_rules.emplace_back("~" + rule.Format());
-    }
-    return android::base::Join(prune_rules, " ");
-}
-
-bool PruneList::IsHighPriority(LogBufferElement* element) const {
-    for (const auto& rule : high_priority_prune_) {
-        if (rule.Matches(element)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool PruneList::IsLowPriority(LogBufferElement* element) const {
-    for (const auto& rule : low_priority_prune_) {
-        if (rule.Matches(element)) {
-            return true;
-        }
-    }
-    return false;
-}
diff --git a/logd/PruneList.h b/logd/PruneList.h
deleted file mode 100644
index 94de5c5..0000000
--- a/logd/PruneList.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <string.h>
-#include <list>
-
-#include "LogBufferElement.h"
-
-class Prune {
-  public:
-    static const uid_t UID_ALL = (uid_t)-1;
-    static const pid_t PID_ALL = (pid_t)-1;
-
-    Prune(uid_t uid, pid_t pid) : uid_(uid), pid_(pid) {}
-
-    bool Matches(LogBufferElement* element) const;
-    std::string Format() const;
-
-    uid_t uid() const { return uid_; }
-    pid_t pid() const { return pid_; }
-
-  private:
-    const uid_t uid_;
-    const pid_t pid_;
-};
-
-class PruneList {
-  public:
-    PruneList();
-
-    bool Init(const char* str);
-    std::string Format() const;
-
-    bool IsHighPriority(LogBufferElement* element) const;
-    bool IsLowPriority(LogBufferElement* element) const;
-
-    bool HasHighPriorityPruneRules() const { return !high_priority_prune_.empty(); }
-    bool HasLowPriorityPruneRules() const { return !low_priority_prune_.empty(); }
-
-    bool worst_uid_enabled() const { return worst_uid_enabled_; }
-    bool worst_pid_of_system_enabled() const { return worst_pid_of_system_enabled_; }
-
-  private:
-    std::list<Prune> high_priority_prune_;
-    std::list<Prune> low_priority_prune_;
-
-    bool worst_uid_enabled_;
-    bool worst_pid_of_system_enabled_;
-};
diff --git a/logd/README.auditd b/logd/README.auditd
deleted file mode 100644
index 3f614a3..0000000
--- a/logd/README.auditd
+++ /dev/null
@@ -1,17 +0,0 @@
-Auditd Daemon
-
-The audit daemon is a simplified version of its desktop
-counterpart designed to gather the audit logs from the
-audit kernel subsystem. The audit subsystem of the kernel
-includes Linux Security Modules (LSM) messages as well.
-
-To enable the audit subsystem, you must add this to your
-kernel config:
-CONFIG_AUDIT=y
-
-To enable a LSM, you must consult that LSM's documentation, the
-example below is for SELinux:
-CONFIG_SECURITY_SELINUX=y
-
-This does not include possible dependencies that may need to be
-satisfied for that particular LSM.
diff --git a/logd/README.compression.md b/logd/README.compression.md
deleted file mode 100644
index 4ba634a..0000000
--- a/logd/README.compression.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Log Compression instead of Chatty in Android S
-
-## The problem
-
-* Log buffer space is precious, but suffers from the tragedy of the commons
-* Log spam fills the buffers making them less useful in logcat/bugreports
-* “Spam” is often in the eye of the beholder: which messages are important depends on what you’re trying to debug
-
-## The idea
-
-* Chatty isn’t helping as much as we’d hoped, and is surprisingly expensive
-* Compress logs to make more efficient use of the buffer
-* Address the root cause of log spam at its source:
-    * Do not hide log spam at runtime, which de-incentivize fixes
-    * Add presubmit coverage similar to SELinux violations to keep log spam down
-
----
-
-## Chatty in Theory
-
-* Delete messages classified as spam to extend the range of logs from other sources
-* “Spam” defined as:
-    * Logs from UIDs whose logs consume over 12.5% of a log buffer
-    * Back-to-back exact duplicate messages
-
-## Chatty in Practice
-
-* Developer confusion about missing and de-duplicated logs
-* Lowered incentive to fix the root cause of bad logging behavior
-* High CPU overhead
-* Memory usage greatly exceeds configured buffer size
-* Only marginal increase in log range
-
----
-
-## Log Compression in Theory
-
-* Store many more logs in the same log buffer size => better for diagnosis
-* Memory usage stays below configured log size => better system health
-* No gaps in logs, no de-duplicated logs => no developer confusion
-* No hiding bad behavior => increased accountability/incentive to fix root causes
-
-## Log Compression Preliminary Results
-
-* Captured 2, 5 day periods of full time personal usage of Pixel 4 and replayed the logs offline
-* Compression vs Chatty:
-    * **3.5x more log messages on average**
-    * **50% less CPU usage**
-    * **50% less memory usage**
-
----
-
-## Log Messages in 1MB
-
-* The number of log messages still available in logcat after ‘Message Count’ messages have been logged to a 1MB log buffer
-* Note: ‘Simple’ is the Chatty code without log spam detection and without de-duplication.
-
-![Total Log Count](doc_images/total_log_count.png)
-
----
-
-## CPU Time
-
-* Total CPU time on ARM64 (Walleye) and 32bit x86 (Cuttlefish)
-* X axis represents different log buffer size configurations.
-    * Chatty uses significantly more CPU time at 1MB (the default Pixel configuration)
-    * Chatty scales poorly with increased log buffer sizes
-* Note: “simple” isn’t “compression without actually compressing”, it’s “chatty without doing the chatty elimination”, which is why “simple” is more expensive than “compression” on walleye.
-
-![CPU Time Walleye](doc_images/cpu_walleye.png)
-![CPU Time Cuttlefish](doc_images/cpu_cuttlefish.png)
-
----
-
-## Memory Usage
-
-* The memory used by ‘Message Count’ messages, on both Walleye and Cuttlefish
-* Note: Chatty does not consider the metadata (UID, PID, timestamp, etc) in its calculation of log buffer size, so a 1MB log buffer will consume more than 1MB.  Note that there are 8 log buffers, 5 of which are typically filled.
-
-![Memory Usage](doc_images/memory_usage.png)
-
diff --git a/logd/README.property b/logd/README.property
deleted file mode 100644
index 8fd7f48..0000000
--- a/logd/README.property
+++ /dev/null
@@ -1,72 +0,0 @@
-The properties that logd and friends react to are:
-
-name                       type default  description
-ro.logd.auditd             bool   true   Enable selinux audit daemon
-ro.logd.auditd.dmesg       bool   true   selinux audit messages sent to dmesg.
-ro.logd.auditd.main        bool   true   selinux audit messages sent to main.
-ro.logd.auditd.events      bool   true   selinux audit messages sent to events.
-persist.logd.security      bool   false  Enable security buffer.
-ro.organization_owned      bool   false  Override persist.logd.security to false
-ro.logd.kernel             bool  svelte+ Enable klogd daemon
-logd.statistics            bool  svelte+ Enable logcat -S statistics.
-ro.debuggable              number        if not "1", logd.statistics &
-                                         ro.logd.kernel default false.
-logd.logpersistd.enable    bool   auto   Safe to start logpersist daemon service
-logd.logpersistd          string persist Enable logpersist daemon, "logcatd"
-                                         turns on logcat -f in logd context.
-					 Responds to logcatd, clear and stop.
-logd.logpersistd.buffer          persist logpersistd buffers to collect
-logd.logpersistd.size            persist logpersistd size in MB
-logd.logpersistd.rotate_kbytes   	 persist logpersistd outout file size in KB.
-persist.logd.logpersistd   string        Enable logpersist daemon, "logcatd"
-                                         turns on logcat -f in logd context.
-persist.logd.logpersistd.buffer    all   logpersistd buffers to collect
-persist.logd.logpersistd.size      256   logpersistd size in MB
-persist.logd.logpersistd.count     256   sets max number of rotated logs to <count>.
-persist.logd.logpersistd.rotate_kbytes   1024  logpersistd output file size in KB
-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>
-ro.logd.size               number svelte default for persist.logd.size. Larger
-                                         platform default sizes than 256KB are
-                                         known to not scale well under log spam
-                                         pressure. Address the spam first,
-                                         resist increasing the log buffer.
-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,
-                                         ro.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 "~! ~1000/!" default for persist.logd.filter.
-                                         This default means to prune the
-                                         oldest entries of chattiest UID, and
-                                         the chattiest PID of system
-                                         (1000, or AID_SYSTEM).
-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>
-
-logd.buffer_type           string (empty) Set the log buffer type.  Current choices are 'simple',
-                                          'chatty', or 'serialized'.  Defaults to 'chatty' if empty.
-
-NB:
-- auto - managed by /init
-- svelte - see ro.config.low_ram for details.
-- svelte+ - If empty, default to true if `ro.config.low_ram == false && ro.debuggable == true`
-- 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 rules are specified as UID, UID/PID or /PID. A '~' prefix indicates that elements
-  matching the rule should be pruned with higher priority otherwise they're pruned with lower
-  priority. All other pruning activity is oldest first. Special case ~! represents an automatic
-  pruning for the noisiest UID as determined by the current statistics.  Special case ~1000/!
-  represents pruning of the worst PID within AID_SYSTEM when AID_SYSTEM is the noisiest UID.
diff --git a/logd/README.replay.md b/logd/README.replay.md
deleted file mode 100644
index 5f7ec9e..0000000
--- a/logd/README.replay.md
+++ /dev/null
@@ -1,46 +0,0 @@
-logd can record and replay log messages for offline analysis.
-
-Recording Messages
-------------------
-
-logd has a `RecordingLogBuffer` buffer that records messages to /data/misc/logd/recorded-messages.
-It stores messages in memory until that file is accessible, in order to capture all messages since
-the beginning of boot.  It is only meant for logging developers to use and must be manually enabled
-in by adding `RecordingLogBuffer.cpp` to `Android.bp` and setting
-`log_buffer = new SimpleLogBuffer(&reader_list, &log_tags, &log_statistics);` in `main.cpp`.
-
-Recording messages may delay the Log() function from completing and it is highly recommended to make
-the logd socket in `liblog` blocking, by removing `SOCK_NONBLOCK` from the `socket()` call in
-`liblog/logd_writer.cpp`.
-
-Replaying Messages
-------------------
-
-Recorded messages can be replayed offline with the `replay_messages` tool.  It runs on host and
-device and supports the following options:
-
-1. `interesting` - this prints 'interesting' statistics for each of the log buffer types (simple,
-   chatty, serialized).  The statistics are:
-    1. Log Entry Count
-    2. Size (the uncompressed size of the log messages in bytes)
-    3. Overhead (the total cost of the log messages in memory in bytes)
-    4. Range (the range of time that the logs cover in seconds)
-2. `memory_usage BUFFER_TYPE` - this prints the memory usage (sum of private dirty pages of the
-  `replay_messages` process).  Note that the input file is mmap()'ed as RO/Shared so it does not
-  appear in these dirty pages, and a baseline is taken before allocating the log buffers, so only
-  their contributions are measured.  The tool outputs the memory usage every 100,000 messages.
-3. `latency BUFFER_TYPE` - this prints statistics of the latency of the Log() function for the given
-  buffer type.  It specifically prints the 1st, 2nd, and 3rd quartiles; the 95th, 99th, and 99.99th
-  percentiles; and the maximum latency.
-4. `print_logs BUFFER_TYPE [buffers] [print_point]` - this prints the logs as processed by the given
-  buffer_type from the buffers specified by `buffers` starting after the number of logs specified by
-  `print_point` have been logged.  This acts as if a user called `logcat` immediately after the
-  specified logs have been logged, which is particularly useful since it will show the chatty
-  pruning messages at that point.  It additionally prints the statistics from `logcat -S` after the
-  logs.
-  `buffers` is a comma separated list of the numeric buffer id values from `<android/log.h>`.  For
-  example, `0,1,3` represents the main, radio, and system buffers.  It can can also be `all`.
-  `print_point` is an positive integer.  If it is unspecified, logs are printed after the entire
-  input file is consumed.
-5. `nothing BUFFER_TYPE` - this does nothing other than read the input file and call Log() for the
-  given buffer type.  This is used for profiling CPU usage of strictly the log buffer.
diff --git a/logd/RecordedLogMessage.h b/logd/RecordedLogMessage.h
deleted file mode 100644
index f18c422..0000000
--- a/logd/RecordedLogMessage.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <inttypes.h>
-
-#include <log/log_time.h>
-
-struct __attribute__((packed)) RecordedLogMessage {
-    uint32_t uid;
-    uint32_t pid;
-    uint32_t tid;
-    log_time realtime;
-    uint16_t msg_len;
-    uint8_t log_id;
-};
diff --git a/logd/RecordingLogBuffer.cpp b/logd/RecordingLogBuffer.cpp
deleted file mode 100644
index f5991f3..0000000
--- a/logd/RecordingLogBuffer.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 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 "RecordingLogBuffer.h"
-
-#include <android-base/file.h>
-
-static void WriteLogMessage(int fd, const RecordedLogMessage& meta, const std::string& msg) {
-    android::base::WriteFully(fd, &meta, sizeof(meta));
-    android::base::WriteFully(fd, msg.c_str(), meta.msg_len);
-}
-
-void RecordingLogBuffer::RecordLogMessage(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
-                                          pid_t tid, const char* msg, uint16_t len) {
-    auto lock = std::lock_guard{lock_};
-    if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
-        len = LOGGER_ENTRY_MAX_PAYLOAD;
-    }
-
-    RecordedLogMessage recorded_log_message = {
-            .uid = uid,
-            .pid = static_cast<uint32_t>(pid),
-            .tid = static_cast<uint32_t>(tid),
-            .realtime = realtime,
-            .msg_len = len,
-            .log_id = static_cast<uint8_t>(log_id),
-    };
-
-    if (!fd_.ok()) {
-        fd_.reset(open("/data/misc/logd/recorded-messages",
-                       O_WRONLY | O_CREAT | O_APPEND | O_CLOEXEC, 0666));
-        if (!fd_.ok()) {
-            since_boot_messages_.emplace_back(recorded_log_message, std::string(msg, len));
-            return;
-        } else {
-            for (const auto& [meta, msg] : since_boot_messages_) {
-                WriteLogMessage(fd_.get(), meta, msg);
-            }
-        }
-    }
-
-    WriteLogMessage(fd_.get(), recorded_log_message, std::string(msg, len));
-}
-
-int RecordingLogBuffer::Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                            const char* msg, uint16_t len) {
-    RecordLogMessage(log_id, realtime, uid, pid, tid, msg, len);
-    return SimpleLogBuffer::Log(log_id, realtime, uid, pid, tid, msg, len);
-}
\ No newline at end of file
diff --git a/logd/RecordingLogBuffer.h b/logd/RecordingLogBuffer.h
deleted file mode 100644
index 49a0aba..0000000
--- a/logd/RecordingLogBuffer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include "SimpleLogBuffer.h"
-
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-
-#include "RecordedLogMessage.h"
-
-class RecordingLogBuffer : public SimpleLogBuffer {
-  public:
-    RecordingLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats)
-        : SimpleLogBuffer(reader_list, tags, stats) {}
-
-    int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
-            uint16_t len) override;
-
-  private:
-    void RecordLogMessage(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                          const char* msg, uint16_t len);
-
-    std::vector<std::pair<RecordedLogMessage, std::string>> since_boot_messages_;
-    android::base::unique_fd fd_;
-};
diff --git a/logd/ReplayMessages.cpp b/logd/ReplayMessages.cpp
deleted file mode 100644
index 56509ec..0000000
--- a/logd/ReplayMessages.cpp
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Copyright (C) 2020 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 <inttypes.h>
-
-#include <chrono>
-#include <map>
-
-#include <android-base/file.h>
-#include <android-base/mapped_file.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <android/log.h>
-#include <log/log_time.h>
-#include <log/logprint.h>
-
-#include "ChattyLogBuffer.h"
-#include "LogBuffer.h"
-#include "LogStatistics.h"
-#include "RecordedLogMessage.h"
-#include "SerializedLogBuffer.h"
-#include "SimpleLogBuffer.h"
-
-using android::base::MappedFile;
-using android::base::ParseInt;
-using android::base::ParseUint;
-using android::base::Split;
-
-char* android::uidToName(uid_t) {
-    return nullptr;
-}
-
-static size_t GetPrivateDirty() {
-    // Allocate once and hope that we don't need to reallocate >40000, to prevent heap fragmentation
-    static std::string smaps(40000, '\0');
-    android::base::ReadFileToString("/proc/self/smaps", &smaps);
-
-    size_t result = 0;
-    size_t base = 0;
-    size_t found;
-    while (true) {
-        found = smaps.find("Private_Dirty:", base);
-        if (found == smaps.npos) break;
-
-        found += sizeof("Private_Dirty:");
-
-        result += atoi(&smaps[found]);
-
-        base = found + 1;
-    }
-
-    return result;
-}
-
-static AndroidLogFormat* GetLogFormat() {
-    static AndroidLogFormat* format = [] {
-        auto* format = android_log_format_new();
-        android_log_setPrintFormat(format, android_log_formatFromString("threadtime"));
-        android_log_setPrintFormat(format, android_log_formatFromString("uid"));
-        return format;
-    }();
-    return format;
-}
-
-static void PrintMessage(struct log_msg* buf) {
-    bool is_binary =
-            buf->id() == LOG_ID_EVENTS || buf->id() == LOG_ID_STATS || buf->id() == LOG_ID_SECURITY;
-
-    AndroidLogEntry entry;
-    int err;
-    if (is_binary) {
-        char binaryMsgBuf[1024];
-        err = android_log_processBinaryLogBuffer(&buf->entry, &entry, nullptr, binaryMsgBuf,
-                                                 sizeof(binaryMsgBuf));
-    } else {
-        err = android_log_processLogBuffer(&buf->entry, &entry);
-    }
-    if (err < 0) {
-        fprintf(stderr, "Error parsing log message\n");
-    }
-
-    android_log_printLogLine(GetLogFormat(), STDOUT_FILENO, &entry);
-}
-
-static log_time GetFirstTimeStamp(const MappedFile& recorded_messages) {
-    if (sizeof(RecordedLogMessage) >= recorded_messages.size()) {
-        fprintf(stderr, "At least one log message must be present in the input\n");
-        exit(1);
-    }
-
-    auto* meta = reinterpret_cast<RecordedLogMessage*>(recorded_messages.data());
-    return meta->realtime;
-}
-
-static LogMask BuffersToLogMask(const char* buffers) {
-    if (buffers == nullptr || !strcmp(buffers, "all")) {
-        return kLogMaskAll;
-    }
-    auto string_ids = Split(buffers, ",");
-    LogMask log_mask = 0;
-    for (const auto& string_id : string_ids) {
-        int buffer_id;
-        if (!ParseInt(string_id, &buffer_id, 0, 7)) {
-            fprintf(stderr, "Could not parse buffer_id '%s'\n", string_id.c_str());
-            exit(1);
-        }
-        log_mask |= 1 << buffer_id;
-    }
-    return log_mask;
-}
-
-class StdoutWriter : public LogWriter {
-  public:
-    StdoutWriter() : LogWriter(0, true) {}
-    bool Write(const logger_entry& entry, const char* message) override {
-        struct log_msg log_msg;
-        log_msg.entry = entry;
-        if (log_msg.entry.len > LOGGER_ENTRY_MAX_PAYLOAD) {
-            fprintf(stderr, "payload too large %" PRIu16, log_msg.entry.len);
-            exit(1);
-        }
-        memcpy(log_msg.msg(), message, log_msg.entry.len);
-
-        PrintMessage(&log_msg);
-
-        return true;
-    }
-
-    void Shutdown() override {
-        fprintf(stderr, "LogWriter::Shutdown() called\n");
-        exit(1);
-    }
-
-    std::string name() const override { return "stdout writer"; }
-};
-
-class Operation {
-  public:
-    virtual ~Operation() {}
-
-    virtual void Begin() {}
-    virtual void Log(const RecordedLogMessage& meta, const char* msg) = 0;
-    virtual void End() {}
-};
-
-class PrintInteresting : public Operation {
-  public:
-    PrintInteresting(log_time first_log_timestamp)
-        : stats_simple_{false, false, first_log_timestamp},
-          stats_chatty_{false, false, first_log_timestamp},
-          stats_serialized_{false, true, first_log_timestamp} {}
-
-    void Begin() override {
-        printf("message_count,simple_main_lines,simple_radio_lines,simple_events_lines,simple_"
-               "system_lines,simple_crash_lines,simple_stats_lines,simple_security_lines,simple_"
-               "kernel_lines,simple_main_size,simple_radio_size,simple_events_size,simple_system_"
-               "size,simple_crash_size,simple_stats_size,simple_security_size,simple_kernel_size,"
-               "simple_main_overhead,simple_radio_overhead,simple_events_overhead,simple_system_"
-               "overhead,simple_crash_overhead,simple_stats_overhead,simple_security_overhead,"
-               "simple_kernel_overhead,simple_main_range,simple_radio_range,simple_events_range,"
-               "simple_system_range,simple_crash_range,simple_stats_range,simple_security_range,"
-               "simple_kernel_range,chatty_main_lines,chatty_radio_lines,chatty_events_lines,"
-               "chatty_system_lines,chatty_crash_lines,chatty_stats_lines,chatty_security_lines,"
-               "chatty_"
-               "kernel_lines,chatty_main_size,chatty_radio_size,chatty_events_size,chatty_system_"
-               "size,chatty_crash_size,chatty_stats_size,chatty_security_size,chatty_kernel_size,"
-               "chatty_main_overhead,chatty_radio_overhead,chatty_events_overhead,chatty_system_"
-               "overhead,chatty_crash_overhead,chatty_stats_overhead,chatty_security_overhead,"
-               "chatty_kernel_overhead,chatty_main_range,chatty_radio_range,chatty_events_range,"
-               "chatty_system_range,chatty_crash_range,chatty_stats_range,chatty_security_range,"
-               "chatty_kernel_range,serialized_main_lines,serialized_radio_lines,serialized_events_"
-               "lines,serialized_"
-               "system_lines,serialized_crash_lines,serialized_stats_lines,serialized_security_"
-               "lines,serialized_"
-               "kernel_lines,serialized_main_size,serialized_radio_size,serialized_events_size,"
-               "serialized_system_"
-               "size,serialized_crash_size,serialized_stats_size,serialized_security_size,"
-               "serialized_kernel_size,"
-               "serialized_main_overhead,serialized_radio_overhead,serialized_events_overhead,"
-               "serialized_system_"
-               "overhead,serialized_crash_overhead,serialized_stats_overhead,serialized_security_"
-               "overhead,"
-               "serialized_kernel_overhead,serialized_main_range,serialized_radio_range,serialized_"
-               "events_range,"
-               "serialized_system_range,serialized_crash_range,serialized_stats_range,serialized_"
-               "security_range,"
-               "serialized_kernel_range\n");
-    }
-
-    void Log(const RecordedLogMessage& meta, const char* msg) override {
-        simple_log_buffer_.Log(static_cast<log_id_t>(meta.log_id), meta.realtime, meta.uid,
-                               meta.pid, meta.tid, msg, meta.msg_len);
-
-        chatty_log_buffer_.Log(static_cast<log_id_t>(meta.log_id), meta.realtime, meta.uid,
-                               meta.pid, meta.tid, msg, meta.msg_len);
-
-        serialized_log_buffer_.Log(static_cast<log_id_t>(meta.log_id), meta.realtime, meta.uid,
-                                   meta.pid, meta.tid, msg, meta.msg_len);
-
-        if (num_message_ % 10000 == 0) {
-            printf("%" PRIu64 ",%s,%s,%s\n", num_message_,
-                   stats_simple_.ReportInteresting().c_str(),
-                   stats_chatty_.ReportInteresting().c_str(),
-                   stats_serialized_.ReportInteresting().c_str());
-        }
-
-        num_message_++;
-    }
-
-  private:
-    uint64_t num_message_ = 1;
-
-    LogReaderList reader_list_;
-    LogTags tags_;
-    PruneList prune_list_;
-
-    LogStatistics stats_simple_;
-    SimpleLogBuffer simple_log_buffer_{&reader_list_, &tags_, &stats_simple_};
-
-    LogStatistics stats_chatty_;
-    ChattyLogBuffer chatty_log_buffer_{&reader_list_, &tags_, &prune_list_, &stats_chatty_};
-
-    LogStatistics stats_serialized_;
-    SerializedLogBuffer serialized_log_buffer_{&reader_list_, &tags_, &stats_serialized_};
-};
-
-class SingleBufferOperation : public Operation {
-  public:
-    SingleBufferOperation(log_time first_log_timestamp, const char* buffer) {
-        if (!strcmp(buffer, "simple")) {
-            stats_.reset(new LogStatistics{false, false, first_log_timestamp});
-            log_buffer_.reset(new SimpleLogBuffer(&reader_list_, &tags_, stats_.get()));
-        } else if (!strcmp(buffer, "chatty")) {
-            stats_.reset(new LogStatistics{false, false, first_log_timestamp});
-            log_buffer_.reset(
-                    new ChattyLogBuffer(&reader_list_, &tags_, &prune_list_, stats_.get()));
-        } else if (!strcmp(buffer, "serialized")) {
-            stats_.reset(new LogStatistics{false, true, first_log_timestamp});
-            log_buffer_.reset(new SerializedLogBuffer(&reader_list_, &tags_, stats_.get()));
-        } else {
-            fprintf(stderr, "invalid log buffer type '%s'\n", buffer);
-            abort();
-        }
-    }
-
-    void Log(const RecordedLogMessage& meta, const char* msg) override {
-        PreOperation();
-        log_buffer_->Log(static_cast<log_id_t>(meta.log_id), meta.realtime, meta.uid, meta.pid,
-                         meta.tid, msg, meta.msg_len);
-
-        Operation();
-
-        num_message_++;
-    }
-
-    virtual void PreOperation() {}
-    virtual void Operation() {}
-
-  protected:
-    uint64_t num_message_ = 1;
-
-    LogReaderList reader_list_;
-    LogTags tags_;
-    PruneList prune_list_;
-
-    std::unique_ptr<LogStatistics> stats_;
-    std::unique_ptr<LogBuffer> log_buffer_;
-};
-
-class PrintMemory : public SingleBufferOperation {
-  public:
-    PrintMemory(log_time first_log_timestamp, const char* buffer)
-        : SingleBufferOperation(first_log_timestamp, buffer) {}
-
-    void Operation() override {
-        if (num_message_ % 100000 == 0) {
-            printf("%" PRIu64 ",%s\n", num_message_,
-                   std::to_string(GetPrivateDirty() - baseline_memory_).c_str());
-        }
-    }
-
-  private:
-    size_t baseline_memory_ = GetPrivateDirty();
-};
-
-class PrintLogs : public SingleBufferOperation {
-  public:
-    PrintLogs(log_time first_log_timestamp, const char* buffer, const char* buffers,
-              const char* print_point)
-        : SingleBufferOperation(first_log_timestamp, buffer) {
-        mask_ = BuffersToLogMask(buffers);
-        if (print_point != nullptr) {
-            uint64_t result = 0;
-            if (!ParseUint(print_point, &result)) {
-                fprintf(stderr, "Could not parse print point '%s'\n", print_point);
-                exit(1);
-            }
-            print_point_ = result;
-        }
-    }
-
-    void Operation() override {
-        if (print_point_ && num_message_ >= *print_point_) {
-            End();
-            exit(0);
-        }
-    }
-
-    void End() override {
-        std::unique_ptr<LogWriter> test_writer(new StdoutWriter());
-        std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, mask_);
-        log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr);
-
-        auto stats_string = stats_->Format(0, 0, mask_);
-        printf("%s\n", stats_string.c_str());
-    }
-
-  private:
-    LogMask mask_ = kLogMaskAll;
-    std::optional<uint64_t> print_point_;
-};
-
-class PrintLatency : public SingleBufferOperation {
-  public:
-    PrintLatency(log_time first_log_timestamp, const char* buffer)
-        : SingleBufferOperation(first_log_timestamp, buffer) {}
-
-    void PreOperation() override { operation_start_ = std::chrono::steady_clock::now(); }
-
-    void Operation() override {
-        auto end = std::chrono::steady_clock::now();
-        auto duration = (end - operation_start_).count();
-        durations_.emplace_back(duration);
-    }
-
-    void End() override {
-        std::sort(durations_.begin(), durations_.end());
-        auto q1 = durations_.size() / 4;
-        auto q2 = durations_.size() / 2;
-        auto q3 = 3 * durations_.size() / 4;
-
-        auto p95 = 95 * durations_.size() / 100;
-        auto p99 = 99 * durations_.size() / 100;
-        auto p9999 = 9999 * durations_.size() / 10000;
-
-        printf("q1: %lld q2: %lld q3: %lld  p95: %lld p99: %lld p99.99: %lld  max: %lld\n",
-               durations_[q1], durations_[q2], durations_[q3], durations_[p95], durations_[p99],
-               durations_[p9999], durations_.back());
-    }
-
-  private:
-    std::chrono::steady_clock::time_point operation_start_;
-    std::vector<long long> durations_;
-};
-
-class PrintAllLogs : public SingleBufferOperation {
-  public:
-    PrintAllLogs(log_time first_log_timestamp, const char* buffer, const char* buffers)
-        : SingleBufferOperation(first_log_timestamp, buffer) {
-        LogMask mask = BuffersToLogMask(buffers);
-        auto lock = std::unique_lock{reader_list_.reader_threads_lock()};
-        std::unique_ptr<LogWriter> stdout_writer(new StdoutWriter());
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(stdout_writer),
-                                    false, 0, mask, 0, {}, 1, {}));
-        reader_list_.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    void Operation() override {
-        // If the rate of reading logs is slower than the rate of incoming logs, then the reader
-        // thread is disconnected to not overflow log buffers, therefore we artificially slow down
-        // the incoming log rate.
-        usleep(100);
-    }
-};
-
-int main(int argc, char** argv) {
-    if (argc < 3) {
-        fprintf(stderr, "Usage: %s FILE OPERATION [BUFFER] [OPTIONS]\n", argv[0]);
-        return 1;
-    }
-
-    if (strcmp(argv[2], "interesting") != 0 && argc < 4) {
-        fprintf(stderr, "Operations other than 'interesting' require a BUFFER argument\n");
-        return 1;
-    }
-
-    int recorded_messages_fd = open(argv[1], O_RDONLY);
-    if (recorded_messages_fd == -1) {
-        fprintf(stderr, "Couldn't open input file\n");
-        return 1;
-    }
-    struct stat fd_stat;
-    if (fstat(recorded_messages_fd, &fd_stat) != 0) {
-        fprintf(stderr, "Couldn't fstat input file\n");
-        return 1;
-    }
-    auto recorded_messages = MappedFile::FromFd(recorded_messages_fd, 0,
-                                                static_cast<size_t>(fd_stat.st_size), PROT_READ);
-    if (recorded_messages == nullptr) {
-        fprintf(stderr, "Couldn't mmap input file\n");
-        return 1;
-    }
-
-    // LogStatistics typically uses 'now()' to initialize its log range state, but this doesn't work
-    // when replaying older logs, so we instead give it the timestamp from the first log.
-    log_time first_log_timestamp = GetFirstTimeStamp(*recorded_messages);
-
-    std::unique_ptr<Operation> operation;
-    if (!strcmp(argv[2], "interesting")) {
-        operation.reset(new PrintInteresting(first_log_timestamp));
-    } else if (!strcmp(argv[2], "memory_usage")) {
-        operation.reset(new PrintMemory(first_log_timestamp, argv[3]));
-    } else if (!strcmp(argv[2], "latency")) {
-        operation.reset(new PrintLatency(first_log_timestamp, argv[3]));
-    } else if (!strcmp(argv[2], "print_logs")) {
-        operation.reset(new PrintLogs(first_log_timestamp, argv[3], argc > 4 ? argv[4] : nullptr,
-                                      argc > 5 ? argv[5] : nullptr));
-    } else if (!strcmp(argv[2], "print_all_logs")) {
-        operation.reset(
-                new PrintAllLogs(first_log_timestamp, argv[3], argc > 4 ? argv[4] : nullptr));
-    } else if (!strcmp(argv[2], "nothing")) {
-        operation.reset(new SingleBufferOperation(first_log_timestamp, argv[3]));
-    } else {
-        fprintf(stderr, "unknown operation '%s'\n", argv[2]);
-        return 1;
-    }
-
-    // LogBuffer::Log() won't log without this on host.
-    __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
-    // But we still want to suppress messages <= error to not interrupt the rest of the output.
-    __android_log_set_logger([](const struct __android_log_message* log_message) {
-        if (log_message->priority < ANDROID_LOG_ERROR) {
-            return;
-        }
-        __android_log_stderr_logger(log_message);
-    });
-
-    operation->Begin();
-
-    uint64_t read_position = 0;
-    while (read_position + sizeof(RecordedLogMessage) < recorded_messages->size()) {
-        auto* meta =
-                reinterpret_cast<RecordedLogMessage*>(recorded_messages->data() + read_position);
-        if (read_position + sizeof(RecordedLogMessage) + meta->msg_len >=
-            recorded_messages->size()) {
-            break;
-        }
-        char* msg = recorded_messages->data() + read_position + sizeof(RecordedLogMessage);
-        read_position += sizeof(RecordedLogMessage) + meta->msg_len;
-
-        operation->Log(*meta, msg);
-    }
-
-    operation->End();
-
-    return 0;
-}
diff --git a/logd/SerializedData.h b/logd/SerializedData.h
deleted file mode 100644
index d3d1e18..0000000
--- a/logd/SerializedData.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <algorithm>
-#include <memory>
-
-// This class is used instead of std::string or std::vector because their clear(), erase(), etc
-// functions don't actually deallocate.  shrink_to_fit() does deallocate but is not guaranteed to
-// work and swapping with an empty string/vector is clunky.
-class SerializedData {
-  public:
-    SerializedData() {}
-    SerializedData(size_t size) : data_(new uint8_t[size]), size_(size) {}
-
-    void Resize(size_t new_size) {
-        if (size_ == 0) {
-            data_.reset(new uint8_t[new_size]);
-            size_ = new_size;
-        } else if (new_size == 0) {
-            data_.reset();
-            size_ = 0;
-        } else if (new_size != size_) {
-            std::unique_ptr<uint8_t[]> new_data(new uint8_t[new_size]);
-            size_t copy_size = std::min(size_, new_size);
-            memcpy(new_data.get(), data_.get(), copy_size);
-            data_.swap(new_data);
-            size_ = new_size;
-        }
-    }
-
-    uint8_t* data() { return data_.get(); }
-    const uint8_t* data() const { return data_.get(); }
-    size_t size() const { return size_; }
-
-  private:
-    std::unique_ptr<uint8_t[]> data_;
-    size_t size_ = 0;
-};
\ No newline at end of file
diff --git a/logd/SerializedFlushToState.cpp b/logd/SerializedFlushToState.cpp
deleted file mode 100644
index b02ccc3..0000000
--- a/logd/SerializedFlushToState.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2020 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 "SerializedFlushToState.h"
-
-#include <android-base/logging.h>
-
-SerializedFlushToState::SerializedFlushToState(uint64_t start, LogMask log_mask)
-    : FlushToState(start, log_mask) {
-    log_id_for_each(i) {
-        if (((1 << i) & log_mask) == 0) {
-            continue;
-        }
-        logs_needed_from_next_position_[i] = true;
-    }
-}
-
-SerializedFlushToState::~SerializedFlushToState() {
-    log_id_for_each(i) {
-        if (log_positions_[i]) {
-            log_positions_[i]->buffer_it->DecReaderRefCount();
-        }
-    }
-}
-
-void SerializedFlushToState::CreateLogPosition(log_id_t log_id) {
-    CHECK(!logs_[log_id].empty());
-    LogPosition log_position;
-    auto it = logs_[log_id].begin();
-    while (it != logs_[log_id].end() && start() > it->highest_sequence_number()) {
-        ++it;
-    }
-    if (it == logs_[log_id].end()) {
-        --it;
-    }
-    it->IncReaderRefCount();
-    log_position.buffer_it = it;
-
-    // Find the offset of the first log with sequence number >= start().
-    int read_offset = 0;
-    while (read_offset < it->write_offset()) {
-        const auto* entry = it->log_entry(read_offset);
-        if (entry->sequence() >= start()) {
-            break;
-        }
-        read_offset += entry->total_len();
-    }
-    log_position.read_offset = read_offset;
-
-    log_positions_[log_id].emplace(log_position);
-}
-
-void SerializedFlushToState::AddMinHeapEntry(log_id_t log_id) {
-    auto& buffer_it = log_positions_[log_id]->buffer_it;
-    auto read_offset = log_positions_[log_id]->read_offset;
-
-    // If there is another log to read in this buffer, add it to the min heap.
-    if (read_offset < buffer_it->write_offset()) {
-        auto* entry = buffer_it->log_entry(read_offset);
-        min_heap_.emplace(log_id, entry);
-    } else if (read_offset == buffer_it->write_offset()) {
-        // If there are no more logs to read in this buffer and it's the last buffer, then
-        // set logs_needed_from_next_position_ to wait until more logs get logged.
-        if (buffer_it == std::prev(logs_[log_id].end())) {
-            logs_needed_from_next_position_[log_id] = true;
-        } else {
-            // Otherwise, if there is another buffer piece, move to that and do the same check.
-            buffer_it->DecReaderRefCount();
-            ++buffer_it;
-            buffer_it->IncReaderRefCount();
-            log_positions_[log_id]->read_offset = 0;
-            if (buffer_it->write_offset() == 0) {
-                logs_needed_from_next_position_[log_id] = true;
-            } else {
-                auto* entry = buffer_it->log_entry(0);
-                min_heap_.emplace(log_id, entry);
-            }
-        }
-    } else {
-        // read_offset > buffer_it->write_offset() should never happen.
-        CHECK(false);
-    }
-}
-
-void SerializedFlushToState::CheckForNewLogs() {
-    log_id_for_each(i) {
-        if (!logs_needed_from_next_position_[i]) {
-            continue;
-        }
-        if (!log_positions_[i]) {
-            if (logs_[i].empty()) {
-                continue;
-            }
-            CreateLogPosition(i);
-        }
-        logs_needed_from_next_position_[i] = false;
-        // If it wasn't possible to insert, logs_needed_from_next_position will be set back to true.
-        AddMinHeapEntry(i);
-    }
-}
-
-MinHeapElement SerializedFlushToState::PopNextUnreadLog() {
-    auto top = min_heap_.top();
-    min_heap_.pop();
-
-    auto* entry = top.entry;
-    auto log_id = top.log_id;
-
-    log_positions_[log_id]->read_offset += entry->total_len();
-
-    logs_needed_from_next_position_[log_id] = true;
-
-    return top;
-}
-
-void SerializedFlushToState::Prune(log_id_t log_id,
-                                   const std::list<SerializedLogChunk>::iterator& buffer_it) {
-    // If we don't have a position for this log or if we're not referencing buffer_it, ignore.
-    if (!log_positions_[log_id].has_value() || log_positions_[log_id]->buffer_it != buffer_it) {
-        return;
-    }
-
-    // // Decrease the ref count since we're deleting our reference.
-    buffer_it->DecReaderRefCount();
-
-    // Delete in the reference.
-    log_positions_[log_id].reset();
-
-    // Remove the MinHeapElement referencing log_id, if it exists, but retain the others.
-    std::vector<MinHeapElement> old_elements;
-    while (!min_heap_.empty()) {
-        auto& element = min_heap_.top();
-        if (element.log_id != log_id) {
-            old_elements.emplace_back(element);
-        }
-        min_heap_.pop();
-    }
-    for (auto&& element : old_elements) {
-        min_heap_.emplace(element);
-    }
-
-    // Finally set logs_needed_from_next_position_, so CheckForNewLogs() will re-create the
-    // log_position_ object during the next read.
-    logs_needed_from_next_position_[log_id] = true;
-}
diff --git a/logd/SerializedFlushToState.h b/logd/SerializedFlushToState.h
deleted file mode 100644
index 0b20822..0000000
--- a/logd/SerializedFlushToState.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <bitset>
-#include <list>
-#include <queue>
-
-#include "LogBuffer.h"
-#include "SerializedLogChunk.h"
-#include "SerializedLogEntry.h"
-
-struct LogPosition {
-    std::list<SerializedLogChunk>::iterator buffer_it;
-    int read_offset;
-};
-
-struct MinHeapElement {
-    MinHeapElement(log_id_t log_id, const SerializedLogEntry* entry)
-        : log_id(log_id), entry(entry) {}
-    log_id_t log_id;
-    const SerializedLogEntry* entry;
-    // The change of comparison operators is intentional, std::priority_queue uses operator<() to
-    // compare but creates a max heap.  Since we want a min heap, we return the opposite result.
-    bool operator<(const MinHeapElement& rhs) const {
-        return entry->sequence() > rhs.entry->sequence();
-    }
-};
-
-// This class tracks the specific point where a FlushTo client has read through the logs.  It
-// directly references the std::list<> iterators from the parent SerializedLogBuffer and the offset
-// into each log chunk where it has last read.  All interactions with this class, except for its
-// construction, must be done with SerializedLogBuffer::lock_ held.  No log chunks that it
-// references may be pruned, which is handled by ensuring prune does not touch any log chunk with
-// highest sequence number greater or equal to start().
-class SerializedFlushToState : public FlushToState {
-  public:
-    // Initializes this state object.  For each log buffer set in log_mask, this sets
-    // logs_needed_from_next_position_.
-    SerializedFlushToState(uint64_t start, LogMask log_mask);
-
-    // Decrease the reference of all referenced logs.  This happens when a reader is disconnected.
-    ~SerializedFlushToState() override;
-
-    // We can't hold SerializedLogBuffer::lock_ in the constructor, so we must initialize logs here.
-    void InitializeLogs(std::list<SerializedLogChunk>* logs) {
-        if (logs_ == nullptr) logs_ = logs;
-    }
-
-    bool HasUnreadLogs() {
-        CheckForNewLogs();
-        return !min_heap_.empty();
-    }
-
-    // Pops the next unread log from the min heap and sets logs_needed_from_next_position_ to
-    // indicate that we're waiting for more logs from the associated log buffer.
-    MinHeapElement PopNextUnreadLog();
-
-    // If the parent log buffer prunes logs, the reference that this class contains may become
-    // invalid, so this must be called first to drop the reference to buffer_it, if any.
-    void Prune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& buffer_it);
-
-  private:
-    // If there is a log in the serialized log buffer for `log_id` at the read_offset, add it to the
-    // min heap for reading, otherwise set logs_needed_from_next_position_ to indicate that we're
-    // waiting for the next log.
-    void AddMinHeapEntry(log_id_t log_id);
-
-    // Create a LogPosition object for the given log_id by searching through the log chunks for the
-    // first chunk and then first log entry within that chunk that is greater or equal to start().
-    void CreateLogPosition(log_id_t log_id);
-
-    // Checks to see if any log buffers set in logs_needed_from_next_position_ have new logs and
-    // calls AddMinHeapEntry() if so.
-    void CheckForNewLogs();
-
-    std::list<SerializedLogChunk>* logs_ = nullptr;
-    // An optional structure that contains an iterator to the serialized log buffer and offset into
-    // it that this logger should handle next.
-    std::optional<LogPosition> log_positions_[LOG_ID_MAX];
-    // A bit for each log that is set if a given log_id has no logs or if this client has read all
-    // of its logs. In order words: `logs_[i].empty() || (buffer_it == std::prev(logs_.end) &&
-    // next_log_position == logs_write_position_)`.  These will be re-checked in each
-    // loop in case new logs came in.
-    std::bitset<LOG_ID_MAX> logs_needed_from_next_position_ = {};
-    // A min heap that has up to one entry per log buffer, sorted by sequence number, of the next
-    // element that this reader should read.
-    std::priority_queue<MinHeapElement> min_heap_;
-};
diff --git a/logd/SerializedFlushToStateTest.cpp b/logd/SerializedFlushToStateTest.cpp
deleted file mode 100644
index f4515c8..0000000
--- a/logd/SerializedFlushToStateTest.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2020 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 "SerializedFlushToState.h"
-
-#include <map>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <gtest/gtest.h>
-
-using android::base::Join;
-using android::base::StringPrintf;
-
-constexpr size_t kChunkSize = 3 * 4096;
-
-class SerializedFlushToStateTest : public testing::Test {
-  protected:
-    void SetUp() override {
-        // This test spams many unneeded INFO logs, so we suppress them.
-        old_log_severity_ = android::base::SetMinimumLogSeverity(android::base::WARNING);
-    }
-    void TearDown() override { android::base::SetMinimumLogSeverity(old_log_severity_); }
-
-    std::string TestReport(const std::vector<uint64_t>& expected,
-                           const std::vector<uint64_t>& read) {
-        auto sequence_to_log_id = [&](uint64_t sequence) -> int {
-            for (const auto& [log_id, sequences] : sequence_numbers_per_buffer_) {
-                if (std::find(sequences.begin(), sequences.end(), sequence) != sequences.end()) {
-                    return log_id;
-                }
-            }
-            return -1;
-        };
-
-        std::map<int, std::vector<uint64_t>> missing_sequences;
-        std::vector<uint64_t> missing_expected;
-        std::set_difference(expected.begin(), expected.end(), read.begin(), read.end(),
-                            std::back_inserter(missing_expected));
-        for (uint64_t sequence : missing_expected) {
-            int log_id = sequence_to_log_id(sequence);
-            missing_sequences[log_id].emplace_back(sequence);
-        }
-
-        std::map<int, std::vector<uint64_t>> extra_sequences;
-        std::vector<uint64_t> extra_read;
-        std::set_difference(read.begin(), read.end(), expected.begin(), expected.end(),
-                            std::back_inserter(extra_read));
-        for (uint64_t sequence : extra_read) {
-            int log_id = sequence_to_log_id(sequence);
-            extra_sequences[log_id].emplace_back(sequence);
-        }
-
-        std::vector<std::string> errors;
-        for (const auto& [log_id, sequences] : missing_sequences) {
-            errors.emplace_back(
-                    StringPrintf("Log id %d missing %zu sequences", log_id, sequences.size()));
-        }
-
-        for (const auto& [log_id, sequences] : extra_sequences) {
-            errors.emplace_back(
-                    StringPrintf("Log id %d has extra %zu sequences", log_id, sequences.size()));
-        }
-
-        return Join(errors, ", ");
-    }
-
-    // Read sequence numbers in order from SerializedFlushToState for every mask combination and all
-    // sequence numbers from 0 through the highest logged sequence number + 1.
-    // This assumes that all of the logs have already been written.
-    void TestAllReading() {
-        uint64_t max_sequence = sequence_ + 1;
-        uint32_t max_mask = (1 << LOG_ID_MAX) - 1;
-        for (uint64_t sequence = 0; sequence < max_sequence; ++sequence) {
-            for (uint32_t mask = 0; mask < max_mask; ++mask) {
-                auto state = SerializedFlushToState{sequence, mask};
-                state.InitializeLogs(log_chunks_);
-                TestReading(sequence, mask, state);
-            }
-        }
-    }
-
-    // Similar to TestAllReading() except that it doesn't assume any logs are in the buffer, instead
-    // it calls write_logs() in a loop for sequence/mask combination.  It clears log_chunks_ and
-    // sequence_numbers_per_buffer_ between calls, such that only the sequence numbers written in
-    // the previous call to write_logs() are expected.
-    void TestAllReadingWithFutureMessages(const std::function<bool(int)>& write_logs) {
-        uint64_t max_sequence = sequence_ + 1;
-        uint32_t max_mask = (1 << LOG_ID_MAX) - 1;
-        for (uint64_t sequence = 1; sequence < max_sequence; ++sequence) {
-            for (uint32_t mask = 1; mask < max_mask; ++mask) {
-                log_id_for_each(i) { log_chunks_[i].clear(); }
-                auto state = SerializedFlushToState{sequence, mask};
-                state.InitializeLogs(log_chunks_);
-                int loop_count = 0;
-                while (write_logs(loop_count++)) {
-                    TestReading(sequence, mask, state);
-                    sequence_numbers_per_buffer_.clear();
-                }
-            }
-        }
-    }
-
-    void TestReading(uint64_t start, LogMask log_mask, SerializedFlushToState& state) {
-        std::vector<uint64_t> expected_sequence;
-        log_id_for_each(i) {
-            if (((1 << i) & log_mask) == 0) {
-                continue;
-            }
-            for (const auto& sequence : sequence_numbers_per_buffer_[i]) {
-                if (sequence >= start) {
-                    expected_sequence.emplace_back(sequence);
-                }
-            }
-        }
-        std::sort(expected_sequence.begin(), expected_sequence.end());
-
-        std::vector<uint64_t> read_sequence;
-
-        while (state.HasUnreadLogs()) {
-            auto top = state.PopNextUnreadLog();
-            read_sequence.emplace_back(top.entry->sequence());
-        }
-
-        EXPECT_TRUE(std::is_sorted(read_sequence.begin(), read_sequence.end()));
-
-        EXPECT_EQ(expected_sequence.size(), read_sequence.size());
-
-        EXPECT_EQ(expected_sequence, read_sequence)
-                << "start: " << start << " log_mask: " << log_mask << " "
-                << TestReport(expected_sequence, read_sequence);
-    }
-
-    // Add a chunk with the given messages to the a given log buffer.  Keep track of the sequence
-    // numbers for future validation.  Optionally mark the block as having finished writing.
-    void AddChunkWithMessages(bool finish_writing, int buffer,
-                              const std::vector<std::string>& messages) {
-        auto chunk = SerializedLogChunk{kChunkSize};
-        for (const auto& message : messages) {
-            auto sequence = sequence_++;
-            sequence_numbers_per_buffer_[buffer].emplace_back(sequence);
-            ASSERT_TRUE(chunk.CanLog(message.size() + 1));
-            chunk.Log(sequence, log_time(), 0, 1, 1, message.c_str(), message.size() + 1);
-        }
-        if (finish_writing) {
-            chunk.FinishWriting();
-        }
-        log_chunks_[buffer].emplace_back(std::move(chunk));
-    }
-
-    android::base::LogSeverity old_log_severity_;
-    std::map<int, std::vector<uint64_t>> sequence_numbers_per_buffer_;
-    std::list<SerializedLogChunk> log_chunks_[LOG_ID_MAX];
-    uint64_t sequence_ = 1;
-};
-
-// 0: multiple chunks, with variable number of entries, with/without finishing writing
-// 1: 1 chunk with 1 log and finished writing
-// 2: 1 chunk with 1 log and not finished writing
-// 3: 1 chunk with 0 logs and not finished writing
-// 4: 1 chunk with 0 logs and finished writing (impossible, but SerializedFlushToState handles it)
-// 5-7: 0 chunks
-TEST_F(SerializedFlushToStateTest, smoke) {
-    AddChunkWithMessages(true, 0, {"1st", "2nd"});
-    AddChunkWithMessages(true, 1, {"3rd"});
-    AddChunkWithMessages(false, 0, {"4th"});
-    AddChunkWithMessages(true, 0, {"4th", "5th", "more", "even", "more", "go", "here"});
-    AddChunkWithMessages(false, 2, {"6th"});
-    AddChunkWithMessages(true, 0, {"7th"});
-    AddChunkWithMessages(false, 3, {});
-    AddChunkWithMessages(true, 4, {});
-
-    TestAllReading();
-}
-
-TEST_F(SerializedFlushToStateTest, random) {
-    srand(1);
-    for (int count = 0; count < 20; ++count) {
-        unsigned int num_messages = 1 + rand() % 15;
-        auto messages = std::vector<std::string>{num_messages, "same message"};
-
-        bool compress = rand() % 2;
-        int buf = rand() % LOG_ID_MAX;
-
-        AddChunkWithMessages(compress, buf, messages);
-    }
-
-    TestAllReading();
-}
-
-// Same start as smoke, but we selectively write logs to the buffers and ensure they're read.
-TEST_F(SerializedFlushToStateTest, future_writes) {
-    auto write_logs = [&](int loop_count) {
-        switch (loop_count) {
-            case 0:
-                // Initial writes.
-                AddChunkWithMessages(true, 0, {"1st", "2nd"});
-                AddChunkWithMessages(true, 1, {"3rd"});
-                AddChunkWithMessages(false, 0, {"4th"});
-                AddChunkWithMessages(true, 0, {"4th", "5th", "more", "even", "more", "go", "here"});
-                AddChunkWithMessages(false, 2, {"6th"});
-                AddChunkWithMessages(true, 0, {"7th"});
-                AddChunkWithMessages(false, 3, {});
-                AddChunkWithMessages(true, 4, {});
-                break;
-            case 1:
-                // Smoke test, add a simple chunk.
-                AddChunkWithMessages(true, 0, {"1st", "2nd"});
-                break;
-            case 2:
-                // Add chunks to all but one of the logs.
-                AddChunkWithMessages(true, 0, {"1st", "2nd"});
-                AddChunkWithMessages(true, 1, {"1st", "2nd"});
-                AddChunkWithMessages(true, 2, {"1st", "2nd"});
-                AddChunkWithMessages(true, 3, {"1st", "2nd"});
-                AddChunkWithMessages(true, 4, {"1st", "2nd"});
-                AddChunkWithMessages(true, 5, {"1st", "2nd"});
-                AddChunkWithMessages(true, 6, {"1st", "2nd"});
-                break;
-            case 3:
-                // Finally add chunks to all logs.
-                AddChunkWithMessages(true, 0, {"1st", "2nd"});
-                AddChunkWithMessages(true, 1, {"1st", "2nd"});
-                AddChunkWithMessages(true, 2, {"1st", "2nd"});
-                AddChunkWithMessages(true, 3, {"1st", "2nd"});
-                AddChunkWithMessages(true, 4, {"1st", "2nd"});
-                AddChunkWithMessages(true, 5, {"1st", "2nd"});
-                AddChunkWithMessages(true, 6, {"1st", "2nd"});
-                AddChunkWithMessages(true, 7, {"1st", "2nd"});
-                break;
-            default:
-                return false;
-        }
-        return true;
-    };
-
-    TestAllReadingWithFutureMessages(write_logs);
-}
-
-TEST_F(SerializedFlushToStateTest, no_dangling_references) {
-    AddChunkWithMessages(true, 0, {"1st", "2nd"});
-    AddChunkWithMessages(true, 0, {"3rd", "4th"});
-
-    auto state = SerializedFlushToState{1, kLogMaskAll};
-    state.InitializeLogs(log_chunks_);
-
-    ASSERT_EQ(log_chunks_[0].size(), 2U);
-    auto first_chunk = log_chunks_[0].begin();
-    auto second_chunk = std::next(first_chunk);
-
-    ASSERT_TRUE(state.HasUnreadLogs());
-    auto first_log = state.PopNextUnreadLog();
-    EXPECT_STREQ(first_log.entry->msg(), "1st");
-    EXPECT_EQ(first_chunk->reader_ref_count(), 1U);
-    EXPECT_EQ(second_chunk->reader_ref_count(), 0U);
-
-    ASSERT_TRUE(state.HasUnreadLogs());
-    auto second_log = state.PopNextUnreadLog();
-    EXPECT_STREQ(second_log.entry->msg(), "2nd");
-    EXPECT_EQ(first_chunk->reader_ref_count(), 1U);
-    EXPECT_EQ(second_chunk->reader_ref_count(), 0U);
-
-    ASSERT_TRUE(state.HasUnreadLogs());
-    auto third_log = state.PopNextUnreadLog();
-    EXPECT_STREQ(third_log.entry->msg(), "3rd");
-    EXPECT_EQ(first_chunk->reader_ref_count(), 0U);
-    EXPECT_EQ(second_chunk->reader_ref_count(), 1U);
-
-    ASSERT_TRUE(state.HasUnreadLogs());
-    auto fourth_log = state.PopNextUnreadLog();
-    EXPECT_STREQ(fourth_log.entry->msg(), "4th");
-    EXPECT_EQ(first_chunk->reader_ref_count(), 0U);
-    EXPECT_EQ(second_chunk->reader_ref_count(), 1U);
-
-    EXPECT_FALSE(state.HasUnreadLogs());
-}
\ No newline at end of file
diff --git a/logd/SerializedLogBuffer.cpp b/logd/SerializedLogBuffer.cpp
deleted file mode 100644
index 5012d3d..0000000
--- a/logd/SerializedLogBuffer.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2020 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 "SerializedLogBuffer.h"
-
-#include <sys/prctl.h>
-
-#include <limits>
-
-#include <android-base/logging.h>
-#include <android-base/scopeguard.h>
-
-#include "LogSize.h"
-#include "LogStatistics.h"
-#include "SerializedFlushToState.h"
-
-SerializedLogBuffer::SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags,
-                                         LogStatistics* stats)
-    : reader_list_(reader_list), tags_(tags), stats_(stats) {
-    Init();
-}
-
-void SerializedLogBuffer::Init() {
-    log_id_for_each(i) {
-        if (!SetSize(i, GetBufferSizeFromProperties(i))) {
-            SetSize(i, kLogBufferMinSize);
-        }
-    }
-
-    // Release any sleeping reader threads to dump their current content.
-    auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
-    for (const auto& reader_thread : reader_list_->reader_threads()) {
-        reader_thread->triggerReader_Locked();
-    }
-}
-
-bool SerializedLogBuffer::ShouldLog(log_id_t log_id, const char* msg, uint16_t len) {
-    if (log_id == LOG_ID_SECURITY) {
-        return true;
-    }
-
-    int prio = ANDROID_LOG_INFO;
-    const char* tag = nullptr;
-    size_t tag_len = 0;
-    if (IsBinary(log_id)) {
-        int32_t tag_int = MsgToTag(msg, len);
-        tag = tags_->tagToName(tag_int);
-        if (tag) {
-            tag_len = strlen(tag);
-        }
-    } else {
-        prio = *msg;
-        tag = msg + 1;
-        tag_len = strnlen(tag, len - 1);
-    }
-    return __android_log_is_loggable_len(prio, tag, tag_len, ANDROID_LOG_VERBOSE);
-}
-
-int SerializedLogBuffer::Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                             const char* msg, uint16_t len) {
-    if (log_id >= LOG_ID_MAX || len == 0) {
-        return -EINVAL;
-    }
-
-    if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
-        len = LOGGER_ENTRY_MAX_PAYLOAD;
-    }
-
-    if (!ShouldLog(log_id, msg, len)) {
-        stats_->AddTotal(log_id, len);
-        return -EACCES;
-    }
-
-    auto sequence = sequence_.fetch_add(1, std::memory_order_relaxed);
-
-    auto lock = std::lock_guard{lock_};
-
-    if (logs_[log_id].empty()) {
-        logs_[log_id].push_back(SerializedLogChunk(max_size_[log_id] / 4));
-    }
-
-    auto total_len = sizeof(SerializedLogEntry) + len;
-    if (!logs_[log_id].back().CanLog(total_len)) {
-        logs_[log_id].back().FinishWriting();
-        logs_[log_id].push_back(SerializedLogChunk(max_size_[log_id] / 4));
-    }
-
-    auto entry = logs_[log_id].back().Log(sequence, realtime, uid, pid, tid, msg, len);
-    stats_->Add(entry->ToLogStatisticsElement(log_id));
-
-    MaybePrune(log_id);
-
-    reader_list_->NotifyNewLog(1 << log_id);
-    return len;
-}
-
-void SerializedLogBuffer::MaybePrune(log_id_t log_id) {
-    size_t total_size = GetSizeUsed(log_id);
-    size_t after_size = total_size;
-    if (total_size > max_size_[log_id]) {
-        Prune(log_id, total_size - max_size_[log_id], 0);
-        after_size = GetSizeUsed(log_id);
-        LOG(INFO) << "Pruned Logs from log_id: " << log_id << ", previous size: " << total_size
-                  << " after size: " << after_size;
-    }
-
-    stats_->set_overhead(log_id, after_size);
-}
-
-void SerializedLogBuffer::RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk) {
-    chunk.IncReaderRefCount();
-    int read_offset = 0;
-    while (read_offset < chunk.write_offset()) {
-        auto* entry = chunk.log_entry(read_offset);
-        stats_->Subtract(entry->ToLogStatisticsElement(log_id));
-        read_offset += entry->total_len();
-    }
-    chunk.DecReaderRefCount();
-}
-
-void SerializedLogBuffer::NotifyReadersOfPrune(
-        log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) {
-    for (const auto& reader_thread : reader_list_->reader_threads()) {
-        auto& state = reinterpret_cast<SerializedFlushToState&>(reader_thread->flush_to_state());
-        state.Prune(log_id, chunk);
-    }
-}
-
-void SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid) {
-    auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
-
-    auto& log_buffer = logs_[log_id];
-    auto it = log_buffer.begin();
-    while (it != log_buffer.end()) {
-        for (const auto& reader_thread : reader_list_->reader_threads()) {
-            if (!reader_thread->IsWatching(log_id)) {
-                continue;
-            }
-
-            if (reader_thread->deadline().time_since_epoch().count() != 0) {
-                // Always wake up wrapped readers when pruning.  'Wrapped' readers are an
-                // optimization that allows the reader to wait until logs starting at a specified
-                // time stamp are about to be pruned.  This is error-prone however, since if that
-                // timestamp is about to be pruned, the reader is not likely to read the messages
-                // fast enough to not back-up logd.  Instead, we can achieve an nearly-as-efficient
-                // but not error-prune batching effect by waking the reader whenever any chunk is
-                // about to be pruned.
-                reader_thread->triggerReader_Locked();
-            }
-
-            // Some readers may be still reading from this log chunk, log a warning that they are
-            // about to lose logs.
-            // TODO: We should forcefully disconnect the reader instead, such that the reader itself
-            // has an indication that they've lost logs.
-            if (reader_thread->start() <= it->highest_sequence_number()) {
-                LOG(WARNING) << "Skipping entries from slow reader, " << reader_thread->name()
-                             << ", from LogBuffer::Prune()";
-            }
-        }
-
-        // Increment ahead of time since we're going to erase this iterator from the list.
-        auto it_to_prune = it++;
-
-        // Readers may have a reference to the chunk to track their last read log_position.
-        // Notify them to delete the reference.
-        NotifyReadersOfPrune(log_id, it_to_prune);
-
-        if (uid != 0) {
-            // Reorder the log buffer to remove logs from the given UID.  If there are no logs left
-            // in the buffer after the removal, delete it.
-            if (it_to_prune->ClearUidLogs(uid, log_id, stats_)) {
-                log_buffer.erase(it_to_prune);
-            }
-        } else {
-            size_t buffer_size = it_to_prune->PruneSize();
-            RemoveChunkFromStats(log_id, *it_to_prune);
-            log_buffer.erase(it_to_prune);
-            if (buffer_size >= bytes_to_free) {
-                return;
-            }
-            bytes_to_free -= buffer_size;
-        }
-    }
-}
-
-std::unique_ptr<FlushToState> SerializedLogBuffer::CreateFlushToState(uint64_t start,
-                                                                      LogMask log_mask) {
-    return std::make_unique<SerializedFlushToState>(start, log_mask);
-}
-
-bool SerializedLogBuffer::FlushTo(
-        LogWriter* writer, FlushToState& abstract_state,
-        const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
-                                         log_time realtime)>& filter) {
-    auto lock = std::unique_lock{lock_};
-
-    auto& state = reinterpret_cast<SerializedFlushToState&>(abstract_state);
-    state.InitializeLogs(logs_);
-
-    while (state.HasUnreadLogs()) {
-        MinHeapElement top = state.PopNextUnreadLog();
-        auto* entry = top.entry;
-        auto log_id = top.log_id;
-
-        if (entry->sequence() < state.start()) {
-            continue;
-        }
-        state.set_start(entry->sequence());
-
-        if (!writer->privileged() && entry->uid() != writer->uid()) {
-            continue;
-        }
-
-        if (filter) {
-            auto ret = filter(log_id, entry->pid(), entry->sequence(), entry->realtime());
-            if (ret == FilterResult::kSkip) {
-                continue;
-            }
-            if (ret == FilterResult::kStop) {
-                break;
-            }
-        }
-
-        // We copy the log entry such that we can flush it without the lock.  We never block pruning
-        // waiting for this Flush() to complete.
-        constexpr size_t kMaxEntrySize = sizeof(*entry) + LOGGER_ENTRY_MAX_PAYLOAD + 1;
-        unsigned char entry_copy[kMaxEntrySize] __attribute__((uninitialized));
-        CHECK_LT(entry->msg_len(), LOGGER_ENTRY_MAX_PAYLOAD + 1);
-        memcpy(entry_copy, entry, sizeof(*entry) + entry->msg_len());
-        lock.unlock();
-
-        if (!reinterpret_cast<SerializedLogEntry*>(entry_copy)->Flush(writer, log_id)) {
-            return false;
-        }
-
-        lock.lock();
-    }
-
-    state.set_start(state.start() + 1);
-    return true;
-}
-
-bool SerializedLogBuffer::Clear(log_id_t id, uid_t uid) {
-    auto lock = std::lock_guard{lock_};
-    Prune(id, ULONG_MAX, uid);
-
-    // Clearing SerializedLogBuffer never waits for readers and therefore is always successful.
-    return true;
-}
-
-size_t SerializedLogBuffer::GetSizeUsed(log_id_t id) {
-    size_t total_size = 0;
-    for (const auto& chunk : logs_[id]) {
-        total_size += chunk.PruneSize();
-    }
-    return total_size;
-}
-
-size_t SerializedLogBuffer::GetSize(log_id_t id) {
-    auto lock = std::lock_guard{lock_};
-    return max_size_[id];
-}
-
-// New SerializedLogChunk objects will be allocated according to the new size, but older one are
-// unchanged.  MaybePrune() is called on the log buffer to reduce it to an appropriate size if the
-// new size is lower.
-bool SerializedLogBuffer::SetSize(log_id_t id, size_t size) {
-    // Reasonable limits ...
-    if (!IsValidBufferSize(size)) {
-        return false;
-    }
-
-    auto lock = std::lock_guard{lock_};
-    max_size_[id] = size;
-
-    MaybePrune(id);
-
-    return true;
-}
diff --git a/logd/SerializedLogBuffer.h b/logd/SerializedLogBuffer.h
deleted file mode 100644
index 294cfe6..0000000
--- a/logd/SerializedLogBuffer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <atomic>
-#include <bitset>
-#include <list>
-#include <mutex>
-#include <queue>
-#include <thread>
-#include <vector>
-
-#include <android-base/thread_annotations.h>
-
-#include "LogBuffer.h"
-#include "LogReaderList.h"
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "SerializedLogChunk.h"
-#include "SerializedLogEntry.h"
-#include "rwlock.h"
-
-class SerializedLogBuffer final : public LogBuffer {
-  public:
-    SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats);
-    void Init() override;
-
-    int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
-            uint16_t len) override;
-    std::unique_ptr<FlushToState> CreateFlushToState(uint64_t start, LogMask log_mask) override;
-    bool FlushTo(LogWriter* writer, FlushToState& state,
-                 const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
-                                                  log_time realtime)>& filter) override;
-
-    bool Clear(log_id_t id, uid_t uid) override;
-    size_t GetSize(log_id_t id) override;
-    bool SetSize(log_id_t id, size_t size) override;
-
-    uint64_t sequence() const override { return sequence_.load(std::memory_order_relaxed); }
-
-  private:
-    bool ShouldLog(log_id_t log_id, const char* msg, uint16_t len);
-    void MaybePrune(log_id_t log_id) REQUIRES(lock_);
-    void Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid) REQUIRES(lock_);
-    void NotifyReadersOfPrune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk)
-            REQUIRES(reader_list_->reader_threads_lock());
-    void RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk);
-    size_t GetSizeUsed(log_id_t id) REQUIRES(lock_);
-
-    LogReaderList* reader_list_;
-    LogTags* tags_;
-    LogStatistics* stats_;
-
-    size_t max_size_[LOG_ID_MAX] GUARDED_BY(lock_) = {};
-    std::list<SerializedLogChunk> logs_[LOG_ID_MAX] GUARDED_BY(lock_);
-    RwLock lock_;
-
-    std::atomic<uint64_t> sequence_ = 1;
-};
diff --git a/logd/SerializedLogChunk.cpp b/logd/SerializedLogChunk.cpp
deleted file mode 100644
index e4d8945..0000000
--- a/logd/SerializedLogChunk.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2020 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 "SerializedLogChunk.h"
-
-#include <android-base/logging.h>
-
-#include "CompressionEngine.h"
-
-SerializedLogChunk::~SerializedLogChunk() {
-    CHECK_EQ(reader_ref_count_, 0U);
-}
-
-void SerializedLogChunk::Compress() {
-    CHECK_EQ(compressed_log_.size(), 0U);
-    CompressionEngine::GetInstance().Compress(contents_, write_offset_, compressed_log_);
-    LOG(INFO) << "Compressed Log, buffer max size: " << contents_.size()
-              << " size used: " << write_offset_ << " compressed size: " << compressed_log_.size();
-}
-
-// TODO: Develop a better reference counting strategy to guard against the case where the writer is
-// much faster than the reader, and we needlessly compess / decompress the logs.
-void SerializedLogChunk::IncReaderRefCount() {
-    if (++reader_ref_count_ != 1 || writer_active_) {
-        return;
-    }
-    contents_.Resize(write_offset_);
-    CompressionEngine::GetInstance().Decompress(compressed_log_, contents_);
-}
-
-void SerializedLogChunk::DecReaderRefCount() {
-    CHECK_NE(reader_ref_count_, 0U);
-    if (--reader_ref_count_ != 0) {
-        return;
-    }
-    if (!writer_active_) {
-        contents_.Resize(0);
-    }
-}
-
-bool SerializedLogChunk::ClearUidLogs(uid_t uid, log_id_t log_id, LogStatistics* stats) {
-    CHECK_EQ(reader_ref_count_, 0U);
-    if (write_offset_ == 0) {
-        return true;
-    }
-
-    IncReaderRefCount();
-
-    int read_offset = 0;
-    int new_write_offset = 0;
-    while (read_offset < write_offset_) {
-        const auto* entry = log_entry(read_offset);
-        if (entry->uid() == uid) {
-            read_offset += entry->total_len();
-            if (stats != nullptr) {
-                stats->Subtract(entry->ToLogStatisticsElement(log_id));
-            }
-            continue;
-        }
-        size_t entry_total_len = entry->total_len();
-        if (read_offset != new_write_offset) {
-            memmove(contents_.data() + new_write_offset, contents_.data() + read_offset,
-                    entry_total_len);
-        }
-        read_offset += entry_total_len;
-        new_write_offset += entry_total_len;
-    }
-
-    if (new_write_offset == 0) {
-        DecReaderRefCount();
-        return true;
-    }
-
-    // Clear the old compressed logs and set write_offset_ appropriately to compress the new
-    // partially cleared log.
-    if (new_write_offset != write_offset_) {
-        write_offset_ = new_write_offset;
-        if (!writer_active_) {
-            compressed_log_.Resize(0);
-            Compress();
-        }
-    }
-
-    DecReaderRefCount();
-
-    return false;
-}
-
-bool SerializedLogChunk::CanLog(size_t len) {
-    return write_offset_ + len <= contents_.size();
-}
-
-SerializedLogEntry* SerializedLogChunk::Log(uint64_t sequence, log_time realtime, uid_t uid,
-                                            pid_t pid, pid_t tid, const char* msg, uint16_t len) {
-    auto new_log_address = contents_.data() + write_offset_;
-    auto* entry = new (new_log_address) SerializedLogEntry(uid, pid, tid, sequence, realtime, len);
-    memcpy(entry->msg(), msg, len);
-    write_offset_ += entry->total_len();
-    highest_sequence_number_ = sequence;
-    return entry;
-}
\ No newline at end of file
diff --git a/logd/SerializedLogChunk.h b/logd/SerializedLogChunk.h
deleted file mode 100644
index 0991eac..0000000
--- a/logd/SerializedLogChunk.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include "LogWriter.h"
-#include "SerializedData.h"
-#include "SerializedLogEntry.h"
-
-class SerializedLogChunk {
-  public:
-    explicit SerializedLogChunk(size_t size) : contents_(size) {}
-    SerializedLogChunk(SerializedLogChunk&& other) noexcept = default;
-    ~SerializedLogChunk();
-
-    void Compress();
-    void IncReaderRefCount();
-    void DecReaderRefCount();
-
-    // Must have no readers referencing this.  Return true if there are no logs left in this chunk.
-    bool ClearUidLogs(uid_t uid, log_id_t log_id, LogStatistics* stats);
-
-    bool CanLog(size_t len);
-    SerializedLogEntry* Log(uint64_t sequence, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                            const char* msg, uint16_t len);
-
-    // If this buffer has been compressed, we only consider its compressed size when accounting for
-    // memory consumption for pruning.  This is since the uncompressed log is only by used by
-    // readers, and thus not a representation of how much these logs cost to keep in memory.
-    size_t PruneSize() const {
-        return sizeof(*this) + (compressed_log_.size() ?: contents_.size());
-    }
-
-    void FinishWriting() {
-        writer_active_ = false;
-        Compress();
-        if (reader_ref_count_ == 0) {
-            contents_.Resize(0);
-        }
-    }
-
-    const SerializedLogEntry* log_entry(int offset) const {
-        return reinterpret_cast<const SerializedLogEntry*>(data() + offset);
-    }
-    const uint8_t* data() const { return contents_.data(); }
-    int write_offset() const { return write_offset_; }
-    uint64_t highest_sequence_number() const { return highest_sequence_number_; }
-
-    // Exposed for testing
-    uint32_t reader_ref_count() const { return reader_ref_count_; }
-
-  private:
-    // The decompressed contents of this log buffer.  Deallocated when the ref_count reaches 0 and
-    // writer_active_ is false.
-    SerializedData contents_;
-    int write_offset_ = 0;
-    uint32_t reader_ref_count_ = 0;
-    bool writer_active_ = true;
-    uint64_t highest_sequence_number_ = 1;
-    SerializedData compressed_log_;
-};
diff --git a/logd/SerializedLogChunkTest.cpp b/logd/SerializedLogChunkTest.cpp
deleted file mode 100644
index 3b45125..0000000
--- a/logd/SerializedLogChunkTest.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2020 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 "SerializedLogChunk.h"
-
-#include <limits>
-
-#include <android-base/stringprintf.h>
-#include <android/log.h>
-#include <gtest/gtest.h>
-
-using android::base::StringPrintf;
-
-TEST(SerializedLogChunk, smoke) {
-    size_t chunk_size = 10 * 4096;
-    auto chunk = SerializedLogChunk{chunk_size};
-    EXPECT_EQ(chunk_size + sizeof(SerializedLogChunk), chunk.PruneSize());
-
-    static const char log_message[] = "log message";
-    size_t expected_total_len = sizeof(SerializedLogEntry) + sizeof(log_message);
-    ASSERT_TRUE(chunk.CanLog(expected_total_len));
-    EXPECT_TRUE(chunk.CanLog(chunk_size));
-    EXPECT_FALSE(chunk.CanLog(chunk_size + 1));
-
-    log_time time(CLOCK_REALTIME);
-    auto* entry = chunk.Log(1234, time, 0, 1, 2, log_message, sizeof(log_message));
-    ASSERT_NE(nullptr, entry);
-
-    EXPECT_EQ(1234U, entry->sequence());
-    EXPECT_EQ(time, entry->realtime());
-    EXPECT_EQ(0U, entry->uid());
-    EXPECT_EQ(1, entry->pid());
-    EXPECT_EQ(2, entry->tid());
-    EXPECT_EQ(sizeof(log_message), entry->msg_len());
-    EXPECT_STREQ(log_message, entry->msg());
-    EXPECT_EQ(expected_total_len, entry->total_len());
-
-    EXPECT_FALSE(chunk.CanLog(chunk_size));
-    EXPECT_EQ(static_cast<int>(expected_total_len), chunk.write_offset());
-    EXPECT_EQ(1234U, chunk.highest_sequence_number());
-}
-
-TEST(SerializedLogChunk, fill_log_exactly) {
-    static const char log_message[] = "this is a log message";
-    size_t individual_message_size = sizeof(SerializedLogEntry) + sizeof(log_message);
-    size_t chunk_size = individual_message_size * 3;
-    auto chunk = SerializedLogChunk{chunk_size};
-    EXPECT_EQ(chunk_size + sizeof(SerializedLogChunk), chunk.PruneSize());
-
-    ASSERT_TRUE(chunk.CanLog(individual_message_size));
-    EXPECT_NE(nullptr, chunk.Log(1, log_time(), 1000, 1, 1, log_message, sizeof(log_message)));
-
-    ASSERT_TRUE(chunk.CanLog(individual_message_size));
-    EXPECT_NE(nullptr, chunk.Log(2, log_time(), 1000, 2, 1, log_message, sizeof(log_message)));
-
-    ASSERT_TRUE(chunk.CanLog(individual_message_size));
-    EXPECT_NE(nullptr, chunk.Log(3, log_time(), 1000, 3, 1, log_message, sizeof(log_message)));
-
-    EXPECT_FALSE(chunk.CanLog(1));
-}
-
-TEST(SerializedLogChunk, three_logs) {
-    size_t chunk_size = 10 * 4096;
-    auto chunk = SerializedLogChunk{chunk_size};
-
-    chunk.Log(2, log_time(0x1234, 0x5678), 0x111, 0x222, 0x333, "initial message",
-              strlen("initial message"));
-    chunk.Log(3, log_time(0x2345, 0x6789), 0x444, 0x555, 0x666, "second message",
-              strlen("second message"));
-    auto uint64_t_max = std::numeric_limits<uint64_t>::max();
-    auto uint32_t_max = std::numeric_limits<uint32_t>::max();
-    chunk.Log(uint64_t_max, log_time(uint32_t_max, uint32_t_max), uint32_t_max, uint32_t_max,
-              uint32_t_max, "last message", strlen("last message"));
-
-    static const char expected_buffer_data[] =
-            "\x11\x01\x00\x00\x22\x02\x00\x00\x33\x03\x00\x00"  // UID PID TID
-            "\x02\x00\x00\x00\x00\x00\x00\x00"                  // Sequence
-            "\x34\x12\x00\x00\x78\x56\x00\x00"                  // Timestamp
-            "\x0F\x00initial message"                           // msg_len + message
-            "\x44\x04\x00\x00\x55\x05\x00\x00\x66\x06\x00\x00"  // UID PID TID
-            "\x03\x00\x00\x00\x00\x00\x00\x00"                  // Sequence
-            "\x45\x23\x00\x00\x89\x67\x00\x00"                  // Timestamp
-            "\x0E\x00second message"                            // msg_len + message
-            "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"  // UID PID TID
-            "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"                  // Sequence
-            "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"                  // Timestamp
-            "\x0C\x00last message";                             // msg_len + message
-
-    for (size_t i = 0; i < chunk_size; ++i) {
-        if (i < sizeof(expected_buffer_data)) {
-            EXPECT_EQ(static_cast<uint8_t>(expected_buffer_data[i]), chunk.data()[i])
-                    << "position: " << i;
-        } else {
-            EXPECT_EQ(0, chunk.data()[i]) << "position: " << i;
-        }
-    }
-}
-
-// Check that the CHECK() in DecReaderRefCount() if the ref count goes bad is caught.
-TEST(SerializedLogChunk, catch_DecCompressedRef_CHECK) {
-    size_t chunk_size = 10 * 4096;
-    auto chunk = SerializedLogChunk{chunk_size};
-    EXPECT_DEATH({ chunk.DecReaderRefCount(); }, "");
-}
-
-// Check that the CHECK() in ClearUidLogs() if the ref count is greater than 0 is caught.
-TEST(SerializedLogChunk, catch_ClearUidLogs_CHECK) {
-    size_t chunk_size = 10 * 4096;
-    auto chunk = SerializedLogChunk{chunk_size};
-    chunk.IncReaderRefCount();
-    EXPECT_DEATH({ chunk.ClearUidLogs(1000, LOG_ID_MAIN, nullptr); }, "");
-    chunk.DecReaderRefCount();
-}
-
-class UidClearTest : public testing::TestWithParam<bool> {
-  protected:
-    template <typename Write, typename Check>
-    void Test(const Write& write, const Check& check, bool expected_result) {
-        write(chunk_);
-
-        bool finish_writing = GetParam();
-        if (finish_writing) {
-            chunk_.FinishWriting();
-        }
-        EXPECT_EQ(expected_result, chunk_.ClearUidLogs(kUidToClear, LOG_ID_MAIN, nullptr));
-        if (finish_writing) {
-            chunk_.IncReaderRefCount();
-        }
-
-        check(chunk_);
-
-        if (finish_writing) {
-            chunk_.DecReaderRefCount();
-        }
-    }
-
-    static constexpr size_t kChunkSize = 10 * 4096;
-    static constexpr uid_t kUidToClear = 1000;
-    static constexpr uid_t kOtherUid = 1234;
-
-    SerializedLogChunk chunk_{kChunkSize};
-};
-
-// Test that ClearUidLogs() is a no-op if there are no logs of that UID in the buffer.
-TEST_P(UidClearTest, no_logs_in_chunk) {
-    auto write = [](SerializedLogChunk&) {};
-    auto check = [](SerializedLogChunk&) {};
-
-    Test(write, check, true);
-}
-
-// Test that ClearUidLogs() is a no-op if there are no logs of that UID in the buffer.
-TEST_P(UidClearTest, no_logs_from_uid) {
-    static const char msg[] = "this is a log message";
-    auto write = [](SerializedLogChunk& chunk) {
-        chunk.Log(1, log_time(), kOtherUid, 1, 2, msg, sizeof(msg));
-    };
-
-    auto check = [](SerializedLogChunk& chunk) {
-        auto* entry = chunk.log_entry(0);
-        EXPECT_STREQ(msg, entry->msg());
-    };
-
-    Test(write, check, false);
-}
-
-// Test that ClearUidLogs() returns true if all logs in a given buffer correspond to the given UID.
-TEST_P(UidClearTest, all_single) {
-    static const char msg[] = "this is a log message";
-    auto write = [](SerializedLogChunk& chunk) {
-        chunk.Log(1, log_time(), kUidToClear, 1, 2, msg, sizeof(msg));
-    };
-    auto check = [](SerializedLogChunk&) {};
-
-    Test(write, check, true);
-}
-
-// Test that ClearUidLogs() returns true if all logs in a given buffer correspond to the given UID.
-TEST_P(UidClearTest, all_multiple) {
-    static const char msg[] = "this is a log message";
-    auto write = [](SerializedLogChunk& chunk) {
-        chunk.Log(2, log_time(), kUidToClear, 1, 2, msg, sizeof(msg));
-        chunk.Log(3, log_time(), kUidToClear, 1, 2, msg, sizeof(msg));
-        chunk.Log(4, log_time(), kUidToClear, 1, 2, msg, sizeof(msg));
-    };
-    auto check = [](SerializedLogChunk&) {};
-
-    Test(write, check, true);
-}
-
-static std::string MakePrintable(const uint8_t* in, size_t length) {
-    std::string result;
-    for (size_t i = 0; i < length; ++i) {
-        uint8_t c = in[i];
-        if (isprint(c)) {
-            result.push_back(c);
-        } else {
-            result.append(StringPrintf("\\%02x", static_cast<int>(c) & 0xFF));
-        }
-    }
-    return result;
-}
-
-// This test clears UID logs at the beginning and end of the buffer, as well as two back to back
-// logs in the interior.
-TEST_P(UidClearTest, clear_beginning_and_end) {
-    static const char msg1[] = "this is a log message";
-    static const char msg2[] = "non-cleared message";
-    static const char msg3[] = "back to back cleared messages";
-    static const char msg4[] = "second in a row gone";
-    static const char msg5[] = "but we save this one";
-    static const char msg6[] = "and this 1!";
-    static const char msg7[] = "the last one goes too";
-    auto write = [](SerializedLogChunk& chunk) {
-        ASSERT_NE(nullptr, chunk.Log(1, log_time(), kUidToClear, 1, 2, msg1, sizeof(msg1)));
-        ASSERT_NE(nullptr, chunk.Log(2, log_time(), kOtherUid, 1, 2, msg2, sizeof(msg2)));
-        ASSERT_NE(nullptr, chunk.Log(3, log_time(), kUidToClear, 1, 2, msg3, sizeof(msg3)));
-        ASSERT_NE(nullptr, chunk.Log(4, log_time(), kUidToClear, 1, 2, msg4, sizeof(msg4)));
-        ASSERT_NE(nullptr, chunk.Log(5, log_time(), kOtherUid, 1, 2, msg5, sizeof(msg5)));
-        ASSERT_NE(nullptr, chunk.Log(6, log_time(), kOtherUid, 1, 2, msg6, sizeof(msg6)));
-        ASSERT_NE(nullptr, chunk.Log(7, log_time(), kUidToClear, 1, 2, msg7, sizeof(msg7)));
-    };
-
-    auto check = [](SerializedLogChunk& chunk) {
-        size_t read_offset = 0;
-        auto* entry = chunk.log_entry(read_offset);
-        EXPECT_STREQ(msg2, entry->msg());
-        read_offset += entry->total_len();
-
-        entry = chunk.log_entry(read_offset);
-        EXPECT_STREQ(msg5, entry->msg());
-        read_offset += entry->total_len();
-
-        entry = chunk.log_entry(read_offset);
-        EXPECT_STREQ(msg6, entry->msg()) << MakePrintable(chunk.data(), chunk.write_offset());
-        read_offset += entry->total_len();
-
-        EXPECT_EQ(static_cast<int>(read_offset), chunk.write_offset());
-    };
-    Test(write, check, false);
-}
-
-// This tests the opposite case of beginning_and_end, in which we don't clear the beginning or end
-// logs.  There is a single log pruned in the middle instead of back to back logs.
-TEST_P(UidClearTest, save_beginning_and_end) {
-    static const char msg1[] = "saved first message";
-    static const char msg2[] = "cleared interior message";
-    static const char msg3[] = "last message stays";
-    auto write = [](SerializedLogChunk& chunk) {
-        ASSERT_NE(nullptr, chunk.Log(1, log_time(), kOtherUid, 1, 2, msg1, sizeof(msg1)));
-        ASSERT_NE(nullptr, chunk.Log(2, log_time(), kUidToClear, 1, 2, msg2, sizeof(msg2)));
-        ASSERT_NE(nullptr, chunk.Log(3, log_time(), kOtherUid, 1, 2, msg3, sizeof(msg3)));
-    };
-
-    auto check = [](SerializedLogChunk& chunk) {
-        size_t read_offset = 0;
-        auto* entry = chunk.log_entry(read_offset);
-        EXPECT_STREQ(msg1, entry->msg());
-        read_offset += entry->total_len();
-
-        entry = chunk.log_entry(read_offset);
-        EXPECT_STREQ(msg3, entry->msg());
-        read_offset += entry->total_len();
-
-        EXPECT_EQ(static_cast<int>(read_offset), chunk.write_offset());
-    };
-    Test(write, check, false);
-}
-
-INSTANTIATE_TEST_CASE_P(UidClearTests, UidClearTest, testing::Values(true, false));
-
-// b/166187079: ClearUidLogs() should not compress the log if writer_active_ is true
-TEST(SerializedLogChunk, ClearUidLogs_then_FinishWriting) {
-    static constexpr size_t kChunkSize = 10 * 4096;
-    static constexpr uid_t kUidToClear = 1000;
-    static constexpr uid_t kOtherUid = 1234;
-
-    SerializedLogChunk chunk{kChunkSize};
-    static const char msg1[] = "saved first message";
-    static const char msg2[] = "cleared interior message";
-    static const char msg3[] = "last message stays";
-    ASSERT_NE(nullptr, chunk.Log(1, log_time(), kOtherUid, 1, 2, msg1, sizeof(msg1)));
-    ASSERT_NE(nullptr, chunk.Log(2, log_time(), kUidToClear, 1, 2, msg2, sizeof(msg2)));
-    ASSERT_NE(nullptr, chunk.Log(3, log_time(), kOtherUid, 1, 2, msg3, sizeof(msg3)));
-
-    chunk.ClearUidLogs(kUidToClear, LOG_ID_MAIN, nullptr);
-
-    ASSERT_NE(nullptr, chunk.Log(4, log_time(), kOtherUid, 1, 2, msg3, sizeof(msg3)));
-
-    chunk.FinishWriting();
-    // The next line would violate a CHECK() during decompression with the faulty code.
-    chunk.IncReaderRefCount();
-    chunk.DecReaderRefCount();
-}
diff --git a/logd/SerializedLogEntry.h b/logd/SerializedLogEntry.h
deleted file mode 100644
index 2f2c244..0000000
--- a/logd/SerializedLogEntry.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include <log/log.h>
-#include <log/log_read.h>
-
-#include "LogStatistics.h"
-#include "LogWriter.h"
-
-// These structs are packed into a single chunk of memory for each log type within a
-// SerializedLogChunk object.  Their message is contained immediately at the end of the struct.  The
-// address of the next log in the buffer is *this + sizeof(SerializedLogEntry) + msg_len_.  If that
-// value would overflow the chunk of memory associated with the SerializedLogChunk object, then a
-// new SerializedLogChunk must be allocated to contain the next SerializedLogEntry.
-class __attribute__((packed)) SerializedLogEntry {
-  public:
-    SerializedLogEntry(uid_t uid, pid_t pid, pid_t tid, uint64_t sequence, log_time realtime,
-                       uint16_t len)
-        : uid_(uid),
-          pid_(pid),
-          tid_(tid),
-          sequence_(sequence),
-          realtime_(realtime),
-          msg_len_(len) {}
-    SerializedLogEntry(const SerializedLogEntry& elem) = delete;
-    SerializedLogEntry& operator=(const SerializedLogEntry& elem) = delete;
-    ~SerializedLogEntry() {
-        // Never place anything in this destructor.  This class is in place constructed and never
-        // destructed.
-    }
-
-    LogStatisticsElement ToLogStatisticsElement(log_id_t log_id) const {
-        return LogStatisticsElement{
-                .uid = uid(),
-                .pid = pid(),
-                .tid = tid(),
-                .tag = IsBinary(log_id) ? MsgToTag(msg(), msg_len()) : 0,
-                .realtime = realtime(),
-                .msg = msg(),
-                .msg_len = msg_len(),
-                .dropped_count = 0,
-                .log_id = log_id,
-                .total_len = total_len(),
-        };
-    }
-
-    bool Flush(LogWriter* writer, log_id_t log_id) const {
-        struct logger_entry entry = {};
-
-        entry.hdr_size = sizeof(struct logger_entry);
-        entry.lid = log_id;
-        entry.pid = pid();
-        entry.tid = tid();
-        entry.uid = uid();
-        entry.sec = realtime().tv_sec;
-        entry.nsec = realtime().tv_nsec;
-        entry.len = msg_len();
-
-        return writer->Write(entry, msg());
-    }
-
-    uid_t uid() const { return uid_; }
-    pid_t pid() const { return pid_; }
-    pid_t tid() const { return tid_; }
-    uint16_t msg_len() const { return msg_len_; }
-    uint64_t sequence() const { return sequence_; }
-    log_time realtime() const { return realtime_; }
-
-    char* msg() { return reinterpret_cast<char*>(this) + sizeof(*this); }
-    const char* msg() const { return reinterpret_cast<const char*>(this) + sizeof(*this); }
-    uint16_t total_len() const { return sizeof(*this) + msg_len_; }
-
-  private:
-    const uint32_t uid_;
-    const uint32_t pid_;
-    const uint32_t tid_;
-    const uint64_t sequence_;
-    const log_time realtime_;
-    const uint16_t msg_len_;
-};
diff --git a/logd/SimpleLogBuffer.cpp b/logd/SimpleLogBuffer.cpp
deleted file mode 100644
index b00dd25..0000000
--- a/logd/SimpleLogBuffer.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2020 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 "SimpleLogBuffer.h"
-
-#include <android-base/logging.h>
-
-#include "LogBufferElement.h"
-#include "LogSize.h"
-
-SimpleLogBuffer::SimpleLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats)
-    : reader_list_(reader_list), tags_(tags), stats_(stats) {
-    Init();
-}
-
-SimpleLogBuffer::~SimpleLogBuffer() {}
-
-void SimpleLogBuffer::Init() {
-    log_id_for_each(i) {
-        if (!SetSize(i, GetBufferSizeFromProperties(i))) {
-            SetSize(i, kLogBufferMinSize);
-        }
-    }
-
-    // Release any sleeping reader threads to dump their current content.
-    auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
-    for (const auto& reader_thread : reader_list_->reader_threads()) {
-        reader_thread->triggerReader_Locked();
-    }
-}
-
-std::list<LogBufferElement>::iterator SimpleLogBuffer::GetOldest(log_id_t log_id) {
-    auto it = logs().begin();
-    if (oldest_[log_id]) {
-        it = *oldest_[log_id];
-    }
-    while (it != logs().end() && it->log_id() != log_id) {
-        it++;
-    }
-    if (it != logs().end()) {
-        oldest_[log_id] = it;
-    }
-    return it;
-}
-
-bool SimpleLogBuffer::ShouldLog(log_id_t log_id, const char* msg, uint16_t len) {
-    if (log_id == LOG_ID_SECURITY) {
-        return true;
-    }
-
-    int prio = ANDROID_LOG_INFO;
-    const char* tag = nullptr;
-    size_t tag_len = 0;
-    if (IsBinary(log_id)) {
-        int32_t numeric_tag = MsgToTag(msg, len);
-        tag = tags_->tagToName(numeric_tag);
-        if (tag) {
-            tag_len = strlen(tag);
-        }
-    } else {
-        prio = *msg;
-        tag = msg + 1;
-        tag_len = strnlen(tag, len - 1);
-    }
-    return __android_log_is_loggable_len(prio, tag, tag_len, ANDROID_LOG_VERBOSE);
-}
-
-int SimpleLogBuffer::Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-                         const char* msg, uint16_t len) {
-    if (log_id >= LOG_ID_MAX) {
-        return -EINVAL;
-    }
-
-    if (!ShouldLog(log_id, msg, len)) {
-        // Log traffic received to total
-        stats_->AddTotal(log_id, len);
-        return -EACCES;
-    }
-
-    // Slip the time by 1 nsec if the incoming lands on xxxxxx000 ns.
-    // This prevents any chance that an outside source can request an
-    // exact entry with time specified in ms or us precision.
-    if ((realtime.tv_nsec % 1000) == 0) ++realtime.tv_nsec;
-
-    auto lock = std::lock_guard{lock_};
-    auto sequence = sequence_.fetch_add(1, std::memory_order_relaxed);
-    LogInternal(LogBufferElement(log_id, realtime, uid, pid, tid, sequence, msg, len));
-    return len;
-}
-
-void SimpleLogBuffer::LogInternal(LogBufferElement&& elem) {
-    log_id_t log_id = elem.log_id();
-
-    logs_.emplace_back(std::move(elem));
-    stats_->Add(logs_.back().ToLogStatisticsElement());
-    MaybePrune(log_id);
-    reader_list_->NotifyNewLog(1 << log_id);
-}
-
-// These extra parameters are only required for chatty, but since they're a no-op for
-// SimpleLogBuffer, it's easier to include them here, then to duplicate FlushTo() for
-// ChattyLogBuffer.
-class ChattyFlushToState : public FlushToState {
-  public:
-    ChattyFlushToState(uint64_t start, LogMask log_mask) : FlushToState(start, log_mask) {}
-
-    pid_t* last_tid() { return last_tid_; }
-
-    bool drop_chatty_messages() const { return drop_chatty_messages_; }
-    void set_drop_chatty_messages(bool value) { drop_chatty_messages_ = value; }
-
-  private:
-    pid_t last_tid_[LOG_ID_MAX] = {};
-    bool drop_chatty_messages_ = true;
-};
-
-std::unique_ptr<FlushToState> SimpleLogBuffer::CreateFlushToState(uint64_t start,
-                                                                  LogMask log_mask) {
-    return std::make_unique<ChattyFlushToState>(start, log_mask);
-}
-
-bool SimpleLogBuffer::FlushTo(
-        LogWriter* writer, FlushToState& abstract_state,
-        const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
-                                         log_time realtime)>& filter) {
-    auto shared_lock = SharedLock{lock_};
-
-    auto& state = reinterpret_cast<ChattyFlushToState&>(abstract_state);
-
-    std::list<LogBufferElement>::iterator it;
-    if (state.start() <= 1) {
-        // client wants to start from the beginning
-        it = logs_.begin();
-    } else {
-        // Client wants to start from some specified time. Chances are
-        // we are better off starting from the end of the time sorted list.
-        for (it = logs_.end(); it != logs_.begin();
-             /* do nothing */) {
-            --it;
-            if (it->sequence() == state.start()) {
-                break;
-            } else if (it->sequence() < state.start()) {
-                it++;
-                break;
-            }
-        }
-    }
-
-    for (; it != logs_.end(); ++it) {
-        LogBufferElement& element = *it;
-
-        state.set_start(element.sequence());
-
-        if (!writer->privileged() && element.uid() != writer->uid()) {
-            continue;
-        }
-
-        if (((1 << element.log_id()) & state.log_mask()) == 0) {
-            continue;
-        }
-
-        if (filter) {
-            FilterResult ret =
-                    filter(element.log_id(), element.pid(), element.sequence(), element.realtime());
-            if (ret == FilterResult::kSkip) {
-                continue;
-            }
-            if (ret == FilterResult::kStop) {
-                break;
-            }
-        }
-
-        // drop_chatty_messages is initialized to true, so if the first message that we attempt to
-        // flush is a chatty message, we drop it.  Once we see a non-chatty message it gets set to
-        // false to let further chatty messages be printed.
-        if (state.drop_chatty_messages()) {
-            if (element.dropped_count() != 0) {
-                continue;
-            }
-            state.set_drop_chatty_messages(false);
-        }
-
-        bool same_tid = state.last_tid()[element.log_id()] == element.tid();
-        // Dropped (chatty) immediately following a valid log from the same source in the same log
-        // buffer indicates we have a multiple identical squash.  chatty that differs source is due
-        // to spam filter.  chatty to chatty of different source is also due to spam filter.
-        state.last_tid()[element.log_id()] =
-                (element.dropped_count() && !same_tid) ? 0 : element.tid();
-
-        shared_lock.unlock();
-        // We never prune logs equal to or newer than any LogReaderThreads' `start` value, so the
-        // `element` pointer is safe here without the lock
-        if (!element.FlushTo(writer, stats_, same_tid)) {
-            return false;
-        }
-        shared_lock.lock_shared();
-    }
-
-    state.set_start(state.start() + 1);
-    return true;
-}
-
-bool SimpleLogBuffer::Clear(log_id_t id, uid_t uid) {
-    // Try three times to clear, then disconnect the readers and try one final time.
-    for (int retry = 0; retry < 3; ++retry) {
-        {
-            auto lock = std::lock_guard{lock_};
-            if (Prune(id, ULONG_MAX, uid)) {
-                return true;
-            }
-        }
-        sleep(1);
-    }
-    // Check if it is still busy after the sleep, we try to prune one entry, not another clear run,
-    // so we are looking for the quick side effect of the return value to tell us if we have a
-    // _blocked_ reader.
-    bool busy = false;
-    {
-        auto lock = std::lock_guard{lock_};
-        busy = !Prune(id, 1, uid);
-    }
-    // It is still busy, disconnect all readers.
-    if (busy) {
-        auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
-        for (const auto& reader_thread : reader_list_->reader_threads()) {
-            if (reader_thread->IsWatching(id)) {
-                LOG(WARNING) << "Kicking blocked reader, " << reader_thread->name()
-                             << ", from LogBuffer::clear()";
-                reader_thread->release_Locked();
-            }
-        }
-    }
-    auto lock = std::lock_guard{lock_};
-    return Prune(id, ULONG_MAX, uid);
-}
-
-// get the total space allocated to "id"
-size_t SimpleLogBuffer::GetSize(log_id_t id) {
-    auto lock = SharedLock{lock_};
-    size_t retval = max_size_[id];
-    return retval;
-}
-
-// set the total space allocated to "id"
-bool SimpleLogBuffer::SetSize(log_id_t id, size_t size) {
-    // Reasonable limits ...
-    if (!IsValidBufferSize(size)) {
-        return false;
-    }
-
-    auto lock = std::lock_guard{lock_};
-    max_size_[id] = size;
-    return true;
-}
-
-void SimpleLogBuffer::MaybePrune(log_id_t id) {
-    unsigned long prune_rows;
-    if (stats_->ShouldPrune(id, max_size_[id], &prune_rows)) {
-        Prune(id, prune_rows, 0);
-    }
-}
-
-bool SimpleLogBuffer::Prune(log_id_t id, unsigned long prune_rows, uid_t caller_uid) {
-    auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
-
-    // Don't prune logs that are newer than the point at which any reader threads are reading from.
-    LogReaderThread* oldest = nullptr;
-    for (const auto& reader_thread : reader_list_->reader_threads()) {
-        if (!reader_thread->IsWatching(id)) {
-            continue;
-        }
-        if (!oldest || oldest->start() > reader_thread->start() ||
-            (oldest->start() == reader_thread->start() &&
-             reader_thread->deadline().time_since_epoch().count() != 0)) {
-            oldest = reader_thread.get();
-        }
-    }
-
-    auto it = GetOldest(id);
-
-    while (it != logs_.end()) {
-        LogBufferElement& element = *it;
-
-        if (element.log_id() != id) {
-            ++it;
-            continue;
-        }
-
-        if (caller_uid != 0 && element.uid() != caller_uid) {
-            ++it;
-            continue;
-        }
-
-        if (oldest && oldest->start() <= element.sequence()) {
-            KickReader(oldest, id, prune_rows);
-            return false;
-        }
-
-        stats_->Subtract(element.ToLogStatisticsElement());
-        it = Erase(it);
-        if (--prune_rows == 0) {
-            return true;
-        }
-    }
-    return true;
-}
-
-std::list<LogBufferElement>::iterator SimpleLogBuffer::Erase(
-        std::list<LogBufferElement>::iterator it) {
-    bool oldest_is_it[LOG_ID_MAX];
-    log_id_for_each(i) { oldest_is_it[i] = oldest_[i] && it == *oldest_[i]; }
-
-    it = logs_.erase(it);
-
-    log_id_for_each(i) {
-        if (oldest_is_it[i]) {
-            if (__predict_false(it == logs().end())) {
-                oldest_[i] = std::nullopt;
-            } else {
-                oldest_[i] = it;  // Store the next iterator even if it does not correspond to
-                                  // the same log_id, as a starting point for GetOldest().
-            }
-        }
-    }
-
-    return it;
-}
-
-// If the selected reader is blocking our pruning progress, decide on
-// what kind of mitigation is necessary to unblock the situation.
-void SimpleLogBuffer::KickReader(LogReaderThread* reader, log_id_t id, unsigned long prune_rows) {
-    if (stats_->Sizes(id) > (2 * max_size_[id])) {  // +100%
-        // A misbehaving or slow reader has its connection
-        // dropped if we hit too much memory pressure.
-        LOG(WARNING) << "Kicking blocked reader, " << reader->name()
-                     << ", from LogBuffer::kickMe()";
-        reader->release_Locked();
-    } else if (reader->deadline().time_since_epoch().count() != 0) {
-        // Allow a blocked WRAP deadline reader to trigger and start reporting the log data.
-        reader->triggerReader_Locked();
-    } else {
-        // tell slow reader to skip entries to catch up
-        LOG(WARNING) << "Skipping " << prune_rows << " entries from slow reader, " << reader->name()
-                     << ", from LogBuffer::kickMe()";
-        reader->triggerSkip_Locked(id, prune_rows);
-    }
-}
diff --git a/logd/SimpleLogBuffer.h b/logd/SimpleLogBuffer.h
deleted file mode 100644
index 8e5b50e..0000000
--- a/logd/SimpleLogBuffer.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <atomic>
-#include <list>
-#include <mutex>
-
-#include "LogBuffer.h"
-#include "LogBufferElement.h"
-#include "LogReaderList.h"
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "rwlock.h"
-
-class SimpleLogBuffer : public LogBuffer {
-  public:
-    SimpleLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats);
-    ~SimpleLogBuffer();
-    void Init() override final;
-
-    int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
-            uint16_t len) override;
-    std::unique_ptr<FlushToState> CreateFlushToState(uint64_t start, LogMask log_mask) override;
-    bool FlushTo(LogWriter* writer, FlushToState& state,
-                 const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
-                                                  log_time realtime)>& filter) override;
-
-    bool Clear(log_id_t id, uid_t uid) override;
-    size_t GetSize(log_id_t id) override;
-    bool SetSize(log_id_t id, size_t size) override final;
-
-    uint64_t sequence() const override { return sequence_.load(std::memory_order_relaxed); }
-
-  protected:
-    virtual bool Prune(log_id_t id, unsigned long prune_rows, uid_t uid) REQUIRES(lock_);
-    virtual void LogInternal(LogBufferElement&& elem) REQUIRES(lock_);
-
-    // Returns an iterator to the oldest element for a given log type, or logs_.end() if
-    // there are no logs for the given log type. Requires logs_lock_ to be held.
-    std::list<LogBufferElement>::iterator GetOldest(log_id_t log_id) REQUIRES(lock_);
-    std::list<LogBufferElement>::iterator Erase(std::list<LogBufferElement>::iterator it)
-            REQUIRES(lock_);
-    void KickReader(LogReaderThread* reader, log_id_t id, unsigned long prune_rows)
-            REQUIRES_SHARED(lock_);
-
-    LogStatistics* stats() { return stats_; }
-    LogReaderList* reader_list() { return reader_list_; }
-    size_t max_size(log_id_t id) REQUIRES_SHARED(lock_) { return max_size_[id]; }
-    std::list<LogBufferElement>& logs() { return logs_; }
-
-    RwLock lock_;
-
-  private:
-    bool ShouldLog(log_id_t log_id, const char* msg, uint16_t len);
-    void MaybePrune(log_id_t id) REQUIRES(lock_);
-
-    LogReaderList* reader_list_;
-    LogTags* tags_;
-    LogStatistics* stats_;
-
-    std::atomic<uint64_t> sequence_ = 1;
-
-    size_t max_size_[LOG_ID_MAX] GUARDED_BY(lock_);
-    std::list<LogBufferElement> logs_ GUARDED_BY(lock_);
-    // Keeps track of the iterator to the oldest log message of a given log type, as an
-    // optimization when pruning logs.  Use GetOldest() to retrieve.
-    std::optional<std::list<LogBufferElement>::iterator> oldest_[LOG_ID_MAX] GUARDED_BY(lock_);
-};
diff --git a/logd/auditctl.cpp b/logd/auditctl.cpp
deleted file mode 100644
index 98bb02d..0000000
--- a/logd/auditctl.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2019 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 <android-base/parseint.h>
-#include <error.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "libaudit.h"
-
-static void usage(const char* cmdline) {
-    fprintf(stderr, "Usage: %s [-r rate]\n", cmdline);
-}
-
-static void do_update_rate(uint32_t rate) {
-    int fd = audit_open();
-    if (fd == -1) {
-        error(EXIT_FAILURE, errno, "Unable to open audit socket");
-    }
-    int result = audit_rate_limit(fd, rate);
-    close(fd);
-    if (result < 0) {
-        fprintf(stderr, "Can't update audit rate limit: %d\n", result);
-        exit(EXIT_FAILURE);
-    }
-}
-
-int main(int argc, char* argv[]) {
-    uint32_t rate = 0;
-    bool update_rate = false;
-    int opt;
-
-    while ((opt = getopt(argc, argv, "r:")) != -1) {
-        switch (opt) {
-            case 'r':
-                if (!android::base::ParseUint<uint32_t>(optarg, &rate)) {
-                    error(EXIT_FAILURE, errno, "Invalid Rate");
-                }
-                update_rate = true;
-                break;
-            default: /* '?' */
-                usage(argv[0]);
-                exit(EXIT_FAILURE);
-        }
-    }
-
-    // In the future, we may add other options to auditctl
-    // so this if statement will expand.
-    // if (!update_rate && !update_backlog && !update_whatever) ...
-    if (!update_rate) {
-        fprintf(stderr, "Nothing to do\n");
-        usage(argv[0]);
-        exit(EXIT_FAILURE);
-    }
-
-    if (update_rate) {
-        do_update_rate(rate);
-    }
-
-    return 0;
-}
diff --git a/logd/doc_images/cpu_cuttlefish.png b/logd/doc_images/cpu_cuttlefish.png
deleted file mode 100644
index 8d809ca..0000000
--- a/logd/doc_images/cpu_cuttlefish.png
+++ /dev/null
Binary files differ
diff --git a/logd/doc_images/cpu_walleye.png b/logd/doc_images/cpu_walleye.png
deleted file mode 100644
index 39c951b..0000000
--- a/logd/doc_images/cpu_walleye.png
+++ /dev/null
Binary files differ
diff --git a/logd/doc_images/memory_usage.png b/logd/doc_images/memory_usage.png
deleted file mode 100644
index 434d6d3..0000000
--- a/logd/doc_images/memory_usage.png
+++ /dev/null
Binary files differ
diff --git a/logd/doc_images/total_log_count.png b/logd/doc_images/total_log_count.png
deleted file mode 100644
index e73c2c1..0000000
--- a/logd/doc_images/total_log_count.png
+++ /dev/null
Binary files differ
diff --git a/logd/event.logtags b/logd/event.logtags
deleted file mode 100644
index fa13a62..0000000
--- a/logd/event.logtags
+++ /dev/null
@@ -1,39 +0,0 @@
-# The entries in this file map a sparse set of log tag numbers to tag names.
-# This is installed on the device, in /system/etc, and parsed by logcat.
-#
-# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
-# negative values alone for now.)
-#
-# Tag names are one or more ASCII letters and numbers or underscores, i.e.
-# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
-# impacts log readability, the latter makes regex searches more annoying).
-#
-# Tag numbers and names are separated by whitespace.  Blank lines and lines
-# starting with '#' are ignored.
-#
-# Optionally, after the tag names can be put a description for the value(s)
-# of the tag. Description are in the format
-#    (<name>|data type[|data unit])
-# Multiple values are separated by commas.
-#
-# The data type is a number from the following values:
-# 1: int
-# 2: long
-# 3: string
-# 4: list
-#
-# The data unit is a number taken from the following list:
-# 1: Number of objects
-# 2: Number of bytes
-# 3: Number of milliseconds
-# 4: Number of allocations
-# 5: Id
-# 6: Percent
-# s: Number of seconds (monotonic time)
-# Default value for data of type int/long is 2 (bytes).
-#
-# TODO: generate ".java" and ".h" files with integer constants from this file.
-
-1003  auditd (avc|3)
-1004  chatty (dropped|3)
-1005  tag_def (tag|1),(name|3),(format|3)
diff --git a/logd/fuzz/Android.bp b/logd/fuzz/Android.bp
deleted file mode 100644
index d346cd7..0000000
--- a/logd/fuzz/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-cc_defaults {
-    name: "log_fuzzer_defaults",
-    static_libs: [
-        "libbase",
-        "libcutils",
-        "libselinux",
-        "liblog",
-        "liblogd",
-        "libcutils",
-        "libz",
-        "libzstd",
-    ],
-    cflags: ["-Wextra"],
-    host_supported: true,
-}
-
-cc_fuzz {
-    name: "log_buffer_log_fuzzer",
-    defaults: ["log_fuzzer_defaults"],
-    srcs: [
-        "log_buffer_log_fuzzer.cpp",
-    ],
-}
-
-cc_fuzz {
-    name: "serialized_log_buffer_fuzzer",
-    defaults: ["log_fuzzer_defaults"],
-    srcs: [
-        "serialized_log_buffer_fuzzer.cpp",
-    ],
-    corpus: [
-        "corpus/logentry_use_after_compress",
-    ]
-}
diff --git a/logd/fuzz/corpus/logentry_use_after_compress b/logd/fuzz/corpus/logentry_use_after_compress
deleted file mode 100644
index 2081b13..0000000
--- a/logd/fuzz/corpus/logentry_use_after_compress
+++ /dev/null
Binary files differ
diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp
deleted file mode 100644
index d71a2f9..0000000
--- a/logd/fuzz/log_buffer_log_fuzzer.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2019 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 <string>
-
-#include <android-base/logging.h>
-
-#include "../ChattyLogBuffer.h"
-#include "../LogReaderList.h"
-#include "../LogReaderThread.h"
-#include "../LogStatistics.h"
-#include "../SerializedLogBuffer.h"
-
-// We don't want to waste a lot of entropy on messages
-#define MAX_MSG_LENGTH 5
-
-// Tag IDs usually start at 1000, we only want to try 1000 through 1009
-#define MIN_TAG_ID 1000
-#define TAG_MOD 10
-
-char* android::uidToName(uid_t) {
-    return strdup("fake");
-}
-
-struct LogInput {
-  public:
-    log_id_t log_id;
-    log_time realtime;
-    uid_t uid;
-    pid_t pid;
-    pid_t tid;
-    unsigned int log_mask;
-};
-
-int write_log_messages(const uint8_t** pdata, size_t* data_left, LogBuffer* log_buffer,
-                       LogStatistics* stats) {
-    const uint8_t* data = *pdata;
-    const LogInput* logInput = reinterpret_cast<const LogInput*>(data);
-    data += sizeof(LogInput);
-    *data_left -= sizeof(LogInput);
-
-    uint32_t tag = MIN_TAG_ID + data[0] % TAG_MOD;
-    uint8_t msg_length = data[1] % MAX_MSG_LENGTH;
-    if (msg_length < 2) {
-        // Not enough data for message
-        return 0;
-    }
-
-    data += 2 * sizeof(uint8_t);
-    *data_left -= 2 * sizeof(uint8_t);
-
-    if (*data_left < msg_length) {
-        // Not enough data for tag and message
-        *pdata = data;
-        return 0;
-    }
-
-    // We need nullterm'd strings
-    char msg[sizeof(uint32_t) + MAX_MSG_LENGTH + sizeof(char)];
-    char* msg_only = msg + sizeof(uint32_t);
-    memcpy(msg, &tag, sizeof(uint32_t));
-    memcpy(msg_only, data, msg_length);
-    msg_only[msg_length] = '\0';
-    data += msg_length;
-    *data_left -= msg_length;
-
-    // Other elements not in enum.
-    log_id_t log_id = static_cast<log_id_t>(unsigned(logInput->log_id) % (LOG_ID_MAX + 1));
-    log_buffer->Log(log_id, logInput->realtime, logInput->uid, logInput->pid, logInput->tid, msg,
-                    sizeof(uint32_t) + msg_length + 1);
-    stats->Format(logInput->uid, logInput->pid, logInput->log_mask);
-    *pdata = data;
-    return 1;
-}
-
-class NoopWriter : public LogWriter {
-  public:
-    NoopWriter() : LogWriter(0, true) {}
-    bool Write(const logger_entry&, const char*) override { return true; }
-
-    std::string name() const override { return "noop_writer"; }
-};
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    // We want a random tag length and a random remaining message length
-    if (data == nullptr || size < sizeof(LogInput) + 2 * sizeof(uint8_t)) {
-        return 0;
-    }
-
-    android::base::SetMinimumLogSeverity(android::base::ERROR);
-
-    LogReaderList reader_list;
-    LogTags tags;
-    PruneList prune_list;
-    LogStatistics stats(true, true);
-    std::unique_ptr<LogBuffer> log_buffer;
-#ifdef FUZZ_SERIALIZED
-    log_buffer.reset(new SerializedLogBuffer(&reader_list, &tags, &stats));
-#else
-    log_buffer.reset(new ChattyLogBuffer(&reader_list, &tags, &prune_list, &stats));
-#endif
-    size_t data_left = size;
-    const uint8_t** pdata = &data;
-
-    prune_list.Init(nullptr);
-    // We want to get pruning code to get called.
-    log_id_for_each(i) { log_buffer->SetSize(i, 10000); }
-
-    while (data_left >= sizeof(LogInput) + 2 * sizeof(uint8_t)) {
-        if (!write_log_messages(pdata, &data_left, log_buffer.get(), &stats)) {
-            return 0;
-        }
-    }
-
-    // Read out all of the logs.
-    {
-        auto lock = std::unique_lock{reader_list.reader_threads_lock()};
-        std::unique_ptr<LogWriter> test_writer(new NoopWriter());
-        std::unique_ptr<LogReaderThread> log_reader(
-                new LogReaderThread(log_buffer.get(), &reader_list, std::move(test_writer), true, 0,
-                                    kLogMaskAll, 0, {}, 1, {}));
-        reader_list.reader_threads().emplace_back(std::move(log_reader));
-    }
-
-    // Wait until the reader has finished.
-    while (true) {
-        usleep(50);
-        auto lock = std::unique_lock{reader_list.reader_threads_lock()};
-        if (reader_list.reader_threads().size() == 0) {
-            break;
-        }
-    }
-
-    log_id_for_each(i) { log_buffer->Clear(i, 0); }
-    return 0;
-}
diff --git a/logd/fuzz/serialized_log_buffer_fuzzer.cpp b/logd/fuzz/serialized_log_buffer_fuzzer.cpp
deleted file mode 100644
index d4795b0..0000000
--- a/logd/fuzz/serialized_log_buffer_fuzzer.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2020 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.
- */
-
-#define FUZZ_SERIALIZED
-
-#include "log_buffer_log_fuzzer.cpp"
diff --git a/logd/libaudit.cpp b/logd/libaudit.cpp
deleted file mode 100644
index ccea0a2..0000000
--- a/logd/libaudit.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright 2012, Samsung Telecommunications of America
- * Copyright (C) 2014 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.
- *
- * Written by William Roberts <w.roberts@sta.samsung.com>
- *
- */
-
-#include "libaudit.h"
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <limits>
-
-/**
- * Waits for an ack from the kernel
- * @param fd
- *  The netlink socket fd
- * @return
- *  This function returns 0 on success, else -errno.
- */
-static int get_ack(int fd) {
-    struct audit_message rep = {};
-    int rc = audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, MSG_PEEK);
-    if (rc < 0) {
-        return rc;
-    }
-
-    if (rep.nlh.nlmsg_type == NLMSG_ERROR) {
-        audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, 0);
-        rc = reinterpret_cast<struct nlmsgerr*>(rep.data)->error;
-        if (rc) {
-            return -rc;
-        }
-    }
-
-    return 0;
-}
-
-/**
- *
- * @param fd
- *  The netlink socket fd
- * @param type
- *  The type of netlink message
- * @param data
- *  The data to send
- * @param size
- *  The length of the data in bytes
- * @return
- *  This function returns a positive sequence number on success, else -errno.
- */
-static int audit_send(int fd, int type, const void* data, size_t size) {
-    struct sockaddr_nl addr = {.nl_family = AF_NETLINK};
-
-    /* Set up the netlink headers */
-    struct audit_message req = {};
-    req.nlh.nlmsg_type = static_cast<uint16_t>(type);
-    req.nlh.nlmsg_len = NLMSG_SPACE(size);
-    req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-
-    /*
-     * Check for a valid fd, even though sendto would catch this, its easier
-     * to always blindly increment the sequence number
-     */
-    if (fd < 0) {
-        return -EBADF;
-    }
-
-    /* Ensure the message is not too big */
-    if (NLMSG_SPACE(size) > MAX_AUDIT_MESSAGE_LENGTH) {
-        return -EINVAL;
-    }
-
-    /* Only memcpy in the data if it was specified */
-    if (size && data) {
-        memcpy(NLMSG_DATA(&req.nlh), data, size);
-    }
-
-    /*
-     * Only increment the sequence number on a guarantee
-     * you will send it to the kernel.
-     */
-    static uint32_t sequence = 0;
-    if (sequence == std::numeric_limits<uint32_t>::max()) {
-        sequence = 1;
-    } else {
-        sequence++;
-    }
-    req.nlh.nlmsg_seq = sequence;
-
-    ssize_t rc = TEMP_FAILURE_RETRY(
-            sendto(fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr)));
-
-    /* Not all the bytes were sent */
-    if (rc < 0) {
-        return -errno;
-    } else if ((uint32_t)rc != req.nlh.nlmsg_len) {
-        return -EPROTO;
-    }
-
-    /* We sent all the bytes, get the ack */
-    rc = get_ack(fd);
-
-    /* If the ack failed, return the error, else return the sequence number */
-    rc = (rc == 0) ? (int)sequence : rc;
-
-    return rc;
-}
-
-int audit_setup(int fd, pid_t pid) {
-    /*
-     * In order to set the auditd PID we send an audit message over the netlink
-     * socket with the pid field of the status struct set to our current pid,
-     * and the the mask set to AUDIT_STATUS_PID
-     */
-    struct audit_status status = {
-            .mask = AUDIT_STATUS_PID,
-            .pid = static_cast<uint32_t>(pid),
-    };
-
-    /* Let the kernel know this pid will be registering for audit events */
-    int rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
-    if (rc < 0) {
-        return rc;
-    }
-
-    /*
-     * In a request where we need to wait for a response, wait for the message
-     * and discard it. This message confirms and sync's us with the kernel.
-     * This daemon is now registered as the audit logger.
-     *
-     * TODO
-     * If the daemon dies and restarts the message didn't come back,
-     * so I went to non-blocking and it seemed to fix the bug.
-     * Need to investigate further.
-     */
-    struct audit_message rep = {};
-    audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
-
-    return 0;
-}
-
-int audit_open() {
-    return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT);
-}
-
-int audit_rate_limit(int fd, uint32_t limit) {
-    struct audit_status status = {
-            .mask = AUDIT_STATUS_RATE_LIMIT, .rate_limit = limit, /* audit entries per second */
-    };
-    return audit_send(fd, AUDIT_SET, &status, sizeof(status));
-}
-
-int audit_get_reply(int fd, struct audit_message* rep, reply_t block, int peek) {
-    if (fd < 0) {
-        return -EBADF;
-    }
-
-    int flags = (block == GET_REPLY_NONBLOCKING) ? MSG_DONTWAIT : 0;
-    flags |= peek;
-
-    /*
-     * Get the data from the netlink socket but on error we need to be carefull,
-     * the interface shows that EINTR can never be returned, other errors,
-     * however, can be returned.
-     */
-    struct sockaddr_nl nladdr;
-    socklen_t nladdrlen = sizeof(nladdr);
-    ssize_t len = TEMP_FAILURE_RETRY(
-            recvfrom(fd, rep, sizeof(*rep), flags, (struct sockaddr*)&nladdr, &nladdrlen));
-
-    /*
-     * EAGAIN should be re-tried until success or another error manifests.
-     */
-    if (len < 0) {
-        if (block == GET_REPLY_NONBLOCKING && errno == EAGAIN) {
-            /* If request is non blocking and errno is EAGAIN, just return 0 */
-            return 0;
-        }
-        return -errno;
-    }
-
-    if (nladdrlen != sizeof(nladdr)) {
-        return -EPROTO;
-    }
-
-    /* Make sure the netlink message was not spoof'd */
-    if (nladdr.nl_pid) {
-        return -EINVAL;
-    }
-
-    /* Check if the reply from the kernel was ok */
-    if (!NLMSG_OK(&rep->nlh, (size_t)len)) {
-        return len == sizeof(*rep) ? -EFBIG : -EBADE;
-    }
-
-    return 0;
-}
-
-void audit_close(int fd) {
-    close(fd);
-}
diff --git a/logd/libaudit.h b/logd/libaudit.h
deleted file mode 100644
index 27b0866..0000000
--- a/logd/libaudit.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2012, Samsung Telecommunications of America
- * Copyright (C) 2014 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.
- *
- * Written by William Roberts <w.roberts@sta.samsung.com>
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <linux/audit.h>
-#include <linux/netlink.h>
-
-__BEGIN_DECLS
-
-#define MAX_AUDIT_MESSAGE_LENGTH 8970
-
-typedef enum { GET_REPLY_BLOCKING = 0, GET_REPLY_NONBLOCKING } reply_t;
-
-/* type == AUDIT_SIGNAL_INFO */
-struct audit_sig_info {
-    uid_t uid;
-    pid_t pid;
-    char ctx[0];
-};
-
-struct audit_message {
-    struct nlmsghdr nlh;
-    char data[MAX_AUDIT_MESSAGE_LENGTH];
-};
-
-/**
- * Opens a connection to the Audit netlink socket
- * @return
- *  A valid fd on success or < 0 on error with errno set.
- *  Returns the same errors as man 2 socket.
- */
-extern int audit_open(void);
-
-/**
- * Closes the fd returned from audit_open()
- * @param fd
- *  The fd to close
- */
-extern void audit_close(int fd);
-
-/**
- *
- * @param fd
- *  The fd returned by a call to audit_open()
- * @param rep
- *  The response struct to store the response in.
- * @param block
- *  Whether or not to block on IO
- * @param peek
- *  Whether or not we are to remove the message from
- *  the queue when we do a read on the netlink socket.
- * @return
- *  This function returns 0 on success, else -errno.
- */
-extern int audit_get_reply(int fd, struct audit_message* rep, reply_t block,
-                           int peek);
-
-/**
- * Sets a pid to receive audit netlink events from the kernel
- * @param fd
- *  The fd returned by a call to audit_open()
- * @param pid
- *  The pid whom to set as the receiver of audit messages
- * @return
- *  This function returns 0 on success, -errno on error.
- */
-extern int audit_setup(int fd, pid_t pid);
-
-/**
- * Throttle kernel messages at the provided rate
- * @param fd
- *  The fd returned by a call to audit_open()
- * @param rate
- *  The rate, in messages per second, above which the kernel
- *  should drop audit messages.
- * @return
- *  This function returns 0 on success, -errno on error.
- */
-extern int audit_rate_limit(int fd, uint32_t limit);
-
-__END_DECLS
diff --git a/logd/logd.rc b/logd/logd.rc
deleted file mode 100644
index 530f342..0000000
--- a/logd/logd.rc
+++ /dev/null
@@ -1,35 +0,0 @@
-service logd /system/bin/logd
-    socket logd stream 0666 logd logd
-    socket logdr seqpacket 0666 logd logd
-    socket logdw dgram+passcred 0222 logd logd
-    file /proc/kmsg r
-    file /dev/kmsg w
-    user logd
-    group logd system package_info readproc
-    capabilities SYSLOG AUDIT_CONTROL
-    priority 10
-    writepid /dev/cpuset/system-background/tasks
-
-service logd-reinit /system/bin/logd --reinit
-    oneshot
-    disabled
-    user logd
-    group logd
-    writepid /dev/cpuset/system-background/tasks
-
-# Limit SELinux denial generation to 5/second
-service logd-auditctl /system/bin/auditctl -r 5
-    oneshot
-    disabled
-    user logd
-    group logd
-    capabilities AUDIT_CONTROL
-
-on fs
-    write /dev/event-log-tags "# content owned by logd
-"
-    chown logd logd /dev/event-log-tags
-    chmod 0644 /dev/event-log-tags
-
-on property:sys.boot_completed=1
-    start logd-auditctl
diff --git a/logd/logd_test.cpp b/logd/logd_test.cpp
deleted file mode 100644
index 828f580..0000000
--- a/logd/logd_test.cpp
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * Copyright (C) 2014 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 <ctype.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-#include <cutils/sockets.h>
-#include <gtest/gtest.h>
-#include <log/log_read.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-#ifdef __ANDROID__
-#include <selinux/selinux.h>
-#endif
-
-#include "LogUtils.h"  // For LOGD_SNDTIMEO.
-
-using android::base::unique_fd;
-
-#ifdef __ANDROID__
-static void send_to_control(char* buf, size_t len) {
-    int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                   SOCK_STREAM);
-    if (sock >= 0) {
-        if (write(sock, buf, strlen(buf) + 1) > 0) {
-            ssize_t ret;
-            while ((ret = read(sock, buf, len)) > 0) {
-                if (((size_t)ret == len) || (len < PAGE_SIZE)) {
-                    break;
-                }
-                len -= ret;
-                buf += ret;
-
-                struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 };
-
-                ret = poll(&p, 1, 20);
-                if ((ret <= 0) || !(p.revents & POLLIN)) {
-                    break;
-                }
-            }
-        }
-        close(sock);
-    }
-}
-
-/*
- * returns statistics
- */
-static void my_android_logger_get_statistics(char* buf, size_t len) {
-    snprintf(buf, len, "getStatistics 0 1 2 3 4");
-    send_to_control(buf, len);
-}
-
-static void alloc_statistics(char** buffer, size_t* length) {
-    size_t len = 8192;
-    char* buf;
-
-    for (int retry = 32; (retry >= 0); delete[] buf, --retry) {
-        buf = new char[len];
-        my_android_logger_get_statistics(buf, len);
-
-        buf[len - 1] = '\0';
-        size_t ret = atol(buf) + 1;
-        if (ret < 4) {
-            delete[] buf;
-            buf = nullptr;
-            break;
-        }
-        bool check = ret <= len;
-        len = ret;
-        if (check) {
-            break;
-        }
-        len += len / 8;  // allow for some slop
-    }
-    *buffer = buf;
-    *length = len;
-}
-
-static char* find_benchmark_spam(char* cp) {
-    // liblog_benchmarks has been run designed to SPAM.  The signature of
-    // a noisiest UID statistics is:
-    //
-    // Chattiest UIDs in main log buffer:                           Size Pruned
-    // UID   PACKAGE                                                BYTES LINES
-    // 0     root                                                  54164 147569
-    //
-    char* benchmark = nullptr;
-    do {
-        static const char signature[] = "\n0     root ";
-
-        benchmark = strstr(cp, signature);
-        if (!benchmark) {
-            break;
-        }
-        cp = benchmark + sizeof(signature);
-        while (isspace(*cp)) {
-            ++cp;
-        }
-        benchmark = cp;
-#ifdef DEBUG
-        char* end = strstr(benchmark, "\n");
-        if (end == nullptr) {
-            end = benchmark + strlen(benchmark);
-        }
-        fprintf(stderr, "parse for spam counter in \"%.*s\"\n",
-                (int)(end - benchmark), benchmark);
-#endif
-        // content
-        while (isdigit(*cp)) {
-            ++cp;
-        }
-        while (isspace(*cp)) {
-            ++cp;
-        }
-        // optional +/- field?
-        if ((*cp == '-') || (*cp == '+')) {
-            while (isdigit(*++cp) || (*cp == '.') || (*cp == '%') ||
-                   (*cp == 'X')) {
-                ;
-            }
-            while (isspace(*cp)) {
-                ++cp;
-            }
-        }
-        // number of entries pruned
-        unsigned long value = 0;
-        while (isdigit(*cp)) {
-            value = value * 10ULL + *cp - '0';
-            ++cp;
-        }
-        if (value > 10UL) {
-            break;
-        }
-        benchmark = nullptr;
-    } while (*cp);
-    return benchmark;
-}
-#endif
-
-#ifdef LOGD_ENABLE_FLAKY_TESTS
-TEST(logd, statistics) {
-#ifdef __ANDROID__
-    size_t len;
-    char* buf;
-
-    // Drop cache so that any access problems can be discovered.
-    if (!android::base::WriteStringToFile("3\n", "/proc/sys/vm/drop_caches")) {
-        GTEST_LOG_(INFO) << "Could not open trigger dropping inode cache";
-    }
-
-    alloc_statistics(&buf, &len);
-
-    ASSERT_TRUE(nullptr != buf);
-
-    // remove trailing FF
-    char* cp = buf + len - 1;
-    *cp = '\0';
-    bool truncated = *--cp != '\f';
-    if (!truncated) {
-        *cp = '\0';
-    }
-
-    // squash out the byte count
-    cp = buf;
-    if (!truncated) {
-        while (isdigit(*cp) || (*cp == '\n')) {
-            ++cp;
-        }
-    }
-
-    fprintf(stderr, "%s", cp);
-
-    EXPECT_LT((size_t)64, strlen(cp));
-
-    EXPECT_EQ(0, truncated);
-
-    char* main_logs = strstr(cp, "\nChattiest UIDs in main ");
-    EXPECT_TRUE(nullptr != main_logs);
-
-    char* radio_logs = strstr(cp, "\nChattiest UIDs in radio ");
-    if (!radio_logs)
-        GTEST_LOG_(INFO) << "Value of: nullptr != radio_logs\n"
-                            "Actual: false\n"
-                            "Expected: false\n";
-
-    char* system_logs = strstr(cp, "\nChattiest UIDs in system ");
-    EXPECT_TRUE(nullptr != system_logs);
-
-    char* events_logs = strstr(cp, "\nChattiest UIDs in events ");
-    EXPECT_TRUE(nullptr != events_logs);
-
-    // Check if there is any " u0_a#### " as this means packagelistparser broken
-    char* used_getpwuid = nullptr;
-    int used_getpwuid_len;
-    char* uid_name = cp;
-    static const char getpwuid_prefix[] = " u0_a";
-    while ((uid_name = strstr(uid_name, getpwuid_prefix)) != nullptr) {
-        used_getpwuid = uid_name + 1;
-        uid_name += strlen(getpwuid_prefix);
-        while (isdigit(*uid_name)) ++uid_name;
-        used_getpwuid_len = uid_name - used_getpwuid;
-        if (isspace(*uid_name)) break;
-        used_getpwuid = nullptr;
-    }
-    EXPECT_TRUE(nullptr == used_getpwuid);
-    if (used_getpwuid) {
-        fprintf(stderr, "libpackagelistparser failed to pick up %.*s\n",
-                used_getpwuid_len, used_getpwuid);
-    }
-
-    delete[] buf;
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif
-
-#ifdef __ANDROID__
-static void caught_signal(int /* signum */) {
-}
-
-static void dump_log_msg(const char* prefix, log_msg* msg, int lid) {
-    std::cout << std::flush;
-    std::cerr << std::flush;
-    fflush(stdout);
-    fflush(stderr);
-    EXPECT_GE(msg->entry.hdr_size, sizeof(logger_entry));
-
-    fprintf(stderr, "%s: [%u] ", prefix, msg->len());
-    fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size);
-    fprintf(stderr, "pid=%u tid=%u %u.%09u ", msg->entry.pid, msg->entry.tid, msg->entry.sec,
-            msg->entry.nsec);
-    lid = msg->entry.lid;
-
-    switch (lid) {
-        case 0:
-            fprintf(stderr, "lid=main ");
-            break;
-        case 1:
-            fprintf(stderr, "lid=radio ");
-            break;
-        case 2:
-            fprintf(stderr, "lid=events ");
-            break;
-        case 3:
-            fprintf(stderr, "lid=system ");
-            break;
-        case 4:
-            fprintf(stderr, "lid=crash ");
-            break;
-        case 5:
-            fprintf(stderr, "lid=security ");
-            break;
-        case 6:
-            fprintf(stderr, "lid=kernel ");
-            break;
-        default:
-            if (lid >= 0) {
-                fprintf(stderr, "lid=%d ", lid);
-            }
-    }
-
-    unsigned int len = msg->entry.len;
-    fprintf(stderr, "msg[%u]={", len);
-    unsigned char* cp = reinterpret_cast<unsigned char*>(msg->msg());
-    if (!cp) {
-        static const unsigned char garbage[] = "<INVALID>";
-        cp = const_cast<unsigned char*>(garbage);
-        len = strlen(reinterpret_cast<const char*>(garbage));
-    }
-    while (len) {
-        unsigned char* p = cp;
-        while (*p && (((' ' <= *p) && (*p < 0x7F)) || (*p == '\n'))) {
-            ++p;
-        }
-        if (((p - cp) > 3) && !*p && ((unsigned int)(p - cp) < len)) {
-            fprintf(stderr, "\"");
-            while (*cp) {
-                if (*cp != '\n') {
-                    fprintf(stderr, "%c", *cp);
-                } else {
-                    fprintf(stderr, "\\n");
-                }
-                ++cp;
-                --len;
-            }
-            fprintf(stderr, "\"");
-        } else {
-            fprintf(stderr, "%02x", *cp);
-        }
-        ++cp;
-        if (--len) {
-            fprintf(stderr, ", ");
-        }
-    }
-    fprintf(stderr, "}\n");
-    fflush(stderr);
-}
-#endif
-
-#ifdef __ANDROID__
-// BAD ROBOT
-//   Benchmark threshold are generally considered bad form unless there is
-//   is some human love applied to the continued maintenance and whether the
-//   thresholds are tuned on a per-target basis. Here we check if the values
-//   are more than double what is expected. Doubling will not prevent failure
-//   on busy or low-end systems that could have a tendency to stretch values.
-//
-//   The primary goal of this test is to simulate a spammy app (benchmark
-//   being the worst) and check to make sure the logger can deal with it
-//   appropriately by checking all the statistics are in an expected range.
-//
-TEST(logd, benchmark) {
-    size_t len;
-    char* buf;
-
-    alloc_statistics(&buf, &len);
-    bool benchmark_already_run = buf && find_benchmark_spam(buf);
-    delete[] buf;
-
-    if (benchmark_already_run) {
-        fprintf(stderr,
-                "WARNING: spam already present and too much history\n"
-                "         false OK for prune by worst UID check\n");
-    }
-
-    FILE* fp;
-
-    // Introduce some extreme spam for the worst UID filter
-    ASSERT_TRUE(
-        nullptr !=
-        (fp = popen("/data/nativetest/liblog-benchmarks/liblog-benchmarks"
-                    " BM_log_maximum_retry"
-                    " BM_log_maximum"
-                    " BM_clock_overhead"
-                    " BM_log_print_overhead"
-                    " BM_log_latency"
-                    " BM_log_delay",
-                    "r")));
-
-    char buffer[5120];
-
-    static const char* benchmarks[] = {
-        "BM_log_maximum_retry ",  "BM_log_maximum ", "BM_clock_overhead ",
-        "BM_log_print_overhead ", "BM_log_latency ", "BM_log_delay "
-    };
-    static const unsigned int log_maximum_retry = 0;
-    static const unsigned int log_maximum = 1;
-    static const unsigned int clock_overhead = 2;
-    static const unsigned int log_print_overhead = 3;
-    static const unsigned int log_latency = 4;
-    static const unsigned int log_delay = 5;
-
-    unsigned long ns[arraysize(benchmarks)];
-
-    memset(ns, 0, sizeof(ns));
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        for (unsigned i = 0; i < arraysize(ns); ++i) {
-            char* cp = strstr(buffer, benchmarks[i]);
-            if (!cp) {
-                continue;
-            }
-            sscanf(cp, "%*s %lu %lu", &ns[i], &ns[i]);
-            fprintf(stderr, "%-22s%8lu\n", benchmarks[i], ns[i]);
-        }
-    }
-    int ret = pclose(fp);
-
-    if (!WIFEXITED(ret) || (WEXITSTATUS(ret) == 127)) {
-        fprintf(stderr,
-                "WARNING: "
-                "/data/nativetest/liblog-benchmarks/liblog-benchmarks missing\n"
-                "         can not perform test\n");
-        return;
-    }
-
-    EXPECT_GE(200000UL, ns[log_maximum_retry]);  // 104734 user
-    EXPECT_NE(0UL, ns[log_maximum_retry]);       // failure to parse
-
-    EXPECT_GE(90000UL, ns[log_maximum]);  // 46913 user
-    EXPECT_NE(0UL, ns[log_maximum]);      // failure to parse
-
-    EXPECT_GE(4096UL, ns[clock_overhead]);  // 4095
-    EXPECT_NE(0UL, ns[clock_overhead]);     // failure to parse
-
-    EXPECT_GE(250000UL, ns[log_print_overhead]);  // 126886 user
-    EXPECT_NE(0UL, ns[log_print_overhead]);       // failure to parse
-
-    EXPECT_GE(10000000UL,
-              ns[log_latency]);  // 1453559 user space (background cgroup)
-    EXPECT_NE(0UL, ns[log_latency]);  // failure to parse
-
-    EXPECT_GE(20000000UL, ns[log_delay]);  // 10500289 user
-    EXPECT_NE(0UL, ns[log_delay]);         // failure to parse
-
-    alloc_statistics(&buf, &len);
-
-    bool collected_statistics = !!buf;
-    EXPECT_EQ(true, collected_statistics);
-
-    ASSERT_TRUE(nullptr != buf);
-
-    char* benchmark_statistics_found = find_benchmark_spam(buf);
-    ASSERT_TRUE(benchmark_statistics_found != nullptr);
-
-    // Check how effective the SPAM filter is, parse out Now size.
-    // 0     root                      54164 147569
-    //                                 ^-- benchmark_statistics_found
-
-    unsigned long nowSpamSize = atol(benchmark_statistics_found);
-
-    delete[] buf;
-
-    ASSERT_NE(0UL, nowSpamSize);
-
-    // Determine if we have the spam filter enabled
-    int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                   SOCK_STREAM);
-
-    ASSERT_TRUE(sock >= 0);
-
-    static const char getPruneList[] = "getPruneList";
-    if (write(sock, getPruneList, sizeof(getPruneList)) > 0) {
-        char buffer[80];
-        memset(buffer, 0, sizeof(buffer));
-        read(sock, buffer, sizeof(buffer));
-        char* cp = strchr(buffer, '\n');
-        if (!cp || (cp[1] != '~') || (cp[2] != '!')) {
-            close(sock);
-            fprintf(stderr,
-                    "WARNING: "
-                    "Logger has SPAM filtration turned off \"%s\"\n",
-                    buffer);
-            return;
-        }
-    } else {
-        int save_errno = errno;
-        close(sock);
-        FAIL() << "Can not send " << getPruneList << " to logger -- "
-               << strerror(save_errno);
-    }
-
-    static const unsigned long expected_absolute_minimum_log_size = 65536UL;
-    unsigned long totalSize = expected_absolute_minimum_log_size;
-    static const char getSize[] = { 'g', 'e', 't', 'L', 'o', 'g',
-                                    'S', 'i', 'z', 'e', ' ', LOG_ID_MAIN + '0',
-                                    '\0' };
-    if (write(sock, getSize, sizeof(getSize)) > 0) {
-        char buffer[80];
-        memset(buffer, 0, sizeof(buffer));
-        read(sock, buffer, sizeof(buffer));
-        totalSize = atol(buffer);
-        if (totalSize < expected_absolute_minimum_log_size) {
-            fprintf(stderr,
-                    "WARNING: "
-                    "Logger had unexpected referenced size \"%s\"\n",
-                    buffer);
-            totalSize = expected_absolute_minimum_log_size;
-        }
-    }
-    close(sock);
-
-    // logd allows excursions to 110% of total size
-    totalSize = (totalSize * 11) / 10;
-
-    // 50% threshold for SPAM filter (<20% typical, lots of engineering margin)
-    ASSERT_GT(totalSize, nowSpamSize * 2);
-}
-#endif
-
-// b/26447386 confirm fixed
-void timeout_negative(const char* command) {
-#ifdef __ANDROID__
-    log_msg msg_wrap, msg_timeout;
-    bool content_wrap = false, content_timeout = false, written = false;
-    unsigned int alarm_wrap = 0, alarm_timeout = 0;
-    // A few tries to get it right just in case wrap kicks in due to
-    // content providers being active during the test.
-    int i = 3;
-
-    while (--i) {
-        int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                     SOCK_SEQPACKET);
-        ASSERT_LT(0, fd);
-
-        std::string ask(command);
-
-        struct sigaction ignore, old_sigaction;
-        memset(&ignore, 0, sizeof(ignore));
-        ignore.sa_handler = caught_signal;
-        sigemptyset(&ignore.sa_mask);
-        sigaction(SIGALRM, &ignore, &old_sigaction);
-        unsigned int old_alarm = alarm(3);
-
-        size_t len = ask.length() + 1;
-        written = write(fd, ask.c_str(), len) == (ssize_t)len;
-        if (!written) {
-            alarm(old_alarm);
-            sigaction(SIGALRM, &old_sigaction, nullptr);
-            close(fd);
-            continue;
-        }
-
-        // alarm triggers at 50% of the --wrap time out
-        content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0;
-
-        alarm_wrap = alarm(5);
-
-        // alarm triggers at 133% of the --wrap time out
-        content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
-        if (!content_timeout) {  // make sure we hit dumpAndClose
-            content_timeout =
-                recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
-        }
-
-        if (old_alarm > 0) {
-            unsigned int time_spent = 3 - alarm_wrap;
-            if (old_alarm > time_spent + 1) {
-                old_alarm -= time_spent;
-            } else {
-                old_alarm = 2;
-            }
-        }
-        alarm_timeout = alarm(old_alarm);
-        sigaction(SIGALRM, &old_sigaction, nullptr);
-
-        close(fd);
-
-        if (content_wrap && alarm_wrap && content_timeout && alarm_timeout) {
-            break;
-        }
-    }
-
-    if (content_wrap) {
-        dump_log_msg("wrap", &msg_wrap, -1);
-    }
-
-    if (content_timeout) {
-        dump_log_msg("timeout", &msg_timeout, -1);
-    }
-
-    EXPECT_TRUE(written);
-    EXPECT_TRUE(content_wrap);
-    EXPECT_NE(0U, alarm_wrap);
-    EXPECT_TRUE(content_timeout);
-    EXPECT_NE(0U, alarm_timeout);
-#else
-    command = nullptr;
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(logd, timeout_no_start) {
-    timeout_negative("dumpAndClose lids=0,1,2,3,4,5 timeout=6");
-}
-
-TEST(logd, timeout_start_epoch) {
-    timeout_negative(
-        "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=0.000000000");
-}
-
-#ifdef ENABLE_FLAKY_TESTS
-// b/26447386 refined behavior
-TEST(logd, timeout) {
-#ifdef __ANDROID__
-    // b/33962045 This test interferes with other log reader tests that
-    // follow because of file descriptor socket persistence in the same
-    // process.  So let's fork it to isolate it from giving us pain.
-
-    pid_t pid = fork();
-
-    if (pid) {
-        siginfo_t info = {};
-        ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));
-        ASSERT_EQ(0, info.si_status);
-        return;
-    }
-
-    log_msg msg_wrap, msg_timeout;
-    bool content_wrap = false, content_timeout = false, written = false;
-    unsigned int alarm_wrap = 0, alarm_timeout = 0;
-    // A few tries to get it right just in case wrap kicks in due to
-    // content providers being active during the test.
-    int i = 5;
-    log_time start(CLOCK_REALTIME);
-    start.tv_sec -= 30;  // reach back a moderate period of time
-
-    while (--i) {
-        int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                     SOCK_SEQPACKET);
-        int save_errno = errno;
-        if (fd < 0) {
-            fprintf(stderr, "failed to open /dev/socket/logdr %s\n",
-                    strerror(save_errno));
-            _exit(fd);
-        }
-
-        std::string ask = android::base::StringPrintf(
-            "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" PRIu32
-            ".%09" PRIu32,
-            start.tv_sec, start.tv_nsec);
-
-        struct sigaction ignore, old_sigaction;
-        memset(&ignore, 0, sizeof(ignore));
-        ignore.sa_handler = caught_signal;
-        sigemptyset(&ignore.sa_mask);
-        sigaction(SIGALRM, &ignore, &old_sigaction);
-        unsigned int old_alarm = alarm(3);
-
-        size_t len = ask.length() + 1;
-        written = write(fd, ask.c_str(), len) == (ssize_t)len;
-        if (!written) {
-            alarm(old_alarm);
-            sigaction(SIGALRM, &old_sigaction, nullptr);
-            close(fd);
-            continue;
-        }
-
-        // alarm triggers at 50% of the --wrap time out
-        content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0;
-
-        alarm_wrap = alarm(5);
-
-        // alarm triggers at 133% of the --wrap time out
-        content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
-        if (!content_timeout) {  // make sure we hit dumpAndClose
-            content_timeout =
-                recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
-        }
-
-        if (old_alarm > 0) {
-            unsigned int time_spent = 3 - alarm_wrap;
-            if (old_alarm > time_spent + 1) {
-                old_alarm -= time_spent;
-            } else {
-                old_alarm = 2;
-            }
-        }
-        alarm_timeout = alarm(old_alarm);
-        sigaction(SIGALRM, &old_sigaction, nullptr);
-
-        close(fd);
-
-        if (!content_wrap && !alarm_wrap && content_timeout && alarm_timeout) {
-            break;
-        }
-
-        // modify start time in case content providers are relatively
-        // active _or_ inactive during the test.
-        if (content_timeout) {
-            log_time msg(msg_timeout.entry.sec, msg_timeout.entry.nsec);
-            if (msg < start) {
-                fprintf(stderr, "%u.%09u < %u.%09u\n", msg_timeout.entry.sec,
-                        msg_timeout.entry.nsec, (unsigned)start.tv_sec,
-                        (unsigned)start.tv_nsec);
-                _exit(-1);
-            }
-            if (msg > start) {
-                start = msg;
-                start.tv_sec += 30;
-                log_time now = log_time(CLOCK_REALTIME);
-                if (start > now) {
-                    start = now;
-                    --start.tv_sec;
-                }
-            }
-        } else {
-            start.tv_sec -= 120;  // inactive, reach further back!
-        }
-    }
-
-    if (content_wrap) {
-        dump_log_msg("wrap", &msg_wrap, -1);
-    }
-
-    if (content_timeout) {
-        dump_log_msg("timeout", &msg_timeout, -1);
-    }
-
-    if (content_wrap || !content_timeout) {
-        fprintf(stderr, "start=%" PRIu32 ".%09" PRIu32 "\n", start.tv_sec,
-                start.tv_nsec);
-    }
-
-    EXPECT_TRUE(written);
-    EXPECT_FALSE(content_wrap);
-    EXPECT_EQ(0U, alarm_wrap);
-    EXPECT_TRUE(content_timeout);
-    EXPECT_NE(0U, alarm_timeout);
-
-    _exit(!written + content_wrap + alarm_wrap + !content_timeout +
-          !alarm_timeout);
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif
-
-#ifdef LOGD_ENABLE_FLAKY_TESTS
-// b/27242723 confirmed fixed
-TEST(logd, SNDTIMEO) {
-#ifdef __ANDROID__
-    static const unsigned sndtimeo =
-        LOGD_SNDTIMEO;  // <sigh> it has to be done!
-    static const unsigned sleep_time = sndtimeo + 3;
-    static const unsigned alarm_time = sleep_time + 5;
-
-    int fd;
-
-    ASSERT_TRUE(
-        (fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                  SOCK_SEQPACKET)) > 0);
-
-    struct sigaction ignore, old_sigaction;
-    memset(&ignore, 0, sizeof(ignore));
-    ignore.sa_handler = caught_signal;
-    sigemptyset(&ignore.sa_mask);
-    sigaction(SIGALRM, &ignore, &old_sigaction);
-    unsigned int old_alarm = alarm(alarm_time);
-
-    static const char ask[] = "stream lids=0,1,2,3,4,5,6";  // all sources
-    bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask);
-    EXPECT_TRUE(reader_requested);
-
-    log_msg msg;
-    bool read_one = recv(fd, msg.buf, sizeof(msg), 0) > 0;
-
-    EXPECT_TRUE(read_one);
-    if (read_one) {
-        dump_log_msg("user", &msg, -1);
-    }
-
-    fprintf(stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo);
-    sleep(sleep_time);
-
-    // flush will block if we did not trigger. if it did, last entry returns 0
-    int recv_ret;
-    do {
-        recv_ret = recv(fd, msg.buf, sizeof(msg), 0);
-    } while (recv_ret > 0);
-    int save_errno = (recv_ret < 0) ? errno : 0;
-
-    EXPECT_NE(0U, alarm(old_alarm));
-    sigaction(SIGALRM, &old_sigaction, nullptr);
-
-    EXPECT_EQ(0, recv_ret);
-    if (recv_ret > 0) {
-        dump_log_msg("user", &msg, -1);
-    }
-    EXPECT_EQ(0, save_errno);
-
-    close(fd);
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-#endif
-
-TEST(logd, getEventTag_list) {
-#ifdef __ANDROID__
-    char buffer[256];
-    memset(buffer, 0, sizeof(buffer));
-    snprintf(buffer, sizeof(buffer), "getEventTag name=*");
-    send_to_control(buffer, sizeof(buffer));
-    buffer[sizeof(buffer) - 1] = '\0';
-    char* cp;
-    long ret = strtol(buffer, &cp, 10);
-    EXPECT_GT(ret, 4096);
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(logd, getEventTag_42) {
-#ifdef __ANDROID__
-    char buffer[256];
-    memset(buffer, 0, sizeof(buffer));
-    snprintf(buffer, sizeof(buffer), "getEventTag id=42");
-    send_to_control(buffer, sizeof(buffer));
-    buffer[sizeof(buffer) - 1] = '\0';
-    char* cp;
-    long ret = strtol(buffer, &cp, 10);
-    EXPECT_GT(ret, 16);
-    EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != nullptr);
-    EXPECT_TRUE(strstr(buffer, "answer") != nullptr);
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(logd, getEventTag_newentry) {
-#ifdef __ANDROID__
-    char buffer[256];
-    memset(buffer, 0, sizeof(buffer));
-    log_time now(CLOCK_MONOTONIC);
-    char name[64];
-    snprintf(name, sizeof(name), "a%" PRIu64, now.nsec());
-    snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"",
-             name);
-    send_to_control(buffer, sizeof(buffer));
-    buffer[sizeof(buffer) - 1] = '\0';
-    char* cp;
-    long ret = strtol(buffer, &cp, 10);
-    EXPECT_GT(ret, 16);
-    EXPECT_TRUE(strstr(buffer, "\t(new|1)") != nullptr);
-    EXPECT_TRUE(strstr(buffer, name) != nullptr);
-// ToDo: also look for this in /data/misc/logd/event-log-tags and
-// /dev/event-log-tags.
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
-TEST(logd, no_epipe) {
-#ifdef __ANDROID__
-    // Actually generating SIGPIPE in logd is racy, since we need to close the socket quicker than
-    // logd finishes writing the data to it, so we try 10 times, which should be enough to trigger
-    // SIGPIPE if logd isn't ignoring SIGPIPE
-    for (int i = 0; i < 10; ++i) {
-        unique_fd sock1(
-                socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
-        ASSERT_GT(sock1, 0);
-        unique_fd sock2(
-                socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
-        ASSERT_GT(sock2, 0);
-
-        std::string message = "getStatistics 0 1 2 3 4 5 6 7";
-
-        ASSERT_GT(write(sock1, message.c_str(), message.length()), 0);
-        sock1.reset();
-        ASSERT_GT(write(sock2, message.c_str(), message.length()), 0);
-
-        struct pollfd p = {.fd = sock2, .events = POLLIN, .revents = 0};
-
-        int ret = poll(&p, 1, 20);
-        EXPECT_EQ(ret, 1);
-        EXPECT_TRUE(p.revents & POLLIN);
-        EXPECT_FALSE(p.revents & POLL_ERR);
-    }
-#else
-    GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
diff --git a/logd/logtagd.rc b/logd/logtagd.rc
deleted file mode 100644
index 248a78c..0000000
--- a/logd/logtagd.rc
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# logtagd event log tag service (debug only)
-#
-on post-fs-data
-    mkdir /data/misc/logd 0750 logd log
-    write /data/misc/logd/event-log-tags ""
-    chown logd log /data/misc/logd/event-log-tags
-    chmod 0600 /data/misc/logd/event-log-tags
-    restorecon /data/misc/logd/event-log-tags
diff --git a/logd/main.cpp b/logd/main.cpp
deleted file mode 100644
index c92c5b7..0000000
--- a/logd/main.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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 <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/capability.h>
-#include <poll.h>
-#include <sched.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/capability.h>
-#include <sys/klog.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include <memory>
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <cutils/android_get_control_file.h>
-#include <cutils/sockets.h>
-#include <log/event_tag_map.h>
-#include <packagelistparser/packagelistparser.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-#include <processgroup/sched_policy.h>
-#include <utils/threads.h>
-
-#include "ChattyLogBuffer.h"
-#include "CommandListener.h"
-#include "LogAudit.h"
-#include "LogBuffer.h"
-#include "LogKlog.h"
-#include "LogListener.h"
-#include "LogReader.h"
-#include "LogStatistics.h"
-#include "LogTags.h"
-#include "LogUtils.h"
-#include "SerializedLogBuffer.h"
-#include "SimpleLogBuffer.h"
-
-using android::base::GetBoolProperty;
-using android::base::GetProperty;
-using android::base::SetProperty;
-
-#define KMSG_PRIORITY(PRI)                                 \
-    '<', '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \
-        '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, '>'
-
-// The service is designed to be run by init, it does not respond well to starting up manually. Init
-// has a 'sigstop' feature that sends SIGSTOP to a service immediately before calling exec().  This
-// allows debuggers, etc to be attached to logd at the very beginning, while still having init
-// handle the user, groups, capabilities, files, etc setup.
-static void DropPrivs(bool klogd, bool auditd) {
-    if (set_sched_policy(0, SP_BACKGROUND) < 0) {
-        PLOG(FATAL) << "failed to set background scheduling policy";
-    }
-
-    sched_param param = {};
-    if (sched_setscheduler((pid_t)0, SCHED_BATCH, &param) < 0) {
-        PLOG(FATAL) << "failed to set batch scheduler";
-    }
-
-    if (!GetBoolProperty("ro.debuggable", false)) {
-        if (prctl(PR_SET_DUMPABLE, 0) == -1) {
-            PLOG(FATAL) << "failed to clear PR_SET_DUMPABLE";
-        }
-    }
-
-    std::unique_ptr<struct _cap_struct, int (*)(void*)> caps(cap_init(), cap_free);
-    if (cap_clear(caps.get()) < 0) {
-        PLOG(FATAL) << "cap_clear() failed";
-    }
-    if (klogd) {
-        cap_value_t cap_syslog = CAP_SYSLOG;
-        if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, &cap_syslog, CAP_SET) < 0 ||
-            cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, &cap_syslog, CAP_SET) < 0) {
-            PLOG(FATAL) << "Failed to set CAP_SYSLOG";
-        }
-    }
-    if (auditd) {
-        cap_value_t cap_audit_control = CAP_AUDIT_CONTROL;
-        if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, &cap_audit_control, CAP_SET) < 0 ||
-            cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, &cap_audit_control, CAP_SET) < 0) {
-            PLOG(FATAL) << "Failed to set CAP_AUDIT_CONTROL";
-        }
-    }
-    if (cap_set_proc(caps.get()) < 0) {
-        PLOG(FATAL) << "cap_set_proc() failed";
-    }
-}
-
-// GetBoolProperty that defaults to true if `ro.debuggable == true && ro.config.low_rawm == false`.
-static bool GetBoolPropertyEngSvelteDefault(const std::string& name) {
-    bool default_value =
-            GetBoolProperty("ro.debuggable", false) && !GetBoolProperty("ro.config.low_ram", false);
-
-    return GetBoolProperty(name, default_value);
-}
-
-char* android::uidToName(uid_t u) {
-    struct Userdata {
-        uid_t uid;
-        char* name;
-    } userdata = {
-            .uid = u,
-            .name = nullptr,
-    };
-
-    packagelist_parse(
-            [](pkg_info* info, void* callback_parameter) {
-                auto userdata = reinterpret_cast<Userdata*>(callback_parameter);
-                bool result = true;
-                if (info->uid == userdata->uid) {
-                    userdata->name = strdup(info->name);
-                    // false to stop processing
-                    result = false;
-                }
-                packagelist_free(info);
-                return result;
-            },
-            &userdata);
-
-    return userdata.name;
-}
-
-static void readDmesg(LogAudit* al, LogKlog* kl) {
-    if (!al && !kl) {
-        return;
-    }
-
-    int rc = klogctl(KLOG_SIZE_BUFFER, nullptr, 0);
-    if (rc <= 0) {
-        return;
-    }
-
-    // Margin for additional input race or trailing nul
-    ssize_t len = rc + 1024;
-    std::unique_ptr<char[]> buf(new char[len]);
-
-    rc = klogctl(KLOG_READ_ALL, buf.get(), len);
-    if (rc <= 0) {
-        return;
-    }
-
-    if (rc < len) {
-        len = rc + 1;
-    }
-    buf[--len] = '\0';
-
-    ssize_t sublen;
-    for (char *ptr = nullptr, *tok = buf.get();
-         (rc >= 0) && !!(tok = android::log_strntok_r(tok, len, ptr, sublen));
-         tok = nullptr) {
-        if ((sublen <= 0) || !*tok) continue;
-        if (al) {
-            rc = al->log(tok, sublen);
-        }
-        if (kl) {
-            rc = kl->log(tok, sublen);
-        }
-    }
-}
-
-static int issueReinit() {
-    int sock = TEMP_FAILURE_RETRY(socket_local_client(
-        "logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
-    if (sock < 0) return -errno;
-
-    static const char reinitStr[] = "reinit";
-    ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinitStr, sizeof(reinitStr)));
-    if (ret < 0) return -errno;
-
-    struct pollfd p;
-    memset(&p, 0, sizeof(p));
-    p.fd = sock;
-    p.events = POLLIN;
-    ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000));
-    if (ret < 0) return -errno;
-    if ((ret == 0) || !(p.revents & POLLIN)) return -ETIME;
-
-    static const char success[] = "success";
-    char buffer[sizeof(success) - 1];
-    memset(buffer, 0, sizeof(buffer));
-    ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
-    if (ret < 0) return -errno;
-
-    return strncmp(buffer, success, sizeof(success) - 1) != 0;
-}
-
-// Foreground waits for exit of the main persistent threads
-// that are started here. The threads are created to manage
-// UNIX domain client sockets for writing, reading and
-// controlling the user space logger, and for any additional
-// logging plugins like auditd and restart control. Additional
-// transitory per-client threads are created for each reader.
-int main(int argc, char* argv[]) {
-    // We want EPIPE when a reader disconnects, not to terminate logd.
-    signal(SIGPIPE, SIG_IGN);
-    // logd is written under the assumption that the timezone is UTC.
-    // If TZ is not set, persist.sys.timezone is looked up in some time utility
-    // libc functions, including mktime. It confuses the logd time handling,
-    // so here explicitly set TZ to UTC, which overrides the property.
-    setenv("TZ", "UTC", 1);
-    // issue reinit command. KISS argument parsing.
-    if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
-        return issueReinit();
-    }
-
-    android::base::InitLogging(
-            argv, [](android::base::LogId log_id, android::base::LogSeverity severity,
-                     const char* tag, const char* file, unsigned int line, const char* message) {
-                if (tag && strcmp(tag, "logd") != 0) {
-                    auto prefixed_message = android::base::StringPrintf("%s: %s", tag, message);
-                    android::base::KernelLogger(log_id, severity, "logd", file, line,
-                                                prefixed_message.c_str());
-                } else {
-                    android::base::KernelLogger(log_id, severity, "logd", file, line, message);
-                }
-            });
-
-    static const char dev_kmsg[] = "/dev/kmsg";
-    int fdDmesg = android_get_control_file(dev_kmsg);
-    if (fdDmesg < 0) {
-        fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC));
-    }
-
-    int fdPmesg = -1;
-    bool klogd = GetBoolPropertyEngSvelteDefault("ro.logd.kernel");
-    if (klogd) {
-        SetProperty("ro.logd.kernel", "true");
-        static const char proc_kmsg[] = "/proc/kmsg";
-        fdPmesg = android_get_control_file(proc_kmsg);
-        if (fdPmesg < 0) {
-            fdPmesg = TEMP_FAILURE_RETRY(
-                open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC));
-        }
-        if (fdPmesg < 0) PLOG(ERROR) << "Failed to open " << proc_kmsg;
-    }
-
-    bool auditd = GetBoolProperty("ro.logd.auditd", true);
-    DropPrivs(klogd, auditd);
-
-    // A cache of event log tags
-    LogTags log_tags;
-
-    // Pruning configuration.
-    PruneList prune_list;
-
-    std::string buffer_type = GetProperty("logd.buffer_type", "serialized");
-
-    // Partial (required for chatty) or full logging statistics.
-    LogStatistics log_statistics(GetBoolPropertyEngSvelteDefault("logd.statistics"),
-                                 buffer_type == "serialized");
-
-    // Serves the purpose of managing the last logs times read on a socket connection, and as a
-    // reader lock on a range of log entries.
-    LogReaderList reader_list;
-
-    // LogBuffer is the object which is responsible for holding all log entries.
-    LogBuffer* log_buffer = nullptr;
-    if (buffer_type == "chatty") {
-        log_buffer = new ChattyLogBuffer(&reader_list, &log_tags, &prune_list, &log_statistics);
-    } else if (buffer_type == "serialized") {
-        log_buffer = new SerializedLogBuffer(&reader_list, &log_tags, &log_statistics);
-    } else if (buffer_type == "simple") {
-        log_buffer = new SimpleLogBuffer(&reader_list, &log_tags, &log_statistics);
-    } else {
-        LOG(FATAL) << "buffer_type must be one of 'chatty', 'serialized', or 'simple'";
-    }
-
-    // LogReader listens on /dev/socket/logdr. When a client
-    // connects, log entries in the LogBuffer are written to the client.
-    LogReader* reader = new LogReader(log_buffer, &reader_list);
-    if (reader->startListener()) {
-        return EXIT_FAILURE;
-    }
-
-    // LogListener listens on /dev/socket/logdw for client
-    // initiated log messages. New log entries are added to LogBuffer
-    // and LogReader is notified to send updates to connected clients.
-    LogListener* swl = new LogListener(log_buffer);
-    if (!swl->StartListener()) {
-        return EXIT_FAILURE;
-    }
-
-    // Command listener listens on /dev/socket/logd for incoming logd
-    // administrative commands.
-    CommandListener* cl = new CommandListener(log_buffer, &log_tags, &prune_list, &log_statistics);
-    if (cl->startListener()) {
-        return EXIT_FAILURE;
-    }
-
-    // LogAudit listens on NETLINK_AUDIT socket for selinux
-    // initiated log messages. New log entries are added to LogBuffer
-    // and LogReader is notified to send updates to connected clients.
-    LogAudit* al = nullptr;
-    if (auditd) {
-        int dmesg_fd = GetBoolProperty("ro.logd.auditd.dmesg", true) ? fdDmesg : -1;
-        al = new LogAudit(log_buffer, dmesg_fd, &log_statistics);
-    }
-
-    LogKlog* kl = nullptr;
-    if (klogd) {
-        kl = new LogKlog(log_buffer, fdDmesg, fdPmesg, al != nullptr, &log_statistics);
-    }
-
-    readDmesg(al, kl);
-
-    // failure is an option ... messages are in dmesg (required by standard)
-    if (kl && kl->startListener()) {
-        delete kl;
-    }
-
-    if (al && al->startListener()) {
-        delete al;
-    }
-
-    TEMP_FAILURE_RETRY(pause());
-
-    return EXIT_SUCCESS;
-}
diff --git a/logd/rwlock.h b/logd/rwlock.h
deleted file mode 100644
index c37721e..0000000
--- a/logd/rwlock.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2020 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/LICENSE2.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.
- */
-
-#pragma once
-
-#include <pthread.h>
-
-#include <android-base/macros.h>
-#include <android-base/thread_annotations.h>
-
-// As of the end of May 2020, std::shared_mutex is *not* simply a pthread_rwlock, but rather a
-// combination of std::mutex and std::condition variable, which is obviously less efficient.  This
-// immitates what std::shared_mutex should be doing and is compatible with RAII thread wrappers.
-
-class SHARED_CAPABILITY("mutex") RwLock {
-  public:
-    RwLock() {}
-    ~RwLock() {}
-
-    void lock() ACQUIRE() { pthread_rwlock_wrlock(&rwlock_); }
-    void lock_shared() ACQUIRE_SHARED() { pthread_rwlock_rdlock(&rwlock_); }
-
-    void unlock() RELEASE() { pthread_rwlock_unlock(&rwlock_); }
-
-  private:
-    pthread_rwlock_t rwlock_ = PTHREAD_RWLOCK_INITIALIZER;
-};
-
-// std::shared_lock does not have thread annotations, so we need our own.
-
-class SCOPED_CAPABILITY SharedLock {
-  public:
-    explicit SharedLock(RwLock& lock) ACQUIRE_SHARED(lock) : lock_(lock) { lock_.lock_shared(); }
-    ~SharedLock() RELEASE() { lock_.unlock(); }
-
-    void lock_shared() ACQUIRE_SHARED() { lock_.lock_shared(); }
-    void unlock() RELEASE() { lock_.unlock(); }
-
-    DISALLOW_IMPLICIT_CONSTRUCTORS(SharedLock);
-
-  private:
-    RwLock& lock_;
-};
diff --git a/logwrapper b/logwrapper
new file mode 120000
index 0000000..a65ffdf
--- /dev/null
+++ b/logwrapper
@@ -0,0 +1 @@
+../logging/logwrapper
\ No newline at end of file
diff --git a/logwrapper/Android.bp b/logwrapper/Android.bp
deleted file mode 100644
index 8851a47..0000000
--- a/logwrapper/Android.bp
+++ /dev/null
@@ -1,70 +0,0 @@
-cc_defaults {
-    name: "logwrapper_defaults",
-    cflags: [
-        "-Werror",
-    ],
-}
-
-// ========================================================
-// Static and shared library
-// ========================================================
-
-cc_library {
-    name: "liblogwrap",
-    defaults: ["logwrapper_defaults"],
-    recovery_available: true,
-    srcs: ["logwrap.cpp"],
-    shared_libs: [
-        "libcutils",
-        "liblog",
-    ],
-    header_libs: ["libbase_headers"],
-    export_include_dirs: ["include"],
-    local_include_dirs: ["include"],
-}
-
-// ========================================================
-// Executable
-// ========================================================
-
-cc_defaults {
-    name: "logwrapper_common",
-    defaults: ["logwrapper_defaults"],
-    local_include_dirs: ["include"],
-    srcs: [
-        "logwrap.cpp",
-        "logwrapper.cpp",
-    ],
-    header_libs: ["libbase_headers"],
-    shared_libs: ["libcutils", "liblog"],
-}
-
-cc_binary {
-    name: "logwrapper",
-    defaults: ["logwrapper_common"],
-}
-
-cc_binary {
-    name: "logwrapper_vendor",
-    defaults: ["logwrapper_common"],
-    stem: "logwrapper",
-    vendor: true,
-}
-
-// ========================================================
-// Benchmark
-// ========================================================
-
-cc_benchmark {
-    name: "logwrap_fork_execvp_benchmark",
-    defaults: ["logwrapper_defaults"],
-    srcs: [
-        "logwrap_fork_execvp_benchmark.cpp",
-    ],
-    shared_libs: [
-        "libbase",
-        "libcutils",
-        "liblog",
-        "liblogwrap",
-    ],
-}
diff --git a/logwrapper/NOTICE b/logwrapper/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/logwrapper/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/logwrapper/OWNERS b/logwrapper/OWNERS
deleted file mode 100644
index babbe4d..0000000
--- a/logwrapper/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tomcherry@google.com
diff --git a/logwrapper/include/logwrap/logwrap.h b/logwrapper/include/logwrap/logwrap.h
deleted file mode 100644
index cb40ee2..0000000
--- a/logwrapper/include/logwrap/logwrap.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* system/core/include/logwrap/logwrap.h
- *
- * Copyright 2013, 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.
- */
-
-#pragma once
-
-/*
- * Run a command while logging its stdout and stderr
- *
- * Arguments:
- *   argc:   the number of elements in argv
- *   argv:   an array of strings containing the command to be executed and its
- *           arguments as separate strings. argv does not need to be
- *           NULL-terminated
- *   status: the equivalent child status as populated by wait(status). This
- *           value is only valid when logwrap successfully completes. If NULL
- *           the return value of the child will be the function's return value.
- *   forward_signals: set to true if you want to forward SIGINT, SIGQUIT, and
- *           SIGHUP to the child process, while it is running.  You likely do
- *           not need to use this; it is primarily for the logwrapper
- *           executable itself.
- *   log_target: Specify where to log the output of the child, either LOG_NONE,
- *           LOG_ALOG (for the Android system log), LOG_KLOG (for the kernel
- *           log), or LOG_FILE (and you need to specify a pathname in the
- *           file_path argument, otherwise pass NULL).  These are bit fields,
- *           and can be OR'ed together to log to multiple places.
- *   abbreviated: If true, capture up to the first 100 lines and last 4K of
- *           output from the child.  The abbreviated output is not dumped to
- *           the specified log until the child has exited.
- *   file_path: if log_target has the LOG_FILE bit set, then this parameter
- *           must be set to the pathname of the file to log to.
- *
- * Return value:
- *   0 when logwrap successfully run the child process and captured its status
- *   -1 when an internal error occurred
- *   -ECHILD if status is NULL and the child didn't exit properly
- *   the return value of the child if it exited properly and status is NULL
- *
- */
-
-/* Values for the log_target parameter logwrap_fork_execvp() */
-#define LOG_NONE        0
-#define LOG_ALOG        1
-#define LOG_KLOG        2
-#define LOG_FILE        4
-
-int logwrap_fork_execvp(int argc, const char* const* argv, int* status, bool forward_signals,
-                        int log_target, bool abbreviated, const char* file_path);
diff --git a/logwrapper/logwrap.cpp b/logwrapper/logwrap.cpp
deleted file mode 100644
index 5a518bc..0000000
--- a/logwrapper/logwrap.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Copyright (C) 2008 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 <fcntl.h>
-#include <libgen.h>
-#include <poll.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <algorithm>
-
-#include <android-base/macros.h>
-#include <cutils/klog.h>
-#include <log/log.h>
-#include <logwrap/logwrap.h>
-
-static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
-// Protected by fd_mutex.  These signals must be blocked while modifying as well.
-static pid_t child_pid;
-static struct sigaction old_int;
-static struct sigaction old_quit;
-static struct sigaction old_hup;
-
-#define ERROR(fmt, args...)                         \
-    do {                                            \
-        fprintf(stderr, fmt, ##args);               \
-        ALOG(LOG_ERROR, "logwrapper", fmt, ##args); \
-    } while (0)
-
-#define FATAL_CHILD(fmt, args...) \
-    do {                          \
-        ERROR(fmt, ##args);       \
-        _exit(-1);                \
-    } while (0)
-
-#define MAX_KLOG_TAG 16
-
-/* This is a simple buffer that holds up to the first beginning_buf->buf_size
- * bytes of output from a command.
- */
-#define BEGINNING_BUF_SIZE 0x1000
-struct beginning_buf {
-    char* buf;
-    size_t alloc_len;
-    /* buf_size is the usable space, which is one less than the allocated size */
-    size_t buf_size;
-    size_t used_len;
-};
-
-/* This is a circular buf that holds up to the last ending_buf->buf_size bytes
- * of output from a command after the first beginning_buf->buf_size bytes
- * (which are held in beginning_buf above).
- */
-#define ENDING_BUF_SIZE 0x1000
-struct ending_buf {
-    char* buf;
-    ssize_t alloc_len;
-    /* buf_size is the usable space, which is one less than the allocated size */
-    ssize_t buf_size;
-    ssize_t used_len;
-    /* read and write offsets into the circular buffer */
-    int read;
-    int write;
-};
-
-/* A structure to hold all the abbreviated buf data */
-struct abbr_buf {
-    struct beginning_buf b_buf;
-    struct ending_buf e_buf;
-    int beginning_buf_full;
-};
-
-/* Collect all the various bits of info needed for logging in one place. */
-struct log_info {
-    int log_target;
-    char klog_fmt[MAX_KLOG_TAG * 2];
-    const char* btag;
-    bool abbreviated;
-    FILE* fp;
-    struct abbr_buf a_buf;
-};
-
-/* Forware declaration */
-static void add_line_to_abbr_buf(struct abbr_buf* a_buf, char* linebuf, int linelen);
-
-/* Return 0 on success, and 1 when full */
-static int add_line_to_linear_buf(struct beginning_buf* b_buf, char* line, ssize_t line_len) {
-    int full = 0;
-
-    if ((line_len + b_buf->used_len) > b_buf->buf_size) {
-        full = 1;
-    } else {
-        /* Add to the end of the buf */
-        memcpy(b_buf->buf + b_buf->used_len, line, line_len);
-        b_buf->used_len += line_len;
-    }
-
-    return full;
-}
-
-static void add_line_to_circular_buf(struct ending_buf* e_buf, char* line, ssize_t line_len) {
-    ssize_t free_len;
-    ssize_t needed_space;
-    int cnt;
-
-    if (e_buf->buf == nullptr) {
-        return;
-    }
-
-    if (line_len > e_buf->buf_size) {
-        return;
-    }
-
-    free_len = e_buf->buf_size - e_buf->used_len;
-
-    if (line_len > free_len) {
-        /* remove oldest entries at read, and move read to make
-         * room for the new string */
-        needed_space = line_len - free_len;
-        e_buf->read = (e_buf->read + needed_space) % e_buf->buf_size;
-        e_buf->used_len -= needed_space;
-    }
-
-    /* Copy the line into the circular buffer, dealing with possible
-     * wraparound.
-     */
-    cnt = std::min(line_len, e_buf->buf_size - e_buf->write);
-    memcpy(e_buf->buf + e_buf->write, line, cnt);
-    if (cnt < line_len) {
-        memcpy(e_buf->buf, line + cnt, line_len - cnt);
-    }
-    e_buf->used_len += line_len;
-    e_buf->write = (e_buf->write + line_len) % e_buf->buf_size;
-}
-
-/* Log directly to the specified log */
-static void do_log_line(struct log_info* log_info, const char* line) {
-    if (log_info->log_target & LOG_KLOG) {
-        klog_write(6, log_info->klog_fmt, line);
-    }
-    if (log_info->log_target & LOG_ALOG) {
-        ALOG(LOG_INFO, log_info->btag, "%s", line);
-    }
-    if (log_info->log_target & LOG_FILE) {
-        fprintf(log_info->fp, "%s\n", line);
-    }
-}
-
-/* Log to either the abbreviated buf, or directly to the specified log
- * via do_log_line() above.
- */
-static void log_line(struct log_info* log_info, char* line, int len) {
-    if (log_info->abbreviated) {
-        add_line_to_abbr_buf(&log_info->a_buf, line, len);
-    } else {
-        do_log_line(log_info, line);
-    }
-}
-
-/*
- * The kernel will take a maximum of 1024 bytes in any single write to
- * the kernel logging device file, so find and print each line one at
- * a time.  The allocated size for buf should be at least 1 byte larger
- * than buf_size (the usable size of the buffer) to make sure there is
- * room to temporarily stuff a null byte to terminate a line for logging.
- */
-static void print_buf_lines(struct log_info* log_info, char* buf, int buf_size) {
-    char* line_start;
-    char c;
-    int i;
-
-    line_start = buf;
-    for (i = 0; i < buf_size; i++) {
-        if (*(buf + i) == '\n') {
-            /* Found a line ending, print the line and compute new line_start */
-            /* Save the next char and replace with \0 */
-            c = *(buf + i + 1);
-            *(buf + i + 1) = '\0';
-            do_log_line(log_info, line_start);
-            /* Restore the saved char */
-            *(buf + i + 1) = c;
-            line_start = buf + i + 1;
-        } else if (*(buf + i) == '\0') {
-            /* The end of the buffer, print the last bit */
-            do_log_line(log_info, line_start);
-            break;
-        }
-    }
-    /* If the buffer was completely full, and didn't end with a newline, just
-     * ignore the partial last line.
-     */
-}
-
-static void init_abbr_buf(struct abbr_buf* a_buf) {
-    char* new_buf;
-
-    memset(a_buf, 0, sizeof(struct abbr_buf));
-    new_buf = static_cast<char*>(malloc(BEGINNING_BUF_SIZE));
-    if (new_buf) {
-        a_buf->b_buf.buf = new_buf;
-        a_buf->b_buf.alloc_len = BEGINNING_BUF_SIZE;
-        a_buf->b_buf.buf_size = BEGINNING_BUF_SIZE - 1;
-    }
-    new_buf = static_cast<char*>(malloc(ENDING_BUF_SIZE));
-    if (new_buf) {
-        a_buf->e_buf.buf = new_buf;
-        a_buf->e_buf.alloc_len = ENDING_BUF_SIZE;
-        a_buf->e_buf.buf_size = ENDING_BUF_SIZE - 1;
-    }
-}
-
-static void free_abbr_buf(struct abbr_buf* a_buf) {
-    free(a_buf->b_buf.buf);
-    free(a_buf->e_buf.buf);
-}
-
-static void add_line_to_abbr_buf(struct abbr_buf* a_buf, char* linebuf, int linelen) {
-    if (!a_buf->beginning_buf_full) {
-        a_buf->beginning_buf_full = add_line_to_linear_buf(&a_buf->b_buf, linebuf, linelen);
-    }
-    if (a_buf->beginning_buf_full) {
-        add_line_to_circular_buf(&a_buf->e_buf, linebuf, linelen);
-    }
-}
-
-static void print_abbr_buf(struct log_info* log_info) {
-    struct abbr_buf* a_buf = &log_info->a_buf;
-
-    /* Add the abbreviated output to the kernel log */
-    if (a_buf->b_buf.alloc_len) {
-        print_buf_lines(log_info, a_buf->b_buf.buf, a_buf->b_buf.used_len);
-    }
-
-    /* Print an ellipsis to indicate that the buffer has wrapped or
-     * is full, and some data was not logged.
-     */
-    if (a_buf->e_buf.used_len == a_buf->e_buf.buf_size) {
-        do_log_line(log_info, "...\n");
-    }
-
-    if (a_buf->e_buf.used_len == 0) {
-        return;
-    }
-
-    /* Simplest way to print the circular buffer is allocate a second buf
-     * of the same size, and memcpy it so it's a simple linear buffer,
-     * and then cal print_buf_lines on it */
-    if (a_buf->e_buf.read < a_buf->e_buf.write) {
-        /* no wrap around, just print it */
-        print_buf_lines(log_info, a_buf->e_buf.buf + a_buf->e_buf.read, a_buf->e_buf.used_len);
-    } else {
-        /* The circular buffer will always have at least 1 byte unused,
-         * so by allocating alloc_len here we will have at least
-         * 1 byte of space available as required by print_buf_lines().
-         */
-        char* nbuf = static_cast<char*>(malloc(a_buf->e_buf.alloc_len));
-        if (!nbuf) {
-            return;
-        }
-        int first_chunk_len = a_buf->e_buf.buf_size - a_buf->e_buf.read;
-        memcpy(nbuf, a_buf->e_buf.buf + a_buf->e_buf.read, first_chunk_len);
-        /* copy second chunk */
-        memcpy(nbuf + first_chunk_len, a_buf->e_buf.buf, a_buf->e_buf.write);
-        print_buf_lines(log_info, nbuf, first_chunk_len + a_buf->e_buf.write);
-        free(nbuf);
-    }
-}
-
-static void signal_handler(int signal_num);
-
-static void block_signals(sigset_t* oldset) {
-    sigset_t blockset;
-
-    sigemptyset(&blockset);
-    sigaddset(&blockset, SIGINT);
-    sigaddset(&blockset, SIGQUIT);
-    sigaddset(&blockset, SIGHUP);
-    pthread_sigmask(SIG_BLOCK, &blockset, oldset);
-}
-
-static void unblock_signals(sigset_t* oldset) {
-    pthread_sigmask(SIG_SETMASK, oldset, nullptr);
-}
-
-static void setup_signal_handlers(pid_t pid) {
-    struct sigaction handler = {.sa_handler = signal_handler};
-
-    child_pid = pid;
-    sigaction(SIGINT, &handler, &old_int);
-    sigaction(SIGQUIT, &handler, &old_quit);
-    sigaction(SIGHUP, &handler, &old_hup);
-}
-
-static void restore_signal_handlers() {
-    sigaction(SIGINT, &old_int, nullptr);
-    sigaction(SIGQUIT, &old_quit, nullptr);
-    sigaction(SIGHUP, &old_hup, nullptr);
-    child_pid = 0;
-}
-
-static void signal_handler(int signal_num) {
-    if (child_pid == 0 || kill(child_pid, signal_num) != 0) {
-        restore_signal_handlers();
-        raise(signal_num);
-    }
-}
-
-static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, int log_target,
-                  bool abbreviated, const char* file_path, bool forward_signals) {
-    int status = 0;
-    char buffer[4096];
-    struct pollfd poll_fds[] = {
-            {
-                    .fd = parent_read,
-                    .events = POLLIN,
-            },
-    };
-    int rc = 0;
-    int fd;
-
-    struct log_info log_info;
-
-    int a = 0;  // start index of unprocessed data
-    int b = 0;  // end index of unprocessed data
-    int sz;
-    bool found_child = false;
-    // There is a very small chance that opening child_ptty in the child will fail, but in this case
-    // POLLHUP will not be generated below.  Therefore, we use a 1 second timeout for poll() until
-    // we receive a message from child_ptty.  If this times out, we call waitpid() with WNOHANG to
-    // check the status of the child process and exit appropriately if it has terminated.
-    bool received_messages = false;
-    char tmpbuf[256];
-
-    log_info.btag = basename(tag);
-    if (!log_info.btag) {
-        log_info.btag = tag;
-    }
-
-    if (abbreviated && (log_target == LOG_NONE)) {
-        abbreviated = 0;
-    }
-    if (abbreviated) {
-        init_abbr_buf(&log_info.a_buf);
-    }
-
-    if (log_target & LOG_KLOG) {
-        snprintf(log_info.klog_fmt, sizeof(log_info.klog_fmt), "<6>%.*s: %%s\n", MAX_KLOG_TAG,
-                 log_info.btag);
-    }
-
-    if ((log_target & LOG_FILE) && !file_path) {
-        /* No file_path specified, clear the LOG_FILE bit */
-        log_target &= ~LOG_FILE;
-    }
-
-    if (log_target & LOG_FILE) {
-        fd = open(file_path, O_WRONLY | O_CREAT | O_CLOEXEC, 0664);
-        if (fd < 0) {
-            ERROR("Cannot log to file %s\n", file_path);
-            log_target &= ~LOG_FILE;
-        } else {
-            lseek(fd, 0, SEEK_END);
-            log_info.fp = fdopen(fd, "a");
-        }
-    }
-
-    log_info.log_target = log_target;
-    log_info.abbreviated = abbreviated;
-
-    while (!found_child) {
-        int timeout = received_messages ? -1 : 1000;
-        if (TEMP_FAILURE_RETRY(poll(poll_fds, arraysize(poll_fds), timeout)) < 0) {
-            ERROR("poll failed\n");
-            rc = -1;
-            goto err_poll;
-        }
-
-        if (poll_fds[0].revents & POLLIN) {
-            received_messages = true;
-            sz = TEMP_FAILURE_RETRY(read(parent_read, &buffer[b], sizeof(buffer) - 1 - b));
-
-            sz += b;
-            // Log one line at a time
-            for (b = 0; b < sz; b++) {
-                if (buffer[b] == '\r') {
-                    if (abbreviated) {
-                        /* The abbreviated logging code uses newline as
-                         * the line separator.  Lucikly, the pty layer
-                         * helpfully cooks the output of the command
-                         * being run and inserts a CR before NL.  So
-                         * I just change it to NL here when doing
-                         * abbreviated logging.
-                         */
-                        buffer[b] = '\n';
-                    } else {
-                        buffer[b] = '\0';
-                    }
-                } else if (buffer[b] == '\n') {
-                    buffer[b] = '\0';
-                    log_line(&log_info, &buffer[a], b - a);
-                    a = b + 1;
-                }
-            }
-
-            if (a == 0 && b == sizeof(buffer) - 1) {
-                // buffer is full, flush
-                buffer[b] = '\0';
-                log_line(&log_info, &buffer[a], b - a);
-                b = 0;
-            } else if (a != b) {
-                // Keep left-overs
-                b -= a;
-                memmove(buffer, &buffer[a], b);
-                a = 0;
-            } else {
-                a = 0;
-                b = 0;
-            }
-        }
-
-        if (!received_messages || (poll_fds[0].revents & POLLHUP)) {
-            int ret;
-            sigset_t oldset;
-
-            if (forward_signals) {
-                // Our signal handlers forward these signals to 'child_pid', but waitpid() may reap
-                // the child, so we must block these signals until we either 1) conclude that the
-                // child is still running or 2) determine the child has been reaped and we have
-                // reset the signals to their original disposition.
-                block_signals(&oldset);
-            }
-
-            int flags = (poll_fds[0].revents & POLLHUP) ? 0 : WNOHANG;
-            ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, flags));
-            if (ret < 0) {
-                rc = errno;
-                ALOG(LOG_ERROR, "logwrap", "waitpid failed with %s\n", strerror(errno));
-                goto err_waitpid;
-            }
-            if (ret > 0) {
-                found_child = true;
-            }
-
-            if (forward_signals) {
-                if (found_child) {
-                    restore_signal_handlers();
-                }
-                unblock_signals(&oldset);
-            }
-        }
-    }
-
-    if (chld_sts != nullptr) {
-        *chld_sts = status;
-    } else {
-        if (WIFEXITED(status))
-            rc = WEXITSTATUS(status);
-        else
-            rc = -ECHILD;
-    }
-
-    // Flush remaining data
-    if (a != b) {
-        buffer[b] = '\0';
-        log_line(&log_info, &buffer[a], b - a);
-    }
-
-    /* All the output has been processed, time to dump the abbreviated output */
-    if (abbreviated) {
-        print_abbr_buf(&log_info);
-    }
-
-    if (WIFEXITED(status)) {
-        if (WEXITSTATUS(status)) {
-            snprintf(tmpbuf, sizeof(tmpbuf), "%s terminated by exit(%d)\n", log_info.btag,
-                     WEXITSTATUS(status));
-            do_log_line(&log_info, tmpbuf);
-        }
-    } else {
-        if (WIFSIGNALED(status)) {
-            snprintf(tmpbuf, sizeof(tmpbuf), "%s terminated by signal %d\n", log_info.btag,
-                     WTERMSIG(status));
-            do_log_line(&log_info, tmpbuf);
-        } else if (WIFSTOPPED(status)) {
-            snprintf(tmpbuf, sizeof(tmpbuf), "%s stopped by signal %d\n", log_info.btag,
-                     WSTOPSIG(status));
-            do_log_line(&log_info, tmpbuf);
-        }
-    }
-
-err_waitpid:
-err_poll:
-    if (log_target & LOG_FILE) {
-        fclose(log_info.fp); /* Also closes underlying fd */
-    }
-    if (abbreviated) {
-        free_abbr_buf(&log_info.a_buf);
-    }
-    return rc;
-}
-
-static void child(int argc, const char* const* argv) {
-    // create null terminated argv_child array
-    char* argv_child[argc + 1];
-    memcpy(argv_child, argv, argc * sizeof(char*));
-    argv_child[argc] = nullptr;
-
-    if (execvp(argv_child[0], argv_child)) {
-        FATAL_CHILD("executing %s failed: %s\n", argv_child[0], strerror(errno));
-    }
-}
-
-int logwrap_fork_execvp(int argc, const char* const* argv, int* status, bool forward_signals,
-                        int log_target, bool abbreviated, const char* file_path) {
-    pid_t pid;
-    int parent_ptty;
-    sigset_t oldset;
-    int rc = 0;
-
-    rc = pthread_mutex_lock(&fd_mutex);
-    if (rc) {
-        ERROR("failed to lock signal_fd mutex\n");
-        goto err_lock;
-    }
-
-    /* Use ptty instead of socketpair so that STDOUT is not buffered */
-    parent_ptty = TEMP_FAILURE_RETRY(posix_openpt(O_RDWR | O_CLOEXEC));
-    if (parent_ptty < 0) {
-        ERROR("Cannot create parent ptty\n");
-        rc = -1;
-        goto err_open;
-    }
-
-    char child_devname[64];
-    if (grantpt(parent_ptty) || unlockpt(parent_ptty) ||
-        ptsname_r(parent_ptty, child_devname, sizeof(child_devname)) != 0) {
-        ERROR("Problem with /dev/ptmx\n");
-        rc = -1;
-        goto err_ptty;
-    }
-
-    if (forward_signals) {
-        // Block these signals until we have the child pid and our signal handlers set up.
-        block_signals(&oldset);
-    }
-
-    pid = fork();
-    if (pid < 0) {
-        ERROR("Failed to fork\n");
-        rc = -1;
-        goto err_fork;
-    } else if (pid == 0) {
-        pthread_mutex_unlock(&fd_mutex);
-        if (forward_signals) {
-            unblock_signals(&oldset);
-        }
-
-        setsid();
-
-        int child_ptty = TEMP_FAILURE_RETRY(open(child_devname, O_RDWR | O_CLOEXEC));
-        if (child_ptty < 0) {
-            FATAL_CHILD("Cannot open child_ptty: %s\n", strerror(errno));
-        }
-        close(parent_ptty);
-
-        dup2(child_ptty, 1);
-        dup2(child_ptty, 2);
-        close(child_ptty);
-
-        child(argc, argv);
-    } else {
-        if (forward_signals) {
-            setup_signal_handlers(pid);
-            unblock_signals(&oldset);
-        }
-
-        rc = parent(argv[0], parent_ptty, pid, status, log_target, abbreviated, file_path,
-                    forward_signals);
-
-        if (forward_signals) {
-            restore_signal_handlers();
-        }
-    }
-
-err_fork:
-    if (forward_signals) {
-        unblock_signals(&oldset);
-    }
-err_ptty:
-    close(parent_ptty);
-err_open:
-    pthread_mutex_unlock(&fd_mutex);
-err_lock:
-    return rc;
-}
diff --git a/logwrapper/logwrap_fork_execvp_benchmark.cpp b/logwrapper/logwrap_fork_execvp_benchmark.cpp
deleted file mode 100644
index b2d0c71..0000000
--- a/logwrapper/logwrap_fork_execvp_benchmark.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "logwrap/logwrap.h"
-
-#include <android-base/logging.h>
-#include <benchmark/benchmark.h>
-
-static void BM_android_fork_execvp_ext(benchmark::State& state) {
-    const char* argv[] = {"/system/bin/echo", "hello", "world"};
-    const int argc = 3;
-    while (state.KeepRunning()) {
-        int rc = logwrap_fork_execvp(argc, argv, nullptr, false, LOG_NONE, false, nullptr);
-        CHECK_EQ(0, rc);
-    }
-}
-BENCHMARK(BM_android_fork_execvp_ext);
-
-BENCHMARK_MAIN();
diff --git a/logwrapper/logwrapper.cpp b/logwrapper/logwrapper.cpp
deleted file mode 100644
index 7118d12..0000000
--- a/logwrapper/logwrapper.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2008 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 <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <cutils/klog.h>
-#include <log/log.h>
-#include <logwrap/logwrap.h>
-
-void fatal(const char* msg) {
-    fprintf(stderr, "%s", msg);
-    ALOG(LOG_ERROR, "logwrapper", "%s", msg);
-    exit(-1);
-}
-
-void usage() {
-    fatal("Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n"
-          "\n"
-          "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n"
-          "the Android logging system. Tag is set to BINARY, priority is\n"
-          "always LOG_INFO.\n"
-          "\n"
-          "-a: Causes logwrapper to do abbreviated logging.\n"
-          "    This logs up to the first 4K and last 4K of the command\n"
-          "    being run, and logs the output when the command exits\n"
-          "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n"
-          "    fault address is set to the status of wait()\n"
-          "-k: Causes logwrapper to log to the kernel log instead of\n"
-          "    the Android system log\n");
-}
-
-int main(int argc, char* argv[]) {
-    int seg_fault_on_exit = 0;
-    int log_target = LOG_ALOG;
-    bool abbreviated = false;
-    int ch;
-    int status = 0xAAAA;
-    int rc;
-
-    while ((ch = getopt(argc, argv, "adk")) != -1) {
-        switch (ch) {
-            case 'a':
-                abbreviated = true;
-                break;
-            case 'd':
-                seg_fault_on_exit = 1;
-                break;
-            case 'k':
-                log_target = LOG_KLOG;
-                klog_set_level(6);
-                break;
-            case '?':
-            default:
-                usage();
-        }
-    }
-    argc -= optind;
-    argv += optind;
-
-    if (argc < 1) {
-        usage();
-    }
-
-    rc = logwrap_fork_execvp(argc, &argv[0], &status, true, log_target, abbreviated, nullptr);
-    if (!rc) {
-        if (WIFEXITED(status))
-            rc = WEXITSTATUS(status);
-        else
-            rc = -ECHILD;
-    }
-
-    if (seg_fault_on_exit) {
-        uintptr_t fault_address = (uintptr_t)status;
-        *(int*)fault_address = 0;  // causes SIGSEGV with fault_address = status
-    }
-
-    return rc;
-}
diff --git a/rootdir/avb/Android.mk b/rootdir/avb/Android.mk
index f96ffdd..3978593 100644
--- a/rootdir/avb/Android.mk
+++ b/rootdir/avb/Android.mk
@@ -1,5 +1,11 @@
 LOCAL_PATH:= $(call my-dir)
 
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+  my_gsi_avb_keys_path := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
+else
+  my_gsi_avb_keys_path := $(TARGET_RAMDISK_OUT)/avb
+endif
+
 #######################################
 # q-gsi.avbpubkey
 include $(CLEAR_VARS)
@@ -7,11 +13,7 @@
 LOCAL_MODULE := q-gsi.avbpubkey
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
-else
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
-endif
+LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
 
 include $(BUILD_PREBUILT)
 
@@ -22,11 +24,7 @@
 LOCAL_MODULE := q-developer-gsi.avbpubkey
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
-else
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
-endif
+LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
 
 include $(BUILD_PREBUILT)
 
@@ -37,11 +35,7 @@
 LOCAL_MODULE := r-gsi.avbpubkey
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
-else
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
-endif
+LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
 
 include $(BUILD_PREBUILT)
 
@@ -52,11 +46,7 @@
 LOCAL_MODULE := r-developer-gsi.avbpubkey
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
-else
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
-endif
+LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
 
 include $(BUILD_PREBUILT)
 
@@ -67,11 +57,7 @@
 LOCAL_MODULE := s-gsi.avbpubkey
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
-else
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
-endif
+LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
 
 include $(BUILD_PREBUILT)
 
@@ -82,10 +68,8 @@
 LOCAL_MODULE := s-developer-gsi.avbpubkey
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
-else
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
-endif
+LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
 
 include $(BUILD_PREBUILT)
+
+my_gsi_avb_keys_path :=
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 427d460..0c41ed4 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -578,13 +578,19 @@
     # Make sure that apexd is started in the default namespace
     enter_default_mount_ns
 
+    # Start tombstoned early to be able to store tombstones.
+    mkdir /data/tombstones 0771 system system encryption=Require
+    mkdir /data/vendor/tombstones 0771 root root
+    mkdir /data/vendor/tombstones/wifi 0771 wifi wifi
+    start tombstoned
+
     # /data/apex is now available. Start apexd to scan and activate APEXes.
     mkdir /data/apex 0755 root system encryption=None
     mkdir /data/apex/active 0755 root system
     mkdir /data/apex/backup 0700 root system
     mkdir /data/apex/hashtree 0700 root system
     mkdir /data/apex/sessions 0700 root system
-    mkdir /data/app-staging 0750 system system encryption=None
+    mkdir /data/app-staging 0750 system system encryption=DeleteIfNecessary
     start apexd
 
     # Avoid predictable entropy pool. Carry over entropy from previous boot.
@@ -678,9 +684,6 @@
     mkdir /data/app-lib 0771 system system encryption=Require
     mkdir /data/app 0771 system system encryption=Require
     mkdir /data/property 0700 root root encryption=Require
-    mkdir /data/tombstones 0771 system system encryption=Require
-    mkdir /data/vendor/tombstones 0771 root root
-    mkdir /data/vendor/tombstones/wifi 0771 wifi wifi
 
     # Create directories to push tests to for each linker namespace.
     # Create the subdirectories in case the first test is run as root
diff --git a/run-as/Android.bp b/run-as/Android.bp
index 840a43c..accd07d 100644
--- a/run-as/Android.bp
+++ b/run-as/Android.bp
@@ -25,4 +25,5 @@
         "libpackagelistparser",
         "libminijail",
     ],
+    header_libs: ["libcutils_headers"],
 }
diff --git a/trusty/keymaster/set_attestation_key/set_attestation_key.cpp b/trusty/keymaster/set_attestation_key/set_attestation_key.cpp
index a89a4a8..6f74833 100644
--- a/trusty/keymaster/set_attestation_key/set_attestation_key.cpp
+++ b/trusty/keymaster/set_attestation_key/set_attestation_key.cpp
@@ -292,9 +292,14 @@
                 value = xmlTextReaderConstValue(xml);
                 uint32_t cmd;
                 if (xmlStrEqual(element, BAD_CAST "PrivateKey")) {
-                    cmd = KM_SET_ATTESTATION_KEY;
-                } else if (xmlStrEqual(element, BAD_CAST "WrappedPrivateKey")) {
-                    cmd = KM_SET_WRAPPED_ATTESTATION_KEY;
+                    if (xmlStrEqual(element_format, BAD_CAST "pem")) {
+                        cmd = KM_SET_ATTESTATION_KEY;
+                    } else if (xmlStrEqual(element_format, BAD_CAST "iecs")) {
+                        cmd = KM_SET_WRAPPED_ATTESTATION_KEY;
+                    } else {
+                        printf("unsupported key format: %s\n", element_format);
+                        return -1;
+                    }
                 } else if (xmlStrEqual(element, BAD_CAST "Certificate")) {
                     cmd = KM_APPEND_ATTESTATION_CERT_CHAIN;
                 } else {
diff --git a/trusty/utils/rpmb_dev/rpmb_dev.c b/trusty/utils/rpmb_dev/rpmb_dev.c
index 5de1efa..2025621 100644
--- a/trusty/utils/rpmb_dev/rpmb_dev.c
+++ b/trusty/utils/rpmb_dev/rpmb_dev.c
@@ -283,6 +283,7 @@
                 {
                         .func = rpmb_dev_data_read,
                         .resp = RPMB_RESP_DATA_READ,
+                        .check_key_programmed = true,
                         .check_addr = true,
                         .multi_packet_res = true,
                         .res_mac = true,
diff --git a/trusty/utils/rpmb_dev/rpmb_dev.rc b/trusty/utils/rpmb_dev/rpmb_dev.rc
index 9f60e81..9e203b8 100644
--- a/trusty/utils/rpmb_dev/rpmb_dev.rc
+++ b/trusty/utils/rpmb_dev/rpmb_dev.rc
@@ -16,7 +16,7 @@
     disabled
     user root
 
-service rpmb_mock_init /vendor/bin/rpmb_dev --dev /data/vendor/ss/RPMB_DATA --init --key "ea df 64 44 ea 65 5d 1c 87 27 d4 20 71 0d 53 42 dd 73 a3 38 63 e1 d7 94 c3 72 a6 ea e0 64 64 e6" --size 2048
+service rpmb_mock_init /vendor/bin/rpmb_dev --dev /data/vendor/ss/RPMB_DATA --init --size 2048
     disabled
     user system
     group system