Merge changes I5cf0d014,Ib46f0646

* changes:
  logd: remove LogBufferElement dependency of LogReaderThread
  logd: rename FlushToResult to FilterResult
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 0825a77..f333a85 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -408,16 +408,17 @@
     return fstab_result;
 }
 
-// Identify path to fstab file. Lookup is based on pattern fstab.<hardware>,
-// fstab.<hardware.platform> in folders /odm/etc, vendor/etc, or /.
+// Identify path to fstab file. Lookup is based on pattern
+// fstab.<fstab_suffix>, fstab.<hardware>, fstab.<hardware.platform> in
+// folders /odm/etc, vendor/etc, or /.
 std::string GetFstabPath() {
-    for (const char* prop : {"hardware", "hardware.platform"}) {
-        std::string hw;
+    for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
+        std::string suffix;
 
-        if (!fs_mgr_get_boot_config(prop, &hw)) continue;
+        if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
 
         for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
-            std::string fstab_path = prefix + hw;
+            std::string fstab_path = prefix + suffix;
             if (access(fstab_path.c_str(), F_OK) == 0) {
                 return fstab_path;
             }
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 732dbea..89a47b1 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -144,7 +144,6 @@
     std::vector<std::unique_ptr<Extent>> extents_;
     uint32_t attributes_;
     uint64_t size_;
-    bool disabled_;
 };
 
 // An interval in the metadata. This is similar to a LinearExtent with one difference.
@@ -321,9 +320,6 @@
     // Set the LP_HEADER_FLAG_VIRTUAL_AB_DEVICE flag.
     void SetVirtualABDeviceFlag();
 
-    // If set, checks for slot suffixes will be ignored internally.
-    void IgnoreSlotSuffixing();
-
     bool GetBlockDeviceInfo(const std::string& partition_name, BlockDeviceInfo* info) const;
     bool UpdateBlockDeviceInfo(const std::string& partition_name, const BlockDeviceInfo& info);
 
diff --git a/init/README.md b/init/README.md
index b70366b..0dd1490 100644
--- a/init/README.md
+++ b/init/README.md
@@ -547,13 +547,16 @@
   * `ref`: use the systemwide DE key
   * `per_boot_ref`: use the key freshly generated on each boot.
 
-`mount_all <fstab> [ <path> ]\* [--<option>]`
+`mount_all [ <fstab> ] [--<option>]`
 > Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
   options "early" and "late".
   With "--early" set, the init executable will skip mounting entries with
   "latemount" flag and triggering fs encryption state event. With "--late" set,
   init executable will only mount entries with "latemount" flag. By default,
   no option is set, and mount\_all will process all entries in the given fstab.
+  If the fstab parameter is not specified, fstab.${ro.boot.fstab_suffix},
+  fstab.${ro.hardware} or fstab.${ro.hardware.platform} will be scanned for
+  under /odm/etc, /vendor/etc, or / at runtime, in that order.
 
 `mount <type> <device> <dir> [ <flag>\* ] [<options>]`
 > Attempt to mount the named device at the directory _dir_
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 149a766..e918e12 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -518,21 +518,21 @@
 
 /* Imports .rc files from the specified paths. Default ones are applied if none is given.
  *
- * start_index: index of the first path in the args list
+ * rc_paths: list of paths to rc files to import
  */
-static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
+static void import_late(const std::vector<std::string>& rc_paths) {
     auto& action_manager = ActionManager::GetInstance();
     auto& service_list = ServiceList::GetInstance();
     Parser parser = CreateParser(action_manager, service_list);
-    if (end_index <= start_index) {
+    if (rc_paths.empty()) {
         // Fallbacks for partitions on which early mount isn't enabled.
         for (const auto& path : late_import_paths) {
             parser.ParseConfig(path);
         }
         late_import_paths.clear();
     } else {
-        for (size_t i = start_index; i < end_index; ++i) {
-            parser.ParseConfig(args[i]);
+        for (const auto& rc_path : rc_paths) {
+            parser.ParseConfig(rc_path);
         }
     }
 
@@ -633,48 +633,44 @@
 
 static int initial_mount_fstab_return_code = -1;
 
-/* mount_all <fstab> [ <path> ]* [--<options>]*
+/* <= Q: mount_all <fstab> [ <path> ]* [--<options>]*
+ * >= R: mount_all [ <fstab> ] [--<options>]*
  *
  * This function might request a reboot, in which case it will
  * not return.
  */
 static Result<void> do_mount_all(const BuiltinArguments& args) {
-    std::size_t na = 0;
-    bool import_rc = true;
-    bool queue_event = true;
-    int mount_mode = MOUNT_MODE_DEFAULT;
-    const auto& fstab_file = args[1];
-    std::size_t path_arg_end = args.size();
-    const char* prop_post_fix = "default";
+    auto mount_all = ParseMountAll(args.args);
+    if (!mount_all.ok()) return mount_all.error();
 
-    for (na = args.size() - 1; na > 1; --na) {
-        if (args[na] == "--early") {
-            path_arg_end = na;
-            queue_event = false;
-            mount_mode = MOUNT_MODE_EARLY;
-            prop_post_fix = "early";
-        } else if (args[na] == "--late") {
-            path_arg_end = na;
-            import_rc = false;
-            mount_mode = MOUNT_MODE_LATE;
-            prop_post_fix = "late";
-        }
+    const char* prop_post_fix = "default";
+    bool queue_event = true;
+    if (mount_all->mode == MOUNT_MODE_EARLY) {
+        prop_post_fix = "early";
+        queue_event = false;
+    } else if (mount_all->mode == MOUNT_MODE_LATE) {
+        prop_post_fix = "late";
     }
 
     std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
     android::base::Timer t;
 
     Fstab fstab;
-    if (!ReadFstabFromFile(fstab_file, &fstab)) {
-        return Error() << "Could not read fstab";
+    if (mount_all->fstab_path.empty()) {
+        if (!ReadDefaultFstab(&fstab)) {
+            return Error() << "Could not read default fstab";
+        }
+    } else {
+        if (!ReadFstabFromFile(mount_all->fstab_path, &fstab)) {
+            return Error() << "Could not read fstab";
+        }
     }
 
-    auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode);
+    auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode);
     SetProperty(prop_name, std::to_string(t.duration().count()));
 
-    if (import_rc && SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
-        /* Paths of .rc files are specified at the 2nd argument and beyond */
-        import_late(args.args, 2, path_arg_end);
+    if (mount_all->import_rc) {
+        import_late(mount_all->rc_paths);
     }
 
     if (queue_event) {
@@ -690,11 +686,20 @@
     return {};
 }
 
-/* umount_all <fstab> */
+/* umount_all [ <fstab> ] */
 static Result<void> do_umount_all(const BuiltinArguments& args) {
+    auto umount_all = ParseUmountAll(args.args);
+    if (!umount_all.ok()) return umount_all.error();
+
     Fstab fstab;
-    if (!ReadFstabFromFile(args[1], &fstab)) {
-        return Error() << "Could not read fstab";
+    if (umount_all->empty()) {
+        if (!ReadDefaultFstab(&fstab)) {
+            return Error() << "Could not read default fstab";
+        }
+    } else {
+        if (!ReadFstabFromFile(*umount_all, &fstab)) {
+            return Error() << "Could not read fstab";
+        }
     }
 
     if (auto result = fs_mgr_umount_all(&fstab); result != 0) {
@@ -1349,11 +1354,11 @@
         // mount_all is currently too complex to run in vendor_init as it queues action triggers,
         // imports rc scripts, etc.  It should be simplified and run in vendor_init context.
         // mount and umount are run in the same context as mount_all for symmetry.
-        {"mount_all",               {1,     kMax, {false,  do_mount_all}}},
+        {"mount_all",               {0,     kMax, {false,  do_mount_all}}},
         {"mount",                   {3,     kMax, {false,  do_mount}}},
         {"perform_apex_config",     {0,     0,    {false,  do_perform_apex_config}}},
         {"umount",                  {1,     1,    {false,  do_umount}}},
-        {"umount_all",              {1,     1,    {false,  do_umount_all}}},
+        {"umount_all",              {0,     1,    {false,  do_umount_all}}},
         {"update_linker_config",    {0,     0,    {false,  do_update_linker_config}}},
         {"readahead",               {1,     2,    {true,   do_readahead}}},
         {"remount_userdata",        {0,     0,    {false,  do_remount_userdata}}},
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index d1a84f3..450c079 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -123,6 +123,14 @@
     return {};
 }
 
+Result<void> check_mount_all(const BuiltinArguments& args) {
+    auto options = ParseMountAll(args.args);
+    if (!options.ok()) {
+        return options.error();
+    }
+    return {};
+}
+
 Result<void> check_mkdir(const BuiltinArguments& args) {
     auto options = ParseMkdir(args.args);
     if (!options.ok()) {
@@ -204,6 +212,14 @@
     return {};
 }
 
+Result<void> check_umount_all(const BuiltinArguments& args) {
+    auto options = ParseUmountAll(args.args);
+    if (!options.ok()) {
+        return options.error();
+    }
+    return {};
+}
+
 Result<void> check_wait(const BuiltinArguments& args) {
     if (args.size() == 3 && !args[2].empty()) {
         double timeout_double;
diff --git a/init/check_builtins.h b/init/check_builtins.h
index fb34556..725a6fd 100644
--- a/init/check_builtins.h
+++ b/init/check_builtins.h
@@ -32,11 +32,13 @@
 Result<void> check_load_system_props(const BuiltinArguments& args);
 Result<void> check_loglevel(const BuiltinArguments& args);
 Result<void> check_mkdir(const BuiltinArguments& args);
+Result<void> check_mount_all(const BuiltinArguments& args);
 Result<void> check_restorecon(const BuiltinArguments& args);
 Result<void> check_restorecon_recursive(const BuiltinArguments& args);
 Result<void> check_setprop(const BuiltinArguments& args);
 Result<void> check_setrlimit(const BuiltinArguments& args);
 Result<void> check_sysclktz(const BuiltinArguments& args);
+Result<void> check_umount_all(const BuiltinArguments& args);
 Result<void> check_wait(const BuiltinArguments& args);
 Result<void> check_wait_for_prop(const BuiltinArguments& args);
 
diff --git a/init/util.cpp b/init/util.cpp
index f9be055..40f24b1 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -572,6 +572,48 @@
     return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
 }
 
+Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args) {
+    bool compat_mode = false;
+    bool import_rc = false;
+    if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+        if (args.size() <= 1) {
+            return Error() << "mount_all requires at least 1 argument";
+        }
+        compat_mode = true;
+        import_rc = true;
+    }
+
+    std::size_t first_option_arg = args.size();
+    enum mount_mode mode = MOUNT_MODE_DEFAULT;
+
+    // If we are <= Q, then stop looking for non-fstab arguments at slot 2.
+    // Otherwise, stop looking at slot 1 (as the fstab path argument is optional >= R).
+    for (std::size_t na = args.size() - 1; na > (compat_mode ? 1 : 0); --na) {
+        if (args[na] == "--early") {
+            first_option_arg = na;
+            mode = MOUNT_MODE_EARLY;
+        } else if (args[na] == "--late") {
+            first_option_arg = na;
+            mode = MOUNT_MODE_LATE;
+            import_rc = false;
+        }
+    }
+
+    std::string fstab_path;
+    if (first_option_arg > 1) {
+        fstab_path = args[1];
+    } else if (compat_mode) {
+        return Error() << "mount_all argument 1 must be the fstab path";
+    }
+
+    std::vector<std::string> rc_paths;
+    for (std::size_t na = 2; na < first_option_arg; ++na) {
+        rc_paths.push_back(args[na]);
+    }
+
+    return MountAllOptions{rc_paths, fstab_path, mode, import_rc};
+}
+
 Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
         const std::vector<std::string>& args) {
     struct flag_type {
@@ -612,6 +654,15 @@
     return std::pair(flag, paths);
 }
 
+Result<std::string> ParseUmountAll(const std::vector<std::string>& args) {
+    if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+        if (args.size() <= 1) {
+            return Error() << "umount_all requires at least 1 argument";
+        }
+    }
+    return args[1];
+}
+
 static void InitAborter(const char* abort_message) {
     // When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
     // simply abort instead of trying to reboot the system.
diff --git a/init/util.h b/init/util.h
index 8167b02..28f6b18 100644
--- a/init/util.h
+++ b/init/util.h
@@ -22,6 +22,7 @@
 #include <chrono>
 #include <functional>
 #include <string>
+#include <vector>
 
 #include <android-base/chrono_utils.h>
 
@@ -33,6 +34,12 @@
 namespace android {
 namespace init {
 
+enum mount_mode {
+    MOUNT_MODE_DEFAULT = 0,
+    MOUNT_MODE_EARLY = 1,
+    MOUNT_MODE_LATE = 2,
+};
+
 static const char kColdBootDoneProp[] = "ro.cold_boot_done";
 
 extern void (*trigger_shutdown)(const std::string& command);
@@ -73,9 +80,20 @@
 
 Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args);
 
+struct MountAllOptions {
+    std::vector<std::string> rc_paths;
+    std::string fstab_path;
+    mount_mode mode;
+    bool import_rc;
+};
+
+Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args);
+
 Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
         const std::vector<std::string>& args);
 
+Result<std::string> ParseUmountAll(const std::vector<std::string>& args);
+
 void SetStdioToDevNull(char** argv);
 void InitKernelLogging(char** argv);
 void InitSecondStageLogging(char** argv);
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index d7c83a2..60400c9 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -152,6 +152,7 @@
         "iosched_policy.cpp",
         "load_file.cpp",
         "native_handle.cpp",
+        "properties.cpp",
         "record_stream.cpp",
         "strlcpy.c",
         "threads.cpp",
@@ -187,7 +188,6 @@
                 "fs_config.cpp",
                 "klog.cpp",
                 "partition_utils.cpp",
-                "properties.cpp",
                 "qtaguid.cpp",
                 "trace-dev.cpp",
                 "uevent.cpp",
@@ -268,6 +268,7 @@
     name: "libcutils_test_default",
     srcs: [
         "native_handle_test.cpp",
+        "properties_test.cpp",
         "sockets_test.cpp",
     ],
 
@@ -280,7 +281,6 @@
                 "fs_config_test.cpp",
                 "memset_test.cpp",
                 "multiuser_test.cpp",
-                "properties_test.cpp",
                 "sched_policy_test.cpp",
                 "str_parms_test.cpp",
                 "trace-dev_test.cpp",
diff --git a/libcutils/include/cutils/properties.h b/libcutils/include/cutils/properties.h
index d2e0871..78d8bc6 100644
--- a/libcutils/include/cutils/properties.h
+++ b/libcutils/include/cutils/properties.h
@@ -14,27 +14,30 @@
  * limitations under the License.
  */
 
-#ifndef __CUTILS_PROPERTIES_H
-#define __CUTILS_PROPERTIES_H
+#pragma once
 
 #include <sys/cdefs.h>
 #include <stddef.h>
-#include <sys/system_properties.h>
 #include <stdint.h>
 
+#if __has_include(<sys/system_properties.h>)
+#include <sys/system_properties.h>
+#else
+#define PROP_VALUE_MAX 92
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* System properties are *small* name value pairs managed by the
-** property service.  If your data doesn't fit in the provided
-** space it is not appropriate for a system property.
-**
-** WARNING: system/bionic/include/sys/system_properties.h also defines
-**          these, but with different names.  (TODO: fix that)
-*/
-#define PROPERTY_KEY_MAX   PROP_NAME_MAX
-#define PROPERTY_VALUE_MAX  PROP_VALUE_MAX
+//
+// Deprecated.
+//
+// See <android-base/properties.h> for better API.
+//
+
+#define PROPERTY_KEY_MAX PROP_NAME_MAX
+#define PROPERTY_VALUE_MAX PROP_VALUE_MAX
 
 /* property_get: returns the length of the value which will never be
 ** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.
@@ -146,5 +149,3 @@
 #ifdef __cplusplus
 }
 #endif
-
-#endif
diff --git a/libcutils/properties.cpp b/libcutils/properties.cpp
index 5dbbeba..03f0496 100644
--- a/libcutils/properties.cpp
+++ b/libcutils/properties.cpp
@@ -16,27 +16,19 @@
 
 #include <cutils/properties.h>
 
-#define LOG_TAG "properties"
-// #define LOG_NDEBUG 0
-
-#include <assert.h>
-#include <ctype.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#include <cutils/sockets.h>
-#include <log/log.h>
+#include <android-base/properties.h>
 
-int8_t property_get_bool(const char *key, int8_t default_value) {
-    if (!key) {
-        return default_value;
-    }
+int8_t property_get_bool(const char* key, int8_t default_value) {
+    if (!key) return default_value;
 
     int8_t result = default_value;
-    char buf[PROPERTY_VALUE_MAX] = {'\0'};
+    char buf[PROPERTY_VALUE_MAX] = {};
 
     int len = property_get(key, buf, "");
     if (len == 1) {
@@ -57,73 +49,53 @@
     return result;
 }
 
-// Convert string property to int (default if fails); return default value if out of bounds
-static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
-                                  intmax_t default_value) {
-    if (!key) {
-        return default_value;
+template <typename T>
+static T property_get_int(const char* key, T default_value) {
+    if (!key) return default_value;
+
+    char value[PROPERTY_VALUE_MAX] = {};
+    if (property_get(key, value, "") < 1) return default_value;
+
+    // libcutils unwisely allows octal, which libbase doesn't.
+    T result = default_value;
+    int saved_errno = errno;
+    errno = 0;
+    char* end = nullptr;
+    intmax_t v = strtoimax(value, &end, 0);
+    if (errno != ERANGE && end != value && v >= std::numeric_limits<T>::min() &&
+        v <= std::numeric_limits<T>::max()) {
+        result = v;
     }
-
-    intmax_t result = default_value;
-    char buf[PROPERTY_VALUE_MAX] = {'\0'};
-    char *end = NULL;
-
-    int len = property_get(key, buf, "");
-    if (len > 0) {
-        int tmp = errno;
-        errno = 0;
-
-        // Infer base automatically
-        result = strtoimax(buf, &end, /*base*/ 0);
-        if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {
-            // Over or underflow
-            result = default_value;
-            ALOGV("%s(%s,%" PRIdMAX ") - overflow", __FUNCTION__, key, default_value);
-        } else if (result < lower_bound || result > upper_bound) {
-            // Out of range of requested bounds
-            result = default_value;
-            ALOGV("%s(%s,%" PRIdMAX ") - out of range", __FUNCTION__, key, default_value);
-        } else if (end == buf) {
-            // Numeric conversion failed
-            result = default_value;
-            ALOGV("%s(%s,%" PRIdMAX ") - numeric conversion failed", __FUNCTION__, key,
-                  default_value);
-        }
-
-        errno = tmp;
-    }
-
+    errno = saved_errno;
     return result;
 }
 
-int64_t property_get_int64(const char *key, int64_t default_value) {
-    return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value);
+int64_t property_get_int64(const char* key, int64_t default_value) {
+    return property_get_int<int64_t>(key, default_value);
 }
 
-int32_t property_get_int32(const char *key, int32_t default_value) {
-    return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);
+int32_t property_get_int32(const char* key, int32_t default_value) {
+    return property_get_int<int32_t>(key, default_value);
 }
 
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-
-int property_set(const char *key, const char *value) {
+int property_set(const char* key, const char* value) {
     return __system_property_set(key, value);
 }
 
-int property_get(const char *key, char *value, const char *default_value) {
+int property_get(const char* key, char* value, const char* default_value) {
     int len = __system_property_get(key, value);
-    if (len > 0) {
-        return len;
-    }
-    if (default_value) {
-        len = strnlen(default_value, PROPERTY_VALUE_MAX - 1);
-        memcpy(value, default_value, len);
-        value[len] = '\0';
+    if (len < 1 && default_value) {
+        snprintf(value, PROPERTY_VALUE_MAX, "%s", default_value);
+        return strlen(value);
     }
     return len;
 }
 
+#if __has_include(<sys/system_properties.h>)
+
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+
 struct callback_data {
     void (*callback)(const char* name, const char* value, void* cookie);
     void* cookie;
@@ -139,6 +111,8 @@
 }
 
 int property_list(void (*fn)(const char* name, const char* value, void* cookie), void* cookie) {
-    callback_data data = { fn, cookie };
+    callback_data data = {fn, cookie};
     return __system_property_foreach(property_list_callback, &data);
 }
+
+#endif
diff --git a/libcutils/properties_test.cpp b/libcutils/properties_test.cpp
index 7921972..efc0183 100644
--- a/libcutils/properties_test.cpp
+++ b/libcutils/properties_test.cpp
@@ -93,160 +93,179 @@
     }
 };
 
-TEST_F(PropertiesTest, SetString) {
-
+TEST_F(PropertiesTest, property_set_null_key) {
     // Null key -> unsuccessful set
-    {
-        // Null key -> fails
-        EXPECT_GT(0, property_set(/*key*/NULL, PROPERTY_TEST_VALUE_DEFAULT));
-    }
+    EXPECT_GT(0, property_set(/*key*/ NULL, PROPERTY_TEST_VALUE_DEFAULT));
+}
 
-    // Null value -> returns default value
-    {
-        // Null value -> OK , and it clears the value
-        EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
-        ResetValue();
+TEST_F(PropertiesTest, property_set_null_value) {
+    // Null value -> OK, and it clears the value
+    EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/ NULL));
+    ResetValue();
 
-        // Since the value is null, default value will be returned
-        size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
-        EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);
-        EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);
-    }
+    // Since the value is null, default value will be returned
+    size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
+    EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);
+    EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);
+}
 
