Merge "Migrate liblog to ndk_library."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 31e60ca..5b5eff4 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -59,3 +59,4 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_DEVICE).so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc)
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 056dbef..9ae3f1c 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -48,9 +48,9 @@
 #include "transport.h"
 
 #if !ADB_HOST
-#include <cutils/properties.h>
 #include <sys/capability.h>
 #include <sys/mount.h>
+#include <android-base/properties.h>
 #endif
 
 std::string adb_version() {
@@ -200,11 +200,9 @@
         "ro.product.device",
     };
 
-    for (const auto& prop_name : cnxn_props) {
-        char value[PROPERTY_VALUE_MAX];
-        property_get(prop_name, value, "");
-        connection_properties.push_back(
-            android::base::StringPrintf("%s=%s", prop_name, value));
+    for (const auto& prop : cnxn_props) {
+        std::string value = std::string(prop) + "=" + android::base::GetProperty(prop, "");
+        connection_properties.push_back(value);
     }
 #endif
 
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
index 62900c0..369dec9 100644
--- a/adb/adb_trace.cpp
+++ b/adb/adb_trace.cpp
@@ -27,7 +27,7 @@
 #include "adb.h"
 
 #if !ADB_HOST
-#include <cutils/properties.h>
+#include <android-base/properties.h>
 #endif
 
 #if !ADB_HOST
@@ -88,19 +88,11 @@
     return std::string(setting);
 }
 
-#if !ADB_HOST
-std::string get_trace_setting_from_prop() {
-    char buf[PROPERTY_VALUE_MAX];
-    property_get("persist.adb.trace_mask", buf, "");
-    return std::string(buf);
-}
-#endif
-
 std::string get_trace_setting() {
 #if ADB_HOST
     return get_trace_setting_from_env();
 #else
-    return get_trace_setting_from_prop();
+    return android::base::GetProperty("persist.adb.trace_mask", "");
 #endif
 }
 
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index b54243e..094988a 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -29,11 +29,11 @@
 
 #include <android-base/logging.h>
 #include <android-base/macros.h>
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <libminijail.h>
 #include <scoped_minijail.h>
 
-#include "cutils/properties.h"
 #include "debuggerd/client.h"
 #include "private/android_filesystem_config.h"
 #include "selinux/android.h"
@@ -48,9 +48,7 @@
 
 static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
 #if defined(ALLOW_ADBD_ROOT)
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.debuggable", value, "");
-    if (strcmp(value, "1") == 0) {
+    if (android::base::GetBoolProperty("ro.debuggable", false)) {
         return;
     }
 #endif
@@ -59,8 +57,6 @@
 
 static bool should_drop_privileges() {
 #if defined(ALLOW_ADBD_ROOT)
-    char value[PROPERTY_VALUE_MAX];
-
     // The properties that affect `adb root` and `adb unroot` are ro.secure and
     // ro.debuggable. In this context the names don't make the expected behavior
     // particularly obvious.
@@ -71,24 +67,19 @@
     //
     // ro.secure:
     //   Drop privileges by default. Set to 1 on userdebug and user builds.
-    property_get("ro.secure", value, "1");
-    bool ro_secure = (strcmp(value, "1") == 0);
-
-    property_get("ro.debuggable", value, "");
-    bool ro_debuggable = (strcmp(value, "1") == 0);
+    bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
+    bool ro_debuggable = android::base::GetBoolProperty("ro.debuggable", false);
 
     // Drop privileges if ro.secure is set...
     bool drop = ro_secure;
 
-    property_get("service.adb.root", value, "");
-    bool adb_root = (strcmp(value, "1") == 0);
-    bool adb_unroot = (strcmp(value, "0") == 0);
-
     // ... except "adb root" lets you keep privileges in a debuggable build.
+    std::string prop = android::base::GetProperty("service.adb.root", "");
+    bool adb_root = (prop == "1");
+    bool adb_unroot = (prop == "0");
     if (ro_debuggable && adb_root) {
         drop = false;
     }
-
     // ... and "adb unroot" lets you explicitly drop privileges.
     if (adb_unroot) {
         drop = true;
@@ -159,7 +150,7 @@
     // descriptor will always be open.
     adbd_cloexec_auth_socket();
 
-    if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) {
+    if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) {
         auth_required = false;
     }
 
@@ -187,14 +178,13 @@
     // If one of these properties is set, also listen on that port.
     // If one of the properties isn't set and we couldn't listen on usb, listen
     // on the default port.
-    char prop_port[PROPERTY_VALUE_MAX];
-    property_get("service.adb.tcp.port", prop_port, "");
-    if (prop_port[0] == '\0') {
-        property_get("persist.adb.tcp.port", prop_port, "");
+    std::string prop_port = android::base::GetProperty("service.adb.tcp.port", "");
+    if (prop_port.empty()) {
+        prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
     }
 
     int port;
-    if (sscanf(prop_port, "%d", &port) == 1 && port > 0) {
+    if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
         D("using port=%d", port);
         // Listen on TCP port specified by service.adb.tcp.port property.
         local_init(port);
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 8f1c9b0..5ca73cc 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -29,10 +29,11 @@
 
 #include <string>
 
+#include <android-base/properties.h>
+
 #include "adb.h"
 #include "adb_io.h"
 #include "adb_utils.h"
-#include "cutils/properties.h"
 #include "fs_mgr.h"
 
 // Returns the device used to mount a directory in /proc/mounts.
@@ -53,10 +54,7 @@
 
 // Returns the device used to mount a directory in the fstab.
 static std::string find_fstab_mount(const char* dir) {
-    char propbuf[PROPERTY_VALUE_MAX];
-
-    property_get("ro.hardware", propbuf, "");
-    std::string fstab_filename = std::string("/fstab.") + propbuf;
+    std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
     struct fstab* fstab = fs_mgr_read_fstab(fstab_filename.c_str());
     struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, dir);
     std::string dev = rec ? std::string(rec->blk_device) : "";
@@ -113,12 +111,8 @@
         return;
     }
 
-    char prop_buf[PROPERTY_VALUE_MAX];
-    property_get("partition.system.verified", prop_buf, "");
-    bool system_verified = (strlen(prop_buf) > 0);
-
-    property_get("partition.vendor.verified", prop_buf, "");
-    bool vendor_verified = (strlen(prop_buf) > 0);
+    bool system_verified = !(android::base::GetProperty("partition.system.verified", "").empty());
+    bool vendor_verified = !(android::base::GetProperty("partition.vendor.verified", "").empty());
 
     if (system_verified || vendor_verified) {
         // Allow remount but warn of likely bad effects
@@ -136,9 +130,7 @@
     }
 
     bool success = true;
-    property_get("ro.build.system_root_image", prop_buf, "");
-    bool system_root = !strcmp(prop_buf, "true");
-    if (system_root) {
+    if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
         success &= remount_partition(fd, "/");
     } else {
         success &= remount_partition(fd, "/system");
diff --git a/adb/services.cpp b/adb/services.cpp
index 2207a3e..0c3dd00 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -39,7 +39,7 @@
 
 #if !ADB_HOST
 #include "cutils/android_reboot.h"
-#include "cutils/properties.h"
+#include <android-base/properties.h>
 #endif
 
 #include "adb.h"
@@ -73,15 +73,13 @@
         WriteFdExactly(fd, "adbd is already running as root\n");
         adb_close(fd);
     } else {
-        char value[PROPERTY_VALUE_MAX];
-        property_get("ro.debuggable", value, "");
-        if (strcmp(value, "1") != 0) {
+        if (!android::base::GetBoolProperty("ro.debuggable", false)) {
             WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
             adb_close(fd);
             return;
         }
 
-        property_set("service.adb.root", "1");
+        android::base::SetProperty("service.adb.root", "1");
         WriteFdExactly(fd, "restarting adbd as root\n");
         adb_close(fd);
     }
@@ -92,7 +90,7 @@
         WriteFdExactly(fd, "adbd not running as root\n");
         adb_close(fd);
     } else {
-        property_set("service.adb.root", "0");
+        android::base::SetProperty("service.adb.root", "0");
         WriteFdExactly(fd, "restarting adbd as non root\n");
         adb_close(fd);
     }
@@ -106,15 +104,13 @@
         return;
     }
 
-    char value[PROPERTY_VALUE_MAX];
-    snprintf(value, sizeof(value), "%d", port);
-    property_set("service.adb.tcp.port", value);
+    android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
     WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port);
     adb_close(fd);
 }
 
 void restart_usb_service(int fd, void *cookie) {
-    property_set("service.adb.tcp.port", "0");
+    android::base::SetProperty("service.adb.tcp.port", "0");
     WriteFdExactly(fd, "restarting in USB mode\n");
     adb_close(fd);
 }
