Merge "perfboot: significant figures + units for summary"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 1abeb2e..89bd66a 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -16,13 +16,19 @@
       "name": "adb_tls_connection_test"
     },
     {
+      "name": "CtsFsMgrTestCases"
+    },
+    {
       "name": "CtsInitTestCases"
     },
     {
-      "name": "debuggerd_test"
+      "name": "CtsLiblogTestCases"
     },
     {
-      "name": "CtsFsMgrTestCases"
+      "name": "CtsLogdTestCases"
+    },
+    {
+      "name": "debuggerd_test"
     },
     {
       "name": "fs_mgr_vendor_overlay_test"
@@ -61,5 +67,10 @@
     {
       "name": "propertyinfoserializer_tests"
     }
+  ],
+  "imports": [
+    {
+      "path": "frameworks/base/tests/StagedInstallTest"
+    }
   ]
 }
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 66cba12..e72d8b6 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -55,7 +55,7 @@
 
 bool set_file_block_mode(borrowed_fd fd, bool block);
 
-// Given forward/reverse targets, returns true if they look sane. If an error is found, fills
+// Given forward/reverse targets, returns true if they look valid. If an error is found, fills
 // |error| and returns false.
 // Currently this only checks "tcp:" targets. Additional checking could be added for other targets
 // if needed.
diff --git a/adb/client/incremental.cpp b/adb/client/incremental.cpp
index 3033059..60735f8 100644
--- a/adb/client/incremental.cpp
+++ b/adb/client/incremental.cpp
@@ -55,9 +55,10 @@
         return {};
     }
 
-    std::vector<char> invalid_signature;
+    auto [signature, tree_size] = read_id_sig_headers(fd);
 