+TEST_F(PropertiesTest, property_set) {
     // Trivial case => get returns what was set
-    {
-        size_t len = SetAndGetProperty("hello_world");
-        EXPECT_EQ(strlen("hello_world"), len) << "hello_world key";
-        EXPECT_STREQ("hello_world", mValue);
-        ResetValue();
-    }
+    size_t len = SetAndGetProperty("hello_world");
+    EXPECT_EQ(strlen("hello_world"), len) << "hello_world key";
+    EXPECT_STREQ("hello_world", mValue);
+    ResetValue();
+}
 
+TEST_F(PropertiesTest, property_set_empty) {
     // Set to empty string => get returns default always
-    {
-        const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING";
-        size_t len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
-        EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key";
-        EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);
-        ResetValue();
-    }
+    const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING";
+    size_t len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
+    EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key";
+    EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);
+    ResetValue();
+}
 
+TEST_F(PropertiesTest, property_set_max_length) {
     // Set to max length => get returns what was set
-    {
-        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');
+    std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'a');
 
-        int len = SetAndGetProperty(maxLengthString.c_str());
-        EXPECT_EQ(PROPERTY_VALUE_MAX-1, len) << "max length key";
-        EXPECT_STREQ(maxLengthString.c_str(), mValue);
-        ResetValue();
-    }
+    int len = SetAndGetProperty(maxLengthString.c_str());
+    EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len) << "max length key";
+    EXPECT_STREQ(maxLengthString.c_str(), mValue);
+    ResetValue();
+}
 