@@ -155,16 +151,9 @@
 
     sync();
 
-    char property_val[PROPERTY_VALUE_MAX];
-    int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
-    if (ret >= static_cast<int>(sizeof(property_val))) {
-        WriteFdFmt(fd, "reboot string too long: %d\n", ret);
-        return false;
-    }
-
-    ret = property_set(ANDROID_RB_PROPERTY, property_val);
-    if (ret < 0) {
-        WriteFdFmt(fd, "reboot failed: %d\n", ret);
+    std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg);
+    if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
+        WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str());
         return false;
     }
 
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index f5188e9..ae628e4 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -24,16 +24,17 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
-#include "cutils/properties.h"
+#include "android-base/properties.h"
+#include "android-base/stringprintf.h"
 
 #include "adb.h"
 #include "adb_io.h"
+#include "adb_unique_fd.h"
 #include "fs_mgr.h"
 #include "remount_service.h"
 
 #include "fec/io.h"
 
-#define FSTAB_PREFIX "/fstab."
 struct fstab *fstab;
 
 #ifdef ALLOW_ADBD_DISABLE_VERITY
@@ -88,56 +89,46 @@
     return 0;
 }
 
-void set_verity_enabled_state_service(int fd, void* cookie)
-{
+void set_verity_enabled_state_service(int fd, void* cookie) {
+    unique_fd closer(fd);
+
     bool enable = (cookie != NULL);
-    if (kAllowDisableVerity) {
-        char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-        char propbuf[PROPERTY_VALUE_MAX];
-        int i;
-        bool any_changed = false;
-
-        property_get("ro.secure", propbuf, "0");
-        if (strcmp(propbuf, "1")) {
-            WriteFdFmt(fd, "verity not enabled - ENG build\n");
-            goto errout;
-        }
-
-        property_get("ro.debuggable", propbuf, "0");
-        if (strcmp(propbuf, "1")) {
-            WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
-            goto errout;
-        }
-
-        property_get("ro.hardware", propbuf, "");
-        snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s",
-                 propbuf);
-
-        fstab = fs_mgr_read_fstab(fstab_filename);
-        if (!fstab) {
-            WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename);
-            goto errout;
-        }
-
-        /* Loop through entries looking for ones that vold manages */
-        for (i = 0; i < fstab->num_entries; i++) {
-            if(fs_mgr_is_verified(&fstab->recs[i])) {
-                if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
-                                              fstab->recs[i].mount_point,
-                                              enable)) {
-                    any_changed = true;
-                }
-           }
-        }
-
-        if (any_changed) {
-            WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
-        }
-    } else {
+    if (!kAllowDisableVerity) {
         WriteFdFmt(fd, "%s-verity only works for userdebug builds\n",
                    enable ? "enable" : "disable");
     }
 
-errout:
-    adb_close(fd);
+    if (!android::base::GetBoolProperty("ro.secure", false)) {
+        WriteFdFmt(fd, "verity not enabled - ENG build\n");
+        return;
+    }
+
+    if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+        WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
+        return;
+    }
+
+    std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
+
+    fstab = fs_mgr_read_fstab(fstab_filename.c_str());
+    if (!fstab) {
+        WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename.c_str());
+        return;
+    }
+
+    // Loop through entries looking for ones that vold manages.
+    bool any_changed = false;
+    for (int i = 0; i < fstab->num_entries; i++) {
+        if (fs_mgr_is_verified(&fstab->recs[i])) {
+            if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+                                          fstab->recs[i].mount_point,
+                                          enable)) {
+                any_changed = true;
+            }
+        }
+    }
+
+    if (any_changed) {
+        WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
+    }
 }
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index abba745..503e018 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -31,7 +31,7 @@
 #include <vector>
 
 #if !ADB_HOST
-#include "cutils/properties.h"
+#include <android-base/properties.h>
 #endif
 
 #include "adb.h"
@@ -416,12 +416,12 @@
     D("LS(%d): bound to '%s' via %d", s->id, name, fd);
 
 #if !ADB_HOST
-    char debug[PROPERTY_VALUE_MAX];
+    bool debuggable = false;
     if (!strncmp(name, "root:", 5)) {
-        property_get("ro.debuggable", debug, "");
+        debuggable = android::base::GetBoolProperty("ro.debuggable", false);
     }
 
-    if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0) ||
+    if ((!strncmp(name, "root:", 5) && getuid() != 0 && debuggable) ||
         (!strncmp(name, "unroot:", 7) && getuid() == 0) ||
         !strncmp(name, "usb:", 4) ||
         !strncmp(name, "tcpip:", 6)) {
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index f895943..a94b41e 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -33,7 +33,7 @@
 #include <cutils/sockets.h>
 
 #if !ADB_HOST
-#include "cutils/properties.h"
+#include <android-base/properties.h>
 #endif
 
 #include "adb.h"
@@ -356,15 +356,13 @@
     func = client_socket_thread;
     debug_name = "client";
 #else
-    /* For the adbd daemon in the system image we need to distinguish
-     * between the device, and the emulator. */
-    char is_qemu[PROPERTY_VALUE_MAX];
-    property_get("ro.kernel.qemu", is_qemu, "");
-    if (!strcmp(is_qemu, "1")) {
-        /* Running inside the emulator: use QEMUD pipe as the transport. */
+    // For the adbd daemon in the system image we need to distinguish
+    // between the device, and the emulator.
+    if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
+        // Running inside the emulator: use QEMUD pipe as the transport.
         func = qemu_socket_thread;
     } else {
-        /* Running inside the device: use TCP socket as the transport. */
+        // Running inside the device: use TCP socket as the transport.
         func = server_socket_thread;
     }
     debug_name = "server";
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 1b05439..6de10f5 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -18,7 +18,6 @@
 
 #include "sysdeps.h"
 
-#include <cutils/properties.h>
 #include <dirent.h>
 #include <errno.h>
 #include <linux/usb/ch9.h>
@@ -36,6 +35,7 @@
 #include <mutex>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 
 #include "adb.h"
 #include "transport.h"
@@ -478,7 +478,7 @@
             }
             adb_sleep_ms(1000);
         }
-        property_set("sys.usb.ffs.ready", "1");
+        android::base::SetProperty("sys.usb.ffs.ready", "1");
 
         D("[ usb_thread - registering device ]");
         register_usb_transport(usb, 0, 0, 1);
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index ddde454..adcbb3e 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -177,6 +177,7 @@
         kr = (*iface)->GetDevice(iface, &usbDevice);
         if (kIOReturnSuccess != kr || !usbDevice) {
             LOG(ERROR) << "Couldn't grab device from interface (" << std::hex << kr << ")";
+            (*iface)->Release(iface);
             continue;
         }
 