-    if (st.st_size > kMaxSignatureSize) {
+    std::vector<char> invalid_signature;
+    if (signature.size() > kMaxSignatureSize) {
         if (!silent) {
             fprintf(stderr, "Signature is too long. Max allowed is %d. Abort.\n",
                     kMaxSignatureSize);
@@ -65,7 +66,6 @@
         return {std::move(fd), std::move(invalid_signature)};
     }
 
-    auto [signature, tree_size] = read_id_sig_headers(fd);
     if (auto expected = verity_tree_size_for_file(file_size); tree_size != expected) {
         if (!silent) {
             fprintf(stderr,
diff --git a/adb/fdevent/fdevent_test.h b/adb/fdevent/fdevent_test.h
index ecda4da..fcbf181 100644
--- a/adb/fdevent/fdevent_test.h
+++ b/adb/fdevent/fdevent_test.h
@@ -65,7 +65,7 @@
         ASSERT_EQ(0u, fdevent_installed_count());
     }
 
-    // Register a dummy socket used to wake up the fdevent loop to tell it to die.
+    // Register a placeholder socket used to wake up the fdevent loop to tell it to die.
     void PrepareThread() {
         int dummy_fds[2];
         if (adb_socketpair(dummy_fds) != 0) {
@@ -84,7 +84,7 @@
     }
 
     size_t GetAdditionalLocalSocketCount() {
-        // dummy socket installed in PrepareThread()
+        // placeholder socket installed in PrepareThread()
         return 1;
     }
 
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 13a4737..33b9524 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -856,7 +856,7 @@
     s->peer->shutdown = nullptr;
     s->peer->close = local_socket_close_notify;
     s->peer->peer = nullptr;
-    /* give him our transport and upref it */
+    /* give them our transport and upref it */
     s->peer->transport = s->transport;
 
     connect_to_remote(s->peer, std::string_view(s->smart_socket_data).substr(4));
diff --git a/bootstat/boot_reason_test.sh b/bootstat/boot_reason_test.sh
index 2f2919f..7cff7dc 100755
--- a/bootstat/boot_reason_test.sh
+++ b/bootstat/boot_reason_test.sh
@@ -1331,7 +1331,7 @@
     shift
   fi
 
-  # Check if all conditions for the script are sane
+  # Check if all conditions for the script are valid
 
   if [ -z "${ANDROID_SERIAL}" ]; then
     ndev=`(
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index face02b..7af99c9 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -174,12 +174,8 @@
 }
 
 static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) {
-  // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ...
-  // TODO: Why is this controlled by thread name?
-  if (thread_info.thread_name == "logd" ||
-      android::base::StartsWith(thread_info.thread_name, "logd.")) {
-    log->should_retrieve_logcat = false;
-  }
+  // Don't try to collect logs from the threads that implement the logging system itself.
+  if (thread_info.uid == AID_LOGD) log->should_retrieve_logcat = false;
 
   _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());
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index f43092c..4e6df09 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -44,7 +44,6 @@
 
 using android::base::unique_fd;
 
-// Whitelist output desired in the logcat output.
 bool is_allowed_in_logcat(enum logtype ltype) {
   if ((ltype == HEADER)
    || (ltype == REGISTERS)
diff --git a/diagnose_usb/diagnose_usb.cpp b/diagnose_usb/diagnose_usb.cpp
index 5695ece..35edb5e 100644
--- a/diagnose_usb/diagnose_usb.cpp
+++ b/diagnose_usb/diagnose_usb.cpp
@@ -49,7 +49,7 @@
     // additionally just to be sure.
     if (group_member(plugdev_group->gr_gid) || getegid() == plugdev_group->gr_gid) {
         // The user is in plugdev so the problem is likely with the udev rules.
-        return "user in plugdev group; are your udev rules wrong?";
+        return "missing udev rules? user is in the plugdev group";
     }
     passwd* pwd = getpwuid(getuid());
     return android::base::StringPrintf("user %s is not in the plugdev group",
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index bdb786c..6673543 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -271,6 +271,7 @@
     required: [
         "mke2fs",
         "make_f2fs",
+        "make_f2fs_casefold",
     ],
     dist: {
         targets: [
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index fd009e7..0e918a3 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -21,6 +21,7 @@
 my_dist_files := $(SOONG_HOST_OUT_EXECUTABLES)/mke2fs
 my_dist_files += $(SOONG_HOST_OUT_EXECUTABLES)/e2fsdroid
 my_dist_files += $(SOONG_HOST_OUT_EXECUTABLES)/make_f2fs
+my_dist_files += $(SOONG_HOST_OUT_EXECUTABLES)/make_f2fs_casefold
 my_dist_files += $(SOONG_HOST_OUT_EXECUTABLES)/sload_f2fs
 $(call dist-for-goals,dist_files sdk win_sdk,$(my_dist_files))
 my_dist_files :=
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 0ae5787..88bb234 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -607,7 +607,7 @@
 
     LINFO << "Enabling ext4 metadata_csum on " << blk_device;
 
-    // requires to give last_fsck_time to current to avoid insane time.
+    // Must give `-T now` to prevent last_fsck_time from growing too large,
     // otherwise, tune2fs won't enable metadata_csum.
     const char* tune2fs_args[] = {TUNE2FS_BIN, "-O",        "metadata_csum,64bit,extent",
                                   "-T",        "now", blk_device.c_str()};
diff --git a/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp b/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp
index 12101a2..17a0c96 100644
--- a/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp
+++ b/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp
@@ -39,6 +39,8 @@
 SnapshotMetadataUpdater::SnapshotMetadataUpdater(MetadataBuilder* builder, uint32_t target_slot,
                                                  const DeltaArchiveManifest& manifest)
     : builder_(builder), target_suffix_(SlotSuffixForSlotNumber(target_slot)) {
+    partial_update_ = manifest.partial_update();
+
     if (!manifest.has_dynamic_partition_metadata()) {
         return;
     }
@@ -63,7 +65,6 @@
         }
     }
 
-    partial_update_ = manifest.partial_update();
 }
 
 bool SnapshotMetadataUpdater::ShrinkPartitions() const {
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index f8359bc..59cc140 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -44,50 +44,17 @@
 namespace init {
 namespace {
 
-static bool BindMount(const std::string& source, const std::string& mount_point,
-                      bool recursive = false) {
-    unsigned long mountflags = MS_BIND;
-    if (recursive) {
-        mountflags |= MS_REC;
-    }
-    if (mount(source.c_str(), mount_point.c_str(), nullptr, mountflags, nullptr) == -1) {
+static bool BindMount(const std::string& source, const std::string& mount_point) {
+    if (mount(source.c_str(), mount_point.c_str(), nullptr, MS_BIND | MS_REC, nullptr) == -1) {
         PLOG(ERROR) << "Failed to bind mount " << source;
         return false;
     }
     return true;
 }
 
-static bool MakeShared(const std::string& mount_point, bool recursive = false) {
-    unsigned long mountflags = MS_SHARED;
-    if (recursive) {
-        mountflags |= MS_REC;
-    }
+static bool ChangeMount(const std::string& mount_point, unsigned long mountflags) {
     if (mount(nullptr, mount_point.c_str(), nullptr, mountflags, nullptr) == -1) {
-        PLOG(ERROR) << "Failed to change propagation type to shared";
-        return false;
-    }
-    return true;
-}
-
-static bool MakeSlave(const std::string& mount_point, bool recursive = false) {
-    unsigned long mountflags = MS_SLAVE;
-    if (recursive) {
-        mountflags |= MS_REC;
-    }
-    if (mount(nullptr, mount_point.c_str(), nullptr, mountflags, nullptr) == -1) {
-        PLOG(ERROR) << "Failed to change propagation type to slave";
-        return false;
-    }
-    return true;
-}
-
-static bool MakePrivate(const std::string& mount_point, bool recursive = false) {
-    unsigned long mountflags = MS_PRIVATE;
-    if (recursive) {
-        mountflags |= MS_REC;
-    }
-    if (mount(nullptr, mount_point.c_str(), nullptr, mountflags, nullptr) == -1) {
-        PLOG(ERROR) << "Failed to change propagation type to private";
+        PLOG(ERROR) << "Failed to remount " << mount_point << " as " << std::hex << mountflags;
         return false;
     }
     return true;
@@ -225,17 +192,17 @@
     // needed for /foo/bar, then we will make /foo/bar as a mount point (by
     // bind-mounting by to itself) and set the propagation type of the mount
     // point to private.
-    if (!MakeShared("/", true /*recursive*/)) return false;
+    if (!ChangeMount("/", MS_SHARED | MS_REC)) return false;
 
     // /apex is a private mountpoint to give different sets of APEXes for
     // the bootstrap and default mount namespaces. The processes running with
     // the bootstrap namespace get APEXes from the read-only partition.
-    if (!(MakePrivate("/apex"))) return false;
+    if (!(ChangeMount("/apex", MS_PRIVATE))) return false;
 
     // /linkerconfig is a private mountpoint to give a different linker configuration
     // based on the mount namespace. Subdirectory will be bind-mounted based on current mount
     // namespace
-    if (!(MakePrivate("/linkerconfig"))) return false;
+    if (!(ChangeMount("/linkerconfig", MS_PRIVATE))) return false;
 
     // The two mount namespaces present challenges for scoped storage, because
     // vold, which is responsible for most of the mounting, lives in the
@@ -266,15 +233,15 @@
     if (!mkdir_recursive("/mnt/user", 0755)) return false;
     if (!mkdir_recursive("/mnt/installer", 0755)) return false;
     if (!mkdir_recursive("/mnt/androidwritable", 0755)) return false;
-    if (!(BindMount("/mnt/user", "/mnt/installer", true))) return false;
-    if (!(BindMount("/mnt/user", "/mnt/androidwritable", true))) return false;
+    if (!(BindMount("/mnt/user", "/mnt/installer"))) return false;
+    if (!(BindMount("/mnt/user", "/mnt/androidwritable"))) return false;
     // First, make /mnt/installer and /mnt/androidwritable a slave bind mount
-    if (!(MakeSlave("/mnt/installer"))) return false;
-    if (!(MakeSlave("/mnt/androidwritable"))) return false;
+    if (!(ChangeMount("/mnt/installer", MS_SLAVE))) return false;
+    if (!(ChangeMount("/mnt/androidwritable", MS_SLAVE))) return false;
     // Then, make it shared again - effectively creating a new peer group, that
     // will be inherited by new mount namespaces.
-    if (!(MakeShared("/mnt/installer"))) return false;
-    if (!(MakeShared("/mnt/androidwritable"))) return false;
+    if (!(ChangeMount("/mnt/installer", MS_SHARED))) return false;
+    if (!(ChangeMount("/mnt/androidwritable", MS_SHARED))) return false;
 
     bootstrap_ns_fd.reset(OpenMountNamespace());
     bootstrap_ns_id = GetMountNamespaceId();
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 1fa3362..a1e0969 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -994,7 +994,7 @@
                                       &property_infos)) {
             return;
         }
-        // Don't check for failure here, so we always have a sane list of properties.
+        // Don't check for failure here, since we don't always have all of these partitions.
         // E.g. In case of recovery, the vendor partition will not have mounted and we
         // still need the system / platform properties to function.
         if (access("/system_ext/etc/selinux/system_ext_property_contexts", R_OK) != -1) {
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index 05e632b..f2383d7 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -60,13 +60,14 @@
 Result<void> SetUpMountNamespace(bool remount_proc, bool remount_sys) {
     constexpr unsigned int kSafeFlags = MS_NODEV | MS_NOEXEC | MS_NOSUID;
 
-    // Recursively remount / as slave like zygote does so unmounting and mounting /proc
-    // doesn't interfere with the parent namespace's /proc mount. This will also
-    // prevent any other mounts/unmounts initiated by the service from interfering
-    // with the parent namespace but will still allow mount events from the parent
+    // Recursively remount / as MS_SLAVE like zygote does so that
+    // unmounting and mounting /proc doesn't interfere with the parent
+    // namespace's /proc mount. This will also prevent any other
+    // mounts/unmounts initiated by the service from interfering with the
+    // parent namespace but will still allow mount events from the parent
     // namespace to propagate to the child.
     if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
-        return ErrnoError() << "Could not remount(/) recursively as slave";
+        return ErrnoError() << "Could not remount(/) recursively as MS_SLAVE";
     }
 
     // umount() then mount() /proc and/or /sys
diff --git a/init/test_kill_services/init_kill_services_test.cpp b/init/test_kill_services/init_kill_services_test.cpp
index 7e543f2..66a3328 100644
--- a/init/test_kill_services/init_kill_services_test.cpp
+++ b/init/test_kill_services/init_kill_services_test.cpp
@@ -54,7 +54,7 @@
 TEST_P(InitKillServicesTest, KillCriticalProcesses) {
     ExpectKillingServiceRecovers(GetParam());
 
-    // sanity check init is still responding
+    // Ensure that init is still responding
     EXPECT_TRUE(SetProperty("test.death.test", "asdf"));
     EXPECT_EQ(GetProperty("test.death.test", ""), "asdf");
     EXPECT_TRUE(SetProperty("test.death.test", ""));
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index f4191b9..cc32b6d 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -1584,7 +1584,7 @@
   // Verify the flag is set.
   ASSERT_EQ(PROT_DEVICE_MAP, map.flags & PROT_DEVICE_MAP);
 
-  // Quick sanity checks.
+  // Quick basic checks of functionality.
   uint64_t offset;
   ASSERT_EQ(std::string(""), backtrace->GetFunctionName(device_map_uint, &offset));
   ASSERT_EQ(std::string(""), backtrace->GetFunctionName(device_map_uint, &offset, &map));
diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp
index 8c232f0..20cd659 100644
--- a/libcutils/ashmem-dev.cpp
+++ b/libcutils/ashmem-dev.cpp
@@ -122,7 +122,8 @@
         return true;
     }
 
-    /* If its not a number, assume string, but check if its a sane string */
+    // Non-numeric should be a single ASCII character. Characters after the
+    // first are ignored.
     if (tolower(vndk_version[0]) < 'a' || tolower(vndk_version[0]) > 'z') {
         ALOGE("memfd: ro.vndk.version not defined or invalid (%s), this is mandated since P.\n",
               vndk_version.c_str());
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index e4f45a8..b4fe2e6 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -36,7 +36,7 @@
 
 #pragma once
 
-/* This is the master Users and Groups config for the platform.
+/* This is the main Users and Groups config for the platform.
  * DO NOT EVER RENUMBER
  */
 
diff --git a/libcutils/qtaguid.cpp b/libcutils/qtaguid.cpp
index b94d134..2fe877c 100644
--- a/libcutils/qtaguid.cpp
+++ b/libcutils/qtaguid.cpp
@@ -38,24 +38,24 @@
     int (*netdDeleteTagData)(uint32_t, uid_t);
 };
 
-int dummyTagSocket(int, uint32_t, uid_t) {
+int stubTagSocket(int, uint32_t, uid_t) {
     return -EREMOTEIO;
 }
 
-int dummyUntagSocket(int) {
+int stubUntagSocket(int) {
     return -EREMOTEIO;
 }
 
-int dummySetCounterSet(uint32_t, uid_t) {
+int stubSetCounterSet(uint32_t, uid_t) {
     return -EREMOTEIO;
 }
 
-int dummyDeleteTagData(uint32_t, uid_t) {
+int stubDeleteTagData(uint32_t, uid_t) {
     return -EREMOTEIO;
 }
 
 netdHandler initHandler(void) {
-    netdHandler handler = {dummyTagSocket, dummyUntagSocket, dummySetCounterSet, dummyDeleteTagData};
+    netdHandler handler = {stubTagSocket, stubUntagSocket, stubSetCounterSet, stubDeleteTagData};
 
     void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
     if (!netdClientHandle) {
diff --git a/libkeyutils/keyutils_test.cpp b/libkeyutils/keyutils_test.cpp
index d41c91b..d03747b 100644
--- a/libkeyutils/keyutils_test.cpp
+++ b/libkeyutils/keyutils_test.cpp
@@ -33,7 +33,7 @@
 #include <gtest/gtest.h>
 
 TEST(keyutils, smoke) {
-  // Check that the exported type is sane.
+  // Check that the exported type is the right size.
   ASSERT_EQ(4U, sizeof(key_serial_t));
 
   // Check that all the functions actually exist.
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 6051ac7..3a91969 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -17,6 +17,7 @@
 liblog_sources = [
     "log_event_list.cpp",
     "log_event_write.cpp",
+    "log_size.cpp",
     "logger_name.cpp",
     "logger_read.cpp",
     "logger_write.cpp",
diff --git a/liblog/include/log/log_properties.h b/liblog/include/log/log_properties.h
index 3497d63..2a0230f 100644
--- a/liblog/include/log/log_properties.h
+++ b/liblog/include/log/log_properties.h
@@ -20,6 +20,7 @@
 extern "C" {
 #endif
 
+/* Returns `1` if the device is debuggable or `0` if not. */
 int __android_log_is_debuggable();
 
 #ifdef __cplusplus
diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h
index d3b72bc..de4c430 100644
--- a/liblog/include/private/android_logger.h
+++ b/liblog/include/private/android_logger.h
@@ -144,14 +144,6 @@
 int __android_log_security_bswrite(int32_t tag, const char* payload);
 int __android_log_security(); /* Device Owner is present */
 
-#define BOOL_DEFAULT_FLAG_TRUE_FALSE 0x1
-#define BOOL_DEFAULT_FALSE 0x0        /* false if property not present   */
-#define BOOL_DEFAULT_TRUE 0x1         /* true if property not present    */
-#define BOOL_DEFAULT_FLAG_PERSIST 0x2 /* <key>, persist.<key>, ro.<key>  */
-#define BOOL_DEFAULT_FLAG_ENG 0x4     /* off for user                    */
-#define BOOL_DEFAULT_FLAG_SVELTE 0x8  /* off for low_ram                 */
-bool __android_logger_property_get_bool(const char* key, int flag);
-
 #define LOG_BUFFER_SIZE (256 * 1024) /* Tuned with ro.logd.size per-platform \
                                       */
 #define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt
index 161fcf1..2e01101 100644
--- a/liblog/liblog.map.txt
+++ b/liblog/liblog.map.txt
@@ -85,7 +85,6 @@
     __android_log_pmsg_file_read;
     __android_log_pmsg_file_write;
     __android_logger_get_buffer_size;
-    __android_logger_property_get_bool;
     android_openEventTagMap;
     android_log_processBinaryLogBuffer;
     android_log_processLogBuffer;
diff --git a/liblog/log_size.cpp b/liblog/log_size.cpp
new file mode 100644
index 0000000..7f13c8c
--- /dev/null
+++ b/liblog/log_size.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 <private/android_logger.h>
+
+#include <array>
+#include <optional>
+#include <string>
+
+#include <android-base/parseint.h>
+
+#ifdef __ANDROID__
+#include <sys/system_properties.h>
+#endif
+
+bool __android_logger_valid_buffer_size(unsigned long value) {
+  return LOG_BUFFER_MIN_SIZE <= value && value <= LOG_BUFFER_MAX_SIZE;
+}
+
+#ifdef __ANDROID__
+
+static std::optional<unsigned long> GetBufferSizeProperty(const std::string& key) {
+  char value[PROP_VALUE_MAX] = {};
+  if (__system_property_get(key.c_str(), value) <= 0) {
+    return {};
+  }
+
+  uint32_t size;
+  if (!android::base::ParseByteCount(value, &size)) {
+    return {};
+  }
+
+  if (!__android_logger_valid_buffer_size(size)) {
+    return {};
+  }
+
+  return size;
+}
+
+unsigned long __android_logger_get_buffer_size(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;
+    }
+  }
+
+  char value[PROP_VALUE_MAX] = {};
+  if (__system_property_get("ro.config.low_ram", value) > 0 && !strcmp(value, "true")) {
+    return LOG_BUFFER_MIN_SIZE;
+  }
+
+  return LOG_BUFFER_SIZE;
+}
+
+#else
+
+// Default to 1MB for host.
+unsigned long __android_logger_get_buffer_size(log_id_t) {
+  return 1024 * 1024;
+}
+
+#endif
\ No newline at end of file
diff --git a/liblog/properties.cpp b/liblog/properties.cpp
index 2392112..88f0bf1 100644
--- a/liblog/properties.cpp
+++ b/liblog/properties.cpp
@@ -294,33 +294,12 @@
 }
 
 int __android_log_is_debuggable() {
-  static uint32_t serial;
-  static struct cache_char tag_cache;
-  static const char key[] = "ro.debuggable";
-  int ret;
+  static int is_debuggable = [] {
+    char value[PROP_VALUE_MAX] = {};
+    return __system_property_get("ro.debuggable", value) > 0 && !strcmp(value, "1");
+  }();
 
-  if (tag_cache.c) { /* ro property does not change after set */
-    ret = tag_cache.c == '1';
-  } else if (lock()) {
-    struct cache_char temp_cache = {{NULL, 0xFFFFFFFF}, '\0'};
-    refresh_cache(&temp_cache, key);
-    ret = temp_cache.c == '1';
-  } else {
-    int change_detected = check_cache(&tag_cache.cache);
-    uint32_t current_serial = __system_property_area_serial();
-    if (current_serial != serial) {
-      change_detected = 1;
-    }
-    if (change_detected) {
-      refresh_cache(&tag_cache, key);
-      serial = current_serial;
-    }
-    ret = tag_cache.c == '1';
-
-    unlock();
-  }
-
-  return ret;
+  return is_debuggable;
 }
 
 /*
@@ -385,216 +364,6 @@
   return do_cache2_char(&security);
 }
 
-/*
- * Interface that represents the logd buffer size determination so that others
- * need not guess our intentions.
- */
-
-/* Property helper */
-static bool check_flag(const char* prop, const char* flag) {
-  const char* cp = strcasestr(prop, flag);
-  if (!cp) {
-    return false;
-  }
-  /* We only will document comma (,) */
-  static const char sep[] = ",:;|+ \t\f";
-  if ((cp != prop) && !strchr(sep, cp[-1])) {
-    return false;
-  }
-  cp += strlen(flag);
-  return !*cp || !!strchr(sep, *cp);
-}
-
-/* cache structure */
-struct cache_property {
-  struct cache cache;
-  char property[PROP_VALUE_MAX];
-};
-
-static void refresh_cache_property(struct cache_property* cache, const char* key) {
-  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, cache->property);
-}
-
-/* get boolean with the logger twist that supports eng adjustments */
-bool __android_logger_property_get_bool(const char* key, int flag) {
-  struct cache_property property = {{NULL, 0xFFFFFFFF}, {0}};
-  if (flag & BOOL_DEFAULT_FLAG_PERSIST) {
-    char newkey[strlen("persist.") + strlen(key) + 1];
-    snprintf(newkey, sizeof(newkey), "ro.%s", key);
-    refresh_cache_property(&property, newkey);
-    property.cache.pinfo = NULL;
-    property.cache.serial = 0xFFFFFFFF;
-    snprintf(newkey, sizeof(newkey), "persist.%s", key);
-    refresh_cache_property(&property, newkey);
-    property.cache.pinfo = NULL;
-    property.cache.serial = 0xFFFFFFFF;
-  }
-
-  refresh_cache_property(&property, key);
-
-  if (check_flag(property.property, "true")) {
-    return true;
-  }
-  if (check_flag(property.property, "false")) {
-    return false;
-  }
-  if (property.property[0]) {
-    flag &= ~(BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE);
-  }
-  if (check_flag(property.property, "eng")) {
-    flag |= BOOL_DEFAULT_FLAG_ENG;
-  }
-  /* this is really a "not" flag */
-  if (check_flag(property.property, "svelte")) {
-    flag |= BOOL_DEFAULT_FLAG_SVELTE;
-  }
-
-  /* Sanity Check */
-  if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) {
-    flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE;
-    flag |= BOOL_DEFAULT_TRUE;
-  }
-
-  if ((flag & BOOL_DEFAULT_FLAG_SVELTE) &&
-      __android_logger_property_get_bool("ro.config.low_ram", BOOL_DEFAULT_FALSE)) {
-    return false;
-  }
-  if ((flag & BOOL_DEFAULT_FLAG_ENG) && !__android_log_is_debuggable()) {
-    return false;
-  }
-
-  return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE;
-}
-
-bool __android_logger_valid_buffer_size(unsigned long value) {
-  return LOG_BUFFER_MIN_SIZE <= value && value <= LOG_BUFFER_MAX_SIZE;
-}
-
-struct cache2_property_size {
-  pthread_mutex_t lock;
-  uint32_t serial;
-  const char* key_persist;
-  struct cache_property cache_persist;
-  const char* key_ro;
-  struct cache_property cache_ro;
-  unsigned long (*const evaluate)(const struct cache2_property_size* self);
-};
-
-static inline unsigned long do_cache2_property_size(struct cache2_property_size* self) {
-  uint32_t current_serial;
-  int change_detected;
-  unsigned long v;
-
-  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_property(&self->cache_persist, self->key_persist);
-    refresh_cache_property(&self->cache_ro, self->key_ro);
-    self->serial = current_serial;
-  }
-  v = self->evaluate(self);
-
-  pthread_mutex_unlock(&self->lock);
-
-  return v;
-}
-
-static unsigned long property_get_size_from_cache(const struct cache_property* cache) {
-  char* cp;
-  unsigned long value = strtoul(cache->property, &cp, 10);
-
-  switch (*cp) {
-    case 'm':
-    case 'M':
-      value *= 1024;
-      [[fallthrough]];
-    case 'k':
-    case 'K':
-      value *= 1024;
-      [[fallthrough]];
-    case '\0':
-      break;
-
-    default:
-      value = 0;
-  }
-
-  if (!__android_logger_valid_buffer_size(value)) {
-    value = 0;
-  }
-
-  return value;
-}
-
-static unsigned long evaluate_property_get_size(const struct cache2_property_size* self) {
-  unsigned long size = property_get_size_from_cache(&self->cache_persist);
-  if (size) {
-    return size;
-  }
-  return property_get_size_from_cache(&self->cache_ro);
-}
-
-unsigned long __android_logger_get_buffer_size(log_id_t logId) {
-  static const char global_tunable[] = "persist.logd.size"; /* Settings App */
-  static const char global_default[] = "ro.logd.size";      /* BoardConfig.mk */
-  static struct cache2_property_size global = {
-      /* clang-format off */
-    PTHREAD_MUTEX_INITIALIZER, 0,
-    global_tunable, { { NULL, 0xFFFFFFFF }, {} },
-    global_default, { { NULL, 0xFFFFFFFF }, {} },
-    evaluate_property_get_size
-      /* clang-format on */
-  };
-  char key_persist[strlen(global_tunable) + strlen(".security") + 1];
-  char key_ro[strlen(global_default) + strlen(".security") + 1];
-  struct cache2_property_size local = {
-      /* clang-format off */
-    PTHREAD_MUTEX_INITIALIZER, 0,
-    key_persist, { { NULL, 0xFFFFFFFF }, {} },
-    key_ro,      { { NULL, 0xFFFFFFFF }, {} },
-    evaluate_property_get_size
-      /* clang-format on */
-  };
-  unsigned long property_size, default_size;
-
-  default_size = do_cache2_property_size(&global);
-  if (!default_size) {
-    default_size = __android_logger_property_get_bool("ro.config.low_ram", BOOL_DEFAULT_FALSE)
-                       ? LOG_BUFFER_MIN_SIZE /* 64K  */
-                       : LOG_BUFFER_SIZE;    /* 256K */
-  }
-
-  snprintf(key_persist, sizeof(key_persist), "%s.%s", global_tunable,
-           android_log_id_to_name(logId));
-  snprintf(key_ro, sizeof(key_ro), "%s.%s", global_default, android_log_id_to_name(logId));
-  property_size = do_cache2_property_size(&local);
-
-  if (!property_size) {
-    property_size = default_size;
-  }
-
-  if (!property_size) {
-    property_size = LOG_BUFFER_SIZE;
-  }
-
-  return property_size;
-}
-
 #else
 
 int __android_log_is_loggable(int prio, const char*, int) {
@@ -613,4 +382,4 @@
   return 1;
 }
 
-#endif
\ No newline at end of file
+#endif
diff --git a/liblog/tests/Android.bp b/liblog/tests/Android.bp
index 2a6424b..a17d90c 100644
--- a/liblog/tests/Android.bp
+++ b/liblog/tests/Android.bp
@@ -97,6 +97,7 @@
     cflags: ["-DNO_PSTORE"],
     test_suites: [
         "cts",
+        "device-tests",
         "vts10",
     ],
 }
diff --git a/liblog/tests/liblog_global_state.cpp b/liblog/tests/liblog_global_state.cpp
index 3508818..1d7ff9f 100644
--- a/liblog/tests/liblog_global_state.cpp
+++ b/liblog/tests/liblog_global_state.cpp
@@ -153,56 +153,65 @@
   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) {
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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) {
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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__
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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.") + LOG_TAG;
-  android::base::SetProperty(log_tag_property, "d");
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, 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));
 
-  android::base::SetProperty(log_tag_property, "w");
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, 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));
 
-  android::base::SetProperty(log_tag_property, "");
+  ASSERT_TRUE(android::base::SetProperty(log_tag_property, ""));
 #else
   GTEST_SKIP() << "No log tag properties on host";
 #endif
@@ -210,39 +219,40 @@
 
 TEST(liblog_global_state, is_loggable_both_set) {
 #ifdef __ANDROID__
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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.") + LOG_TAG;
-  android::base::SetProperty(log_tag_property, "w");
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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'
-  android::base::SetProperty(log_tag_property, "d");
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, LOG_TAG, ANDROID_LOG_INFO));
-  EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, LOG_TAG, ANDROID_LOG_INFO));
+  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));
 
-  android::base::SetProperty(log_tag_property, "");
+  ASSERT_TRUE(android::base::SetProperty(log_tag_property, ""));
 #else
   GTEST_SKIP() << "No log tag properties on host";
 #endif
diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp
index 3e09617..7acd363 100644
--- a/liblog/tests/log_read_test.cpp
+++ b/liblog/tests/log_read_test.cpp
@@ -20,6 +20,7 @@
 
 #include <string>
 
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android/log.h>  // minimal logging API
 #include <gtest/gtest.h>
@@ -29,6 +30,8 @@
 // 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
@@ -38,31 +41,27 @@
 
   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;
-    }
-    fprintf(stderr, "log buffer %s\r", name);
+    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 (strcmp("security", name)) {
-      EXPECT_LT(0, get_log_size);
+    if (name != "security") {
+      EXPECT_GT(get_log_size, 0);
       // crash buffer is allowed to be empty, that is actually healthy!
-      // kernel buffer is allowed to be empty on "user" builds
-      // stats buffer is allowed to be empty TEMPORARILY.
-      // TODO: remove stats buffer from here once we start to use it in
-      // framework (b/68266385).
-      EXPECT_LE(  // boolean 1 or 0 depending on expected content or empty
-          !!((strcmp("crash", name) != 0) &&
-             ((strcmp("kernel", name) != 0) ||
-              __android_logger_property_get_bool(
-                  "ro.logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_ENG |
-                                        BOOL_DEFAULT_FLAG_SVELTE)) &&
-             (strcmp("stats", name) != 0)),
-          android_logger_get_log_readable_size(logger));
+      // 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) {
@@ -71,7 +70,6 @@
         EXPECT_LE(0, android_logger_get_log_readable_size(logger));
       }
     }
-    EXPECT_LT(0, android_logger_get_log_version(logger));
   }
 
   android_logger_list_close(logger_list);
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 9c1621b..3b6cfd8 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -185,7 +185,6 @@
     if (!checkRtNetlinkLength(nh, sizeof(*ifaddr)))
         return false;
 
-    // Sanity check.
     int type = nh->nlmsg_type;
     if (type != RTM_NEWADDR && type != RTM_DELADDR) {
         SLOGE("parseIfAddrMessage on incorrect message type 0x%x\n", type);
@@ -349,7 +348,6 @@
     uint8_t type = nh->nlmsg_type;
     const char *msgname = rtMessageName(type);
 
-    // Sanity check.
     if (type != RTM_NEWROUTE && type != RTM_DELROUTE) {
         SLOGE("%s: incorrect message type %d (%s)\n", __func__, type, msgname);
         return false;
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index fe2f3d6..e90afcd 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -201,50 +201,31 @@
         return 0;
     }
 
-    int ret = 0;
-    int e = 0; // SLOGW and sigaction are not inert regarding errno
     int current = 0;
 
-    struct sigaction new_action, old_action;
-    memset(&new_action, 0, sizeof(new_action));
-    new_action.sa_handler = SIG_IGN;
-    sigaction(SIGPIPE, &new_action, &old_action);
-
     for (;;) {
-        ssize_t rc = TEMP_FAILURE_RETRY(
-            writev(mSocket, iov + current, iovcnt - current));
-
-        if (rc > 0) {
-            size_t written = rc;
-            while ((current < iovcnt) && (written >= iov[current].iov_len)) {
-                written -= iov[current].iov_len;
-                current++;
-            }
-            if (current == iovcnt) {
-                break;
-            }
-            iov[current].iov_base = (char *)iov[current].iov_base + written;
-            iov[current].iov_len -= written;
-            continue;
-        }
+        ssize_t rc = TEMP_FAILURE_RETRY(writev(mSocket, iov + current, iovcnt - current));
 
         if (rc == 0) {
-            e = EIO;
+            errno = EIO;
             SLOGW("0 length write :(");
-        } else {
-            e = errno;
-            SLOGW("write error (%s)", strerror(e));
+            return -1;
+        } else if (rc < 0) {
+            SLOGW("write error (%s)", strerror(errno));
+            return -1;
         }
-        ret = -1;
-        break;
-    }
 
-    sigaction(SIGPIPE, &old_action, &new_action);
-
-    if (e != 0) {
-        errno = e;
+        size_t written = rc;
+        while (current < iovcnt && written >= iov[current].iov_len) {
+            written -= iov[current].iov_len;
+            current++;
+        }
+        if (current == iovcnt) {
+            return 0;
+        }
+        iov[current].iov_base = (char*)iov[current].iov_base + written;
+        iov[current].iov_len -= written;
     }
-    return ret;
 }
 
 void SocketClient::incRef() {
diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp
index b08e061..b6e457b 100644
--- a/libutils/Unicode.cpp
+++ b/libutils/Unicode.cpp
@@ -162,9 +162,9 @@
     if (index >= src_len) {
         return -1;
     }
-    size_t dummy_index;
+    size_t unused_index;
     if (next_index == nullptr) {
-        next_index = &dummy_index;
+        next_index = &unused_index;
     }
     size_t num_read;
     int32_t ret = utf32_at_internal(src + index, &num_read);
diff --git a/libutils/include/utils/Vector.h b/libutils/include/utils/Vector.h
index ddf71de..be35ea2 100644
--- a/libutils/include/utils/Vector.h
+++ b/libutils/include/utils/Vector.h
@@ -23,15 +23,13 @@
 #include <log/log.h>
 #include <utils/TypeHelpers.h>
 #include <utils/VectorImpl.h>
-
-/*
- * Used to blacklist some functions from CFI.
- *
- */
 #ifndef __has_attribute
 #define __has_attribute(x) 0
 #endif
 
+/*
+ * Used to exclude some functions from CFI.
+ */
 #if __has_attribute(no_sanitize)
 #define UTILS_VECTOR_NO_CFI __attribute__((no_sanitize("cfi")))
 #else
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index d15fa2b..c7d1634 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -616,15 +616,15 @@
                 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 dummy = ANDROID_LOG_WRAP_DEFAULT_TIMEOUT;
-                    if (optarg && (!ParseUint(optarg, &dummy) || dummy < 1)) {
+                    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 (dummy != ANDROID_LOG_WRAP_DEFAULT_TIMEOUT) {
+                    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,
-                                dummy);
+                                timeout);
                     }
                     break;
                 }
diff --git a/logd/Android.bp b/logd/Android.bp
index fe97871..265e19e 100644
--- a/logd/Android.bp
+++ b/logd/Android.bp
@@ -177,6 +177,7 @@
     },
     test_suites: [
         "cts",
+        "device-tests",
         "vts10",
     ],
 }
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 0ce9796..0e17476 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -32,7 +32,7 @@
 #include <sstream>
 
 #include <android-base/macros.h>
-#include <log/log_properties.h>
+#include <android-base/properties.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
@@ -40,6 +40,8 @@
 #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, '>'
@@ -48,8 +50,8 @@
     : SocketListener(getLogSocket(), false),
       logbuf(buf),
       fdDmesg(fdDmesg),
-      main(__android_logger_property_get_bool("ro.logd.auditd.main", BOOL_DEFAULT_TRUE)),
-      events(__android_logger_property_get_bool("ro.logd.auditd.events", BOOL_DEFAULT_TRUE)),
+      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),
diff --git a/logd/LogBufferTest.cpp b/logd/LogBufferTest.cpp
index 47d2a2f..1911105 100644
--- a/logd/LogBufferTest.cpp
+++ b/logd/LogBufferTest.cpp
@@ -34,16 +34,6 @@
 using android::base::Split;
 using android::base::StringPrintf;
 
-#ifndef __ANDROID__
-unsigned long __android_logger_get_buffer_size(log_id_t) {
-    return 1024 * 1024;
-}
-
-bool __android_logger_valid_buffer_size(unsigned long) {
-    return true;
-}
-#endif
-
 char* android::uidToName(uid_t) {
     return nullptr;
 }
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index dbdf7fd..d6c7d25 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -381,8 +381,8 @@
         }
         if ((i == 9) && (cp[i] == ' ')) {
             int pid = 0;
-            char dummy;
-            if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) {
+            char placeholder;
+            if (sscanf(cp + 4, "%d%c", &pid, &placeholder) == 2) {
                 buf = cp + 10;  // skip-it-all
                 return pid;
             }
@@ -392,8 +392,8 @@
         // Mediatek kernels with modified printk
         if (*cp == '[') {
             int pid = 0;
-            char dummy;
-            if (sscanf(cp, "[%d:%*[a-z_./0-9:A-Z]]%c", &pid, &dummy) == 2) {
+            char placeholder;
+            if (sscanf(cp, "[%d:%*[a-z_./0-9:A-Z]]%c", &pid, &placeholder) == 2) {
                 return pid;
             }
             break;  // Only the first one
@@ -703,7 +703,7 @@
         p = " ";
         b = 1;
     }
-    // paranoid sanity check, can not happen ...
+    // This shouldn't happen, but clamp the size if it does.
     if (b > LOGGER_ENTRY_MAX_PAYLOAD) {
         b = LOGGER_ENTRY_MAX_PAYLOAD;
     }
@@ -712,7 +712,7 @@
     }
     // calculate buffer copy requirements
     ssize_t n = 1 + taglen + 1 + b + 1;
-    // paranoid sanity check, first two just can not happen ...
+    // Extra checks for likely impossible cases.
     if ((taglen > n) || (b > n) || (n > (ssize_t)USHRT_MAX) || (n <= 0)) {
         return -EINVAL;
     }
@@ -722,7 +722,7 @@
     // 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
-    // of stack sanity and speedup, loss is truncated long-line content.
+    // against stack corruption and speedup, loss is truncated long-line content.
     char newstr[n];
     char* np = newstr;
 
diff --git a/logd/README.property b/logd/README.property
index 1d7d990..8fd7f48 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -7,8 +7,8 @@
 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
-ro.logd.statistics         bool+ svelte+ Enable logcat -S statistics.
+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
@@ -57,11 +57,8 @@
 
 NB:
 - auto - managed by /init
-- bool+ - "true", "false" and comma separated list of "eng" (forced false if
-  ro.debuggable is not "1") or "svelte" (forced false if ro.config.low_ram is
-  true).
 - svelte - see ro.config.low_ram for details.
-- svelte+ - see ro.config.low_ram and ro.debuggable 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.
diff --git a/logd/ReplayMessages.cpp b/logd/ReplayMessages.cpp
index 73b0bd0..56509ec 100644
--- a/logd/ReplayMessages.cpp
+++ b/logd/ReplayMessages.cpp
@@ -40,17 +40,6 @@
 using android::base::ParseUint;
 using android::base::Split;
 
-#ifndef __ANDROID__
-// This is hard coded to 1MB on host.  On device use persist.logd.size to configure.
-unsigned long __android_logger_get_buffer_size(log_id_t) {
-    return 1 * 1024 * 1024;
-}
-
-bool __android_logger_valid_buffer_size(unsigned long) {
-    return true;
-}
-#endif
-
 char* android::uidToName(uid_t) {
     return nullptr;
 }
@@ -117,6 +106,23 @@
     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) {}
@@ -134,6 +140,11 @@
         return true;
     }
 
+    void Shutdown() override {
+        fprintf(stderr, "LogWriter::Shutdown() called\n");
+        exit(1);
+    }
+
     std::string name() const override { return "stdout writer"; }
 };
 
@@ -291,24 +302,7 @@
     PrintLogs(log_time first_log_timestamp, const char* buffer, const char* buffers,
               const char* print_point)
         : SingleBufferOperation(first_log_timestamp, buffer) {
-        if (buffers != nullptr) {
-            if (strcmp(buffers, "all") != 0) {
-                std::vector<int> buffer_ids;
-                auto string_ids = Split(buffers, ",");
-                for (const auto& string_id : string_ids) {
-                    int result;
-                    if (!ParseInt(string_id, &result, 0, 7)) {
-                        fprintf(stderr, "Could not parse buffer_id '%s'\n", string_id.c_str());
-                        exit(1);
-                    }
-                    buffer_ids.emplace_back(result);
-                }
-                mask_ = 0;
-                for (const auto& buffer_id : buffer_ids) {
-                    mask_ |= 1 << buffer_id;
-                }
-            }
-        }
+        mask_ = BuffersToLogMask(buffers);
         if (print_point != nullptr) {
             uint64_t result = 0;
             if (!ParseUint(print_point, &result)) {
@@ -326,7 +320,7 @@
         }
     }
 
-    void End() {
+    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);
@@ -353,7 +347,7 @@
         durations_.emplace_back(duration);
     }
 
-    void End() {
+    void End() override {
         std::sort(durations_.begin(), durations_.end());
         auto q1 = durations_.size() / 4;
         auto q2 = durations_.size() / 2;
@@ -373,6 +367,27 @@
     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]);
@@ -415,6 +430,9 @@
     } 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 {
diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp
index 8309f95..d71a2f9 100644
--- a/logd/fuzz/log_buffer_log_fuzzer.cpp
+++ b/logd/fuzz/log_buffer_log_fuzzer.cpp
@@ -30,16 +30,6 @@
 #define MIN_TAG_ID 1000
 #define TAG_MOD 10
 
-#ifndef __ANDROID__
-unsigned long __android_logger_get_buffer_size(log_id_t) {
-    return 1024 * 1024;
-}
-
-bool __android_logger_valid_buffer_size(unsigned long) {
-    return true;
-}
-#endif
-
 char* android::uidToName(uid_t) {
     return strdup("fake");
 }
diff --git a/logd/logd_test.cpp b/logd/logd_test.cpp
index 307610e..5a0585a 100644
--- a/logd/logd_test.cpp
+++ b/logd/logd_test.cpp
@@ -162,6 +162,7 @@
 }
 #endif
 
+#ifdef LOGD_ENABLE_FLAKY_TESTS
 TEST(logd, statistics) {
 #ifdef __ANDROID__
     size_t len;
@@ -237,6 +238,7 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
+#endif
 
 #ifdef __ANDROID__
 static void caught_signal(int /* signum */) {
@@ -720,6 +722,7 @@
 }
 #endif
 
+#ifdef LOGD_ENABLE_FLAKY_TESTS
 // b/27242723 confirmed fixed
 TEST(logd, SNDTIMEO) {
 #ifdef __ANDROID__
@@ -777,6 +780,7 @@
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
+#endif
 
 TEST(logd, getEventTag_list) {
 #ifdef __ANDROID__
diff --git a/logd/main.cpp b/logd/main.cpp
index e7a69eb..c92c5b7 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -62,7 +62,9 @@
 #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, \
@@ -82,9 +84,10 @@
         PLOG(FATAL) << "failed to set batch scheduler";
     }
 
-    if (!__android_logger_property_get_bool("ro.debuggable", BOOL_DEFAULT_FALSE) &&
-        prctl(PR_SET_DUMPABLE, 0) == -1) {
-        PLOG(FATAL) << "failed to clear PR_SET_DUMPABLE";
+    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);
@@ -110,6 +113,14 @@
     }
 }
 
+// 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;
@@ -207,6 +218,8 @@
 // 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,
@@ -236,10 +249,9 @@
     }
 
     int fdPmesg = -1;
-    bool klogd = __android_logger_property_get_bool(
-        "ro.logd.kernel",
-        BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE);
+    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) {
@@ -249,7 +261,7 @@
         if (fdPmesg < 0) PLOG(ERROR) << "Failed to open " << proc_kmsg;
     }
 
-    bool auditd = __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE);
+    bool auditd = GetBoolProperty("ro.logd.auditd", true);
     DropPrivs(klogd, auditd);
 
     // A cache of event log tags
@@ -261,10 +273,8 @@
     std::string buffer_type = GetProperty("logd.buffer_type", "serialized");
 
     // Partial (required for chatty) or full logging statistics.
-    bool enable_full_log_statistics = __android_logger_property_get_bool(
-            "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST |
-                                       BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE);
-    LogStatistics log_statistics(enable_full_log_statistics, buffer_type == "serialized");
+    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.
@@ -309,9 +319,7 @@
     // and LogReader is notified to send updates to connected clients.
     LogAudit* al = nullptr;
     if (auditd) {
-        int dmesg_fd = __android_logger_property_get_bool("ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE)
-                               ? fdDmesg
-                               : -1;
+        int dmesg_fd = GetBoolProperty("ro.logd.auditd.dmesg", true) ? fdDmesg : -1;
         al = new LogAudit(log_buffer, dmesg_fd, &log_statistics);
     }
 
diff --git a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
index a643062..3907413 100644
--- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
@@ -139,7 +139,7 @@
 
   auto property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_trie.data());
 
-  // Sanity check
+  // Smoke test
   auto root_node = property_info_area->root_node();
   EXPECT_STREQ("root", root_node.name());
   EXPECT_STREQ("default", property_info_area->context(root_node.context_index()));
diff --git a/qemu_pipe/qemu_pipe.cpp b/qemu_pipe/qemu_pipe.cpp
index beeccb0..03afb21 100644
--- a/qemu_pipe/qemu_pipe.cpp
+++ b/qemu_pipe/qemu_pipe.cpp
@@ -35,7 +35,6 @@
 #endif
 
 int qemu_pipe_open(const char* pipeName) {
-    // Sanity check.
     if (!pipeName) {
         errno = EINVAL;
         return -1;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index fb58432..6ef3bdc 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -81,6 +81,11 @@
     # Mount tracefs
     mount tracefs tracefs /sys/kernel/tracing
 
+    # create sys dirctory
+    mkdir /dev/sys 0755 system system
+    mkdir /dev/sys/fs 0755 system system
+    mkdir /dev/sys/block 0755 system system
+
 # Run boringssl self test for each ABI so that later processes can skip it. http://b/139348610
 on early-init && property:ro.product.cpu.abilist32=*
     exec_start boringssl_self_test32
@@ -867,18 +872,26 @@
     chown root system /sys/block/zram0/writeback
     chmod 0664 /sys/block/zram0/writeback
 
+    # to access F2FS sysfs on dm-<num> directly
+    mkdir /dev/sys/fs/by-name 0755 system system
+    symlink /sys/fs/f2fs/${dev.mnt.blk.data} /dev/sys/fs/by-name/userdata
+
+    # to access dm-<num> sysfs
+    mkdir /dev/sys/block/by-name 0755 system system
+    symlink /sys/devices/virtual/block/${dev.mnt.blk.data} /dev/sys/block/by-name/userdata
+
     # F2FS tuning. Set cp_interval larger than dirty_expire_centisecs, 30 secs,
     # to avoid power consumption when system becomes mostly idle. Be careful
     # to make it too large, since it may bring userdata loss, if they
     # are not aware of using fsync()/sync() to prepare sudden power-cut.
-    write /sys/fs/f2fs/${dev.mnt.blk.data}/cp_interval 200
-    write /sys/fs/f2fs/${dev.mnt.blk.data}/gc_urgent_sleep_time 50
-    write /sys/fs/f2fs/${dev.mnt.blk.data}/iostat_enable 1
+    write /dev/sys/fs/by-name/userdata/cp_interval 200
+    write /dev/sys/fs/by-name/userdata/gc_urgent_sleep_time 50
+    write /dev/sys/fs/by-name/userdata/iostat_enable 1
 
     # limit discard size to 128MB in order to avoid long IO latency
     # for filesystem tuning first (dm or sda)
     # Note that, if dm-<num> is used, sda/mmcblk0 should be tuned in vendor/init.rc
-    write /sys/devices/virtual/block/${dev.mnt.blk.data}/queue/discard_max_bytes 134217728
+    write /dev/sys/block/by-name/userdata/queue/discard_max_bytes 134217728
 
     # Permissions for System Server and daemons.
     chown system system /sys/power/autosleep
diff --git a/trusty/confirmationui/NotSoSecureInput.cpp b/trusty/confirmationui/NotSoSecureInput.cpp
index 3d9a2d6..18e45cd 100644
--- a/trusty/confirmationui/NotSoSecureInput.cpp
+++ b/trusty/confirmationui/NotSoSecureInput.cpp
@@ -82,7 +82,7 @@
 
 /**
  * This is an implementation of the SecureInput protocol in unserspace. This is
- * just an example and should not be used as is. The protocol implemented her
+ * just an example and should not be used as is. The protocol implemented here
  * should be used by a trusted input device that can assert user events with
  * high assurance even if the HLOS kernel is compromised. A confirmationui HAL
  * that links directly against this implementation is not secure and shal not be
diff --git a/trusty/gatekeeper/trusty_gatekeeper.cpp b/trusty/gatekeeper/trusty_gatekeeper.cpp
index d149664..e416fb2 100644
--- a/trusty/gatekeeper/trusty_gatekeeper.cpp
+++ b/trusty/gatekeeper/trusty_gatekeeper.cpp
@@ -56,9 +56,9 @@
 
 SizedBuffer hidl_vec2sized_buffer(const hidl_vec<uint8_t>& vec) {
     if (vec.size() == 0 || vec.size() > std::numeric_limits<uint32_t>::max()) return {};
-    auto dummy = new uint8_t[vec.size()];
-    std::copy(vec.begin(), vec.end(), dummy);
-    return {dummy, static_cast<uint32_t>(vec.size())};
+    auto buffer = new uint8_t[vec.size()];
+    std::copy(vec.begin(), vec.end(), buffer);
+    return {buffer, static_cast<uint32_t>(vec.size())};
 }
 
 Return<void> TrustyGateKeeperDevice::enroll(uint32_t uid,
diff --git a/trusty/keymaster/TrustyKeymaster.cpp b/trusty/keymaster/TrustyKeymaster.cpp
index f3ef747..750a9d7 100644
--- a/trusty/keymaster/TrustyKeymaster.cpp
+++ b/trusty/keymaster/TrustyKeymaster.cpp
@@ -173,7 +173,7 @@
 }
 
 GetHmacSharingParametersResponse TrustyKeymaster::GetHmacSharingParameters() {
-    // Dummy empty buffer to allow ForwardCommand to have something to serialize
+    // Empty buffer to allow ForwardCommand to have something to serialize
     Buffer request;
     GetHmacSharingParametersResponse response;
     ForwardCommand(KM_GET_HMAC_SHARING_PARAMETERS, request, &response);
diff --git a/trusty/libtrusty/include/trusty/ipc.h b/trusty/libtrusty/include/trusty/ipc.h
new file mode 100644
index 0000000..1fa6fe4
--- /dev/null
+++ b/trusty/libtrusty/include/trusty/ipc.h
@@ -0,0 +1,77 @@
+/*
+ * 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 _UAPI_LINUX_TRUSTY_IPC_H_
+#define _UAPI_LINUX_TRUSTY_IPC_H_
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/uio.h>
+
+/**
+ * enum transfer_kind - How to send an fd to Trusty
+ * @TRUSTY_SHARE: Memory will be accessible by Linux and Trusty. On ARM it will
+ *                be mapped as nonsecure. Suitable for shared memory. The paired
+ *                fd must be a "memfd".
+ * @TRUSTY_LEND:  Memory will be accessible only to Trusty. On ARM it will be
+ *                transitioned to "Secure" memory if Trusty is in TrustZone.
+ *                This transfer kind is suitable for donating video buffers or
+ *                other similar resources. The paired fd may need to come from a
+ *                platform-specific allocator for memory that may be
+ *                transitioned to "Secure".
+ *
+ * Describes how the user would like the resource in question to be sent to
+ * Trusty. Options may be valid only for certain kinds of fds.
+ */
+enum transfer_kind {
+    TRUSTY_SHARE = 0,
+    TRUSTY_LEND = 1,
+};
+
+/**
+ * struct trusty_shm - Describes a transfer of memory to Trusty
+ * @fd:       The fd to transfer
+ * @transfer: How to transfer it - see &enum transfer_kind
+ */
+struct trusty_shm {
+    __s32 fd;
+    __u32 transfer;
+};
+
+/**
+ * struct tipc_send_msg_req - Request struct for @TIPC_IOC_SEND_MSG
+ * @iov:     Pointer to an array of &struct iovec describing data to be sent
+ * @shm:     Pointer to an array of &struct trusty_shm describing any file
+ *           descriptors to be transferred.
+ * @iov_cnt: Number of elements in the @iov array
+ * @shm_cnt: Number of elements in the @shm array
+ */
+struct tipc_send_msg_req {
+    __u64 iov;
+    __u64 shm;
+    __u64 iov_cnt;
+    __u64 shm_cnt;
+};
+
+#define TIPC_IOC_MAGIC 'r'
+#define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char*)
+#define TIPC_IOC_SEND_MSG _IOW(TIPC_IOC_MAGIC, 0x81, struct tipc_send_msg_req)
+
+#if defined(CONFIG_COMPAT)
+#define TIPC_IOC_CONNECT_COMPAT _IOW(TIPC_IOC_MAGIC, 0x80, compat_uptr_t)
+#endif
+
+#endif
diff --git a/trusty/libtrusty/include/trusty/tipc.h b/trusty/libtrusty/include/trusty/tipc.h
index a3f2a3f..b44afd3 100644
--- a/trusty/libtrusty/include/trusty/tipc.h
+++ b/trusty/libtrusty/include/trusty/tipc.h
@@ -21,7 +21,11 @@
 extern "C" {
 #endif
 
+#include <sys/uio.h>
+#include <trusty/ipc.h>
+
 int tipc_connect(const char *dev_name, const char *srv_name);
+ssize_t tipc_send(int fd, const struct iovec* iov, int iovcnt, struct trusty_shm* shm, int shmcnt);
 int tipc_close(int fd);
 
 #ifdef __cplusplus
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index d20d4ee..ca581dc 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -21,6 +21,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <getopt.h>
+#define __USE_GNU
+#include <sys/mman.h>
 #include <sys/uio.h>
 
 #include <trusty/tipc.h>
@@ -39,6 +41,7 @@
 static const char *closer2_name = "com.android.ipc-unittest.srv.closer2";
 static const char *closer3_name = "com.android.ipc-unittest.srv.closer3";
 static const char *main_ctrl_name = "com.android.ipc-unittest.ctrl";
+static const char* receiver_name = "com.android.trusty.memref.receiver";
 
 static const char *_sopts = "hsvD:t:r:m:b:";
 static const struct option _lopts[] =  {
@@ -66,25 +69,25 @@
 "\n"
 ;
 
-static const char *usage_long =
-"\n"
-"The following tests are available:\n"
-"   connect      - connect to datasink service\n"
-"   connect_foo  - connect to non existing service\n"
-"   burst_write  - send messages to datasink service\n"
-"   echo         - send/receive messages to echo service\n"
-"   select       - test select call\n"
-"   blocked_read - test blocked read\n"
-"   closer1      - connection closed by remote (test1)\n"
-"   closer2      - connection closed by remote (test2)\n"
-"   closer3      - connection closed by remote (test3)\n"
-"   ta2ta-ipc    - execute TA to TA unittest\n"
-"   dev-uuid     - print device uuid\n"
-"   ta-access    - test ta-access flags\n"
-"   writev       - writev test\n"
-"   readv        - readv test\n"
-"\n"
-;
+static const char* usage_long =
+        "\n"
+        "The following tests are available:\n"
+        "   connect      - connect to datasink service\n"
+        "   connect_foo  - connect to non existing service\n"
+        "   burst_write  - send messages to datasink service\n"
+        "   echo         - send/receive messages to echo service\n"
+        "   select       - test select call\n"
+        "   blocked_read - test blocked read\n"
+        "   closer1      - connection closed by remote (test1)\n"
+        "   closer2      - connection closed by remote (test2)\n"
+        "   closer3      - connection closed by remote (test3)\n"
+        "   ta2ta-ipc    - execute TA to TA unittest\n"
+        "   dev-uuid     - print device uuid\n"
+        "   ta-access    - test ta-access flags\n"
+        "   writev       - writev test\n"
+        "   readv        - readv test\n"
+        "   send-fd      - transmit memfd to trusty, use as shm\n"
+        "\n";
 
 static uint opt_repeat  = 1;
 static uint opt_msgsize = 32;
@@ -885,6 +888,66 @@
 	return 0;
 }
 
+static int send_fd_test(void) {
+    int ret;
+    int memfd = -1;
+    int fd = -1;
+    volatile char* buf = MAP_FAILED;
+
+    fd = tipc_connect(dev_name, receiver_name);
+    if (fd < 0) {
+        fprintf(stderr, "Failed to connect to test support TA - is it missing?\n");
+        ret = -1;
+        goto cleanup;
+    }
+
+    memfd = memfd_create("tipc-send-fd", 0);
+    if (memfd < 0) {
+        fprintf(stderr, "Failed to create memfd: %s\n", strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+
+    if (ftruncate(memfd, PAGE_SIZE) < 0) {
+        fprintf(stderr, "Failed to resize memfd: %s\n", strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+
+    buf = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0);
+    if (buf == MAP_FAILED) {
+        fprintf(stderr, "Failed to map memfd: %s\n", strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+
+    strcpy((char*)buf, "From NS");
+
+    struct trusty_shm shm = {
+            .fd = memfd,
+            .transfer = TRUSTY_SHARE,
+    };
+
+    ssize_t rc = tipc_send(fd, NULL, 0, &shm, 1);
+    if (rc < 0) {
+        fprintf(stderr, "tipc_send failed\n");
+        ret = rc;
+        goto cleanup;
+    }
+    char c;
+    read(fd, &c, 1);
+    tipc_close(fd);
+
+    ret = strcmp("Hello from Trusty!", (const char*)buf) ? (-1) : 0;
+
+cleanup:
+    if (buf != MAP_FAILED) {
+        munmap((char*)buf, PAGE_SIZE);
+    }
+    close(memfd);
+    tipc_close(fd);
+    return ret;
+}
 
 int main(int argc, char **argv)
 {
@@ -933,10 +996,12 @@
 		rc = writev_test(opt_repeat, opt_msgsize, opt_variable);
 	} else if (strcmp(test_name, "readv") == 0) {
 		rc = readv_test(opt_repeat, opt_msgsize, opt_variable);
-	} else {
-		fprintf(stderr, "Unrecognized test name '%s'\n", test_name);
-		print_usage_and_exit(argv[0], EXIT_FAILURE, true);
-	}
+    } else if (strcmp(test_name, "send-fd") == 0) {
+        rc = send_fd_test();
+    } else {
+        fprintf(stderr, "Unrecognized test name '%s'\n", test_name);
+        print_usage_and_exit(argv[0], EXIT_FAILURE, true);
+    }
 
-	return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+    return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/trusty/libtrusty/tipc_ioctl.h b/trusty/libtrusty/tipc_ioctl.h
deleted file mode 100644
index 27da56a..0000000
--- a/trusty/libtrusty/tipc_ioctl.h
+++ /dev/null
@@ -1,26 +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.
- */
-
-#ifndef _TIPC_IOCTL_H
-#define _TIPC_IOCTL_H
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-#define TIPC_IOC_MAGIC			'r'
-#define TIPC_IOC_CONNECT		_IOW(TIPC_IOC_MAGIC, 0x80, char *)
-
-#endif
diff --git a/trusty/libtrusty/trusty.c b/trusty/libtrusty/trusty.c
index a6238af..ad4d8cd 100644
--- a/trusty/libtrusty/trusty.c
+++ b/trusty/libtrusty/trusty.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -27,7 +27,7 @@
 
 #include <log/log.h>
 
-#include "tipc_ioctl.h"
+#include <trusty/ipc.h>
 
 int tipc_connect(const char *dev_name, const char *srv_name)
 {
@@ -55,6 +55,22 @@
 	return fd;
 }
 
+ssize_t tipc_send(int fd, const struct iovec* iov, int iovcnt, struct trusty_shm* shms,
+                  int shmcnt) {
+    struct tipc_send_msg_req req;
+    req.iov = (__u64)iov;
+    req.iov_cnt = (__u64)iovcnt;
+    req.shm = (__u64)shms;
+    req.shm_cnt = (__u64)shmcnt;
+
+    int rc = ioctl(fd, TIPC_IOC_SEND_MSG, &req);
+    if (rc < 0) {
+        ALOGE("%s: failed to send message (err=%d)\n", __func__, rc);
+    }
+
+    return rc;
+}
+
 void tipc_close(int fd)
 {
 	close(fd);