+TEST_F(PropertiesTest, property_set_too_long) {
     // Set to max length + 1 => set fails
-    {
-        const char* VALID_TEST_VALUE = "VALID_VALUE";
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE));
+    const char* VALID_TEST_VALUE = "VALID_VALUE";
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE));
 
-        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
+    std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
 
-        // Expect that the value set fails since it's too long
-        EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));
-        size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
+    // Expect that the value set fails since it's too long
+    EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));
+    size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
 
-        EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed";
-        EXPECT_STREQ(VALID_TEST_VALUE, mValue);
-        ResetValue();
-    }
+    EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed";
+    EXPECT_STREQ(VALID_TEST_VALUE, mValue);
+    ResetValue();
 }
 
-TEST_F(PropertiesTest, GetString) {
-
+TEST_F(PropertiesTest, property_get_too_long) {
     // Try to use a default value that's too long => get truncates the value
-    {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
 
-        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'a');
-        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
+    std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'a');
+    std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
 
-        // Expect that the value is truncated since it's too long (by 1)
-        int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
-        EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
-        EXPECT_STREQ(maxLengthString.c_str(), mValue);
-        ResetValue();
-    }
-
-    // Try to use a default value that's the max length => get succeeds
-    {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
-
-        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'b');
-
-        // Expect that the value matches maxLengthString
-        int len = property_get(PROPERTY_TEST_KEY, mValue, maxLengthString.c_str());
-        EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
-        EXPECT_STREQ(maxLengthString.c_str(), mValue);
-        ResetValue();
-    }
-
-    // Try to use a default value of length one => get succeeds
-    {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
-
-        std::string oneCharString = std::string(1, 'c');
-
-        // Expect that the value matches oneCharString
-        int len = property_get(PROPERTY_TEST_KEY, mValue, oneCharString.c_str());
-        EXPECT_EQ(1, len);
-        EXPECT_STREQ(oneCharString.c_str(), mValue);
-        ResetValue();
-    }
-
-    // Try to use a default value of length zero => get succeeds
-    {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
-
-        std::string zeroCharString = std::string(0, 'd');
-
-        // Expect that the value matches oneCharString
-        int len = property_get(PROPERTY_TEST_KEY, mValue, zeroCharString.c_str());
-        EXPECT_EQ(0, len);
-        EXPECT_STREQ(zeroCharString.c_str(), mValue);
-        ResetValue();
-    }
-
-    // Try to use a NULL default value => get returns 0
-    {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
-
-        // Expect a return value of 0
-        int len = property_get(PROPERTY_TEST_KEY, mValue, NULL);
-        EXPECT_EQ(0, len);
-        ResetValue();
-    }
+    // Expect that the value is truncated since it's too long (by 1)
+    int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
+    EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
+    EXPECT_STREQ(maxLengthString.c_str(), mValue);
+    ResetValue();
 }
 