@@ -191,6 +192,7 @@
         (void)IOObjectRelease(usbDevice);
         if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
             LOG(ERROR) << "Unable to create a device plug-in (" << std::hex << kr << ")";
+            (*iface)->Release(iface);
             continue;
         }
 
@@ -200,6 +202,7 @@
         (*plugInInterface)->Release(plugInInterface);
         if (result || !dev) {
             LOG(ERROR) << "Couldn't create a device interface (" << std::hex << result << ")";
+            (*iface)->Release(iface);
             continue;
         }
 
@@ -211,6 +214,8 @@
         if (kr == KERN_SUCCESS) {
             devpath = android::base::StringPrintf("usb:%" PRIu32 "X", locationId);
             if (IsKnownDevice(devpath)) {
+                (*dev)->Release(dev);
+                (*iface)->Release(iface);
                 continue;
             }
         }
diff --git a/base/Android.bp b/base/Android.bp
index e260412..88d8ad1 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -39,7 +39,10 @@
     shared_libs: ["liblog"],
     target: {
         android: {
-            srcs: ["errors_unix.cpp"],
+            srcs: [
+                "errors_unix.cpp",
+                "properties.cpp",
+            ],
             cppflags: ["-Wexit-time-destructors"],
         },
         darwin: {
@@ -78,6 +81,9 @@
         "test_main.cpp",
     ],
     target: {
+        android: {
+            srcs: ["properties_test.cpp"],
+        },
         windows: {
             srcs: ["utf8_test.cpp"],
             enabled: true,
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h
index 1285f53..50677a3 100644
--- a/base/include/android-base/logging.h
+++ b/base/include/android-base/logging.h
@@ -120,10 +120,22 @@
   DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
 };
 
+// A helper macro that produces an expression that accepts both a qualified name and an
+// unqualified name for a LogSeverity, and returns a LogSeverity value.
+// Note: DO NOT USE DIRECTLY. This is an implementation detail.
+#define SEVERITY_LAMBDA(severity) ([&]() {    \
+  using ::android::base::VERBOSE;             \
+  using ::android::base::DEBUG;               \
+  using ::android::base::INFO;                \
+  using ::android::base::WARNING;             \
+  using ::android::base::ERROR;               \
+  using ::android::base::FATAL_WITHOUT_ABORT; \
+  using ::android::base::FATAL;               \
+  return (severity); }())
+
 // Defines whether the given severity will be logged or silently swallowed.
-#define WOULD_LOG(severity) WOULD_LOG_SEVERITY(::android::base::severity)
-#define WOULD_LOG_SEVERITY(severity) \
-  UNLIKELY((severity) >= ::android::base::GetMinimumLogSeverity())
+#define WOULD_LOG(severity) \
+  UNLIKELY((SEVERITY_LAMBDA(severity)) >= ::android::base::GetMinimumLogSeverity())
 
 // Get an ostream that can be used for logging at the given severity and to the default
 // destination.
@@ -132,23 +144,20 @@
 // 1) This will not check whether the severity is high enough. One should use WOULD_LOG to filter
 //    usage manually.
 // 2) This does not save and restore errno.
-#define LOG_STREAM(severity) LOG_STREAM_S(::android::base::severity)
-#define LOG_STREAM_S(severity) LOG_STREAM_TO_S(DEFAULT, severity)
+#define LOG_STREAM(severity) LOG_STREAM_TO(DEFAULT, severity)
 
 // Get an ostream that can be used for logging at the given severity and to the
 // given destination. The same notes as for LOG_STREAM apply.
-#define LOG_STREAM_TO(dest, severity) LOG_STREAM_TO_S(dest, ::android::base::severity)
-#define LOG_STREAM_TO_S(dest, severity)                                 \
+#define LOG_STREAM_TO(dest, severity)                                   \
   ::android::base::LogMessage(__FILE__, __LINE__,                       \
                               ::android::base::dest,                    \
-                              severity, -1).stream()
+                              SEVERITY_LAMBDA(severity), -1).stream()
 
 // Logs a message to logcat on Android otherwise to stderr. If the severity is
 // FATAL it also causes an abort. For example:
 //
 //     LOG(FATAL) << "We didn't expect to reach here";
-#define LOG(severity) LOG_S(::android::base::severity)
-#define LOG_S(severity) LOG_TO_S(DEFAULT, severity)
+#define LOG(severity) LOG_TO(DEFAULT, severity)
 
 // Logs a message to logcat with the specified log ID on Android otherwise to
 // stderr. If the severity is FATAL it also causes an abort.
@@ -156,25 +165,23 @@
 // else statement after LOG() macro, it won't bind to the if statement in the macro.
 // do-while(0) statement doesn't work here. Because we need to support << operator
 // following the macro, like "LOG(DEBUG) << xxx;".
-#define LOG_TO(dest, severity) LOG_TO_S(dest, ::android::base::severity)
-#define LOG_TO_S(dest, severity)           \
-  WOULD_LOG_SEVERITY(severity) &&          \
+
+#define LOG_TO(dest, severity) \
+  WOULD_LOG(severity) &&                   \
     ::android::base::ErrnoRestorer() &&    \
-      LOG_STREAM_TO_S(dest, severity)      \
+      LOG_STREAM_TO(dest, severity)
 
 // A variant of LOG that also logs the current errno value. To be used when
 // library calls fail.
-#define PLOG(severity) PLOG_S(::android::base::severity)
-#define PLOG_S(severity) PLOG_TO_S(DEFAULT, severity)
+#define PLOG(severity) PLOG_TO(DEFAULT, severity)
 
 // Behaves like PLOG, but logs to the specified log ID.
-#define PLOG_TO(dest, severity) PLOG_TO_S(dest, ::android::base::severity)
-#define PLOG_TO_S(dest, severity)                       \
-  WOULD_LOG_SEVERITY(severity) &&                       \
+#define PLOG_TO(dest, severity)                         \
+  WOULD_LOG(SEVERITY_LAMBDA(severity)) &&               \
     ::android::base::ErrnoRestorer() &&                 \
       ::android::base::LogMessage(__FILE__, __LINE__,   \
           ::android::base::dest,                        \
-          severity, errno).stream()
+          SEVERITY_LAMBDA(severity), errno).stream()
 
 // Marker that code is yet to be implemented.
 #define UNIMPLEMENTED(level) \
diff --git a/base/include/android-base/properties.h b/base/include/android-base/properties.h
new file mode 100644
index 0000000..95d1b6a
--- /dev/null
+++ b/base/include/android-base/properties.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BASE_PROPERTIES_H
+#define ANDROID_BASE_PROPERTIES_H
+
+#include <sys/cdefs.h>
+
+#if !defined(__BIONIC__)
+#error Only bionic supports system properties.
+#endif
+
+#include <limits>
+#include <string>
+
+namespace android {
+namespace base {
+
+// Returns the current value of the system property `key`,
+// or `default_value` if the property is empty or doesn't exist.
+std::string GetProperty(const std::string& key, const std::string& default_value);
+
+// Returns true if the system property `key` has the value "1", "y", "yes", "on", or "true",
+// false for "0", "n", "no", "off", or "false", or `default_value` otherwise.
+bool GetBoolProperty(const std::string& key, bool default_value);
+
+// Returns the signed integer corresponding to the system property `key`.
+// If the property is empty, doesn't exist, doesn't have an integer value, or is outside
+// the optional bounds, returns `default_value`.
+template <typename T> T GetIntProperty(const std::string& key,
+                                       T default_value,
+                                       T min = std::numeric_limits<T>::min(),
+                                       T max = std::numeric_limits<T>::max());
+
+// Returns the unsigned integer corresponding to the system property `key`.
+// If the property is empty, doesn't exist, doesn't have an integer value, or is outside
+// the optional bound, returns `default_value`.
+template <typename T> T GetUintProperty(const std::string& key,
+                                        T default_value,
+                                        T max = std::numeric_limits<T>::max());
+
+// Sets the system property `key` to `value`.
+// Note that system property setting is inherently asynchronous so a return value of `true`
+// isn't particularly meaningful, and immediately reading back the value won't necessarily
+// tell you whether or not your call succeeded. A `false` return value definitely means failure.
+bool SetProperty(const std::string& key, const std::string& value);
+
+} // namespace base
+} // namespace android
+
+#endif  // ANDROID_BASE_MEMORY_H
diff --git a/base/logging.cpp b/base/logging.cpp
index 77a0a43..eaed9ab 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -390,6 +390,11 @@
 }
 
 LogMessage::~LogMessage() {
+  // Check severity again. This is duplicate work wrt/ LOG macros, but not LOG_STREAM.
+  if (!WOULD_LOG(data_->GetSeverity())) {
+    return;
+  }
+
   // Finish constructing the message.
   if (data_->GetError() != -1) {
     data_->GetBuffer() << ": " << strerror(data_->GetError());
diff --git a/base/logging_test.cpp b/base/logging_test.cpp
index a1ed05b..9fc7736 100644
--- a/base/logging_test.cpp
+++ b/base/logging_test.cpp
@@ -142,22 +142,35 @@
   // we don't get more bit-rot).
 }
 
-#define CHECK_WOULD_LOG_DISABLED(severity)                                             \
-  static_assert(android::base::severity < android::base::FATAL, "Bad input");          \
-  for (size_t i = static_cast<size_t>(android::base::severity) + 1;                    \
-       i <= static_cast<size_t>(android::base::FATAL);                                 \
-       ++i) {                                                                          \
-    android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
-    EXPECT_FALSE(WOULD_LOG(severity)) << i;                                            \
-  }
 
-#define CHECK_WOULD_LOG_ENABLED(severity)                                              \
-  for (size_t i = static_cast<size_t>(android::base::VERBOSE);                         \
-       i <= static_cast<size_t>(android::base::severity);                              \
-       ++i) {                                                                          \
-    android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
-    EXPECT_TRUE(WOULD_LOG(severity)) << i;                                             \
-  }
+#define CHECK_WOULD_LOG_DISABLED(severity)                                               \
+  static_assert(android::base::severity < android::base::FATAL, "Bad input");            \
+  for (size_t i = static_cast<size_t>(android::base::severity) + 1;                      \
+       i <= static_cast<size_t>(android::base::FATAL);                                   \
+       ++i) {                                                                            \
+    {                                                                                    \
+      android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
+      EXPECT_FALSE(WOULD_LOG(severity)) << i;                                            \
+    }                                                                                    \
+    {                                                                                    \
+      android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
+      EXPECT_FALSE(WOULD_LOG(::android::base::severity)) << i;                           \
+    }                                                                                    \
+  }                                                                                      \
+
+#define CHECK_WOULD_LOG_ENABLED(severity)                                                \
+  for (size_t i = static_cast<size_t>(android::base::VERBOSE);                           \
+       i <= static_cast<size_t>(android::base::severity);                                \
+       ++i) {                                                                            \
+    {                                                                                    \
+      android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
+      EXPECT_TRUE(WOULD_LOG(severity)) << i;                                             \
+    }                                                                                    \
+    {                                                                                    \
+      android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
+      EXPECT_TRUE(WOULD_LOG(::android::base::severity)) << i;                            \
+    }                                                                                    \
+  }                                                                                      \
 
 TEST(logging, WOULD_LOG_FATAL) {
   CHECK_WOULD_LOG_ENABLED(FATAL);
@@ -215,78 +228,6 @@
 #undef CHECK_WOULD_LOG_ENABLED
 
 
-#define CHECK_WOULD_LOG_SEVERITY_DISABLED(severity)                                    \
-  static_assert(android::base::severity < android::base::FATAL, "Bad input");          \
-  for (size_t i = static_cast<size_t>(android::base::severity) + 1;                    \
-       i <= static_cast<size_t>(android::base::FATAL);                                 \
-       ++i) {                                                                          \
-    android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
-    EXPECT_FALSE(WOULD_LOG_SEVERITY(::android::base::severity)) << i;                  \
-  }
-
-#define CHECK_WOULD_LOG_SEVERITY_ENABLED(severity)                                     \
-  for (size_t i = static_cast<size_t>(android::base::VERBOSE);                         \
-       i <= static_cast<size_t>(android::base::severity);                              \
-       ++i) {                                                                          \
-    android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
-    EXPECT_TRUE(WOULD_LOG_SEVERITY(::android::base::severity)) << i;                   \
-  }
-
-TEST(logging,WOULD_LOG_SEVERITY_FATAL) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(FATAL);
-}
-
-TEST(logging,WOULD_LOG_SEVERITY_FATAL_WITHOUT_ABORT_disabled) {
-  CHECK_WOULD_LOG_SEVERITY_DISABLED(FATAL_WITHOUT_ABORT);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_FATAL_WITHOUT_ABORT_enabled) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(FATAL_WITHOUT_ABORT);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_ERROR_disabled) {
-  CHECK_WOULD_LOG_SEVERITY_DISABLED(ERROR);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_ERROR_enabled) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(ERROR);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_WARNING_disabled) {
-  CHECK_WOULD_LOG_SEVERITY_DISABLED(WARNING);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_WARNING_enabled) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(WARNING);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_INFO_disabled) {
-  CHECK_WOULD_LOG_SEVERITY_DISABLED(INFO);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_INFO_enabled) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(INFO);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_DEBUG_disabled) {
-  CHECK_WOULD_LOG_SEVERITY_DISABLED(DEBUG);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_DEBUG_enabled) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(DEBUG);
-}
-
-TEST(logging, WOULD_LOG_SEVERITYVERBOSE_disabled) {
-  CHECK_WOULD_LOG_SEVERITY_DISABLED(VERBOSE);
-}
-
-TEST(logging, WOULD_LOG_SEVERITY_VERBOSE_enabled) {
-  CHECK_WOULD_LOG_SEVERITY_ENABLED(VERBOSE);
-}
-
-#undef CHECK_WOULD_LOG_SEVERITY_DISABLED
-#undef CHECK_WOULD_LOG_SEVERITY_ENABLED
-
 static std::string make_log_pattern(android::base::LogSeverity severity,
                                     const char* message) {
   static const char log_characters[] = "VDIWEFF";
@@ -317,85 +258,118 @@
 #endif
 }
 
-#define CHECK_LOG_STREAM(severity) \
-  android::base::ScopedLogSeverity sls2(android::base::severity); \
-  CapturedStderr cap2; \
-  LOG_STREAM(severity) << "foobar"; \
-  CheckMessage(cap2, android::base::severity, "foobar"); \
 