-TEST_F(PropertiesTest, GetBool) {
-    /**
-     * TRUE
-     */
-    const char *valuesTrue[] = { "1", "true", "y", "yes", "on", };
-    for (size_t i = 0; i < arraysize(valuesTrue); ++i) {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesTrue[i]));
-        bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);
-        EXPECT_TRUE(val) << "Property should've been TRUE for value: '" << valuesTrue[i] << "'";
-    }
+TEST_F(PropertiesTest, property_get_default_too_long) {
+    // Try to use a default value that's the max length => get succeeds
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
 
-    /**
-     * FALSE
-     */
-    const char *valuesFalse[] = { "0", "false", "n", "no", "off", };
-    for (size_t i = 0; i < arraysize(valuesFalse); ++i) {
-        ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesFalse[i]));
-        bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);
-        EXPECT_FALSE(val) << "Property shoud've been FALSE For string value: '" << valuesFalse[i] << "'";
-    }
+    std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'b');
 
-    /**
-     * NEITHER
-     */
+    // Expect that the value matches maxLengthString
+    int len = property_get(PROPERTY_TEST_KEY, mValue, maxLengthString.c_str());
+    EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
+    EXPECT_STREQ(maxLengthString.c_str(), mValue);
+    ResetValue();
+}
+
+TEST_F(PropertiesTest, property_get_default_okay) {
+    // Try to use a default value of length one => get succeeds
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+    std::string oneCharString = std::string(1, 'c');
+
+    // Expect that the value matches oneCharString
+    int len = property_get(PROPERTY_TEST_KEY, mValue, oneCharString.c_str());
+    EXPECT_EQ(1, len);
+    EXPECT_STREQ(oneCharString.c_str(), mValue);
+    ResetValue();
+}
+
+TEST_F(PropertiesTest, property_get_default_empty) {
+    // Try to use a default value of length zero => get succeeds
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+    std::string zeroCharString = std::string(0, 'd');
+
+    // Expect that the value matches oneCharString
+    int len = property_get(PROPERTY_TEST_KEY, mValue, zeroCharString.c_str());
+    EXPECT_EQ(0, len);
+    EXPECT_STREQ(zeroCharString.c_str(), mValue);
+    ResetValue();
+}
+
+TEST_F(PropertiesTest, property_get_default_NULL) {
+    // Try to use a NULL default value => get returns 0
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+    // Expect a return value of 0
+    int len = property_get(PROPERTY_TEST_KEY, mValue, NULL);
+    EXPECT_EQ(0, len);
+    ResetValue();
+}
+
+TEST_F(PropertiesTest, property_get_bool_0) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "0"));
+    ASSERT_FALSE(property_get_bool(PROPERTY_TEST_KEY, true));
+}
+
+TEST_F(PropertiesTest, property_get_bool_1) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "1"));
+    ASSERT_TRUE(property_get_bool(PROPERTY_TEST_KEY, false));
+}
+
+TEST_F(PropertiesTest, property_get_bool_false) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "false"));
+    ASSERT_FALSE(property_get_bool(PROPERTY_TEST_KEY, true));
+}
+
+TEST_F(PropertiesTest, property_get_bool_n) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "n"));
+    ASSERT_FALSE(property_get_bool(PROPERTY_TEST_KEY, true));
+}
+
+TEST_F(PropertiesTest, property_get_bool_no) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "no"));
+    ASSERT_FALSE(property_get_bool(PROPERTY_TEST_KEY, true));
+}
+
+TEST_F(PropertiesTest, property_get_bool_off) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "off"));
+    ASSERT_FALSE(property_get_bool(PROPERTY_TEST_KEY, true));
+}
+
+TEST_F(PropertiesTest, property_get_bool_on) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "on"));
+    ASSERT_TRUE(property_get_bool(PROPERTY_TEST_KEY, false));
+}
+
+TEST_F(PropertiesTest, property_get_bool_true) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "true"));
+    ASSERT_TRUE(property_get_bool(PROPERTY_TEST_KEY, false));
+}
+
+TEST_F(PropertiesTest, property_get_bool_y) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "y"));
+    ASSERT_TRUE(property_get_bool(PROPERTY_TEST_KEY, false));
+}
+
+TEST_F(PropertiesTest, property_get_bool_yes) {
+    ASSERT_OK(property_set(PROPERTY_TEST_KEY, "yes"));
+    ASSERT_TRUE(property_get_bool(PROPERTY_TEST_KEY, false));
+}
+
+TEST_F(PropertiesTest, property_get_bool_neither) {
     const char *valuesNeither[] = { "x0", "x1", "2", "-2", "True", "False", "garbage", "", " ",
             "+1", "  1  ", "  true", "  true  ", "  y  ", "  yes", "yes  ",
             "+0", "-0", "00", "  00  ", "  false", "false  ",
@@ -263,7 +282,7 @@
     }
 }
 