-TEST(logging, LOG_STREAM_FATAL_WITHOUT_ABORT) {
-  CHECK_LOG_STREAM(FATAL_WITHOUT_ABORT);
+#define CHECK_LOG_STREAM_DISABLED(severity) \
+  { \
+    android::base::ScopedLogSeverity sls1(android::base::FATAL); \
+    CapturedStderr cap1; \
+    LOG_STREAM(severity) << "foo bar"; \
+    ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  } \
+  { \
+    android::base::ScopedLogSeverity sls1(android::base::FATAL); \
+    CapturedStderr cap1; \
+    LOG_STREAM(::android::base::severity) << "foo bar"; \
+    ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  } \
+
+#define CHECK_LOG_STREAM_ENABLED(severity) \
+  { \
+    android::base::ScopedLogSeverity sls2(android::base::severity); \
+    CapturedStderr cap2; \
+    LOG_STREAM(severity) << "foobar"; \
+    CheckMessage(cap2, android::base::severity, "foobar"); \
+  } \
+  { \
+    android::base::ScopedLogSeverity sls2(android::base::severity); \
+    CapturedStderr cap2; \
+    LOG_STREAM(::android::base::severity) << "foobar"; \
+    CheckMessage(cap2, android::base::severity, "foobar"); \
+  } \
+
+TEST(logging, LOG_STREAM_FATAL_WITHOUT_ABORT_disabled) {
+  CHECK_LOG_STREAM_DISABLED(FATAL_WITHOUT_ABORT);
 }
 
-TEST(logging, LOG_STREAM_ERROR) {
-  CHECK_LOG_STREAM(ERROR);
+TEST(logging, LOG_STREAM_FATAL_WITHOUT_ABORT_enabled) {
+  CHECK_LOG_STREAM_ENABLED(FATAL_WITHOUT_ABORT);
 }
 
-TEST(logging, LOG_STREAM_WARNING) {
-  CHECK_LOG_STREAM(WARNING);
+TEST(logging, LOG_STREAM_ERROR_disabled) {
+  CHECK_LOG_STREAM_DISABLED(ERROR);
 }
 
-TEST(logging, LOG_STREAM_INFO) {
-  CHECK_LOG_STREAM(INFO);
+TEST(logging, LOG_STREAM_ERROR_enabled) {
+  CHECK_LOG_STREAM_ENABLED(ERROR);
 }
 
-TEST(logging, LOG_STREAM_DEBUG) {
-  CHECK_LOG_STREAM(DEBUG);
+TEST(logging, LOG_STREAM_WARNING_disabled) {
+  CHECK_LOG_STREAM_DISABLED(WARNING);
 }
 
-TEST(logging, LOG_STREAM_VERBOSE) {
-  CHECK_LOG_STREAM(VERBOSE);
+TEST(logging, LOG_STREAM_WARNING_enabled) {
+  CHECK_LOG_STREAM_ENABLED(WARNING);
 }
 
-#undef CHECK_LOG_STREAM
-
-#define CHECK_LOG_STREAM_S(severity) \
-  android::base::ScopedLogSeverity sls2(android::base::severity); \
-  CapturedStderr cap2; \
-  LOG_STREAM_S(android::base::severity) << "foobar"; \
-  CheckMessage(cap2, android::base::severity, "foobar"); \
-
-TEST(logging, LOG_STREAM_S_FATAL_WITHOUT_ABORT) {
-  CHECK_LOG_STREAM_S(FATAL_WITHOUT_ABORT);
+TEST(logging, LOG_STREAM_INFO_disabled) {
+  CHECK_LOG_STREAM_DISABLED(INFO);
 }
 
-TEST(logging, LOG_STREAM_S_ERROR) {
-  CHECK_LOG_STREAM_S(ERROR);
+TEST(logging, LOG_STREAM_INFO_enabled) {
+  CHECK_LOG_STREAM_ENABLED(INFO);
 }
 
-TEST(logging, LOG_STREAM_S_WARNING) {
-  CHECK_LOG_STREAM_S(WARNING);
+TEST(logging, LOG_STREAM_DEBUG_disabled) {
+  CHECK_LOG_STREAM_DISABLED(DEBUG);
 }
 
-TEST(logging, LOG_STREAM_S_INFO) {
-  CHECK_LOG_STREAM_S(INFO);
+TEST(logging, LOG_STREAM_DEBUG_enabled) {
+  CHECK_LOG_STREAM_ENABLED(DEBUG);
 }
 
-TEST(logging, LOG_STREAM_S_DEBUG) {
-  CHECK_LOG_STREAM_S(DEBUG);
+TEST(logging, LOG_STREAM_VERBOSE_disabled) {
+  CHECK_LOG_STREAM_DISABLED(VERBOSE);
 }
 
-TEST(logging, LOG_STREAM_S_VERBOSE) {
-  CHECK_LOG_STREAM_S(VERBOSE);
+TEST(logging, LOG_STREAM_VERBOSE_enabled) {
+  CHECK_LOG_STREAM_ENABLED(VERBOSE);
 }
 
-#undef CHECK_LOG_STREAM_S
+#undef CHECK_LOG_STREAM_DISABLED
+#undef CHECK_LOG_STREAM_ENABLED
 
 
 #define CHECK_LOG_DISABLED(severity) \
-  android::base::ScopedLogSeverity sls1(android::base::FATAL); \
-  CapturedStderr cap1; \
-  LOG(severity) << "foo bar"; \
-  ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  { \
+    android::base::ScopedLogSeverity sls1(android::base::FATAL); \
+    CapturedStderr cap1; \
+    LOG(severity) << "foo bar"; \
+    ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  } \
+  { \
+    android::base::ScopedLogSeverity sls1(android::base::FATAL); \
+    CapturedStderr cap1; \
+    LOG(::android::base::severity) << "foo bar"; \
+    ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  } \
 
 #define CHECK_LOG_ENABLED(severity) \
-  android::base::ScopedLogSeverity sls2(android::base::severity); \
-  CapturedStderr cap2; \
-  LOG(severity) << "foobar"; \
-  CheckMessage(cap2, android::base::severity, "foobar"); \
+  { \
+    android::base::ScopedLogSeverity sls2(android::base::severity); \
+    CapturedStderr cap2; \
+    LOG(severity) << "foobar"; \
+    CheckMessage(cap2, android::base::severity, "foobar"); \
+  } \
+  { \
+    android::base::ScopedLogSeverity sls2(android::base::severity); \
+    CapturedStderr cap2; \
+    LOG(::android::base::severity) << "foobar"; \
+    CheckMessage(cap2, android::base::severity, "foobar"); \
+  } \
 
 TEST(logging, LOG_FATAL) {
   ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << "foobar";}, "foobar");
+  ASSERT_DEATH({SuppressAbortUI(); LOG(::android::base::FATAL) << "foobar";}, "foobar");
 }
 
 TEST(logging, LOG_FATAL_WITHOUT_ABORT_disabled) {
@@ -449,80 +423,14 @@
 #undef CHECK_LOG_DISABLED
 #undef CHECK_LOG_ENABLED
 
-#define CHECK_LOG_S_DISABLED(severity) \
-  android::base::ScopedLogSeverity sls1(android::base::FATAL); \
-  CapturedStderr cap1; \
-  LOG_S(::android::base::severity) << "foo bar"; \
-  ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
 
-#define CHECK_LOG_S_ENABLED(severity) \
-  android::base::ScopedLogSeverity sls2(android::base::severity); \
-  CapturedStderr cap2; \
-  LOG_S(::android::base::severity) << "foobar"; \
-  CheckMessage(cap2, android::base::severity, "foobar"); \
-
-TEST(logging, LOG_S_FATAL) {
-  ASSERT_DEATH({SuppressAbortUI(); LOG_S(::android::base::FATAL) << "foobar";}, "foobar");
-}
-
-TEST(logging, LOG_S_FATAL_WITHOUT_ABORT_disabled) {
-  CHECK_LOG_S_DISABLED(FATAL_WITHOUT_ABORT);
-}
-
-TEST(logging, LOG_S_FATAL_WITHOUT_ABORT_enabled) {
-  CHECK_LOG_S_ENABLED(FATAL_WITHOUT_ABORT);
-}
-
-TEST(logging, LOG_S_ERROR_disabled) {
-  CHECK_LOG_S_DISABLED(ERROR);
-}
-
-TEST(logging, LOG_S_ERROR_enabled) {
-  CHECK_LOG_S_ENABLED(ERROR);
-}
-
-TEST(logging, LOG_S_WARNING_disabled) {
-  CHECK_LOG_S_DISABLED(WARNING);
-}
-
-TEST(logging, LOG_S_WARNING_enabled) {
-  CHECK_LOG_S_ENABLED(WARNING);
-}
-
-TEST(logging, LOG_S_INFO_disabled) {
-  CHECK_LOG_S_DISABLED(INFO);
-}
-
-TEST(logging, LOG_S_INFO_enabled) {
-  CHECK_LOG_S_ENABLED(INFO);
-}
-
-TEST(logging, LOG_S_DEBUG_disabled) {
-  CHECK_LOG_S_DISABLED(DEBUG);
-}
-
-TEST(logging, LOG_S_DEBUG_enabled) {
-  CHECK_LOG_S_ENABLED(DEBUG);
-}
-
-TEST(logging, LOG_S_VERBOSE_disabled) {
-  CHECK_LOG_S_DISABLED(VERBOSE);
-}
-
-TEST(logging, LOG_S_VERBOSE_enabled) {
-  CHECK_LOG_S_ENABLED(VERBOSE);
-}
-
-#undef CHECK_LOG_S_DISABLED
-#undef CHECK_LOG_S_ENABLED
-
-TEST(logging, LOG_S_complex_param) {
-#define CHECK_LOG_S_COMBINATION(use_scoped_log_severity_info, use_logging_severity_info)           \
+TEST(logging, LOG_complex_param) {
+#define CHECK_LOG_COMBINATION(use_scoped_log_severity_info, use_logging_severity_info)             \
   {                                                                                                \
     android::base::ScopedLogSeverity sls(                                                          \
         (use_scoped_log_severity_info) ? ::android::base::INFO : ::android::base::WARNING);        \
     CapturedStderr cap;                                                                            \
-    LOG_S((use_logging_severity_info) ? ::android::base::INFO : ::android::base::WARNING)          \
+    LOG((use_logging_severity_info) ? ::android::base::INFO : ::android::base::WARNING)            \
         << "foobar";                                                                               \
     if ((use_scoped_log_severity_info) || !(use_logging_severity_info)) {                          \
       CheckMessage(cap,                                                                            \
@@ -533,12 +441,12 @@
     }                                                                                              \
   }
 
-  CHECK_LOG_S_COMBINATION(false,false);
-  CHECK_LOG_S_COMBINATION(false,true);
-  CHECK_LOG_S_COMBINATION(true,false);
-  CHECK_LOG_S_COMBINATION(true,true);
+  CHECK_LOG_COMBINATION(false,false);
+  CHECK_LOG_COMBINATION(false,true);
+  CHECK_LOG_COMBINATION(true,false);
+  CHECK_LOG_COMBINATION(true,true);
 
-#undef CHECK_LOG_S_COMBINATION
+#undef CHECK_LOG_COMBINATION
 }
 
 
@@ -551,15 +459,6 @@
   CheckMessage(cap, android::base::INFO, "67890");
 }
 
-TEST(logging, LOG_S_does_not_clobber_errno) {
-  CapturedStderr cap;
-  errno = 12345;
-  LOG_S(::android::base::INFO) << (errno = 67890);
-  EXPECT_EQ(12345, errno) << "errno was not restored";
-
-  CheckMessage(cap, android::base::INFO, "67890");
-}
-
 TEST(logging, PLOG_does_not_clobber_errno) {
   CapturedStderr cap;
   errno = 12345;
@@ -569,16 +468,6 @@
   CheckMessage(cap, android::base::INFO, "67890");
 }
 
-TEST(logging, PLOG_S_does_not_clobber_errno) {
-  CapturedStderr cap;
-  errno = 12345;
-  PLOG_S(::android::base::INFO) << (errno = 67890);
-  EXPECT_EQ(12345, errno) << "errno was not restored";
-
-  CheckMessage(cap, android::base::INFO, "67890");
-}
-
-
 TEST(logging, LOG_does_not_have_dangling_if) {
   CapturedStderr cap; // So the logging below has no side-effects.
 
@@ -600,39 +489,41 @@
     flag = true;
 
   EXPECT_FALSE(flag) << "LOG macro probably has a dangling if with no else";
-
-  flag = false;
-  if (true)
-    LOG_S(::android::base::INFO) << "foobar";
-  else
-    flag = true;
-
-  EXPECT_FALSE(flag) << "LOG_S macro probably has a dangling if with no else";
-
-  flag = false;
-  if (true)
-    LOG_S(::android::base::VERBOSE) << "foobar";
-  else
-    flag = true;
-
-  EXPECT_FALSE(flag) << "LOG_S macro probably has a dangling if with no else";
 }
 
 #define CHECK_PLOG_DISABLED(severity) \
-  android::base::ScopedLogSeverity sls1(android::base::FATAL); \
-  CapturedStderr cap1; \
-  PLOG(severity) << "foo bar"; \
-  ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  { \
+    android::base::ScopedLogSeverity sls1(android::base::FATAL); \
+    CapturedStderr cap1; \
+    PLOG(severity) << "foo bar"; \
+    ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  } \
+  { \
+    android::base::ScopedLogSeverity sls1(android::base::FATAL); \
+    CapturedStderr cap1; \
+    PLOG(severity) << "foo bar"; \
+    ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
+  } \
 
 #define CHECK_PLOG_ENABLED(severity) \
-  android::base::ScopedLogSeverity sls2(android::base::severity); \
-  CapturedStderr cap2; \
-  errno = ENOENT; \
-  PLOG(severity) << "foobar"; \
-  CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
+  { \
+    android::base::ScopedLogSeverity sls2(android::base::severity); \
+    CapturedStderr cap2; \
+    errno = ENOENT; \
+    PLOG(severity) << "foobar"; \
+    CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
+  } \
+  { \
+    android::base::ScopedLogSeverity sls2(android::base::severity); \
+    CapturedStderr cap2; \
+    errno = ENOENT; \
+    PLOG(severity) << "foobar"; \
+    CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
+  } \
 
 TEST(logging, PLOG_FATAL) {
   ASSERT_DEATH({SuppressAbortUI(); PLOG(FATAL) << "foobar";}, "foobar");
+  ASSERT_DEATH({SuppressAbortUI(); PLOG(::android::base::FATAL) << "foobar";}, "foobar");
 }
 
 TEST(logging, PLOG_FATAL_WITHOUT_ABORT_disabled) {
@@ -687,75 +578,6 @@
 #undef CHECK_PLOG_ENABLED
 
 
-#define CHECK_PLOG_S_DISABLED(severity) \
-  android::base::ScopedLogSeverity sls1(android::base::FATAL); \
-  CapturedStderr cap1; \
-  PLOG_S(android::base::severity) << "foo bar"; \
-  ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
-
-#define CHECK_PLOG_S_ENABLED(severity) \
-  android::base::ScopedLogSeverity sls2(android::base::severity); \
-  CapturedStderr cap2; \
-  errno = ENOENT; \
-  PLOG_S(android::base::severity) << "foobar"; \
-  CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
-
-TEST(logging, PLOG_S_FATAL) {
-  ASSERT_DEATH({SuppressAbortUI(); PLOG_S(::android::base::FATAL) << "foobar";}, "foobar");
-}
-
-TEST(logging, PLOG_S_FATAL_WITHOUT_ABORT_disabled) {
-  CHECK_PLOG_S_DISABLED(FATAL_WITHOUT_ABORT);
-}
-
-TEST(logging, PLOG_S_FATAL_WITHOUT_ABORT_enabled) {
-  CHECK_PLOG_S_ENABLED(FATAL_WITHOUT_ABORT);
-}
-
-TEST(logging, PLOG_S_ERROR_disabled) {
-  CHECK_PLOG_S_DISABLED(ERROR);
-}
-
-TEST(logging, PLOG_S_ERROR_enabled) {
-  CHECK_PLOG_S_ENABLED(ERROR);
-}
-
-TEST(logging, PLOG_S_WARNING_disabled) {
-  CHECK_PLOG_S_DISABLED(WARNING);
-}
-
-TEST(logging, PLOG_S_WARNING_enabled) {
-  CHECK_PLOG_S_ENABLED(WARNING);
-}
-
-TEST(logging, PLOG_S_INFO_disabled) {
-  CHECK_PLOG_S_DISABLED(INFO);
-}
-
-TEST(logging, PLOG_S_INFO_enabled) {
-  CHECK_PLOG_S_ENABLED(INFO);
-}
-
-TEST(logging, PLOG_S_DEBUG_disabled) {
-  CHECK_PLOG_S_DISABLED(DEBUG);
-}
-
-TEST(logging, PLOG_S_DEBUG_enabled) {
-  CHECK_PLOG_S_ENABLED(DEBUG);
-}
-
-TEST(logging, PLOG_S_VERBOSE_disabled) {
-  CHECK_PLOG_S_DISABLED(VERBOSE);
-}
-
-TEST(logging, PLOG_S_VERBOSE_enabled) {
-  CHECK_PLOG_S_ENABLED(VERBOSE);
-}
-
-#undef CHECK_PLOG_S_DISABLED
-#undef CHECK_PLOG_S_ENABLED
-
-
 TEST(logging, UNIMPLEMENTED) {
   std::string expected = android::base::StringPrintf("%s unimplemented ", __PRETTY_FUNCTION__);
 
diff --git a/base/properties.cpp b/base/properties.cpp
new file mode 100644
index 0000000..fab3005
--- /dev/null
+++ b/base/properties.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/properties.h"
+
+#include <sys/system_properties.h>
+
+#include <string>
+
+#include <android-base/parseint.h>
+
+namespace android {
+namespace base {
+
+std::string GetProperty(const std::string& key, const std::string& default_value) {
+  const prop_info* pi = __system_property_find(key.c_str());
+  if (pi == nullptr) return default_value;
+
+  char buf[PROP_VALUE_MAX];
+  if (__system_property_read(pi, nullptr, buf) > 0) return buf;
+
+  // If the property exists but is empty, also return the default value.
+  // Since we can't remove system properties, "empty" is traditionally
+  // the same as "missing" (this was true for cutils' property_get).
+  return default_value;
+}
+
+bool GetBoolProperty(const std::string& key, bool default_value) {
+  std::string value = GetProperty(key, "");
+  if (value == "1" || value == "y" || value == "yes" || value == "on" || value == "true") {
+    return true;
+  } else if (value == "0" || value == "n" || value == "no" || value == "off" || value == "false") {
+    return false;
+  }
+  return default_value;
+}
+
+template <typename T>
+T GetIntProperty(const std::string& key, T default_value, T min, T max) {
+  T result;
+  std::string value = GetProperty(key, "");
+  if (!value.empty() && android::base::ParseInt(value.c_str(), &result, min, max)) return result;
+  return default_value;
+}
+
+template <typename T>
+T GetUintProperty(const std::string& key, T default_value, T max) {
+  T result;
+  std::string value = GetProperty(key, "");
+  if (!value.empty() && android::base::ParseUint(value.c_str(), &result, max)) return result;
+  return default_value;
+}
+
+template int8_t GetIntProperty(const std::string&, int8_t, int8_t, int8_t);
+template int16_t GetIntProperty(const std::string&, int16_t, int16_t, int16_t);
+template int32_t GetIntProperty(const std::string&, int32_t, int32_t, int32_t);
+template int64_t GetIntProperty(const std::string&, int64_t, int64_t, int64_t);
+
+template uint8_t GetUintProperty(const std::string&, uint8_t, uint8_t);
+template uint16_t GetUintProperty(const std::string&, uint16_t, uint16_t);
+template uint32_t GetUintProperty(const std::string&, uint32_t, uint32_t);
+template uint64_t GetUintProperty(const std::string&, uint64_t, uint64_t);
+
+bool SetProperty(const std::string& key, const std::string& value) {
+  return (__system_property_set(key.c_str(), value.c_str()) == 0);
+}
+
+}  // namespace base
+}  // namespace android
diff --git a/base/properties_test.cpp b/base/properties_test.cpp
new file mode 100644
index 0000000..da89ec5
--- /dev/null
+++ b/base/properties_test.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/properties.h"
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+TEST(properties, smoke) {
+  android::base::SetProperty("debug.libbase.property_test", "hello");
+
+  std::string s = android::base::GetProperty("debug.libbase.property_test", "");
+  ASSERT_EQ("hello", s);
+
+  android::base::SetProperty("debug.libbase.property_test", "world");
+  s = android::base::GetProperty("debug.libbase.property_test", "");
+  ASSERT_EQ("world", s);
+
+  s = android::base::GetProperty("this.property.does.not.exist", "");
+  ASSERT_EQ("", s);
+
+  s = android::base::GetProperty("this.property.does.not.exist", "default");
+  ASSERT_EQ("default", s);
+}
+
+TEST(properties, empty) {
+  // Because you can't delete a property, people "delete" them by
+  // setting them to the empty string. In that case we'd want to
+  // keep the default value (like cutils' property_get did).
+  android::base::SetProperty("debug.libbase.property_test", "");
+  std::string s = android::base::GetProperty("debug.libbase.property_test", "default");
+  ASSERT_EQ("default", s);
+}
+
+static void CheckGetBoolProperty(bool expected, const std::string& value, bool default_value) {
+  android::base::SetProperty("debug.libbase.property_test", value.c_str());
+  ASSERT_EQ(expected, android::base::GetBoolProperty("debug.libbase.property_test", default_value));
+}
+
+TEST(properties, GetBoolProperty_true) {
+  CheckGetBoolProperty(true, "1", false);
+  CheckGetBoolProperty(true, "y", false);
+  CheckGetBoolProperty(true, "yes", false);
+  CheckGetBoolProperty(true, "on", false);
+  CheckGetBoolProperty(true, "true", false);
+}
+
+TEST(properties, GetBoolProperty_false) {
+  CheckGetBoolProperty(false, "0", true);
+  CheckGetBoolProperty(false, "n", true);
+  CheckGetBoolProperty(false, "no", true);
+  CheckGetBoolProperty(false, "off", true);
+  CheckGetBoolProperty(false, "false", true);
+}
+
+TEST(properties, GetBoolProperty_default) {
+  CheckGetBoolProperty(true, "burp", true);
+  CheckGetBoolProperty(false, "burp", false);
+}
+
+template <typename T> void CheckGetIntProperty() {
+  // Positive and negative.
+  android::base::SetProperty("debug.libbase.property_test", "-12");
+  EXPECT_EQ(T(-12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
+  android::base::SetProperty("debug.libbase.property_test", "12");
+  EXPECT_EQ(T(12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
+
+  // Default value.
+  android::base::SetProperty("debug.libbase.property_test", "");
+  EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
+
+  // Bounds checks.
+  android::base::SetProperty("debug.libbase.property_test", "0");
+  EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
+  android::base::SetProperty("debug.libbase.property_test", "1");
+  EXPECT_EQ(T(1), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
+  android::base::SetProperty("debug.libbase.property_test", "2");
+  EXPECT_EQ(T(2), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
+  android::base::SetProperty("debug.libbase.property_test", "3");
+  EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
+}
+
+template <typename T> void CheckGetUintProperty() {
+  // Positive.
+  android::base::SetProperty("debug.libbase.property_test", "12");
+  EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
+
+  // Default value.
+  android::base::SetProperty("debug.libbase.property_test", "");
+  EXPECT_EQ(T(45), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
+
+  // Bounds checks.
+  android::base::SetProperty("debug.libbase.property_test", "12");
+  EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 33, 22));
+  android::base::SetProperty("debug.libbase.property_test", "12");
+  EXPECT_EQ(T(5), android::base::GetUintProperty<T>("debug.libbase.property_test", 5, 10));
+}
+
+TEST(properties, GetIntProperty_int8_t) { CheckGetIntProperty<int8_t>(); }
+TEST(properties, GetIntProperty_int16_t) { CheckGetIntProperty<int16_t>(); }
+TEST(properties, GetIntProperty_int32_t) { CheckGetIntProperty<int32_t>(); }
+TEST(properties, GetIntProperty_int64_t) { CheckGetIntProperty<int64_t>(); }
+
+TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); }
+TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); }
+TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
+TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 987ba83..d6b631f 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -402,6 +402,9 @@
             "  --skip-secondary                         Will not flash secondary slots when\n"
             "                                           performing a flashall or update. This\n"
             "                                           will preserve data on other slots.\n"
+            "  --skip-reboot                            Will not reboot the device when\n"
+            "                                           performing commands that normally\n"
+            "                                           trigger a reboot.\n"
 #if !defined(_WIN32)
             "  --wipe-and-use-fbe                       On devices which support it,\n"
             "                                           erase userdata and cache, and\n"
@@ -1392,6 +1395,7 @@
     bool wants_wipe = false;
     bool wants_reboot = false;
     bool wants_reboot_bootloader = false;
+    bool skip_reboot = false;
     bool wants_set_active = false;
     bool skip_secondary = false;
     bool erase_first = true;
@@ -1419,6 +1423,7 @@
         {"set_active", optional_argument, 0, 'a'},
         {"set-active", optional_argument, 0, 'a'},
         {"skip-secondary", no_argument, 0, 0},
+        {"skip-reboot", no_argument, 0, 0},
 #if !defined(_WIN32)
         {"wipe-and-use-fbe", no_argument, 0, 0},
 #endif
@@ -1505,6 +1510,8 @@
                 slot_override = std::string(optarg);
             } else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
                 skip_secondary = true;
+            } else if (strcmp("skip-reboot", longopts[longindex].name) == 0 ) {
+                skip_reboot = true;
 #if !defined(_WIN32)
             } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
                 wants_wipe = true;
@@ -1729,7 +1736,7 @@
                 do_update(transport, "update.zip", slot_override, erase_first, skip_secondary || slot_all);
                 skip(1);
             }
-            wants_reboot = 1;
+            wants_reboot = true;
         } else if(!strcmp(*argv, "set_active")) {
             require(2);
             std::string slot = verify_slot(transport, std::string(argv[1]), false);
@@ -1784,7 +1791,7 @@
     if (wants_set_active) {
         fb_set_active(next_active.c_str());
     }
-    if (wants_reboot) {
+    if (wants_reboot && !skip_reboot) {
         fb_queue_reboot();
         fb_queue_wait_for_disconnect();
     } else if (wants_reboot_bootloader) {
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index 783bd0b..a93c8ea 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -18,6 +18,7 @@
 #define __CUTILS_SOCKETS_H
 
 #include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,28 +52,8 @@
  * android_get_control_socket - simple helper function to get the file
  * descriptor of our init-managed Unix domain socket. `name' is the name of the
  * socket, as given in init.rc. Returns -1 on error.
- *
- * This is inline and not in libcutils proper because we want to use this in
- * third-party daemons with minimal modification.
  */
-static inline int android_get_control_socket(const char* name)
-{
-	char key[64];
-	snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name);
-
-	const char* val = getenv(key);
-	if (!val) {
-		return -1;
-	}
-
-	errno = 0;
-	int fd = strtol(val, NULL, 10);
-	if (errno) {
-		return -1;
-	}
-
-	return fd;
-}
+int android_get_control_socket(const char* name);
 
 /*
  * See also android.os.LocalSocketAddress.Namespace
diff --git a/include/utils/Flattenable.h b/include/utils/Flattenable.h
index 882a8b2..c37ac60 100644
--- a/include/utils/Flattenable.h
+++ b/include/utils/Flattenable.h
@@ -19,10 +19,13 @@
 
 
 #include <stdint.h>
+#include <string.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
 #include <utils/Debug.h>
 
+#include <type_traits>
+
 namespace android {
 
 
@@ -60,14 +63,18 @@
     // write a POD structure
     template<typename T>
     static void write(void*& buffer, size_t& size, const T& value) {
-        *static_cast<T*>(buffer) = value;
+        static_assert(std::is_trivially_copyable<T>::value,
+                      "Cannot flatten a non-trivially-copyable type");
+        memcpy(buffer, &value, sizeof(T));
         advance(buffer, size, sizeof(T));
     }
 
     // read a POD structure
     template<typename T>
     static void read(void const*& buffer, size_t& size, T& value) {
-        value = *static_cast<T const*>(buffer);
+        static_assert(std::is_trivially_copyable<T>::value,
+                      "Cannot unflatten a non-trivially-copyable type");
+        memcpy(&value, buffer, sizeof(T));
         advance(buffer, size, sizeof(T));
     }
 };
diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp
index d9ab146..bba63ac 100644
--- a/libcutils/sockets.cpp
+++ b/libcutils/sockets.cpp
@@ -45,3 +45,24 @@
     }
     return -1;
 }
+
+int android_get_control_socket(const char* name) {
+    char key[64];
+    snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name);
+
+    const char* val = getenv(key);
+    if (!val) {
+        return -1;
+    }
+
+    errno = 0;
+    long ret = strtol(val, NULL, 10);
+    if (errno) {
+        return -1;
+    }
+    if (ret < 0 || ret > INT_MAX) {
+        return -1;
+    }
+
+    return static_cast<int>(ret);
+}
diff --git a/lmkd/Android.mk b/lmkd/Android.mk
index 8c88661..8980d1c 100644
--- a/lmkd/Android.mk
+++ b/lmkd/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := lmkd.c
-LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup
+LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup libcutils
 LOCAL_CFLAGS := -Werror
 
 LOCAL_MODULE := lmkd
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 6315cf4..50ee110 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -556,6 +556,8 @@
     # Define default initial receive window size in segments.
     setprop net.tcp.default_init_rwnd 60
 
+    # Start all binderized HAL daemons
+    start hwservicemanager
     class_start core
 
 on nonencrypted
@@ -645,3 +647,13 @@
 service flash_recovery /system/bin/install-recovery.sh
     class main
     oneshot
+
+service hwservicemanager /system/bin/hwservicemanager
+    user system
+    disabled
+    group system readproc
+    critical
+    writepid /dev/cpuset/system-background/tasks
+
+on property:hwservicemanager.ready=true
+    class_start hal
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 7e13df9..8725113 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -19,6 +19,7 @@
 /dev/hw_random            0440   root       system
 /dev/ashmem               0666   root       root
 /dev/binder               0666   root       root
+/dev/hwbinder             0666   root       root
 
 # Anyone can read the logs, but if they're not in the "logs"
 # group, then they'll only see log entries for their UID.