-TEST_F(PropertiesTest, GetInt64) {
+TEST_F(PropertiesTest, property_get_int64) {
     const int64_t DEFAULT_VALUE = INT64_C(0xDEADBEEFBEEFDEAD);
 
     const std::string longMaxString = ToString(INT64_MAX);
@@ -310,7 +329,7 @@
     }
 }
 
-TEST_F(PropertiesTest, GetInt32) {
+TEST_F(PropertiesTest, property_get_int32) {
     const int32_t DEFAULT_VALUE = INT32_C(0xDEADBEEF);
 
     const std::string intMaxString = ToString(INT32_MAX);
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 0f7044a..ea39d34 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -246,6 +246,7 @@
         "String8_test.cpp",
         "String16_test.cpp",
         "StrongPointer_test.cpp",
+        "Timers_test.cpp",
         "Unicode_test.cpp",
         "Vector_test.cpp",
     ],
diff --git a/libutils/FileMap.cpp b/libutils/FileMap.cpp
index 1d899ab..0abb861 100644
--- a/libutils/FileMap.cpp
+++ b/libutils/FileMap.cpp
@@ -189,7 +189,11 @@
 
     int adjust = offset % mPageSize;
     off64_t adjOffset = offset - adjust;
-    size_t adjLength = length + adjust;
+    size_t adjLength;
+    if (__builtin_add_overflow(length, adjust, &adjLength)) {
+        ALOGE("adjusted length overflow: length %zu adjust %d", length, adjust);
+        return false;
+    }
 
     int flags = MAP_SHARED;
     int prot = PROT_READ;
diff --git a/libutils/FileMap_test.cpp b/libutils/FileMap_test.cpp
index 9f7ce85..fd1c9b0 100644
--- a/libutils/FileMap_test.cpp
+++ b/libutils/FileMap_test.cpp
@@ -52,3 +52,16 @@
     ASSERT_EQ(0u, m.getDataLength());
     ASSERT_EQ(offset, m.getDataOffset());
 }
+
+TEST(FileMap, offset_overflow) {
+    // Make sure that an end that overflows SIZE_MAX will not abort.
+    // See http://b/156997193.
+    TemporaryFile tf;
+    ASSERT_TRUE(tf.fd != -1);
+
+    off64_t offset = 200;
+    size_t length = SIZE_MAX;
+
+    android::FileMap m;
+    ASSERT_FALSE(m.create("test", tf.fd, offset, length, true));
+}
diff --git a/libutils/Timers.cpp b/libutils/Timers.cpp
index 1172ae7..fd3f4a9 100644
--- a/libutils/Timers.cpp
+++ b/libutils/Timers.cpp
@@ -20,31 +20,37 @@
 #include <utils/Timers.h>
 
 #include <limits.h>
+#include <stdlib.h>
 #include <time.h>
 
-// host linux support requires Linux 2.6.39+
+#include <android-base/macros.h>
+
+static constexpr size_t clock_id_max = 5;
+
+static void checkClockId(int clock) {
+    if (clock < 0 || clock >= clock_id_max) abort();
+}
+
 #if defined(__linux__)
-nsecs_t systemTime(int clock)
-{
-    static const clockid_t clocks[] = {
-            CLOCK_REALTIME,
-            CLOCK_MONOTONIC,
-            CLOCK_PROCESS_CPUTIME_ID,
-            CLOCK_THREAD_CPUTIME_ID,
-            CLOCK_BOOTTIME
-    };
-    struct timespec t;
-    t.tv_sec = t.tv_nsec = 0;
+nsecs_t systemTime(int clock) {
+    checkClockId(clock);
+    static constexpr clockid_t clocks[] = {CLOCK_REALTIME, CLOCK_MONOTONIC,
+                                           CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID,
+                                           CLOCK_BOOTTIME};
+    static_assert(clock_id_max == arraysize(clocks));
+    timespec t = {};
     clock_gettime(clocks[clock], &t);
     return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
 }
 #else
-nsecs_t systemTime(int /*clock*/)
-{
+nsecs_t systemTime(int clock) {
+    // TODO: is this ever called with anything but REALTIME on mac/windows?
+    checkClockId(clock);
+
     // Clock support varies widely across hosts. Mac OS doesn't support
-    // CLOCK_BOOTTIME, and Windows is windows.
-    struct timeval t;
-    t.tv_sec = t.tv_usec = 0;
+    // CLOCK_BOOTTIME (and doesn't even have clock_gettime until 10.12).
+    // Windows is windows.
+    timeval t = {};
     gettimeofday(&t, nullptr);
     return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
 }
diff --git a/libutils/Timers_test.cpp b/libutils/Timers_test.cpp
new file mode 100644
index 0000000..ec0051e
--- /dev/null
+++ b/libutils/Timers_test.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 <utils/Timers.h>
+
+#include <gtest/gtest.h>
+
+TEST(Timers, systemTime_invalid) {
+    EXPECT_EXIT(systemTime(-1), testing::KilledBySignal(SIGABRT), "");
+    systemTime(SYSTEM_TIME_REALTIME);
+    systemTime(SYSTEM_TIME_MONOTONIC);
+    systemTime(SYSTEM_TIME_PROCESS);
+    systemTime(SYSTEM_TIME_THREAD);
+    systemTime(SYSTEM_TIME_BOOTTIME);
+    EXPECT_EXIT(systemTime(SYSTEM_TIME_BOOTTIME + 1), testing::KilledBySignal(SIGABRT), "");
+}
diff --git a/libutils/include/utils/Timers.h b/libutils/include/utils/Timers.h
index 54ec474..197fc26 100644
--- a/libutils/include/utils/Timers.h
+++ b/libutils/include/utils/Timers.h
@@ -14,11 +14,7 @@
  * limitations under the License.
  */
 
-//
-// Timer functions.
-//
-#ifndef _LIBS_UTILS_TIMERS_H
-#define _LIBS_UTILS_TIMERS_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -77,11 +73,11 @@
 static CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
 
 enum {
-    SYSTEM_TIME_REALTIME = 0,  // system-wide realtime clock
-    SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
-    SYSTEM_TIME_PROCESS = 2,   // high-resolution per-process clock
-    SYSTEM_TIME_THREAD = 3,    // high-resolution per-thread clock
-    SYSTEM_TIME_BOOTTIME = 4   // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
+    SYSTEM_TIME_REALTIME = 0,   // system-wide realtime clock
+    SYSTEM_TIME_MONOTONIC = 1,  // monotonic time since unspecified starting point
+    SYSTEM_TIME_PROCESS = 2,    // high-resolution per-process clock
+    SYSTEM_TIME_THREAD = 3,     // high-resolution per-thread clock
+    SYSTEM_TIME_BOOTTIME = 4,   // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
 };
 
 // return the system-time according to the specified clock
@@ -104,5 +100,3 @@
 #ifdef __cplusplus
 } // extern "C"
 #endif
-
-#endif // _LIBS_UTILS_TIMERS_H