libnetutil: Check dhcp respose packet length am: 61f25d4a36 am: cee6d38c55 am: 29d054046f am: c29049f4f8 am: 3de04e9840 am: 19702dc499 am: 8191e9ba87 am: 804323c195 am: 4f5f00d879 am: 3a1ff1ad71 am: bab7b1ecd9 am: cdf0fc6018
am: 9f1398c6e3

Change-Id: I4c46a36846dd8f6588f29bc84de9bc3f1d7c088a
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 5b5eff4..d5b7554 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -60,3 +60,13 @@
 $(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)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/secure-storage-unit-test)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/tipc-test)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc)
diff --git a/adb/Android.mk b/adb/Android.mk
index 6ed01fa..ece0645 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -360,8 +360,6 @@
 LOCAL_MODULE := adbd
 
 LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
-LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
 
 LOCAL_SANITIZE := $(adb_target_sanitize)
 LOCAL_STRIP_MODULE := keep_symbols
diff --git a/adb/adb.cpp b/adb/adb.cpp
index bfb1144..6b30be8 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -49,6 +49,7 @@
 #include "adb_auth.h"
 #include "adb_io.h"
 #include "adb_listeners.h"
+#include "adb_unique_fd.h"
 #include "adb_utils.h"
 #include "sysdeps/chrono.h"
 #include "transport.h"
@@ -256,19 +257,6 @@
     send_packet(cp, t);
 }
 
-#if ADB_HOST
-
-void SendConnectOnHost(atransport* t) {
-    // Send an empty message before A_CNXN message. This is because the data toggle of the ep_out on
-    // host and ep_in on device may not be the same.
-    apacket* p = get_apacket();
-    CHECK(p);
-    send_packet(p, t);
-    send_connect(t);
-}
-
-#endif
-
 // qual_overwrite is used to overwrite a qualifier string.  dst is a
 // pointer to a char pointer.  It is assumed that if *dst is non-NULL, it
 // was malloc'ed and needs to freed.  *dst will be set to a dup of src.
@@ -369,7 +357,7 @@
         if (p->msg.arg0){
             send_packet(p, t);
 #if ADB_HOST
-            SendConnectOnHost(t);
+            send_connect(t);
 #endif
         } else {
             t->SetConnectionState(kCsOffline);
@@ -656,6 +644,26 @@
 
 #endif
 
+static void ReportServerStartupFailure(pid_t pid) {
+    fprintf(stderr, "ADB server didn't ACK\n");
+    fprintf(stderr, "Full server startup log: %s\n", GetLogFilePath().c_str());
+    fprintf(stderr, "Server had pid: %d\n", pid);
+
+    unique_fd fd(adb_open(GetLogFilePath().c_str(), O_RDONLY));
+    if (fd == -1) return;
+
+    // Let's not show more than 128KiB of log...
+    adb_lseek(fd, -128 * 1024, SEEK_END);
+    std::string content;
+    if (!android::base::ReadFdToString(fd, &content)) return;
+
+    std::string header = android::base::StringPrintf("--- adb starting (pid %d) ---", pid);
+    std::vector<std::string> lines = android::base::Split(content, "\n");
+    int i = lines.size() - 1;
+    while (i >= 0 && lines[i] != header) --i;
+    while (static_cast<size_t>(i) < lines.size()) fprintf(stderr, "%s\n", lines[i++].c_str());
+}
+
 int launch_server(const std::string& socket_spec) {
 #if defined(_WIN32)
     /* we need to start the server in the background                    */
@@ -835,7 +843,8 @@
                 memcmp(temp, expected, expected_length) == 0) {
                 got_ack = true;
             } else {
-                fprintf(stderr, "ADB server didn't ACK\n");
+                ReportServerStartupFailure(GetProcessId(process_handle.get()));
+                return -1;
             }
         } else {
             const DWORD err = GetLastError();
@@ -909,12 +918,9 @@
                            "--reply-fd", reply_fd, NULL);
         // this should not return
         fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
-    } else  {
+    } else {
         // parent side of the fork
-
-        char  temp[3];
-
-        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
+        char temp[3] = {};
         // wait for the "OK\n" message
         adb_close(fd[1]);
         int ret = adb_read(fd[0], temp, 3);
@@ -925,7 +931,7 @@
             return -1;
         }
         if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
-            fprintf(stderr, "ADB server didn't ACK\n" );
+            ReportServerStartupFailure(pid);
             return -1;
         }
     }
@@ -937,8 +943,8 @@
 // Try to handle a network forwarding request.
 // This returns 1 on success, 0 on failure, and -1 to indicate this is not
 // a forwarding-related request.
-int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd)
-{
+int handle_forward_request(const char* service, TransportType type, const char* serial,
+                           TransportId transport_id, int reply_fd) {
     if (!strcmp(service, "list-forward")) {
         // Create the list of forward redirections.
         std::string listeners = format_listeners();
@@ -991,7 +997,8 @@
         }
 
         std::string error_msg;
-        atransport* transport = acquire_one_transport(type, serial, nullptr, &error_msg);
+        atransport* transport =
+            acquire_one_transport(type, serial, transport_id, nullptr, &error_msg);
         if (!transport) {
             SendFail(reply_fd, error_msg);
             return 1;
@@ -1049,8 +1056,8 @@
     return 0;
 }
 
-int handle_host_request(const char* service, TransportType type,
-                        const char* serial, int reply_fd, asocket* s) {
+int handle_host_request(const char* service, TransportType type, const char* serial,
+                        TransportId transport_id, int reply_fd, asocket* s) {
     if (strcmp(service, "kill") == 0) {
         fprintf(stderr, "adb server killed by remote request\n");
         fflush(stdout);
@@ -1070,7 +1077,14 @@
     if (!strncmp(service, "transport", strlen("transport"))) {
         TransportType type = kTransportAny;
 
-        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
+        if (!strncmp(service, "transport-id:", strlen("transport-id:"))) {
+            service += strlen("transport-id:");
+            transport_id = strtoll(service, const_cast<char**>(&service), 10);
+            if (*service != '\0') {
+                SendFail(reply_fd, "invalid transport id");
+                return 1;
+            }
+        } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
             type = kTransportUsb;
         } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
             type = kTransportLocal;
@@ -1082,7 +1096,7 @@
         }
 
         std::string error;
-        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
+        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t != nullptr) {
             s->transport = t;
             SendOkay(reply_fd);
@@ -1125,7 +1139,7 @@
 
     if (!strcmp(service, "features")) {
         std::string error;
-        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
+        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t != nullptr) {
             SendOkay(reply_fd, FeatureSetToString(t->features()));
         } else {
@@ -1178,7 +1192,7 @@
     // These always report "unknown" rather than the actual error, for scripts.
     if (!strcmp(service, "get-serialno")) {
         std::string error;
-        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
+        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t) {
             return SendOkay(reply_fd, t->serial ? t->serial : "unknown");
         } else {
@@ -1187,7 +1201,7 @@
     }
     if (!strcmp(service, "get-devpath")) {
         std::string error;
-        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
+        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t) {
             return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown");
         } else {
@@ -1196,7 +1210,7 @@
     }
     if (!strcmp(service, "get-state")) {
         std::string error;
-        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
+        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t) {
             return SendOkay(reply_fd, t->connection_state_name());
         } else {
@@ -1214,7 +1228,7 @@
 
     if (!strcmp(service, "reconnect")) {
         std::string response;
-        atransport* t = acquire_one_transport(type, serial, nullptr, &response, true);
+        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true);
         if (t != nullptr) {
             kick_transport(t);
             response =
@@ -1223,7 +1237,7 @@
         return SendOkay(reply_fd, response);
     }
 
-    int ret = handle_forward_request(service, type, serial, reply_fd);
+    int ret = handle_forward_request(service, type, serial, transport_id, reply_fd);
     if (ret >= 0)
       return ret - 1;
     return -1;
diff --git a/adb/adb.h b/adb/adb.h
index d6b2b81..98e2604 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -56,6 +56,7 @@
 // Increment this when we want to force users to start a new adb server.
 #define ADB_SERVER_VERSION 39
 
+using TransportId = uint64_t;
 class atransport;
 
 struct amessage {
@@ -149,7 +150,7 @@
 
 int service_to_fd(const char* name, const atransport* transport);
 #if ADB_HOST
-asocket *host_service_to_socket(const char*  name, const char *serial);
+asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id);
 #endif
 
 #if !ADB_HOST
@@ -159,7 +160,8 @@
 int       create_jdwp_connection_fd(int  jdwp_pid);
 #endif
 
-int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd);
+int handle_forward_request(const char* service, TransportType type, const char* serial,
+                           TransportId transport_id, int reply_fd);
 
 #if !ADB_HOST
 void framebuffer_service(int fd, void *cookie);
@@ -216,15 +218,13 @@
 #define USB_FFS_ADB_IN    USB_FFS_ADB_EP(ep2)
 #endif
 
-int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s);
+int handle_host_request(const char* service, TransportType type, const char* serial,
+                        TransportId transport_id, int reply_fd, asocket* s);
 
 void handle_online(atransport *t);
 void handle_offline(atransport *t);
 
 void send_connect(atransport *t);
-#if ADB_HOST
-void SendConnectOnHost(atransport* t);
-#endif
 
 void parse_banner(const std::string&, atransport* t);
 
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index e533a00..849a6e7 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -20,6 +20,7 @@
 #include "adb_client.h"
 
 #include <errno.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -46,12 +47,20 @@
 
 static TransportType __adb_transport = kTransportAny;
 static const char* __adb_serial = NULL;
+static TransportId __adb_transport_id = 0;
 
 static const char* __adb_server_socket_spec;
 
-void adb_set_transport(TransportType type, const char* serial) {
+void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) {
     __adb_transport = type;
     __adb_serial = serial;
+    __adb_transport_id = transport_id;
+}
+
+void adb_get_transport(TransportType* type, const char** serial, TransportId* transport_id) {
+    if (type) *type = __adb_transport;
+    if (serial) *serial = __adb_serial;
+    if (transport_id) *transport_id = __adb_transport_id;
 }
 
 void adb_set_socket_spec(const char* socket_spec) {
@@ -63,7 +72,10 @@
 
 static int switch_socket_transport(int fd, std::string* error) {
     std::string service;
-    if (__adb_serial) {
+    if (__adb_transport_id) {
+        service += "host:transport-id:";
+        service += std::to_string(__adb_transport_id);
+    } else if (__adb_serial) {
         service += "host:transport:";
         service += __adb_serial;
     } else {
@@ -292,15 +304,18 @@
     return true;
 }
 
-std::string format_host_command(const char* command, TransportType type, const char* serial) {
-    if (serial) {
-        return android::base::StringPrintf("host-serial:%s:%s", serial, command);
+std::string format_host_command(const char* command) {
+    if (__adb_transport_id) {
+        return android::base::StringPrintf("host-transport-id:%" PRIu64 ":%s", __adb_transport_id,
+                                           command);
+    } else if (__adb_serial) {
+        return android::base::StringPrintf("host-serial:%s:%s", __adb_serial, command);
     }
 
     const char* prefix = "host";
-    if (type == kTransportUsb) {
+    if (__adb_transport == kTransportUsb) {
         prefix = "host-usb";
-    } else if (type == kTransportLocal) {
+    } else if (__adb_transport == kTransportLocal) {
         prefix = "host-local";
     }
     return android::base::StringPrintf("%s:%s", prefix, command);
@@ -308,7 +323,7 @@
 
 bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) {
     std::string result;
-    if (adb_query(format_host_command("features", __adb_transport, __adb_serial), &result, error)) {
+    if (adb_query(format_host_command("features"), &result, error)) {
         *feature_set = StringToFeatureSet(result);
         return true;
     }
diff --git a/adb/adb_client.h b/adb/adb_client.h
index fabec00..fca435e 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -40,7 +40,9 @@
                std::string* _Nonnull error);
 
 // Set the preferred transport to connect to.
-void adb_set_transport(TransportType type, const char* _Nullable serial);
+void adb_set_transport(TransportType type, const char* _Nullable serial, TransportId transport_id);
+void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial,
+                       TransportId* _Nullable transport_id);
 
 // Set the socket specification for the adb server.
 // This function can only be called once, and the argument must live to the end of the process.
@@ -57,8 +59,7 @@
 bool adb_status(int fd, std::string* _Nonnull error);
 
 // Create a host command corresponding to selected transport type/serial.
-std::string format_host_command(const char* _Nonnull command, TransportType type,
-                                const char* _Nullable serial);
+std::string format_host_command(const char* _Nonnull command);
 
 // Get the feature set of the current preferred transport.
 bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error);
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 6f2403d..b236fb3 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -157,7 +157,12 @@
 }
 
 std::string dump_hex(const void* data, size_t byte_count) {
-    byte_count = std::min(byte_count, size_t(16));
+    size_t truncate_len = 16;
+    bool truncated = false;
+    if (byte_count > truncate_len) {
+        byte_count = truncate_len;
+        truncated = true;
+    }
 
     const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
 
@@ -172,6 +177,10 @@
         line.push_back(isprint(ch) ? ch : '.');
     }
 
+    if (truncated) {
+        line += " [truncated]";
+    }
+
     return line;
 }
 
@@ -278,3 +287,29 @@
     fprintf(stderr, "\n");
     return 1;
 }
+
+std::string GetLogFilePath() {
+#if defined(_WIN32)
+    const char log_name[] = "adb.log";
+    WCHAR temp_path[MAX_PATH];
+
+    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
+    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
+    if (nchars >= arraysize(temp_path) || nchars == 0) {
+        // If string truncation or some other error.
+        fatal("cannot retrieve temporary file path: %s\n",
+              android::base::SystemErrorCodeToString(GetLastError()).c_str());
+    }
+
+    std::string temp_path_utf8;
+    if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
+        fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
+    }
+
+    return temp_path_utf8 + log_name;
+#else
+    const char* tmp_dir = getenv("TMPDIR");
+    if (tmp_dir == nullptr) tmp_dir = "/tmp";
+    return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
+#endif
+}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 11c0ec9..f764a0e 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -89,4 +89,6 @@
     }
 };
 
+std::string GetLogFilePath();
+
 #endif
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index 372a3b4..abef86a 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -102,7 +102,7 @@
             std::vector<const char*> srcs{src_file_.c_str()};
             SetLineMessage("pulling");
             status_ =
-                br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1;
+                br_->DoSyncPull(srcs, destination.c_str(), false, line_message_.c_str()) ? 0 : 1;
             if (status_ != 0) {
                 fprintf(stderr,
                         "Bug report finished but could not be copied to '%s'.\n"
@@ -195,13 +195,13 @@
     DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
 };
 
-int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
+int Bugreport::DoIt(int argc, const char** argv) {
     if (argc > 2) return syntax_error("adb bugreport [PATH]");
 
     // Gets bugreportz version.
     std::string bugz_stdout, bugz_stderr;
     DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr);
-    int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback);
+    int status = SendShellCommand("bugreportz -v", false, &version_callback);
     std::string bugz_version = android::base::Trim(bugz_stderr);
     std::string bugz_output = android::base::Trim(bugz_stdout);
 
@@ -214,7 +214,7 @@
             fprintf(stderr,
                     "Failed to get bugreportz version, which is only available on devices "
                     "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n");
-            return SendShellCommand(transport_type, serial, "bugreport", false);
+            return SendShellCommand("bugreport", false);
         }
 
         // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling
@@ -265,7 +265,7 @@
         bugz_command = "bugreportz";
     }
     BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this);
-    return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
+    return SendShellCommand(bugz_command, false, &bugz_callback);
 }
 
 void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) {
@@ -274,10 +274,9 @@
         LinePrinter::INFO);
 }
 
-int Bugreport::SendShellCommand(TransportType transport_type, const char* serial,
-                                const std::string& command, bool disable_shell_protocol,
+int Bugreport::SendShellCommand(const std::string& command, bool disable_shell_protocol,
                                 StandardStreamsCallbackInterface* callback) {
-    return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback);
+    return send_shell_command(command, disable_shell_protocol, callback);
 }
 
 bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
diff --git a/adb/bugreport.h b/adb/bugreport.h
index d9a4468..413439b 100644
--- a/adb/bugreport.h
+++ b/adb/bugreport.h
@@ -29,14 +29,13 @@
   public:
     Bugreport() : line_printer_() {
     }
-    int DoIt(TransportType transport_type, const char* serial, int argc, const char** argv);
+    int DoIt(int argc, const char** argv);
 
   protected:
     // Functions below are abstractions of external functions so they can be
     // mocked on tests.
     virtual int SendShellCommand(
-        TransportType transport_type, const char* serial, const std::string& command,
-        bool disable_shell_protocol,
+        const std::string& command, bool disable_shell_protocol,
         StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
 
     virtual bool DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
index d3787b4..72ca59a 100644
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -51,8 +51,8 @@
 // Empty functions so tests don't need to be linked against commandline.cpp
 DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
 
-int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
-                       bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
+int send_shell_command(const std::string& command, bool disable_shell_protocol,
+                       StandardStreamsCallbackInterface* callback) {
     ADD_FAILURE() << "send_shell_command() should have been mocked";
     return -42;
 }
@@ -62,7 +62,7 @@
     kStreamStderr,
 };
 
-// gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher
+// gmock black magic to provide a WithArg<2>(WriteOnStdout(output)) matcher
 typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
 
 class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
@@ -118,9 +118,8 @@
 
 class BugreportMock : public Bugreport {
   public:
-    MOCK_METHOD5(SendShellCommand,
-                 int(TransportType transport_type, const char* serial, const std::string& command,
-                     bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
+    MOCK_METHOD3(SendShellCommand, int(const std::string& command, bool disable_shell_protocol,
+                                       StandardStreamsCallbackInterface* callback));
     MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
                                   bool copy_attrs, const char* name));
     MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
@@ -136,10 +135,9 @@
     }
 
     void ExpectBugreportzVersion(const std::string& version) {
-        EXPECT_CALL(br_,
-                    SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
-            .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
-                            WithArg<4>(ReturnCallbackDone(0))));
+        EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
+            .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version.c_str())),
+                            WithArg<2>(ReturnCallbackDone(0))));
     }
 
     void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
@@ -153,26 +151,26 @@
 // Tests when called with invalid number of arguments
 TEST_F(BugreportTest, InvalidNumberArgs) {
     const char* args[] = {"bugreport", "to", "principal"};
-    ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
+    ASSERT_EQ(1, br_.DoIt(3, args));
 }
 
 // Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
 // to the flat-file format ('bugreport' binary on device)
 TEST_F(BugreportTest, NoArgumentsPreNDevice) {
     // clang-format off
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStderr("")),
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStderr("")),
                         // Write some bogus output on stdout to make sure it's ignored
-                        WithArg<4>(WriteOnStdout("Dude, where is my bugreportz?")),
-                        WithArg<4>(ReturnCallbackDone(0))));
+                        WithArg<2>(WriteOnStdout("Dude, where is my bugreportz?")),
+                        WithArg<2>(ReturnCallbackDone(0))));
     // clang-format on
     std::string bugreport = "Reported the bug was.";
     CaptureStdout();
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout(bugreport)), Return(0)));
+    EXPECT_CALL(br_, SendShellCommand("bugreport", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout(bugreport)), Return(0)));
 
     const char* args[] = {"bugreport"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
+    ASSERT_EQ(0, br_.DoIt(1, args));
     ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport));
 }
 
@@ -183,15 +181,15 @@
 
     std::string dest_file =
         android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("pulling da_bugreport.zip")))
+                                false, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
+    ASSERT_EQ(0, br_.DoIt(1, args));
 }
 
 // Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
@@ -201,47 +199,47 @@
     std::string dest_file =
         android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
     ExpectProgress(50, "da_bugreport.zip");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
-                        WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
-                        WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
+                        WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")),
+                        WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("pulling da_bugreport.zip")))
+                                false, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
+    ASSERT_EQ(0, br_.DoIt(1, args));
 }
 
 // Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
 TEST_F(BugreportTest, OkNDevice) {
     ExpectBugreportzVersion("1.0");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("pulling file.zip")))
+                                false, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when it succeeds but response was sent in
 // multiple buffer writers and without progress updates.
 TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
     ExpectBugreportzVersion("1.0");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
-                        WithArg<4>(WriteOnStdout("/bugreport.zip")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device")),
+                        WithArg<2>(WriteOnStdout("/bugreport.zip")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("pulling file.zip")))
+                                false, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when it succeeds and displays progress.
@@ -252,32 +250,32 @@
     ExpectProgress(50);
     ExpectProgress(99);
     // clang-format off
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
         .WillOnce(DoAll(
             // Name might change on OK, so make sure the right one is picked.
-            WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
+            WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
             // Progress line in one write
-            WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
+            WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")),
             // Add some bogus lines
-            WithArg<4>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
+            WithArg<2>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
             // Multiple progress lines in one write
-            WithArg<4>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
+            WithArg<2>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
             // Progress line in multiple writes
-            WithArg<4>(WriteOnStdout("PROG")),
-            WithArg<4>(WriteOnStdout("RESS:99")),
-            WithArg<4>(WriteOnStdout("/100\n")),
+            WithArg<2>(WriteOnStdout("PROG")),
+            WithArg<2>(WriteOnStdout("RESS:99")),
+            WithArg<2>(WriteOnStdout("/100\n")),
             // Split last message as well, just in case
-            WithArg<4>(WriteOnStdout("OK:/device/bugreport")),
-            WithArg<4>(WriteOnStdout(".zip")),
-            WithArg<4>(ReturnCallbackDone())));
+            WithArg<2>(WriteOnStdout("OK:/device/bugreport")),
+            WithArg<2>(WriteOnStdout(".zip")),
+            WithArg<2>(ReturnCallbackDone())));
     // clang-format on
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("pulling file.zip")))
+                                false, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
@@ -287,28 +285,28 @@
     ExpectProgress(50);
     ExpectProgress(75);
     // clang-format off
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
         .WillOnce(DoAll(
-            WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
-            WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
-            WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
+            WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
+            WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
+            WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
             // 25% should be ignored becaused it receded.
-            WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
-            WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
+            WithArg<2>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
+            WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
             // 75% should be ignored becaused it didn't change.
-            WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
+            WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
             // Try a receeding percentage with a different max progress
-            WithArg<4>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
-            WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
-            WithArg<4>(ReturnCallbackDone())));
+            WithArg<2>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
+            WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
+            WithArg<2>(ReturnCallbackDone())));
     // clang-format on
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("pulling file.zip")))
+                                false, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0%
@@ -317,21 +315,21 @@
     ExpectProgress(0);
     ExpectProgress(1);
     // clang-format off
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
         .WillOnce(DoAll(
-            WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
-            WithArg<4>(WriteOnStdout("PROGRESS:1/100000\n")),
-            WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
-            WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
-            WithArg<4>(ReturnCallbackDone())));
+            WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
+            WithArg<2>(WriteOnStdout("PROGRESS:1/100000\n")),
+            WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
+            WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
+            WithArg<2>(ReturnCallbackDone())));
     // clang-format on
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("pulling file.zip")))
+                                false, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport dir' when it succeeds and destination is a directory.
@@ -341,30 +339,30 @@
     std::string dest_file =
         android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
 
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
-                        WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
+                        WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("pulling da_bugreport.zip")))
+                                false, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", td.path};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file' when it succeeds
 TEST_F(BugreportTest, OkNoExtension) {
     ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("pulling file.zip")))
+                                false, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file"};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
@@ -374,28 +372,28 @@
     std::string dest_file =
         android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
 
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
-                        WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
+                        WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("pulling da_bugreport.zip")))
+                                false, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", td.path};
-    ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(0, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when the bugreport itself failed
 TEST_F(BugreportTest, BugreportzReturnedFail) {
     ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
         .WillOnce(
-            DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
+            DoAll(WithArg<2>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<2>(ReturnCallbackDone())));
 
     CaptureStderr();
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(-1, br_.DoIt(2, args));
     ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
 }
 
@@ -404,13 +402,13 @@
 // multiple buffer writes
 TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
     ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("FAIL")), WithArg<2>(WriteOnStdout(":D'OH!\n")),
+                        WithArg<2>(ReturnCallbackDone())));
 
     CaptureStderr();
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(-1, br_.DoIt(2, args));
     ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
 }
 
@@ -418,23 +416,22 @@
 // response.
 TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
     ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("bugreportz? What am I, a zombie?")),
+                        WithArg<2>(ReturnCallbackDone())));
 
     CaptureStderr();
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(-1, br_.DoIt(2, args));
     ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
 }
 
 // Tests 'adb bugreport file.zip' when the bugreportz -v command failed
 TEST_F(BugreportTest, BugreportzVersionFailed) {
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
-        .WillOnce(Return(666));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)).WillOnce(Return(666));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(666, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
@@ -442,29 +439,28 @@
     ExpectBugreportzVersion("");
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(-1, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when the main bugreportz command failed
 TEST_F(BugreportTest, BugreportzFailed) {
     ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(Return(666));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)).WillOnce(Return(666));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(666, br_.DoIt(2, args));
 }
 
 // Tests 'adb bugreport file.zip' when the bugreport could not be pulled
 TEST_F(BugreportTest, PullFails) {
     ExpectBugreportzVersion("1.1");
-    EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
-        .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
-                        WithArg<4>(ReturnCallbackDone())));
+    EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
+        .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
+                        WithArg<2>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, HasSubstr("file.zip")))
+                                false, HasSubstr("file.zip")))
         .WillOnce(Return(false));
 
     const char* args[] = {"bugreport", "file.zip"};
-    ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+    ASSERT_EQ(1, br_.DoIt(2, args));
 }
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 62798cd..f0d0ce7 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -39,33 +39,7 @@
 #include "sysdeps/chrono.h"
 #include "transport.h"
 
-static std::string GetLogFilePath() {
-#if defined(_WIN32)
-    const char log_name[] = "adb.log";
-    WCHAR temp_path[MAX_PATH];
-
-    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
-    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
-    if (nchars >= arraysize(temp_path) || nchars == 0) {
-        // If string truncation or some other error.
-        fatal("cannot retrieve temporary file path: %s\n",
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-    }
-
-    std::string temp_path_utf8;
-    if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
-        fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
-    }
-
-    return temp_path_utf8 + log_name;
-#else
-    const char* tmp_dir = getenv("TMPDIR");
-    if (tmp_dir == nullptr) tmp_dir = "/tmp";
-    return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
-#endif
-}
-
-static void setup_daemon_logging(void) {
+static void setup_daemon_logging() {
     const std::string log_file_path(GetLogFilePath());
     int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640);
     if (fd == -1) {
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index e7f44c6..8120199 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -333,6 +333,13 @@
             return;
         }
 
+        rc = libusb_set_interface_alt_setting(handle.get(), interface_num, 0);
+        if (rc != 0) {
+            LOG(WARNING) << "failed to set interface alt setting for device '" << device_serial
+                         << "'" << libusb_error_name(rc);
+            return;
+        }
+
         for (uint8_t endpoint : {bulk_in, bulk_out}) {
             rc = libusb_clear_halt(handle.get(), endpoint);
             if (rc != 0) {
@@ -412,8 +419,13 @@
     if (it != usb_handles.end()) {
         if (!it->second->device_handle) {
             // If the handle is null, we were never able to open the device.
-            unregister_usb_transport(it->second.get());
+
+            // Temporarily release the usb handles mutex to avoid deadlock.
+            std::unique_ptr<usb_handle> handle = std::move(it->second);
             usb_handles.erase(it);
+            lock.unlock();
+            unregister_usb_transport(handle.get());
+            lock.lock();
         } else {
             // Closure of the transport will erase the usb_handle.
         }
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index c9f1ee9..9f23473 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -62,11 +62,11 @@
 #include "shell_service.h"
 #include "sysdeps/chrono.h"
 
-static int install_app(TransportType t, const char* serial, int argc, const char** argv);
-static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
-static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
-static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
-static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
+static int install_app(int argc, const char** argv);
+static int install_multiple_app(int argc, const char** argv);
+static int uninstall_app(int argc, const char** argv);
+static int install_app_legacy(int argc, const char** argv);
+static int uninstall_app_legacy(int argc, const char** argv);
 
 extern int gListenAll;
 
@@ -90,6 +90,7 @@
         " -d         use USB device (error if multiple devices connected)\n"
         " -e         use TCP/IP device (error if multiple TCP/IP devices available)\n"
         " -s SERIAL  use device with given serial (overrides $ANDROID_SERIAL)\n"
+        " -t ID      use device with given transport id\n"
         " -H         name of adb server host [default=localhost]\n"
         " -P         port of adb server [default=5037]\n"
         " -L SOCKET  listen on given socket for adb server [default=tcp:localhost:5037]\n"
@@ -685,6 +686,10 @@
 
     // Parse shell-specific command-line options.
     argv[0] = "adb shell"; // So getopt(3) error messages start "adb shell".
+#ifdef _WIN32
+    // fixes "adb shell -l" crash on Windows, b/37284906
+    __argv = const_cast<char**>(argv);
+#endif
     optind = 1; // argv[0] is always "shell", so set `optind` appropriately.
     int opt;
     while ((opt = getopt(argc, const_cast<char**>(argv), "+e:ntTx")) != -1) {
@@ -986,13 +991,16 @@
 #endif /* !defined(_WIN32) */
 }
 
-static bool wait_for_device(const char* service, TransportType t, const char* serial) {
+static bool wait_for_device(const char* service) {
     std::vector<std::string> components = android::base::Split(service, "-");
     if (components.size() < 3 || components.size() > 4) {
         fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service);
         return false;
     }
 
+    TransportType t;
+    adb_get_transport(&t, nullptr, nullptr);
+
     // Was the caller vague about what they'd like us to wait for?
     // If so, check they weren't more specific in their choice of transport type.
     if (components.size() == 3) {
@@ -1019,7 +1027,7 @@
         return false;
     }
 
-    std::string cmd = format_host_command(android::base::Join(components, "-").c_str(), t, serial);
+    std::string cmd = format_host_command(android::base::Join(components, "-").c_str());
     return adb_command(cmd);
 }
 
@@ -1065,8 +1073,8 @@
     return true;
 }
 
-int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
-                       bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
+int send_shell_command(const std::string& command, bool disable_shell_protocol,
+                       StandardStreamsCallbackInterface* callback) {
     int fd;
     bool use_shell_protocol = false;
 
@@ -1097,7 +1105,7 @@
         }
 
         fprintf(stderr, "- waiting for device -\n");
-        if (!wait_for_device("wait-for-device", transport_type, serial)) {
+        if (!wait_for_device("wait-for-device")) {
             return 1;
         }
     }
@@ -1111,7 +1119,7 @@
     return exit_code;
 }
 
-static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
+static int logcat(int argc, const char** argv) {
     char* log_tags = getenv("ANDROID_LOG_TAGS");
     std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
 
@@ -1128,7 +1136,7 @@
     }
 
     // No need for shell protocol with logcat, always disable for simplicity.
-    return send_shell_command(transport, serial, cmd, true);
+    return send_shell_command(cmd, true);
 }
 
 static void write_zeros(int bytes, int fd) {
@@ -1340,6 +1348,7 @@
 
     // We need to check for -d and -e before we look at $ANDROID_SERIAL.
     const char* serial = nullptr;
+    TransportId transport_id = 0;
 
     while (argc > 0) {
         if (!strcmp(argv[0],"server")) {
@@ -1359,7 +1368,7 @@
                 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
                 return 1;
             }
-        } else if (argv[0][0]=='-' && argv[0][1]=='s') {
+        } else if (!strncmp(argv[0], "-s", 2)) {
             if (isdigit(argv[0][2])) {
                 serial = argv[0] + 2;
             } else {
@@ -1368,6 +1377,19 @@
                 argc--;
                 argv++;
             }
+        } else if (!strncmp(argv[0], "-t", 2)) {
+            const char* id;
+            if (isdigit(argv[0][2])) {
+                id = argv[0] + 2;
+            } else {
+                id = argv[1];
+                argc--;
+                argv++;
+            }
+            transport_id = strtoll(id, const_cast<char**>(&id), 10);
+            if (*id != '\0') {
+                return syntax_error("invalid transport id");
+            }
         } else if (!strcmp(argv[0],"-d")) {
             transport_type = kTransportUsb;
         } else if (!strcmp(argv[0],"-e")) {
@@ -1451,7 +1473,7 @@
         serial = getenv("ANDROID_SERIAL");
     }
 
-    adb_set_transport(transport_type, serial);
+    adb_set_transport(transport_type, serial, transport_id);
 
     if (is_server) {
         if (no_daemon || is_daemon) {
@@ -1478,7 +1500,7 @@
     if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
         const char* service = argv[0];
 
-        if (!wait_for_device(service, transport_type, serial)) {
+        if (!wait_for_device(service)) {
             return 1;
         }
 
@@ -1589,7 +1611,7 @@
         return adb_root(argv[0]) ? 0 : 1;
     } else if (!strcmp(argv[0], "bugreport")) {
         Bugreport bugreport;
-        return bugreport.DoIt(transport_type, serial, argc, argv);
+        return bugreport.DoIt(argc, argv);
     } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
         bool reverse = !strcmp(argv[0], "reverse");
         ++argv;
@@ -1685,20 +1707,20 @@
     else if (!strcmp(argv[0], "install")) {
         if (argc < 2) return syntax_error("install requires an argument");
         if (_use_legacy_install()) {
-            return install_app_legacy(transport_type, serial, argc, argv);
+            return install_app_legacy(argc, argv);
         }
-        return install_app(transport_type, serial, argc, argv);
+        return install_app(argc, argv);
     }
     else if (!strcmp(argv[0], "install-multiple")) {
         if (argc < 2) return syntax_error("install-multiple requires an argument");
-        return install_multiple_app(transport_type, serial, argc, argv);
+        return install_multiple_app(argc, argv);
     }
     else if (!strcmp(argv[0], "uninstall")) {
         if (argc < 2) return syntax_error("uninstall requires an argument");
         if (_use_legacy_install()) {
-            return uninstall_app_legacy(transport_type, serial, argc, argv);
+            return uninstall_app_legacy(argc, argv);
         }
-        return uninstall_app(transport_type, serial, argc, argv);
+        return uninstall_app(argc, argv);
     }
     else if (!strcmp(argv[0], "sync")) {
         std::string src;
@@ -1752,11 +1774,11 @@
         !strcmp(argv[0],"get-serialno") ||
         !strcmp(argv[0],"get-devpath"))
     {
-        return adb_query_command(format_host_command(argv[0], transport_type, serial));
+        return adb_query_command(format_host_command(argv[0]));
     }
     /* other commands */
     else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
-        return logcat(transport_type, serial, argc, argv);
+        return logcat(argc, argv);
     }
     else if (!strcmp(argv[0],"ppp")) {
         return ppp(argc, argv);
@@ -1819,7 +1841,7 @@
         return adb_query_command("host:host-features");
     } else if (!strcmp(argv[0], "reconnect")) {
         if (argc == 1) {
-            return adb_query_command(format_host_command(argv[0], transport_type, serial));
+            return adb_query_command(format_host_command(argv[0]));
         } else if (argc == 2) {
             if (!strcmp(argv[1], "device")) {
                 std::string err;
@@ -1838,7 +1860,7 @@
     return 1;
 }
 
-static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
+static int uninstall_app(int argc, const char** argv) {
     // 'adb uninstall' takes the same arguments as 'cmd package uninstall' on device
     std::string cmd = "cmd package";
     while (argc-- > 0) {
@@ -1854,10 +1876,10 @@
         cmd += " " + escape_arg(*argv++);
     }
 
-    return send_shell_command(transport, serial, cmd, false);
+    return send_shell_command(cmd, false);
 }
 
-static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
+static int install_app(int argc, const char** argv) {
     // The last argument must be the APK file
     const char* file = argv[argc - 1];
     if (!android::base::EndsWithIgnoreCase(file, ".apk")) {
@@ -1910,9 +1932,7 @@
     return 1;
 }
 
-static int install_multiple_app(TransportType transport, const char* serial, int argc,
-                                const char** argv)
-{
+static int install_multiple_app(int argc, const char** argv) {
     // Find all APK arguments starting at end.
     // All other arguments passed through verbatim.
     int first_apk = -1;
@@ -2037,17 +2057,17 @@
     return EXIT_FAILURE;
 }
 
-static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
+static int pm_command(int argc, const char** argv) {
     std::string cmd = "pm";
 
     while (argc-- > 0) {
         cmd += " " + escape_arg(*argv++);
     }
 
-    return send_shell_command(transport, serial, cmd, false);
+    return send_shell_command(cmd, false);
 }
 
-static int uninstall_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) {
+static int uninstall_app_legacy(int argc, const char** argv) {
     /* if the user choose the -k option, we refuse to do it until devices are
        out with the option to uninstall the remaining data somehow (adb/ui) */
     int i;
@@ -2063,15 +2083,15 @@
     }
 
     /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
-    return pm_command(transport, serial, argc, argv);
+    return pm_command(argc, argv);
 }
 
-static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
+static int delete_file(const std::string& filename) {
     std::string cmd = "rm -f " + escape_arg(filename);
-    return send_shell_command(transport, serial, cmd, false);
+    return send_shell_command(cmd, false);
 }
 
-static int install_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) {
+static int install_app_legacy(int argc, const char** argv) {
     static const char *const DATA_DEST = "/data/local/tmp/%s";
     static const char *const SD_DEST = "/sdcard/tmp/%s";
     const char* where = DATA_DEST;
@@ -2100,9 +2120,9 @@
         where, android::base::Basename(argv[last_apk]).c_str());
     if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
     argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
-    result = pm_command(transport, serial, argc, argv);
+    result = pm_command(argc, argv);
 
 cleanup_apk:
-    delete_file(transport, serial, apk_dest);
+    delete_file(apk_dest);
     return result;
 }
diff --git a/adb/commandline.h b/adb/commandline.h
index 9ba69a3..36cd798 100644
--- a/adb/commandline.h
+++ b/adb/commandline.h
@@ -91,8 +91,8 @@
 // Connects to the device "shell" service with |command| and prints the
 // resulting output.
 // if |callback| is non-null, stdout/stderr output will be handled by it.
-int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
-                       bool disable_shell_protocol, StandardStreamsCallbackInterface* callback =
-                                                        &DEFAULT_STANDARD_STREAMS_CALLBACK);
+int send_shell_command(
+    const std::string& command, bool disable_shell_protocol,
+    StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
 
 #endif  // COMMANDLINE_H
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 1c94298..3c27582 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -233,8 +233,8 @@
             adb_device_banner = optarg;
             break;
         case 'v':
-            printf("Android Debug Bridge Daemon version %d.%d.%d (%s)\n", ADB_VERSION_MAJOR,
-                   ADB_VERSION_MINOR, ADB_SERVER_VERSION, ADB_VERSION);
+            printf("Android Debug Bridge Daemon version %d.%d.%d\n", ADB_VERSION_MAJOR,
+                   ADB_VERSION_MINOR, ADB_SERVER_VERSION);
             return 0;
         default:
             // getopt already prints "adbd: invalid option -- %c" for us.
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index 2acf661..3448ee0 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -283,25 +283,25 @@
     // reading and throwing away ID_DATA packets until the other side notices
     // that we've reported an error.
     while (true) {
-        if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) goto fail;
+        if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) break;
 
         if (msg.data.id == ID_DONE) {
-            goto abort;
+            break;
         } else if (msg.data.id != ID_DATA) {
             char id[5];
             memcpy(id, &msg.data.id, sizeof(msg.data.id));
             id[4] = '\0';
             D("handle_send_fail received unexpected id '%s' during failure", id);
-            goto abort;
+            break;
         }
 
         if (msg.data.size > buffer.size()) {
             D("handle_send_fail received oversized packet of length '%u' during failure",
               msg.data.size);
-            goto abort;
+            break;
         }
 
-        if (!ReadFdExactly(s, &buffer[0], msg.data.size)) goto abort;
+        if (!ReadFdExactly(s, &buffer[0], msg.data.size)) break;
     }
 
 abort:
diff --git a/adb/services.cpp b/adb/services.cpp
index 9605e6e..1660846 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -58,6 +58,7 @@
 #include "transport.h"
 
 struct stinfo {
+    const char* service_name;
     void (*func)(int fd, void *cookie);
     int fd;
     void *cookie;
@@ -65,7 +66,7 @@
 
 static void service_bootstrap_func(void* x) {
     stinfo* sti = reinterpret_cast<stinfo*>(x);
-    adb_thread_setname(android::base::StringPrintf("service %d", sti->fd));
+    adb_thread_setname(android::base::StringPrintf("%s svc %d", sti->service_name, sti->fd));
     sti->func(sti->fd, sti->cookie);
     free(sti);
 }
@@ -159,8 +160,7 @@
     return true;
 }
 
-void reboot_service(int fd, void* arg)
-{
+void reboot_service(int fd, void* arg) {
     if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
         // Don't return early. Give the reboot command time to take effect
         // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
@@ -187,7 +187,7 @@
         return -1;
     }
     VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
-    if (handle_forward_request(command, kTransportAny, nullptr, s[1]) < 0) {
+    if (handle_forward_request(command, kTransportAny, nullptr, 0, s[1]) < 0) {
         SendFail(s[1], "not a reverse forwarding command");
     }
     adb_close(s[1]);
@@ -235,8 +235,7 @@
 
 #endif  // !ADB_HOST
 
-static int create_service_thread(void (*func)(int, void *), void *cookie)
-{
+static int create_service_thread(const char* service_name, void (*func)(int, void*), void* cookie) {
     int s[2];
     if (adb_socketpair(s)) {
         printf("cannot create service socket pair\n");
@@ -257,6 +256,7 @@
     if (sti == nullptr) {
         fatal("cannot allocate stinfo");
     }
+    sti->service_name = service_name;
     sti->func = func;
     sti->cookie = cookie;
     sti->fd = s[1];
@@ -280,7 +280,7 @@
     } else if(!strncmp("dev:", name, 4)) {
         ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
     } else if(!strncmp(name, "framebuffer:", 12)) {
-        ret = create_service_thread(framebuffer_service, 0);
+        ret = create_service_thread("fb", framebuffer_service, nullptr);
     } else if (!strncmp(name, "jdwp:", 5)) {
         ret = create_jdwp_connection_fd(atoi(name+5));
     } else if(!strncmp(name, "shell", 5)) {
@@ -288,17 +288,17 @@
     } else if(!strncmp(name, "exec:", 5)) {
         ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
     } else if(!strncmp(name, "sync:", 5)) {
-        ret = create_service_thread(file_sync_service, NULL);
+        ret = create_service_thread("sync", file_sync_service, nullptr);
     } else if(!strncmp(name, "remount:", 8)) {
-        ret = create_service_thread(remount_service, NULL);
+        ret = create_service_thread("remount", remount_service, nullptr);
     } else if(!strncmp(name, "reboot:", 7)) {
         void* arg = strdup(name + 7);
         if (arg == NULL) return -1;
-        ret = create_service_thread(reboot_service, arg);
+        ret = create_service_thread("reboot", reboot_service, arg);
     } else if(!strncmp(name, "root:", 5)) {
-        ret = create_service_thread(restart_root_service, NULL);
+        ret = create_service_thread("root", restart_root_service, nullptr);
     } else if(!strncmp(name, "unroot:", 7)) {
-        ret = create_service_thread(restart_unroot_service, NULL);
+        ret = create_service_thread("unroot", restart_unroot_service, nullptr);
     } else if(!strncmp(name, "backup:", 7)) {
         ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s",
                                                           (name + 7)).c_str(),
@@ -311,17 +311,20 @@
         if (sscanf(name + 6, "%d", &port) != 1) {
             return -1;
         }
-        ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port);
+        ret = create_service_thread("tcp", restart_tcp_service, reinterpret_cast<void*>(port));
     } else if(!strncmp(name, "usb:", 4)) {
-        ret = create_service_thread(restart_usb_service, NULL);
+        ret = create_service_thread("usb", restart_usb_service, nullptr);
     } else if (!strncmp(name, "reverse:", 8)) {
         ret = reverse_service(name + 8);
     } else if(!strncmp(name, "disable-verity:", 15)) {
-        ret = create_service_thread(set_verity_enabled_state_service, (void*)0);
+        ret = create_service_thread("verity-on", set_verity_enabled_state_service,
+                                    reinterpret_cast<void*>(0));
     } else if(!strncmp(name, "enable-verity:", 15)) {
-        ret = create_service_thread(set_verity_enabled_state_service, (void*)1);
+        ret = create_service_thread("verity-off", set_verity_enabled_state_service,
+                                    reinterpret_cast<void*>(1));
     } else if (!strcmp(name, "reconnect")) {
-        ret = create_service_thread(reconnect_service, const_cast<atransport*>(transport));
+        ret = create_service_thread("reconnect", reconnect_service,
+                                    const_cast<atransport*>(transport));
 #endif
     }
     if (ret >= 0) {
@@ -334,6 +337,7 @@
 struct state_info {
     TransportType transport_type;
     std::string serial;
+    TransportId transport_id;
     ConnectionState state;
 };
 
@@ -346,7 +350,8 @@
         bool is_ambiguous = false;
         std::string error = "unknown error";
         const char* serial = sinfo->serial.length() ? sinfo->serial.c_str() : NULL;
-        atransport* t = acquire_one_transport(sinfo->transport_type, serial, &is_ambiguous, &error);
+        atransport* t = acquire_one_transport(sinfo->transport_type, serial, sinfo->transport_id,
+                                              &is_ambiguous, &error);
         if (t != nullptr && (sinfo->state == kCsAny || sinfo->state == t->GetConnectionState())) {
             SendOkay(fd);
             break;
@@ -437,7 +442,7 @@
 #endif
 
 #if ADB_HOST
-asocket* host_service_to_socket(const char* name, const char* serial) {
+asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id) {
     if (!strcmp(name,"track-devices")) {
         return create_device_tracker();
     } else if (android::base::StartsWith(name, "wait-for-")) {
@@ -450,6 +455,7 @@
         }
 
         if (serial) sinfo->serial = serial;
+        sinfo->transport_id = transport_id;
 
         if (android::base::StartsWith(name, "local")) {
             name += strlen("local");
@@ -478,11 +484,17 @@
             return nullptr;
         }
 
-        int fd = create_service_thread(wait_for_state, sinfo.release());
+        int fd = create_service_thread("wait", wait_for_state, sinfo.get());
+        if (fd != -1) {
+            sinfo.release();
+        }
         return create_local_socket(fd);
     } else if (!strncmp(name, "connect:", 8)) {
         char* host = strdup(name + 8);
-        int fd = create_service_thread(connect_service, host);
+        int fd = create_service_thread("connect", connect_service, host);
+        if (fd == -1) {
+            free(host);
+        }
         return create_local_socket(fd);
     }
     return NULL;
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index ee821f8..5b48da0 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -435,8 +435,7 @@
 void Subprocess::ThreadHandler(void* userdata) {
     Subprocess* subprocess = reinterpret_cast<Subprocess*>(userdata);
 
-    adb_thread_setname(android::base::StringPrintf(
-            "shell srvc %d", subprocess->pid()));
+    adb_thread_setname(android::base::StringPrintf("shell svc %d", subprocess->pid()));
 
     D("passing data streams for PID %d", subprocess->pid());
     subprocess->PassDataStreams();
diff --git a/adb/socket.h b/adb/socket.h
index 4acdf4a..64d05a9 100644
--- a/adb/socket.h
+++ b/adb/socket.h
@@ -19,84 +19,83 @@
 
 #include <stddef.h>
 
+#include <memory>
+
 #include "fdevent.h"
 
 struct apacket;
 class atransport;
 
 /* An asocket represents one half of a connection between a local and
-** remote entity.  A local asocket is bound to a file descriptor.  A
-** remote asocket is bound to the protocol engine.
-*/
+ * remote entity.  A local asocket is bound to a file descriptor.  A
+ * remote asocket is bound to the protocol engine.
+ */
 struct asocket {
-        /* chain pointers for the local/remote list of
-        ** asockets that this asocket lives in
-        */
-    asocket *next;
-    asocket *prev;
+    /* chain pointers for the local/remote list of
+     * asockets that this asocket lives in
+     */
+    asocket* next;
+    asocket* prev;
 
-        /* the unique identifier for this asocket
-        */
+    /* the unique identifier for this asocket
+     */
     unsigned id;
 
-        /* flag: set when the socket's peer has closed
-        ** but packets are still queued for delivery
-        */
-    int    closing;
+    /* flag: set when the socket's peer has closed
+     * but packets are still queued for delivery
+     */
+    int closing;
 
     // flag: set when the socket failed to write, so the socket will not wait to
     // write packets and close directly.
     bool has_write_error;
 
-        /* flag: quit adbd when both ends close the
-        ** local service socket
-        */
-    int    exit_on_close;
+    /* flag: quit adbd when both ends close the
+     * local service socket
+     */
+    int exit_on_close;
 
-        /* the asocket we are connected to
-        */
+    // the asocket we are connected to
+    asocket* peer;
 
-    asocket *peer;
-
-        /* For local asockets, the fde is used to bind
-        ** us to our fd event system.  For remote asockets
-        ** these fields are not used.
-        */
+    /* For local asockets, the fde is used to bind
+     * us to our fd event system.  For remote asockets
+     * these fields are not used.
+     */
     fdevent fde;
     int fd;
 
-        /* queue of apackets waiting to be written
-        */
-    apacket *pkt_first;
-    apacket *pkt_last;
+    // queue of apackets waiting to be written
+    apacket* pkt_first;
+    apacket* pkt_last;
 
-        /* enqueue is called by our peer when it has data
-        ** for us.  It should return 0 if we can accept more
-        ** data or 1 if not.  If we return 1, we must call
-        ** peer->ready() when we once again are ready to
-        ** receive data.
-        */
-    int (*enqueue)(asocket *s, apacket *pkt);
+    /* enqueue is called by our peer when it has data
+     * for us.  It should return 0 if we can accept more
+     * data or 1 if not.  If we return 1, we must call
+     * peer->ready() when we once again are ready to
+     * receive data.
+     */
+    int (*enqueue)(asocket* s, apacket* pkt);
 
-        /* ready is called by the peer when it is ready for
-        ** us to send data via enqueue again
-        */
-    void (*ready)(asocket *s);
+    /* ready is called by the peer when it is ready for
+     * us to send data via enqueue again
+     */
+    void (*ready)(asocket* s);
 
-        /* shutdown is called by the peer before it goes away.
-        ** the socket should not do any further calls on its peer.
-        ** Always followed by a call to close. Optional, i.e. can be NULL.
-        */
-    void (*shutdown)(asocket *s);
+    /* shutdown is called by the peer before it goes away.
+     * the socket should not do any further calls on its peer.
+     * Always followed by a call to close. Optional, i.e. can be NULL.
+     */
+    void (*shutdown)(asocket* s);
 
-        /* close is called by the peer when it has gone away.
-        ** we are not allowed to make any further calls on the
-        ** peer once our close method is called.
-        */
-    void (*close)(asocket *s);
+    /* close is called by the peer when it has gone away.
+     * we are not allowed to make any further calls on the
+     * peer once our close method is called.
+     */
+    void (*close)(asocket* s);
 
-        /* A socket is bound to atransport */
-    atransport *transport;
+    /* A socket is bound to atransport */
+    atransport* transport;
 
     size_t get_max_payload() const;
 };
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index e0143c6..c53fbb4 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -96,7 +96,7 @@
 }
 
 void remove_socket(asocket* s) {
-    // socket_list_lock should already be held
+    std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
     if (s->prev && s->next) {
         s->prev->next = s->next;
         s->next->prev = s->prev;
@@ -430,10 +430,11 @@
 }
 
 #if ADB_HOST
-static asocket* create_host_service_socket(const char* name, const char* serial) {
+static asocket* create_host_service_socket(const char* name, const char* serial,
+                                           TransportId transport_id) {
     asocket* s;
 
-    s = host_service_to_socket(name, serial);
+    s = host_service_to_socket(name, serial, transport_id);
 
     if (s != NULL) {
         D("LS(%d) bound to '%s'", s->id, name);
@@ -658,6 +659,7 @@
 #if ADB_HOST
     char* service = nullptr;
     char* serial = nullptr;
+    TransportId transport_id = 0;
     TransportType type = kTransportAny;
 #endif
 
@@ -715,6 +717,14 @@
             serial = service;
             service = serial_end + 1;
         }
+    } else if (!strncmp(service, "host-transport-id:", strlen("host-transport-id:"))) {
+        service += strlen("host-transport-id:");
+        transport_id = strtoll(service, &service, 10);
+
+        if (*service != ':') {
+            return -1;
+        }
+        service++;
     } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
         type = kTransportUsb;
         service += strlen("host-usb:");
@@ -736,7 +746,7 @@
         ** the OKAY or FAIL message and all we have to do
         ** is clean up.
         */
-        if (handle_host_request(service, type, serial, s->peer->fd, s) == 0) {
+        if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s) == 0) {
             /* XXX fail message? */
             D("SS(%d): handled host service '%s'", s->id, service);
             goto fail;
@@ -751,7 +761,7 @@
         ** if no such service exists, we'll fail out
         ** and tear down here.
         */
-        s2 = create_host_service_socket(service, serial);
+        s2 = create_host_service_socket(service, serial, transport_id);
         if (s2 == 0) {
             D("SS(%d): couldn't create host service '%s'", s->id, service);
             SendFail(s->peer->fd, "unknown host service");
@@ -783,7 +793,7 @@
 #else /* !ADB_HOST */
     if (s->transport == nullptr) {
         std::string error_msg = "unknown failure";
-        s->transport = acquire_one_transport(kTransportAny, nullptr, nullptr, &error_msg);
+        s->transport = acquire_one_transport(kTransportAny, nullptr, 0, nullptr, &error_msg);
         if (s->transport == nullptr) {
             SendFail(s->peer->fd, error_msg);
             goto fail;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 49c7847..0abb680 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -582,18 +582,12 @@
 #ifdef __APPLE__
     return pthread_setname_np(name.c_str());
 #else
-    const char *s = name.c_str();
-
-    // pthread_setname_np fails rather than truncating long strings.
-    const int max_task_comm_len = 16; // including the null terminator
-    if (name.length() > (max_task_comm_len - 1)) {
-        char buf[max_task_comm_len];
-        strncpy(buf, name.c_str(), sizeof(buf) - 1);
-        buf[sizeof(buf) - 1] = '\0';
-        s = buf;
-    }
-
-    return pthread_setname_np(pthread_self(), s) ;
+    // Both bionic and glibc's pthread_setname_np fails rather than truncating long strings.
+    // glibc doesn't have strlcpy, so we have to fake it.
+    char buf[16];  // MAX_TASK_COMM_LEN, but that's not exported by the kernel headers.
+    strncpy(buf, name.c_str(), sizeof(buf) - 1);
+    buf[sizeof(buf) - 1] = '\0';
+    return pthread_setname_np(pthread_self(), buf);
 #endif
 }
 
diff --git a/adb/test_device.py b/adb/test_device.py
index 9e1a2ec..ddceda9 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -1237,7 +1237,7 @@
                 return m.group(2)
         return None
 
-    def test_killed_when_pushing_a_large_file(self):
+    def disabled_test_killed_when_pushing_a_large_file(self):
         """
            While running adb push with a large file, kill adb server.
            Occasionally the device becomes offline. Because the device is still
@@ -1268,7 +1268,7 @@
         # 4. The device should be online
         self.assertEqual(self._get_device_state(serialno), 'device')
 
-    def test_killed_when_pulling_a_large_file(self):
+    def disabled_test_killed_when_pulling_a_large_file(self):
         """
            While running adb pull with a large file, kill adb server.
            Occasionally the device can't be connected. Because the device is trying to
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 2bbbefd..c644893 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -21,6 +21,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -36,6 +37,7 @@
 #include <android-base/quick_exit.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
 
 #include "adb.h"
 #include "adb_auth.h"
@@ -46,10 +48,11 @@
 
 static void transport_unref(atransport *t);
 
+// TODO: unordered_map<TransportId, atransport*>
 static auto& transport_list = *new std::list<atransport*>();
 static auto& pending_list = *new std::list<atransport*>();
 
-static std::mutex& transport_lock = *new std::mutex();
+static auto& transport_lock = *new std::recursive_mutex();
 
 const char* const kFeatureShell2 = "shell_v2";
 const char* const kFeatureCmd = "cmd";
@@ -57,6 +60,11 @@
 const char* const kFeatureLibusb = "libusb";
 const char* const kFeaturePushSync = "push_sync";
 
+TransportId NextTransportId() {
+    static std::atomic<TransportId> next(1);
+    return next++;
+}
+
 static std::string dump_packet(const char* name, const char* func, apacket* p) {
     unsigned command = p->msg.command;
     int len = p->msg.data_length;
@@ -298,9 +306,11 @@
 }
 
 void kick_transport(atransport* t) {
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     // As kick_transport() can be called from threads without guarantee that t is valid,
     // check if the transport is in transport_list first.
+    //
+    // TODO(jmgao): WTF? Is this actually true?
     if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) {
         t->Kick();
     }
@@ -330,7 +340,7 @@
     device_tracker** pnode = &device_tracker_list;
     device_tracker* node = *pnode;
 
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     while (node) {
         if (node == tracker) {
             *pnode = node->next;
@@ -403,7 +413,7 @@
 
 // Check if all of the USB transports are connected.
 bool iterate_transports(std::function<bool(const atransport*)> fn) {
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     for (const auto& t : transport_list) {
         if (!fn(t)) {
             return false;
@@ -507,7 +517,7 @@
         adb_close(t->fd);
 
         {
-            std::lock_guard<std::mutex> lock(transport_lock);
+            std::lock_guard<std::recursive_mutex> lock(transport_lock);
             transport_list.remove(t);
         }
 
@@ -546,7 +556,7 @@
     }
 
     {
-        std::lock_guard<std::mutex> lock(transport_lock);
+        std::lock_guard<std::recursive_mutex> lock(transport_lock);
         pending_list.remove(t);
         transport_list.push_front(t);
     }
@@ -573,7 +583,7 @@
 
 void kick_all_transports() {
     // To avoid only writing part of a packet to a transport after exit, kick all transports.
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     for (auto t : transport_list) {
         t->Kick();
     }
@@ -603,15 +613,15 @@
 static void transport_unref(atransport* t) {
     CHECK(t != nullptr);
 
-    size_t old_refcount = t->ref_count--;
-    CHECK_GT(old_refcount, 0u);
-
-    if (old_refcount == 1u) {
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
+    CHECK_GT(t->ref_count, 0u);
+    t->ref_count--;
+    if (t->ref_count == 0) {
         D("transport: %s unref (kicking and closing)", t->serial);
         t->close(t);
         remove_transport(t);
     } else {
-        D("transport: %s unref (count=%zu)", t->serial, old_refcount - 1);
+        D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
     }
 }
 
@@ -638,11 +648,15 @@
     return !*to_test;
 }
 
-atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous,
-                                  std::string* error_out, bool accept_any_state) {
+atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
+                                  bool* is_ambiguous, std::string* error_out,
+                                  bool accept_any_state) {
     atransport* result = nullptr;
 
-    if (serial) {
+    if (transport_id != 0) {
+        *error_out =
+            android::base::StringPrintf("no device with transport id '%" PRIu64 "'", transport_id);
+    } else if (serial) {
         *error_out = android::base::StringPrintf("device '%s' not found", serial);
     } else if (type == kTransportLocal) {
         *error_out = "no emulators found";
@@ -652,7 +666,7 @@
         *error_out = "no devices found";
     }
 
-    std::unique_lock<std::mutex> lock(transport_lock);
+    std::unique_lock<std::recursive_mutex> lock(transport_lock);
     for (const auto& t : transport_list) {
         if (t->GetConnectionState() == kCsNoPerm) {
 #if ADB_HOST
@@ -661,8 +675,12 @@
             continue;
         }
 
-        // Check for matching serial number.
-        if (serial) {
+        if (transport_id) {
+            if (t->id == transport_id) {
+                result = t;
+                break;
+            }
+        } else if (serial) {
             if (t->MatchesTarget(serial)) {
                 if (result) {
                     *error_out = "more than one device";
@@ -728,9 +746,6 @@
 }
 
 int atransport::Write(apacket* p) {
-#if ADB_HOST
-    std::lock_guard<std::mutex> lock(write_msg_lock_);
-#endif
     return write_func_(p, this);
 }
 
@@ -738,11 +753,6 @@
     if (!kicked_) {
         kicked_ = true;
         CHECK(kick_func_ != nullptr);
-#if ADB_HOST
-        // On host, adb server should avoid writing part of a packet, so don't
-        // kick a transport whiling writing a packet.
-        std::lock_guard<std::mutex> lock(write_msg_lock_);
-#endif
         kick_func_(this);
     }
 }
@@ -889,18 +899,23 @@
 
 #if ADB_HOST
 
+// We use newline as our delimiter, make sure to never output it.
+static std::string sanitize(std::string str, bool alphanumeric) {
+    auto pred = alphanumeric ? [](const char c) { return !isalnum(c); }
+                             : [](const char c) { return c == '\n'; };
+    std::replace_if(str.begin(), str.end(), pred, '_');
+    return str;
+}
+
 static void append_transport_info(std::string* result, const char* key, const char* value,
-                                  bool sanitize) {
+                                  bool alphanumeric) {
     if (value == nullptr || *value == '\0') {
         return;
     }
 
     *result += ' ';
     *result += key;
-
-    for (const char* p = value; *p; ++p) {
-        result->push_back((!sanitize || isalnum(*p)) ? *p : '_');
-    }
+    *result += sanitize(value, alphanumeric);
 }
 
 static void append_transport(const atransport* t, std::string* result, bool long_listing) {
@@ -920,6 +935,11 @@
         append_transport_info(result, "product:", t->product, false);
         append_transport_info(result, "model:", t->model, true);
         append_transport_info(result, "device:", t->device, false);
+
+        // Put id at the end, so that anyone parsing the output here can always find it by scanning
+        // backwards from newlines, even with hypothetical devices named 'transport_id:1'.
+        *result += " transport_id:";
+        *result += std::to_string(t->id);
     }
     *result += '\n';
 }
@@ -927,7 +947,7 @@
 std::string list_transports(bool long_listing) {
     std::string result;
 
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     for (const auto& t : transport_list) {
         append_transport(t, &result, long_listing);
     }
@@ -935,7 +955,7 @@
 }
 
 void close_usb_devices(std::function<bool(const atransport*)> predicate) {
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     for (auto& t : transport_list) {
         if (predicate(t)) {
             t->Kick();
@@ -964,7 +984,7 @@
         return -1;
     }
 
-    std::unique_lock<std::mutex> lock(transport_lock);
+    std::unique_lock<std::recursive_mutex> lock(transport_lock);
     for (const auto& transport : pending_list) {
         if (transport->serial && strcmp(serial, transport->serial) == 0) {
             VLOG(TRANSPORT) << "socket transport " << transport->serial
@@ -996,7 +1016,7 @@
 atransport* find_transport(const char* serial) {
     atransport* result = nullptr;
 
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     for (auto& t : transport_list) {
         if (t->serial && strcmp(serial, t->serial) == 0) {
             result = t;
@@ -1008,7 +1028,7 @@
 }
 
 void kick_all_tcp_devices() {
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     for (auto& t : transport_list) {
         if (t->IsTcpDevice()) {
             // Kicking breaks the read_transport thread of this transport out of any read, then
@@ -1037,7 +1057,7 @@
     }
 
     {
-        std::lock_guard<std::mutex> lock(transport_lock);
+        std::lock_guard<std::recursive_mutex> lock(transport_lock);
         pending_list.push_front(t);
     }
 
@@ -1046,7 +1066,7 @@
 
 // This should only be used for transports with connection_state == kCsNoPerm.
 void unregister_usb_transport(usb_handle* usb) {
-    std::lock_guard<std::mutex> lock(transport_lock);
+    std::lock_guard<std::recursive_mutex> lock(transport_lock);
     transport_list.remove_if(
         [usb](atransport* t) { return t->usb == usb && t->GetConnectionState() == kCsNoPerm; });
 }
@@ -1079,11 +1099,4 @@
     keys_.pop_front();
     return result;
 }
-bool atransport::SetSendConnectOnError() {
-    if (has_send_connect_on_error_) {
-        return false;
-    }
-    has_send_connect_on_error_ = true;
-    return true;
-}
 #endif
diff --git a/adb/transport.h b/adb/transport.h
index 4a89ed9..0f1a1d4 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -54,14 +54,17 @@
 // The server supports `push --sync`.
 extern const char* const kFeaturePushSync;
 
+TransportId NextTransportId();
+
 class atransport {
-public:
+  public:
     // TODO(danalbert): We expose waaaaaaay too much stuff because this was
     // historically just a struct, but making the whole thing a more idiomatic
     // class in one go is a very large change. Given how bad our testing is,
     // it's better to do this piece by piece.
 
-    atransport(ConnectionState state = kCsOffline) : ref_count(0), connection_state_(state) {
+    atransport(ConnectionState state = kCsOffline)
+        : id(NextTransportId()), connection_state_(state) {
         transport_fde = {};
         protocol_version = A_VERSION;
         max_payload = MAX_PAYLOAD;
@@ -72,12 +75,8 @@
     void (*close)(atransport* t) = nullptr;
 
     void SetWriteFunction(int (*write_func)(apacket*, atransport*)) { write_func_ = write_func; }
-    void SetKickFunction(void (*kick_func)(atransport*)) {
-        kick_func_ = kick_func;
-    }
-    bool IsKicked() {
-        return kicked_;
-    }
+    void SetKickFunction(void (*kick_func)(atransport*)) { kick_func_ = kick_func; }
+    bool IsKicked() { return kicked_; }
     int Write(apacket* p);
     void Kick();
 
@@ -85,10 +84,11 @@
     ConnectionState GetConnectionState() const;
     void SetConnectionState(ConnectionState state);
 
+    const TransportId id;
     int fd = -1;
     int transport_socket = -1;
     fdevent transport_fde;
-    std::atomic<size_t> ref_count;
+    size_t ref_count = 0;
     uint32_t sync_token = 0;
     bool online = false;
     TransportType type = kTransportAny;
@@ -122,7 +122,6 @@
 
 #if ADB_HOST
     std::shared_ptr<RSA> NextKey();
-    bool SetSendConnectOnError();
 #endif
 
     char token[TOKEN_SIZE] = {};
@@ -181,8 +180,6 @@
     std::atomic<ConnectionState> connection_state_;
 #if ADB_HOST
     std::deque<std::shared_ptr<RSA>> keys_;
-    std::mutex write_msg_lock_;
-    bool has_send_connect_on_error_ = false;
 #endif
 
     DISALLOW_COPY_AND_ASSIGN(atransport);
@@ -191,12 +188,14 @@
 /*
  * Obtain a transport from the available transports.
  * If serial is non-null then only the device with that serial will be chosen.
+ * If transport_id is non-zero then only the device with that transport ID will be chosen.
  * If multiple devices/emulators would match, *is_ambiguous (if non-null)
  * is set to true and nullptr returned.
  * If no suitable transport is found, error is set and nullptr returned.
  */
-atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous,
-                                  std::string* error_out, bool accept_any_state = false);
+atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
+                                  bool* is_ambiguous, std::string* error_out,
+                                  bool accept_any_state = false);
 void kick_transport(atransport* t);
 void update_transports(void);
 
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 809ed89..9cd378c 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -388,6 +388,25 @@
     D("transport: qemu_socket_thread() exiting");
     return;
 }
+
+// If adbd is running inside the emulator, it will normally use QEMUD pipe (aka
+// goldfish) as the transport. This can either be explicitly set by the
+// service.adb.transport property, or be inferred from ro.kernel.qemu that is
+// set to "1" for ranchu/goldfish.
+static bool use_qemu_goldfish() {
+    // Legacy way to detect if adbd should use the goldfish pipe is to check for
+    // ro.kernel.qemu, keep that behaviour for backward compatibility.
+    if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
+        return true;
+    }
+    // If service.adb.transport is present and is set to "goldfish", use the
+    // QEMUD pipe.
+    if (android::base::GetProperty("service.adb.transport", "") == "goldfish") {
+        return true;
+    }
+    return false;
+}
+
 #endif  // !ADB_HOST
 
 void local_init(int port)
@@ -401,13 +420,7 @@
 #else
     // 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.
-        func = server_socket_thread;
-    }
+    func = use_qemu_goldfish() ? qemu_socket_thread : server_socket_thread;
     debug_name = "server";
 #endif // !ADB_HOST
 
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index 7e8ae67..e5845f0 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -103,13 +103,6 @@
 
 err_msg:
     p->msg.command = 0;
-    if (t->GetConnectionState() == kCsOffline) {
-        // If the data toggle of ep_out on device and ep_in on host are not the same, we may receive
-        // an error message. In this case, resend one A_CNXN message to connect the device.
-        if (t->SetSendConnectOnError()) {
-            SendConnectOnHost(t);
-        }
-    }
     return 0;
 }
 
@@ -162,8 +155,7 @@
     return 0;
 }
 
-static void remote_close(atransport *t)
-{
+static void remote_close(atransport* t) {
     usb_close(t->usb);
     t->usb = 0;
 }
diff --git a/adf/libadf/Android.bp b/adf/libadf/Android.bp
index c276c53..8eef2ea 100644
--- a/adf/libadf/Android.bp
+++ b/adf/libadf/Android.bp
@@ -12,8 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-cc_library_static {
+cc_library {
     name: "libadf",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     srcs: ["adf.cpp"],
     cflags: ["-Werror"],
     local_include_dirs: ["include"],
diff --git a/base/Android.bp b/base/Android.bp
index b636dc3..6c3a593 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -41,6 +41,10 @@
     vendor_available: true,
     clang: true,
     host_supported: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     srcs: [
         "file.cpp",
         "logging.cpp",
diff --git a/base/chrono_utils.cpp b/base/chrono_utils.cpp
index 5eedf3b..b6bf701 100644
--- a/base/chrono_utils.cpp
+++ b/base/chrono_utils.cpp
@@ -33,5 +33,10 @@
 #endif  // __ANDROID__
 }
 
+std::ostream& operator<<(std::ostream& os, const Timer& t) {
+  os << t.duration().count() << "ms";
+  return os;
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/base/chrono_utils_test.cpp b/base/chrono_utils_test.cpp
index 057132d..da442f4 100644
--- a/base/chrono_utils_test.cpp
+++ b/base/chrono_utils_test.cpp
@@ -19,6 +19,9 @@
 #include <time.h>
 
 #include <chrono>
+#include <sstream>
+#include <string>
+#include <thread>
 
 #include <gtest/gtest.h>
 
@@ -42,5 +45,36 @@
   EXPECT_EQ(now, boot_seconds);
 }
 
+template <typename T>
+void ExpectAboutEqual(T expected, T actual) {
+  auto expected_upper_bound = expected * 1.05f;
+  auto expected_lower_bound = expected * .95;
+  EXPECT_GT(expected_upper_bound, actual);
+  EXPECT_LT(expected_lower_bound, actual);
+}
+
+TEST(ChronoUtilsTest, TimerDurationIsSane) {
+  auto start = boot_clock::now();
+  Timer t;
+  std::this_thread::sleep_for(50ms);
+  auto stop = boot_clock::now();
+  auto stop_timer = t.duration();
+
+  auto expected = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
+  ExpectAboutEqual(expected, stop_timer);
+}
+
+TEST(ChronoUtilsTest, TimerOstream) {
+  Timer t;
+  std::this_thread::sleep_for(50ms);
+  auto stop_timer = t.duration().count();
+  std::stringstream os;
+  os << t;
+  decltype(stop_timer) stop_timer_from_stream;
+  os >> stop_timer_from_stream;
+  EXPECT_NE(0, stop_timer);
+  ExpectAboutEqual(stop_timer, stop_timer_from_stream);
+}
+
 }  // namespace base
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/base/include/android-base/chrono_utils.h b/base/include/android-base/chrono_utils.h
index 0086425..7679d4c 100644
--- a/base/include/android-base/chrono_utils.h
+++ b/base/include/android-base/chrono_utils.h
@@ -18,6 +18,9 @@
 #define ANDROID_BASE_CHRONO_UTILS_H
 
 #include <chrono>
+#include <sstream>
+
+using namespace std::chrono_literals;
 
 namespace android {
 namespace base {
@@ -31,6 +34,20 @@
   static time_point now();
 };
 
+class Timer {
+ public:
+  Timer() : start_(boot_clock::now()) {}
+
+  std::chrono::milliseconds duration() const {
+    return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_);
+  }
+
+ private:
+  boot_clock::time_point start_;
+};
+
+std::ostream& operator<<(std::ostream& os, const Timer& t);
+
 }  // namespace base
 }  // namespace android
 
diff --git a/base/include/android-base/utf8.h b/base/include/android-base/utf8.h
index 2d5a6f6..c9cc1ab 100755
--- a/base/include/android-base/utf8.h
+++ b/base/include/android-base/utf8.h
@@ -22,6 +22,8 @@
 #else
 // Bring in prototypes for standard APIs so that we can import them into the utf8 namespace.
 #include <fcntl.h>      // open
+#include <stdio.h>      // fopen
+#include <sys/stat.h>   // mkdir
 #include <unistd.h>     // unlink
 #endif
 
@@ -53,6 +55,19 @@
 // Convert a UTF-8 std::string (including any embedded NULL characters) to
 // UTF-16. Returns whether the conversion was done successfully.
 bool UTF8ToWide(const std::string& utf8, std::wstring* utf16);
+
+// Convert a file system path, represented as a NULL-terminated string of
+// UTF-8 characters, to a UTF-16 string representing the same file system
+// path using the Windows extended-lengh path representation.
+//
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#MAXPATH:
+//   ```The Windows API has many functions that also have Unicode versions to
+//   permit an extended-length path for a maximum total path length of 32,767
+//   characters. To specify an extended-length path, use the "\\?\" prefix.
+//   For example, "\\?\D:\very long path".```
+//
+// Returns whether the conversion was done successfully.
+bool UTF8PathToWindowsLongPath(const char* utf8, std::wstring* utf16);
 #endif
 
 // The functions in the utf8 namespace take UTF-8 strings. For Windows, these
@@ -73,9 +88,13 @@
 namespace utf8 {
 
 #ifdef _WIN32
+FILE* fopen(const char* name, const char* mode);
+int mkdir(const char* name, mode_t mode);
 int open(const char* name, int flags, ...);
 int unlink(const char* name);
 #else
+using ::fopen;
+using ::mkdir;
 using ::open;
 using ::unlink;
 #endif
diff --git a/base/utf8.cpp b/base/utf8.cpp
index 3cca700..5984fb0 100644
--- a/base/utf8.cpp
+++ b/base/utf8.cpp
@@ -19,7 +19,9 @@
 #include "android-base/utf8.h"
 
 #include <fcntl.h>
+#include <stdio.h>
 
+#include <algorithm>
 #include <string>
 
 #include "android-base/logging.h"
@@ -153,12 +155,58 @@
   return UTF8ToWide(utf8.c_str(), utf8.length(), utf16);
 }
 
+static bool isDriveLetter(wchar_t c) {
+  return (c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z');
+}
+
+bool UTF8PathToWindowsLongPath(const char* utf8, std::wstring* utf16) {
+  if (!UTF8ToWide(utf8, utf16)) {
+    return false;
+  }
+  // Note: Although most Win32 File I/O API are limited to MAX_PATH (260
+  //       characters), the CreateDirectory API is limited to 248 characters.
+  if (utf16->length() >= 248) {
+    // If path is of the form "x:\" or "x:/"
+    if (isDriveLetter((*utf16)[0]) && (*utf16)[1] == L':' &&
+        ((*utf16)[2] == L'\\' || (*utf16)[2] == L'/')) {
+      // Append long path prefix, and make sure there are no unix-style
+      // separators to ensure a fully compliant Win32 long path string.
+      utf16->insert(0, LR"(\\?\)");
+      std::replace(utf16->begin(), utf16->end(), L'/', L'\\');
+    }
+  }
+  return true;
+}
+
 // Versions of standard library APIs that support UTF-8 strings.
 namespace utf8 {
 
+FILE* fopen(const char* name, const char* mode) {
+  std::wstring name_utf16;
+  if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
+    return nullptr;
+  }
+
+  std::wstring mode_utf16;
+  if (!UTF8ToWide(mode, &mode_utf16)) {
+    return nullptr;
+  }
+
+  return _wfopen(name_utf16.c_str(), mode_utf16.c_str());
+}
+
+int mkdir(const char* name, mode_t mode) {
+  std::wstring name_utf16;
+  if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
+    return -1;
+  }
+
+  return _wmkdir(name_utf16.c_str());
+}
+
 int open(const char* name, int flags, ...) {
   std::wstring name_utf16;
-  if (!UTF8ToWide(name, &name_utf16)) {
+  if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
     return -1;
   }
 
@@ -175,7 +223,7 @@
 
 int unlink(const char* name) {
   std::wstring name_utf16;
-  if (!UTF8ToWide(name, &name_utf16)) {
+  if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
     return -1;
   }
 
diff --git a/base/utf8_test.cpp b/base/utf8_test.cpp
index ae8fc8c..fcb25c3 100644
--- a/base/utf8_test.cpp
+++ b/base/utf8_test.cpp
@@ -18,7 +18,12 @@
 
 #include <gtest/gtest.h>
 
+#include <fcntl.h>
+#include <stdlib.h>
+
 #include "android-base/macros.h"
+#include "android-base/test_utils.h"
+#include "android-base/unique_fd.h"
 
 namespace android {
 namespace base {
@@ -408,5 +413,76 @@
   EXPECT_EQ(expected_null, SysUTF8ToWide(utf8_null));
 }
 
+TEST(UTF8PathToWindowsLongPathTest, DontAddPrefixIfShorterThanMaxPath) {
+  std::string utf8 = "c:\\mypath\\myfile.txt";
+
+  std::wstring wide;
+  EXPECT_TRUE(UTF8PathToWindowsLongPath(utf8.c_str(), &wide));
+
+  EXPECT_EQ(std::string::npos, wide.find(LR"(\\?\)"));
+}
+
+TEST(UTF8PathToWindowsLongPathTest, AddPrefixIfLongerThanMaxPath) {
+  std::string utf8 = "c:\\mypath";
+  while (utf8.length() < 300 /* MAX_PATH is 260 */) {
+    utf8 += "\\mypathsegment";
+  }
+
+  std::wstring wide;
+  EXPECT_TRUE(UTF8PathToWindowsLongPath(utf8.c_str(), &wide));
+
+  EXPECT_EQ(0U, wide.find(LR"(\\?\)"));
+  EXPECT_EQ(std::string::npos, wide.find(L"/"));
+}
+
+TEST(UTF8PathToWindowsLongPathTest, AddPrefixAndFixSeparatorsIfLongerThanMaxPath) {
+  std::string utf8 = "c:/mypath";
+  while (utf8.length() < 300 /* MAX_PATH is 260 */) {
+    utf8 += "/mypathsegment";
+  }
+
+  std::wstring wide;
+  EXPECT_TRUE(UTF8PathToWindowsLongPath(utf8.c_str(), &wide));
+
+  EXPECT_EQ(0U, wide.find(LR"(\\?\)"));
+  EXPECT_EQ(std::string::npos, wide.find(L"/"));
+}
+
+namespace utf8 {
+
+TEST(Utf8FilesTest, CanCreateOpenAndDeleteFileWithLongPath) {
+  TemporaryDir td;
+
+  // Create long directory path
+  std::string utf8 = td.path;
+  while (utf8.length() < 300 /* MAX_PATH is 260 */) {
+    utf8 += "\\mypathsegment";
+    EXPECT_EQ(0, mkdir(utf8.c_str(), 0));
+  }
+
+  // Create file
+  utf8 += "\\test-file.bin";
+  int flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
+  int mode = 0666;
+  android::base::unique_fd fd(open(utf8.c_str(), flags, mode));
+  EXPECT_NE(-1, fd.get());
+
+  // Close file
+  fd.reset();
+  EXPECT_EQ(-1, fd.get());
+
+  // Open file with fopen
+  FILE* file = fopen(utf8.c_str(), "rb");
+  EXPECT_NE(nullptr, file);
+
+  if (file) {
+    fclose(file);
+  }
+
+  // Delete file
+  EXPECT_EQ(0, unlink(utf8.c_str()));
+}
+
+}  // namespace utf8
 }  // namespace base
 }  // namespace android
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index a4c2160..f887d46 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -85,12 +85,13 @@
   fprintf(stderr, "Usage: %s [options]\n", cmd);
   fprintf(stderr,
           "options include:\n"
-          "  -h, --help            Show this help\n"
-          "  -l, --log             Log all metrics to logstorage\n"
-          "  -p, --print           Dump the boot event records to the console\n"
-          "  -r, --record          Record the timestamp of a named boot event\n"
-          "  --value               Optional value to associate with the boot event\n"
-          "  --record_boot_reason  Record the reason why the device booted\n"
+          "  -h, --help              Show this help\n"
+          "  -l, --log               Log all metrics to logstorage\n"
+          "  -p, --print             Dump the boot event records to the console\n"
+          "  -r, --record            Record the timestamp of a named boot event\n"
+          "  --value                 Optional value to associate with the boot event\n"
+          "  --record_boot_complete  Record metrics related to the time for the device boot\n"
+          "  --record_boot_reason    Record the reason why the device booted\n"
           "  --record_time_since_factory_reset Record the time since the device was reset\n");
 }
 
@@ -168,6 +169,13 @@
   {"wdog_bark", 42},
   {"wdog_bite", 43},
   {"wdog_reset", 44},
+  {"shutdown,", 45},  // Trailing comma is intentional.
+  {"shutdown,userrequested", 46},
+  {"reboot,bootloader", 47},
+  {"reboot,cold", 48},
+  {"reboot,recovery", 49},
+  {"thermal_shutdown", 50},
+  {"s3_wakeup", 51}
 };
 
 // Converts a string value representing the reason the system booted to an
@@ -350,7 +358,12 @@
 // Records the boot_reason metric by querying the ro.boot.bootreason system
 // property.
 void RecordBootReason() {
-  int32_t boot_reason = BootReasonStrToEnum(GetProperty("ro.boot.bootreason"));
+  std::string boot_reason_str = GetProperty("ro.boot.bootreason");
+  android::metricslogger::LogMultiAction(android::metricslogger::ACTION_BOOT,
+                                         android::metricslogger::FIELD_PLATFORM_REASON,
+                                         boot_reason_str);
+
+  int32_t boot_reason = BootReasonStrToEnum(boot_reason_str);
   BootEventRecordStore boot_event_store;
   boot_event_store.AddBootEventWithValue("boot_reason", boot_reason);
 }
diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc
index f4756d5..2c48fae 100644
--- a/bootstat/bootstat.rc
+++ b/bootstat/bootstat.rc
@@ -1,7 +1,39 @@
 # This file is the LOCAL_INIT_RC file for the bootstat command.
 
 on post-fs-data
-    mkdir /data/misc/bootstat 0700 root root
+    mkdir /data/misc/bootstat 0700 system log
+    # To deal with ota transition resulting from a change in DAC from
+    # root.root to system.log, may be deleted after ota has settled.
+    chown system log /data/misc/bootstat/absolute_boot_time
+    chown system log /data/misc/bootstat/boot_complete
+    chown system log /data/misc/bootstat/boot_complete_no_encryption
+    chown system log /data/misc/bootstat/boot_reason
+    chown system log /data/misc/bootstat/boottime.bootloader.1BLE
+    chown system log /data/misc/bootstat/boottime.bootloader.1BLL
+    chown system log /data/misc/bootstat/boottime.bootloader.2BLE
+    chown system log /data/misc/bootstat/boottime.bootloader.2BLL
+    chown system log /data/misc/bootstat/boottime.bootloader.AVB
+    chown system log /data/misc/bootstat/boottime.bootloader.KD
+    chown system log /data/misc/bootstat/boottime.bootloader.KL
+    chown system log /data/misc/bootstat/boottime.bootloader.ODT
+    chown system log /data/misc/bootstat/boottime.bootloader.SW
+    chown system log /data/misc/bootstat/boottime.bootloader.total
+    chown system log /data/misc/bootstat/build_date
+    chown system log /data/misc/bootstat/factory_reset
+    chown system log /data/misc/bootstat/factory_reset_boot_complete
+    chown system log /data/misc/bootstat/factory_reset_boot_complete_no_encryption
+    chown system log /data/misc/bootstat/factory_reset_current_time
+    chown system log /data/misc/bootstat/factory_reset_record_value
+    chown system log /data/misc/bootstat/last_boot_time_utc
+    chown system log /data/misc/bootstat/ota_boot_complete
+    chown system log /data/misc/bootstat/ota_boot_complete_no_encryption
+    chown system log /data/misc/bootstat/post_decrypt_time_elapsed
+    chown system log /data/misc/bootstat/ro.boottime.init
+    chown system log /data/misc/bootstat/ro.boottime.init.cold_boot_wait
+    chown system log /data/misc/bootstat/ro.boottime.init.selinux
+    chown system log /data/misc/bootstat/time_since_factory_reset
+    chown system log /data/misc/bootstat/time_since_last_boot
+    # end ota transitional support
 
 # Record the time at which the user has successfully entered the pin to decrypt
 # the device, /data is decrypted, and the system is entering the main boot phase.
@@ -10,7 +42,7 @@
 # property:init.svc.bootanim=running: The boot animation is running
 # property:ro.crypto.type=block: FDE device
 on post-fs-data && property:init.svc.bootanim=running && property:ro.crypto.type=block
-    exec - root root -- /system/bin/bootstat -r post_decrypt_time_elapsed
+    exec - system log -- /system/bin/bootstat -r post_decrypt_time_elapsed
 
 # sys.logbootcomplete is a signal to enable the bootstat logging mechanism.
 # This signaling is necessary to prevent logging boot metrics after a runtime
@@ -33,13 +65,13 @@
 # Record boot complete metrics.
 on property:sys.boot_completed=1 && property:sys.logbootcomplete=1
     # Record boot_complete and related stats (decryption, etc).
-    exec - root root -- /system/bin/bootstat --record_boot_complete
+    exec - system log -- /system/bin/bootstat --record_boot_complete
 
     # Record the boot reason.
-    exec - root root -- /system/bin/bootstat --record_boot_reason
+    exec - system log -- /system/bin/bootstat --record_boot_reason
 
     # Record time since factory reset.
-    exec - root root -- /system/bin/bootstat --record_time_since_factory_reset
+    exec - system log -- /system/bin/bootstat --record_time_since_factory_reset
 
     # Log all boot events.
-    exec - root root -- /system/bin/bootstat -l
+    exec - system log -- /system/bin/bootstat -l
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 5565cfd..f86aaa0 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -274,7 +274,7 @@
         "libbase",
         "libdebuggerd_client",
         "liblog",
-        "libselinux",
+        "libprocinfo",
     ],
 
     local_include_dirs: ["include"],
diff --git a/debuggerd/client/debuggerd_client_test.cpp b/debuggerd/client/debuggerd_client_test.cpp
index 8420f03..9c2f0d6 100644
--- a/debuggerd/client/debuggerd_client_test.cpp
+++ b/debuggerd/client/debuggerd_client_test.cpp
@@ -27,6 +27,7 @@
 #include <gtest/gtest.h>
 
 #include <android-base/file.h>
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
@@ -36,8 +37,20 @@
 using namespace std::chrono_literals;
 using android::base::unique_fd;
 
+static int getThreadCount() {
+  int threadCount = 1024;
+  std::vector<std::string> characteristics =
+      android::base::Split(android::base::GetProperty("ro.build.characteristics", ""), ",");
+  if (std::find(characteristics.begin(), characteristics.end(), "embedded")
+      != characteristics.end()) {
+    // 128 is the realistic number for iot devices.
+    threadCount = 128;
+  }
+  return threadCount;
+}
+
 TEST(debuggerd_client, race) {
-  static constexpr int THREAD_COUNT = 1024;
+  static int THREAD_COUNT = getThreadCount();
   pid_t forkpid = fork();
 
   ASSERT_NE(-1, forkpid);
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 5db0e5f..4b1e51d 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -44,6 +44,9 @@
 #include <private/android_filesystem_config.h>
 #include <procinfo/process.h>
 
+#define ATRACE_TAG ATRACE_TAG_BIONIC
+#include <utils/Trace.h>
+
 #include "backtrace.h"
 #include "tombstone.h"
 #include "utility.h"
@@ -101,6 +104,7 @@
 }
 
 static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data) {
+  ATRACE_CALL();
   android::base::unique_fd amfd(socket_local_client(
       "/data/system/ndebugsocket", ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM));
   if (amfd.get() == -1) {
@@ -176,6 +180,7 @@
 }
 
 static void drop_capabilities() {
+  ATRACE_CALL();
   __user_cap_header_struct capheader;
   memset(&capheader, 0, sizeof(capheader));
   capheader.version = _LINUX_CAPABILITY_VERSION_3;
@@ -194,6 +199,8 @@
 }
 
 int main(int argc, char** argv) {
+  atrace_begin(ATRACE_TAG, "before reparent");
+
   pid_t target = getppid();
   bool tombstoned_connected = false;
   unique_fd tombstoned_socket;
@@ -261,6 +268,8 @@
     PLOG(FATAL) << "parent died";
   }
 
+  atrace_end(ATRACE_TAG);
+
   // Reparent ourselves to init, so that the signal handler can waitpid on the
   // original process to avoid leaving a zombie for non-fatal dumps.
   pid_t forkpid = fork();
@@ -270,6 +279,8 @@
     exit(0);
   }
 
+  ATRACE_NAME("after reparent");
+
   // Die if we take too long.
   //
   // Note: processes with many threads and minidebug-info can take a bit to
@@ -278,42 +289,53 @@
 
   std::string attach_error;
 
-  // Seize the main thread.
-  if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
-    LOG(FATAL) << attach_error;
-  }
-
-  // Seize the siblings.
   std::map<pid_t, std::string> threads;
+
   {
-    std::set<pid_t> siblings;
-    if (!android::procinfo::GetProcessTids(target, &siblings)) {
-      PLOG(FATAL) << "failed to get process siblings";
+    ATRACE_NAME("ptrace");
+    // Seize the main thread.
+    if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
+      LOG(FATAL) << attach_error;
     }
 
-    // but not the already attached main thread.
-    siblings.erase(main_tid);
-    // or the handler pseudothread.
-    siblings.erase(pseudothread_tid);
+    // Seize the siblings.
+    {
+      std::set<pid_t> siblings;
+      if (!android::procinfo::GetProcessTids(target, &siblings)) {
+        PLOG(FATAL) << "failed to get process siblings";
+      }
 
-    for (pid_t sibling_tid : siblings) {
-      if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
-        LOG(WARNING) << attach_error;
-      } else {
-        threads.emplace(sibling_tid, get_thread_name(sibling_tid));
+      // but not the already attached main thread.
+      siblings.erase(main_tid);
+      // or the handler pseudothread.
+      siblings.erase(pseudothread_tid);
+
+      for (pid_t sibling_tid : siblings) {
+        if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
+          LOG(WARNING) << attach_error;
+        } else {
+          threads.emplace(sibling_tid, get_thread_name(sibling_tid));
+        }
       }
     }
   }
 
   // Collect the backtrace map, open files, and process/thread names, while we still have caps.
-  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
-  if (!backtrace_map) {
-    LOG(FATAL) << "failed to create backtrace map";
+  std::unique_ptr<BacktraceMap> backtrace_map;
+  {
+    ATRACE_NAME("backtrace map");
+    backtrace_map.reset(BacktraceMap::Create(main_tid));
+    if (!backtrace_map) {
+      LOG(FATAL) << "failed to create backtrace map";
+    }
   }
 
   // Collect the list of open files.
   OpenFilesList open_files;
-  populate_open_files_list(target, &open_files);
+  {
+    ATRACE_NAME("open files");
+    populate_open_files_list(target, &open_files);
+  }
 
   std::string process_name = get_process_name(main_tid);
   threads.emplace(main_tid, get_thread_name(main_tid));
@@ -321,9 +343,12 @@
   // Drop our capabilities now that we've attached to the threads we care about.
   drop_capabilities();
 
-  const DebuggerdDumpType dump_type_enum = static_cast<DebuggerdDumpType>(dump_type);
-  LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type_enum;
-  tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum);
+  {
+    ATRACE_NAME("tombstoned_connect");
+    const DebuggerdDumpType dump_type_enum = static_cast<DebuggerdDumpType>(dump_type);
+    LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type_enum;
+    tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum);
+  }
 
   // Write a '\1' to stdout to tell the crashing process to resume.
   // It also restores the value of PR_SET_DUMPABLE at this point.
@@ -352,9 +377,12 @@
   }
 
   siginfo_t siginfo = {};
-  if (!wait_for_signal(main_tid, &siginfo)) {
-    printf("failed to wait for signal in tid %d: %s\n", main_tid, strerror(errno));
-    exit(1);
+  {
+    ATRACE_NAME("wait_for_signal");
+    if (!wait_for_signal(main_tid, &siginfo)) {
+      printf("failed to wait for signal in tid %d: %s\n", main_tid, strerror(errno));
+      exit(1);
+    }
   }
 
   int signo = siginfo.si_signo;
@@ -376,8 +404,10 @@
 
   std::string amfd_data;
   if (backtrace) {
+    ATRACE_NAME("dump_backtrace");
     dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0);
   } else {
+    ATRACE_NAME("engrave_tombstone");
     engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid,
                       process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr);
   }
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index 6970201..f57349b 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -134,6 +134,14 @@
     free(buf); // GCC is smart enough to warn about this, but we're doing it deliberately.
 }
 
+noinline void leak() {
+    while (true) {
+        void* mapping =
+            mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+        static_cast<volatile char*>(mapping)[0] = 'a';
+    }
+}
+
 noinline void sigsegv_non_null() {
     int* a = (int *)(&do_action);
     *a = 42;
@@ -160,8 +168,8 @@
     fprintf(stderr, "  stack-overflow        recurse until the stack overflows\n");
     fprintf(stderr, "  nostack               crash with a NULL stack pointer\n");
     fprintf(stderr, "\n");
-    fprintf(stderr, "  heap-corruption       cause a libc abort by corrupting the heap\n");
     fprintf(stderr, "  heap-usage            cause a libc abort by abusing a heap function\n");
+    fprintf(stderr, "  leak                  leak memory until we get OOM-killed\n");
     fprintf(stderr, "\n");
     fprintf(stderr, "  abort                 call abort()\n");
     fprintf(stderr, "  assert                call assert() without a function\n");
@@ -265,6 +273,8 @@
         return pthread_join(0, nullptr);
     } else if (!strcasecmp(arg, "heap-usage")) {
         abuse_heap();
+    } else if (!strcasecmp(arg, "leak")) {
+        leak();
     } else if (!strcasecmp(arg, "SIGSEGV-unmapped")) {
         char* map = reinterpret_cast<char*>(mmap(nullptr, sizeof(int), PROT_READ | PROT_WRITE,
                                                  MAP_SHARED | MAP_ANONYMOUS, -1, 0));
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 6298ace..b016e23 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -27,7 +27,7 @@
 #include <android-base/parseint.h>
 #include <android-base/unique_fd.h>
 #include <debuggerd/client.h>
-#include <selinux/selinux.h>
+#include <procinfo/process.h>
 #include "util.h"
 
 using android::base::unique_fd;
@@ -66,6 +66,24 @@
     usage(1);
   }
 
+  if (getuid() != 0) {
+    errx(1, "root is required");
+  }
+
+  // Check to see if the process exists and that we can actually send a signal to it.
+  android::procinfo::ProcessInfo proc_info;
+  if (!android::procinfo::GetProcessInfo(pid, &proc_info)) {
+    err(1, "failed to fetch info for process %d", pid);
+  }
+
+  if (proc_info.state == android::procinfo::kProcessStateZombie) {
+    errx(1, "process %d is a zombie", pid);
+  }
+
+  if (kill(pid, 0) != 0) {
+    err(1, "cannot send signal to process %d", pid);
+  }
+
   unique_fd piperead, pipewrite;
   if (!Pipe(&piperead, &pipewrite)) {
     err(1, "failed to create pipe");
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 2015157..b51fc66 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -88,8 +88,12 @@
     }                                                                                       \
   } while (0)
 
+#define ASSERT_BACKTRACE_FRAME(result, frame_name)                        \
+  ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX \
+                       R"(/libc.so \()" frame_name R"(\+)")
+
 static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd,
-                                 DebuggerdDumpType intercept_type) {
+                                 InterceptStatus* status, DebuggerdDumpType intercept_type) {
   intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName,
                                           ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
   if (intercept_fd->get() == -1) {
@@ -136,7 +140,7 @@
            << ", received " << rc;
   }
 
-  ASSERT_EQ(InterceptStatus::kRegistered, response.status);
+  *status = response.status;
 }
 
 class CrasherTest : public ::testing::Test {
@@ -180,7 +184,9 @@
     FAIL() << "crasher hasn't been started";
   }
 
-  tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, intercept_type);
+  InterceptStatus status;
+  tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, &status, intercept_type);
+  ASSERT_EQ(InterceptStatus::kRegistered, status);
 }
 
 void CrasherTest::FinishIntercept(int* result) {
@@ -305,7 +311,7 @@
 
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)");
+  ASSERT_BACKTRACE_FRAME(result, "abort");
 }
 
 TEST_F(CrasherTest, signal) {
@@ -441,7 +447,7 @@
   FinishIntercept(&intercept_result);
   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+  /system/lib)" ARCH_SUFFIX R"(/libc.so \(read\+)");
+  ASSERT_BACKTRACE_FRAME(result, "read");
 
   int status;
   ASSERT_EQ(0, waitpid(crasher_pid, &status, WNOHANG | WUNTRACED));
@@ -452,7 +458,7 @@
   FinishIntercept(&intercept_result);
   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)");
+  ASSERT_BACKTRACE_FRAME(result, "abort");
 }
 
 TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) {
@@ -472,7 +478,7 @@
 
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)");
+  ASSERT_BACKTRACE_FRAME(result, "abort");
 }
 
 TEST_F(CrasherTest, capabilities) {
@@ -529,7 +535,7 @@
   ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
   ConsumeFd(std::move(output_fd), &result);
   ASSERT_MATCH(result, R"(name: thread_name\s+>>> .+debuggerd_test(32|64) <<<)");
-  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
+  ASSERT_BACKTRACE_FRAME(result, "tgkill");
 }
 
 TEST_F(CrasherTest, fake_pid) {
@@ -560,7 +566,7 @@
 
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
+  ASSERT_BACKTRACE_FRAME(result, "tgkill");
 }
 
 TEST(crash_dump, zombie) {
@@ -598,7 +604,9 @@
     pid_t pid = 123'456'789 + i;
 
     unique_fd intercept_fd, output_fd;
-    tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone);
+    InterceptStatus status;
+    tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
+    ASSERT_EQ(InterceptStatus::kRegistered, status);
 
     {
       unique_fd tombstoned_socket, input_fd;
@@ -630,7 +638,9 @@
       pid_t pid = pid_base + dump;
 
       unique_fd intercept_fd, output_fd;
-      tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone);
+      InterceptStatus status;
+      tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
+      ASSERT_EQ(InterceptStatus::kRegistered, status);
 
       // Pretend to crash, and then immediately close the socket.
       unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName,
@@ -661,7 +671,9 @@
       pid_t pid = pid_base + dump;
 
       unique_fd intercept_fd, output_fd;
-      tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone);
+      InterceptStatus status;
+      tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
+      ASSERT_EQ(InterceptStatus::kRegistered, status);
 
       {
         unique_fd tombstoned_socket, input_fd;
@@ -685,3 +697,65 @@
     thread.join();
   }
 }
+
+TEST(tombstoned, java_trace_intercept_smoke) {
+  // Using a "real" PID is a little dangerous here - if the test fails
+  // or crashes, we might end up getting a bogus / unreliable stack
+  // trace.
+  const pid_t self = getpid();
+
+  unique_fd intercept_fd, output_fd;
+  InterceptStatus status;
+  tombstoned_intercept(self, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace);
+  ASSERT_EQ(InterceptStatus::kRegistered, status);
+
+  // First connect to tombstoned requesting a native backtrace. This
+  // should result in a "regular" FD and not the installed intercept.
+  const char native[] = "native";
+  unique_fd tombstoned_socket, input_fd;
+  ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdNativeBacktrace));
+  ASSERT_TRUE(android::base::WriteFully(input_fd.get(), native, sizeof(native)));
+  tombstoned_notify_completion(tombstoned_socket.get());
+
+  // Then, connect to tombstoned asking for a java backtrace. This *should*
+  // trigger the intercept.
+  const char java[] = "java";
+  ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdJavaBacktrace));
+  ASSERT_TRUE(android::base::WriteFully(input_fd.get(), java, sizeof(java)));
+  tombstoned_notify_completion(tombstoned_socket.get());
+
+  char outbuf[sizeof(java)];
+  ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
+  ASSERT_STREQ("java", outbuf);
+}
+
+TEST(tombstoned, multiple_intercepts) {
+  const pid_t fake_pid = 1'234'567;
+  unique_fd intercept_fd, output_fd;
+  InterceptStatus status;
+  tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace);
+  ASSERT_EQ(InterceptStatus::kRegistered, status);
+
+  unique_fd intercept_fd_2, output_fd_2;
+  tombstoned_intercept(fake_pid, &intercept_fd_2, &output_fd_2, &status, kDebuggerdNativeBacktrace);
+  ASSERT_EQ(InterceptStatus::kFailedAlreadyRegistered, status);
+}
+
+TEST(tombstoned, intercept_any) {
+  const pid_t fake_pid = 1'234'567;
+
+  unique_fd intercept_fd, output_fd;
+  InterceptStatus status;
+  tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdNativeBacktrace);
+  ASSERT_EQ(InterceptStatus::kRegistered, status);
+
+  const char any[] = "any";
+  unique_fd tombstoned_socket, input_fd;
+  ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept));
+  ASSERT_TRUE(android::base::WriteFully(input_fd.get(), any, sizeof(any)));
+  tombstoned_notify_completion(tombstoned_socket.get());
+
+  char outbuf[sizeof(any)];
+  ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
+  ASSERT_STREQ("any", outbuf);
+}
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index 325210d..6be59e7 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -220,21 +220,21 @@
   map.start = 0xa434000;
   map.end = 0xa435000;
   map.offset = 0x1000;
-  map.load_base = 0xd000;
+  map.load_bias = 0xd000;
   map.flags = PROT_WRITE;
   map_mock_->AddMap(map);
 
   map.start = 0xa534000;
   map.end = 0xa535000;
   map.offset = 0x3000;
-  map.load_base = 0x2000;
+  map.load_bias = 0x2000;
   map.flags = PROT_EXEC;
   map_mock_->AddMap(map);
 
   map.start = 0xa634000;
   map.end = 0xa635000;
   map.offset = 0;
-  map.load_base = 0;
+  map.load_bias = 0;
   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
   map.name = "/system/lib/fake.so";
   map_mock_->AddMap(map);
@@ -244,20 +244,20 @@
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  const char* expected_dump = \
-"\nmemory map:\n"
+  const char* expected_dump =
+      "\nmemory map:\n"
 #if defined(__LP64__)
-"    00000000'0a234000-00000000'0a234fff ---         0      1000\n"
-"    00000000'0a334000-00000000'0a334fff r--      f000      1000\n"
-"    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "    00000000'0a234000-00000000'0a234fff ---         0      1000\n"
+      "    00000000'0a334000-00000000'0a334fff r--      f000      1000\n"
+      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #else
-"    0a234000-0a234fff ---         0      1000\n"
-"    0a334000-0a334fff r--      f000      1000\n"
-"    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "    0a234000-0a234fff ---         0      1000\n"
+      "    0a334000-0a334fff r--      f000      1000\n"
+      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #endif
   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
 
@@ -274,21 +274,21 @@
   map.start = 0xa434000;
   map.end = 0xa435000;
   map.offset = 0x1000;
-  map.load_base = 0xd000;
+  map.load_bias = 0xd000;
   map.flags = PROT_WRITE;
   map_mock_->AddMap(map);
 
   map.start = 0xa534000;
   map.end = 0xa535000;
   map.offset = 0x3000;
-  map.load_base = 0x2000;
+  map.load_bias = 0x2000;
   map.flags = PROT_EXEC;
   map_mock_->AddMap(map);
 
   map.start = 0xa634000;
   map.end = 0xa635000;
   map.offset = 0;
-  map.load_base = 0;
+  map.load_bias = 0;
   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
   map.name = "/system/lib/fake.so";
   map_mock_->AddMap(map);
@@ -304,18 +304,18 @@
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  const char* expected_dump = \
-"\nmemory map: (fault address prefixed with --->)\n"
+  const char* expected_dump =
+      "\nmemory map: (fault address prefixed with --->)\n"
 #if defined(__LP64__)
-"--->Fault address falls at 00000000'00001000 before any mapped regions\n"
-"    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
+      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #else
-"--->Fault address falls at 00001000 before any mapped regions\n"
-"    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "--->Fault address falls at 00001000 before any mapped regions\n"
+      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #endif
   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
 
@@ -332,21 +332,21 @@
   map.start = 0xa434000;
   map.end = 0xa435000;
   map.offset = 0x1000;
-  map.load_base = 0xd000;
+  map.load_bias = 0xd000;
   map.flags = PROT_WRITE;
   map_mock_->AddMap(map);
 
   map.start = 0xa534000;
   map.end = 0xa535000;
   map.offset = 0x3000;
-  map.load_base = 0x2000;
+  map.load_bias = 0x2000;
   map.flags = PROT_EXEC;
   map_mock_->AddMap(map);
 
   map.start = 0xa634000;
   map.end = 0xa635000;
   map.offset = 0;
-  map.load_base = 0;
+  map.load_bias = 0;
   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
   map.name = "/system/lib/fake.so";
   map_mock_->AddMap(map);
@@ -362,18 +362,18 @@
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  const char* expected_dump = \
-"\nmemory map: (fault address prefixed with --->)\n"
+  const char* expected_dump =
+      "\nmemory map: (fault address prefixed with --->)\n"
 #if defined(__LP64__)
-"    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"--->Fault address falls at 00000000'0a533000 between mapped regions\n"
-"    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "--->Fault address falls at 00000000'0a533000 between mapped regions\n"
+      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #else
-"    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"--->Fault address falls at 0a533000 between mapped regions\n"
-"    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "--->Fault address falls at 0a533000 between mapped regions\n"
+      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #endif
   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
 
@@ -390,21 +390,21 @@
   map.start = 0xa434000;
   map.end = 0xa435000;
   map.offset = 0x1000;
-  map.load_base = 0xd000;
+  map.load_bias = 0xd000;
   map.flags = PROT_WRITE;
   map_mock_->AddMap(map);
 
   map.start = 0xa534000;
   map.end = 0xa535000;
   map.offset = 0x3000;
-  map.load_base = 0x2000;
+  map.load_bias = 0x2000;
   map.flags = PROT_EXEC;
   map_mock_->AddMap(map);
 
   map.start = 0xa634000;
   map.end = 0xa635000;
   map.offset = 0;
-  map.load_base = 0;
+  map.load_bias = 0;
   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
   map.name = "/system/lib/fake.so";
   map_mock_->AddMap(map);
@@ -420,16 +420,16 @@
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  const char* expected_dump = \
-"\nmemory map: (fault address prefixed with --->)\n"
+  const char* expected_dump =
+      "\nmemory map: (fault address prefixed with --->)\n"
 #if defined(__LP64__)
-"    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"--->00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "--->00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #else
-"    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"--->0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
+      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "--->0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
 #endif
   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
 
@@ -446,21 +446,21 @@
   map.start = 0xa434000;
   map.end = 0xa435000;
   map.offset = 0x1000;
-  map.load_base = 0xd000;
+  map.load_bias = 0xd000;
   map.flags = PROT_WRITE;
   map_mock_->AddMap(map);
 
   map.start = 0xa534000;
   map.end = 0xa535000;
   map.offset = 0x3000;
-  map.load_base = 0x2000;
+  map.load_bias = 0x2000;
   map.flags = PROT_EXEC;
   map_mock_->AddMap(map);
 
   map.start = 0xa634000;
   map.end = 0xa635000;
   map.offset = 0;
-  map.load_base = 0;
+  map.load_bias = 0;
   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
   map.name = "/system/lib/fake.so";
   map_mock_->AddMap(map);
@@ -480,18 +480,18 @@
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  const char* expected_dump = \
-"\nmemory map: (fault address prefixed with --->)\n"
+  const char* expected_dump =
+      "\nmemory map: (fault address prefixed with --->)\n"
 #if defined(__LP64__)
-"    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n"
-"--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
+      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n"
+      "--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
 #else
-"    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
-"    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
-"    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n"
-"--->Fault address falls at 0f534040 after any mapped regions\n";
+      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
+      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
+      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n"
+      "--->Fault address falls at 0f534040 after any mapped regions\n";
 #endif
   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
 
@@ -508,7 +508,7 @@
   map.start = 0xa434000;
   map.end = 0xa435000;
   map.offset = 0x1000;
-  map.load_base = 0xd000;
+  map.load_bias = 0xd000;
   map.flags = PROT_WRITE;
   map_mock_->AddMap(map);
 
@@ -520,12 +520,12 @@
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  const char* expected_dump = \
-"\nmemory map:\n"
+  const char* expected_dump =
+      "\nmemory map:\n"
 #if defined(__LP64__)
-"    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n";
+      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n";
 #else
-"    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n";
+      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n";
 #endif
   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
 
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index edc7be5..b9a0bc7 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -168,6 +168,26 @@
         case TRAP_BRANCH: return "TRAP_BRANCH";
         case TRAP_HWBKPT: return "TRAP_HWBKPT";
       }
+      if ((code & 0xff) == SIGTRAP) {
+        switch ((code >> 8) & 0xff) {
+          case PTRACE_EVENT_FORK:
+            return "PTRACE_EVENT_FORK";
+          case PTRACE_EVENT_VFORK:
+            return "PTRACE_EVENT_VFORK";
+          case PTRACE_EVENT_CLONE:
+            return "PTRACE_EVENT_CLONE";
+          case PTRACE_EVENT_EXEC:
+            return "PTRACE_EVENT_EXEC";
+          case PTRACE_EVENT_VFORK_DONE:
+            return "PTRACE_EVENT_VFORK_DONE";
+          case PTRACE_EVENT_EXIT:
+            return "PTRACE_EVENT_EXIT";
+          case PTRACE_EVENT_SECCOMP:
+            return "PTRACE_EVENT_SECCOMP";
+          case PTRACE_EVENT_STOP:
+            return "PTRACE_EVENT_STOP";
+        }
+      }
       static_assert(NSIGTRAP == TRAP_HWBKPT, "missing TRAP_* si_code");
       break;
   }
@@ -395,15 +415,17 @@
   }
 
   ScopedBacktraceMapIteratorLock lock(map);
-  _LOG(log, logtype::MAPS, "\n");
-  if (!print_fault_address_marker) {
-    _LOG(log, logtype::MAPS, "memory map:\n");
-  } else {
-    _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n");
+  _LOG(log, logtype::MAPS,
+       "\n"
+       "memory map (%zu entries):\n",
+       map->size());
+  if (print_fault_address_marker) {
     if (map->begin() != map->end() && addr < map->begin()->start) {
       _LOG(log, logtype::MAPS, "--->Fault address falls at %s before any mapped regions\n",
            get_addr_string(addr).c_str());
       print_fault_address_marker = false;
+    } else {
+      _LOG(log, logtype::MAPS, "(fault address prefixed with --->)\n");
     }
   }
 
@@ -446,11 +468,11 @@
         line += " (BuildId: " + build_id + ")";
       }
     }
-    if (it->load_base != 0) {
+    if (it->load_bias != 0) {
       if (space_needed) {
         line += ' ';
       }
-      line += StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base);
+      line += StringPrintf(" (load bias 0x%" PRIxPTR ")", it->load_bias);
     }
     _LOG(log, logtype::MAPS, "%s\n", line.c_str());
   }
@@ -763,10 +785,22 @@
   dump_abort_message(backtrace.get(), &log, abort_msg_address);
   dump_registers(&log, ucontext);
 
-  // TODO: Dump registers from the ucontext.
   if (backtrace->Unwind(0, ucontext)) {
     dump_backtrace_and_stack(backtrace.get(), &log);
   } else {
     ALOGE("Unwind failed: pid = %d, tid = %d", pid, tid);
   }
+
+  // TODO: Make this match the format of dump_all_maps above.
+  _LOG(&log, logtype::MAPS, "memory map:\n");
+  android::base::unique_fd maps_fd(open("/proc/self/maps", O_RDONLY | O_CLOEXEC));
+  if (maps_fd == -1) {
+    _LOG(&log, logtype::MAPS, "    failed to open /proc/self/maps: %s", strerror(errno));
+  } else {
+    char buf[256];
+    ssize_t rc;
+    while ((rc = TEMP_FAILURE_RETRY(read(maps_fd.get(), buf, sizeof(buf)))) > 0) {
+      android::base::WriteFully(tombstone_fd, buf, rc);
+    }
+  }
 }
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 09cff45..93c7fb5 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -103,7 +103,7 @@
   }
 
   static CrashQueue* for_anrs() {
-    static CrashQueue queue("/data/anr", "anr_" /* file_name_prefix */,
+    static CrashQueue queue("/data/anr", "trace_" /* file_name_prefix */,
                             GetIntProperty("tombstoned.max_anr_count", 64),
                             4 /* max_concurrent_dumps */);
     return &queue;
@@ -194,7 +194,7 @@
 };
 
 // Whether java trace dumps are produced via tombstoned.
-static constexpr bool kJavaTraceDumpsEnabled = false;
+static constexpr bool kJavaTraceDumpsEnabled = true;
 
 // Forward declare the callbacks so they can be placed in a sensible order.
 static void crash_accept_cb(evconnlistener* listener, evutil_socket_t sockfd, sockaddr*, int, void*);
@@ -343,7 +343,14 @@
   }
 
   if (!crash->crash_path.empty()) {
-    LOG(ERROR) << "Tombstone written to: " << crash->crash_path;
+    if (crash->crash_type == kDebuggerdJavaBacktrace) {
+      LOG(ERROR) << "Traces for pid " << crash->crash_pid << " written to: " << crash->crash_path;
+    } else {
+      // NOTE: Several tools parse this log message to figure out where the
+      // tombstone associated with a given native crash was written. Any changes
+      // to this message must be carefully considered.
+      LOG(ERROR) << "Tombstone written to: " << crash->crash_path;
+    }
   }
 
 fail:
diff --git a/debuggerd/tombstoned/tombstoned.rc b/debuggerd/tombstoned/tombstoned.rc
index b8345ca..53ef01c 100644
--- a/debuggerd/tombstoned/tombstoned.rc
+++ b/debuggerd/tombstoned/tombstoned.rc
@@ -7,4 +7,5 @@
 
     socket tombstoned_crash seqpacket 0666 system system
     socket tombstoned_intercept seqpacket 0666 system system
+    socket tombstoned_java_trace seqpacket 0666 system system
     writepid /dev/cpuset/system-background/tasks
diff --git a/demangle/Android.bp b/demangle/Android.bp
index ce617a7..e55c886 100644
--- a/demangle/Android.bp
+++ b/demangle/Android.bp
@@ -28,10 +28,8 @@
 
 cc_library {
     name: "libdemangle",
-
-    vendor_available: true,
-
     defaults: ["libdemangle_defaults"],
+    vendor_available: true,
 
     srcs: [
         "Demangler.cpp",
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 271ca95..5f2267c 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -93,6 +93,9 @@
 static unsigned second_offset  = 0x00f00000;
 static unsigned tags_offset    = 0x00000100;
 
+static bool g_disable_verity = false;
+static bool g_disable_verification = false;
+
 static const std::string convert_fbe_marker_filename("convert_fbe");
 
 enum fb_buffer_type {
@@ -419,6 +422,10 @@
             "  --skip-reboot                            Will not reboot the device when\n"
             "                                           performing commands that normally\n"
             "                                           trigger a reboot.\n"
+            "  --disable-verity                         Set the disable-verity flag in the\n"
+            "                                           the vbmeta image being flashed.\n"
+            "  --disable-verification                   Set the disable-verification flag in"
+            "                                           the vbmeta image being flashed.\n"
 #if !defined(_WIN32)
             "  --wipe-and-use-fbe                       On devices which support it,\n"
             "                                           erase userdata and cache, and\n"
@@ -858,10 +865,55 @@
     return load_buf_fd(transport, fd.release(), buf);
 }
 
+static void rewrite_vbmeta_buffer(struct fastboot_buffer* buf) {
+    // Buffer needs to be at least the size of the VBMeta struct which
+    // is 256 bytes.
+    if (buf->sz < 256) {
+        return;
+    }
+
+    int fd = make_temporary_fd();
+    if (fd == -1) {
+        die("Failed to create temporary file for vbmeta rewriting");
+    }
+
+    std::string data;
+    if (!android::base::ReadFdToString(buf->fd, &data)) {
+        die("Failed reading from vbmeta");
+    }
+
+    // There's a 32-bit big endian |flags| field at offset 120 where
+    // bit 0 corresponds to disable-verity and bit 1 corresponds to
+    // disable-verification.
+    //
+    // See external/avb/libavb/avb_vbmeta_image.h for the layout of
+    // the VBMeta struct.
+    if (g_disable_verity) {
+        data[123] |= 0x01;
+    }
+    if (g_disable_verification) {
+        data[123] |= 0x02;
+    }
+
+    if (!android::base::WriteStringToFd(data, fd)) {
+        die("Failed writing to modified vbmeta");
+    }
+    close(buf->fd);
+    buf->fd = fd;
+    lseek(fd, 0, SEEK_SET);
+}
+
 static void flash_buf(const char *pname, struct fastboot_buffer *buf)
 {
     sparse_file** s;
 
+    // Rewrite vbmeta if that's what we're flashing and modification has been requested.
+    if ((g_disable_verity || g_disable_verification) &&
+        (strcmp(pname, "vbmeta") == 0 || strcmp(pname, "vbmeta_a") == 0 ||
+         strcmp(pname, "vbmeta_b") == 0)) {
+        rewrite_vbmeta_buffer(buf);
+    }
+
     switch (buf->type) {
         case FB_BUFFER_SPARSE: {
             std::vector<std::pair<sparse_file*, int64_t>> sparse_files;
@@ -1411,7 +1463,7 @@
 
     if (fs_generator_generate(gen, output.path, size, initial_dir,
             eraseBlkSize, logicalBlkSize)) {
-        fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
+        die("Cannot generate image for %s\n", partition);
         return;
     }
 
@@ -1470,6 +1522,8 @@
         {"set-active", optional_argument, 0, 'a'},
         {"skip-secondary", no_argument, 0, 0},
         {"skip-reboot", no_argument, 0, 0},
+        {"disable-verity", no_argument, 0, 0},
+        {"disable-verification", no_argument, 0, 0},
 #if !defined(_WIN32)
         {"wipe-and-use-fbe", no_argument, 0, 0},
 #endif
@@ -1555,6 +1609,10 @@
                 skip_secondary = true;
             } else if (strcmp("skip-reboot", longopts[longindex].name) == 0 ) {
                 skip_reboot = true;
+            } else if (strcmp("disable-verity", longopts[longindex].name) == 0 ) {
+                g_disable_verity = true;
+            } else if (strcmp("disable-verification", longopts[longindex].name) == 0 ) {
+                g_disable_verification = true;
 #if !defined(_WIN32)
             } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
                 wants_wipe = true;
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 4a4a7c0..709f061 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -124,6 +124,8 @@
     }
     mke2fs_args.push_back("-E");
     mke2fs_args.push_back(ext_attr.c_str());
+    mke2fs_args.push_back("-O");
+    mke2fs_args.push_back("uninit_bg");
     mke2fs_args.push_back(fileName);
 
     std::string size_str = std::to_string(partSize / block_size);
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 4441ad0..7fd67c2 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -21,20 +21,6 @@
     },
     local_include_dirs: ["include/"],
     cppflags: ["-Werror"],
-    static_libs: [
-        "libfec",
-        "libfec_rs",
-        "libbase",
-        "libcrypto_utils",
-        "libcrypto",
-        "libext4_utils",
-        "libsquashfs_utils",
-        "libselinux",
-        "libavb",
-    ],
-    whole_static_libs: [
-        "liblogwrap",
-    ],
 }
 
 cc_library_static {
@@ -46,12 +32,28 @@
         "fs_mgr.cpp",
         "fs_mgr_dm_ioctl.cpp",
         "fs_mgr_format.cpp",
-        "fs_mgr_fstab.cpp",
-        "fs_mgr_slotselect.cpp",
         "fs_mgr_verity.cpp",
         "fs_mgr_avb.cpp",
         "fs_mgr_avb_ops.cpp",
-        "fs_mgr_boot_config.cpp",
+    ],
+    static_libs: [
+        "libfec",
+        "libfec_rs",
+        "libbase",
+        "libcrypto_utils",
+        "libcrypto",
+        "libext4_utils",
+        "libsquashfs_utils",
+        "libselinux",
+        "libavb",
+        "libfstab",
+    ],
+    export_static_lib_headers: [
+        "libfstab",
+    ],
+    whole_static_libs: [
+        "liblogwrap",
+        "libfstab",
     ],
     product_variables: {
         debuggable: {
@@ -62,3 +64,16 @@
         },
     },
 }
+
+cc_library_static {
+    name: "libfstab",
+    vendor_available: true,
+    defaults: ["fs_mgr_defaults"],
+    srcs: [
+        "fs_mgr_fstab.cpp",
+        "fs_mgr_boot_config.cpp",
+        "fs_mgr_slotselect.cpp",
+    ],
+    export_include_dirs: ["include_fstab"],
+    header_libs: ["libbase_headers"],
+}
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e009383..91ed496 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -32,6 +32,7 @@
 #include <unistd.h>
 
 #include <memory>
+#include <thread>
 
 #include <android-base/file.h>
 #include <android-base/properties.h>
@@ -78,43 +79,33 @@
     FS_STAT_E2FSCK_F_ALWAYS = 0x0004,
     FS_STAT_UNCLEAN_SHUTDOWN = 0x0008,
     FS_STAT_QUOTA_ENABLED = 0x0010,
-    FS_STAT_TUNE2FS_FAILED = 0x0020,
     FS_STAT_RO_MOUNT_FAILED = 0x0040,
     FS_STAT_RO_UNMOUNT_FAILED = 0x0080,
     FS_STAT_FULL_MOUNT_FAILED = 0x0100,
     FS_STAT_E2FSCK_FAILED = 0x0200,
     FS_STAT_E2FSCK_FS_FIXED = 0x0400,
     FS_STAT_EXT4_INVALID_MAGIC = 0x0800,
+    FS_STAT_TOGGLE_QUOTAS_FAILED = 0x10000,
+    FS_STAT_SET_RESERVED_BLOCKS_FAILED = 0x20000,
+    FS_STAT_ENABLE_ENCRYPTION_FAILED = 0x40000,
 };
 
-/*
- * gettime() - returns the time in seconds of the system's monotonic clock or
- * zero on error.
- */
-static time_t gettime(void)
-{
-    struct timespec ts;
-    int ret;
+// TODO: switch to inotify()
+bool fs_mgr_wait_for_file(const std::string& filename,
+                          const std::chrono::milliseconds relative_timeout) {
+    auto start_time = std::chrono::steady_clock::now();
 
-    ret = clock_gettime(CLOCK_MONOTONIC, &ts);
-    if (ret < 0) {
-        PERROR << "clock_gettime(CLOCK_MONOTONIC) failed";
-        return 0;
+    while (true) {
+        if (!access(filename.c_str(), F_OK) || errno != ENOENT) {
+            return true;
+        }
+
+        std::this_thread::sleep_for(50ms);
+
+        auto now = std::chrono::steady_clock::now();
+        auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
+        if (time_elapsed > relative_timeout) return false;
     }
-
-    return ts.tv_sec;
-}
-
-static int wait_for_file(const char *filename, int timeout)
-{
-    struct stat info;
-    time_t timeout_time = gettime() + timeout;
-    int ret = -1;
-
-    while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
-        usleep(10000);
-
-    return ret;
 }
 
 static void log_fs_stat(const char* blk_device, int fs_stat)
@@ -128,10 +119,16 @@
     }
 }
 
+static bool is_extfs(const std::string& fs_type) {
+    return fs_type == "ext4" || fs_type == "ext3" || fs_type == "ext2";
+}
+
 static bool should_force_check(int fs_stat) {
-    return fs_stat & (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
-                      FS_STAT_TUNE2FS_FAILED | FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED |
-                      FS_STAT_FULL_MOUNT_FAILED | FS_STAT_E2FSCK_FAILED);
+    return fs_stat &
+           (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
+            FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | FS_STAT_FULL_MOUNT_FAILED |
+            FS_STAT_E2FSCK_FAILED | FS_STAT_TOGGLE_QUOTAS_FAILED |
+            FS_STAT_SET_RESERVED_BLOCKS_FAILED | FS_STAT_ENABLE_ENCRYPTION_FAILED);
 }
 
 static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat)
@@ -144,7 +141,7 @@
     const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device};
 
     /* Check for the types of filesystems we know how to check */
-    if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
+    if (is_extfs(fs_type)) {
         if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) {  // will fail, so do not try
             return;
         }
@@ -242,186 +239,208 @@
     return;
 }
 
-/* Function to read the primary superblock */
-static int read_super_block(int fd, struct ext4_super_block *sb)
-{
-    off64_t ret;
-
-    ret = lseek64(fd, 1024, SEEK_SET);
-    if (ret < 0)
-        return ret;
-
-    ret = read(fd, sb, sizeof(*sb));
-    if (ret < 0)
-        return ret;
-    if (ret != sizeof(*sb))
-        return ret;
-
-    return 0;
-}
-
-static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
-{
+static ext4_fsblk_t ext4_blocks_count(const struct ext4_super_block* es) {
     return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
-            le32_to_cpu(es->s_blocks_count_lo);
+           le32_to_cpu(es->s_blocks_count_lo);
 }
 
-static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
-{
+static ext4_fsblk_t ext4_r_blocks_count(const struct ext4_super_block* es) {
     return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
-            le32_to_cpu(es->s_r_blocks_count_lo);
+           le32_to_cpu(es->s_r_blocks_count_lo);
 }
 
-static int do_quota_with_shutdown_check(char *blk_device, char *fs_type,
-                                        struct fstab_rec *rec, int *fs_stat)
-{
-    int force_check = 0;
-    if (!strcmp(fs_type, "ext4")) {
-        /*
-         * Some system images do not have tune2fs for licensing reasons
-         * Detect these and skip reserve blocks.
-         */
-        if (access(TUNE2FS_BIN, X_OK)) {
-            LERROR << "Not running " << TUNE2FS_BIN << " on "
-                   << blk_device << " (executable not in system image)";
-        } else {
-            const char* arg1 = nullptr;
-            const char* arg2 = nullptr;
-            int status = 0;
-            int ret = 0;
-            android::base::unique_fd fd(
-                TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
-            if (fd >= 0) {
-                struct ext4_super_block sb;
-                ret = read_super_block(fd, &sb);
-                if (ret < 0) {
-                    PERROR << "Can't read '" << blk_device << "' super block";
-                    return force_check;
-                }
-                if (sb.s_magic != EXT4_SUPER_MAGIC) {
-                    LINFO << "Invalid ext4 magic:0x" << std::hex << sb.s_magic << "," << blk_device;
-                    *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC;
-                    return 0;  // not a valid fs, tune2fs, fsck, and mount  will all fail.
-                }
-                *fs_stat |= FS_STAT_IS_EXT4;
-                LINFO << "superblock s_max_mnt_count:" << sb.s_max_mnt_count << "," << blk_device;
-                if (sb.s_max_mnt_count == 0xffff) {  // -1 (int16) in ext2, but uint16 in ext4
-                    *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
-                }
-                if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
-                    (sb.s_state & EXT4_VALID_FS) == 0) {
-                    LINFO << __FUNCTION__ << "(): was not clealy shutdown, state flag:"
-                          << std::hex << sb.s_state
-                          << "incompat flag:" << std::hex << sb.s_feature_incompat;
-                    force_check = 1;
-                    *fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
-                }
-                int has_quota = (sb.s_feature_ro_compat
-                        & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
-                int want_quota = fs_mgr_is_quota(rec) != 0;
+// Read the primary superblock from an ext4 filesystem.  On failure return
+// false.  If it's not an ext4 filesystem, also set FS_STAT_EXT4_INVALID_MAGIC.
+static bool read_ext4_superblock(const char* blk_device, struct ext4_super_block* sb, int* fs_stat) {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
 
-                if (has_quota == want_quota) {
-                    LINFO << "Requested quota status is match on " << blk_device;
-                    return force_check;
-                } else if (want_quota) {
-                    LINFO << "Enabling quota on " << blk_device;
-                    arg1 = "-Oquota";
-                    arg2 = "-Qusrquota,grpquota";
-                    force_check = 1;
-                    *fs_stat |= FS_STAT_QUOTA_ENABLED;
-                } else {
-                    LINFO << "Disabling quota on " << blk_device;
-                    arg1 = "-Q^usrquota,^grpquota";
-                    arg2 = "-O^quota";
-                }
-            } else {
-                PERROR << "Failed to open '" << blk_device << "'";
-                return force_check;
-            }
-
-            const char *tune2fs_argv[] = {
-                TUNE2FS_BIN,
-                arg1,
-                arg2,
-                blk_device,
-            };
-            ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv),
-                                          const_cast<char **>(tune2fs_argv),
-                                          &status, true, LOG_KLOG | LOG_FILE,
-                                          true, NULL, NULL, 0);
-            if (ret < 0) {
-                /* No need to check for error in fork, we can't really handle it now */
-                LERROR << "Failed trying to run " << TUNE2FS_BIN;
-                *fs_stat |= FS_STAT_TUNE2FS_FAILED;
-            }
-        }
+    if (fd < 0) {
+        PERROR << "Failed to open '" << blk_device << "'";
+        return false;
     }
-    return force_check;
+
+    if (pread(fd, sb, sizeof(*sb), 1024) != sizeof(*sb)) {
+        PERROR << "Can't read '" << blk_device << "' superblock";
+        return false;
+    }
+
+    if (sb->s_magic != EXT4_SUPER_MAGIC) {
+        LINFO << "Invalid ext4 magic:0x" << std::hex << sb->s_magic << " "
+              << "on '" << blk_device << "'";
+        // not a valid fs, tune2fs, fsck, and mount  will all fail.
+        *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC;
+        return false;
+    }
+    *fs_stat |= FS_STAT_IS_EXT4;
+    LINFO << "superblock s_max_mnt_count:" << sb->s_max_mnt_count << "," << blk_device;
+    if (sb->s_max_mnt_count == 0xffff) {  // -1 (int16) in ext2, but uint16 in ext4
+        *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
+    }
+    return true;
 }
 
-static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec, int *fs_stat)
-{
-    /* Check for the types of filesystems we know how to check */
-    if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
-        /*
-         * Some system images do not have tune2fs for licensing reasons
-         * Detect these and skip reserve blocks.
-         */
-        if (access(TUNE2FS_BIN, X_OK)) {
-            LERROR << "Not running " << TUNE2FS_BIN << " on "
-                   << blk_device << " (executable not in system image)";
+// Some system images do not have tune2fs for licensing reasons.
+// Detect these and skip running it.
+static bool tune2fs_available(void) {
+    return access(TUNE2FS_BIN, X_OK) == 0;
+}
+
+static bool run_tune2fs(const char* argv[], int argc) {
+    int ret;
+
+    ret = android_fork_execvp_ext(argc, const_cast<char**>(argv), nullptr, true,
+                                  LOG_KLOG | LOG_FILE, true, nullptr, nullptr, 0);
+    return ret == 0;
+}
+
+// Enable/disable quota support on the filesystem if needed.
+static void tune_quota(const char* blk_device, const struct fstab_rec* rec,
+                       const struct ext4_super_block* sb, int* fs_stat) {
+    bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
+    bool want_quota = fs_mgr_is_quota(rec) != 0;
+
+    if (has_quota == want_quota) {
+        return;
+    }
+
+    if (!tune2fs_available()) {
+        LERROR << "Unable to " << (want_quota ? "enable" : "disable") << " quotas on " << blk_device
+               << " because " TUNE2FS_BIN " is missing";
+        return;
+    }
+
+    const char* argv[] = {TUNE2FS_BIN, nullptr, nullptr, blk_device};
+
+    if (want_quota) {
+        LINFO << "Enabling quotas on " << blk_device;
+        argv[1] = "-Oquota";
+        argv[2] = "-Qusrquota,grpquota";
+        *fs_stat |= FS_STAT_QUOTA_ENABLED;
+    } else {
+        LINFO << "Disabling quotas on " << blk_device;
+        argv[1] = "-O^quota";
+        argv[2] = "-Q^usrquota,^grpquota";
+    }
+
+    if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
+        LERROR << "Failed to run " TUNE2FS_BIN " to " << (want_quota ? "enable" : "disable")
+               << " quotas on " << blk_device;
+        *fs_stat |= FS_STAT_TOGGLE_QUOTAS_FAILED;
+    }
+}
+
+// Set the number of reserved filesystem blocks if needed.
+static void tune_reserved_size(const char* blk_device, const struct fstab_rec* rec,
+                               const struct ext4_super_block* sb, int* fs_stat) {
+    if (!(rec->fs_mgr_flags & MF_RESERVEDSIZE)) {
+        return;
+    }
+
+    // The size to reserve is given in the fstab, but we won't reserve more
+    // than 2% of the filesystem.
+    const uint64_t max_reserved_blocks = ext4_blocks_count(sb) * 0.02;
+    uint64_t reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(sb);
+
+    if (reserved_blocks > max_reserved_blocks) {
+        LWARNING << "Reserved blocks " << reserved_blocks << " is too large; "
+                 << "capping to " << max_reserved_blocks;
+        reserved_blocks = max_reserved_blocks;
+    }
+
+    if (ext4_r_blocks_count(sb) == reserved_blocks) {
+        return;
+    }
+
+    if (!tune2fs_available()) {
+        LERROR << "Unable to set the number of reserved blocks on " << blk_device
+               << " because " TUNE2FS_BIN " is missing";
+        return;
+    }
+
+    char buf[32];
+    const char* argv[] = {TUNE2FS_BIN, "-r", buf, blk_device};
+
+    snprintf(buf, sizeof(buf), "%" PRIu64, reserved_blocks);
+    LINFO << "Setting reserved block count on " << blk_device << " to " << reserved_blocks;
+    if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
+        LERROR << "Failed to run " TUNE2FS_BIN " to set the number of reserved blocks on "
+               << blk_device;
+        *fs_stat |= FS_STAT_SET_RESERVED_BLOCKS_FAILED;
+    }
+}
+
+// Enable file-based encryption if needed.
+static void tune_encrypt(const char* blk_device, const struct fstab_rec* rec,
+                         const struct ext4_super_block* sb, int* fs_stat) {
+    bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0;
+    bool want_encrypt = fs_mgr_is_file_encrypted(rec) != 0;
+
+    if (has_encrypt || !want_encrypt) {
+        return;
+    }
+
+    if (!tune2fs_available()) {
+        LERROR << "Unable to enable ext4 encryption on " << blk_device
+               << " because " TUNE2FS_BIN " is missing";
+        return;
+    }
+
+    const char* argv[] = {TUNE2FS_BIN, "-Oencrypt", blk_device};
+
+    LINFO << "Enabling ext4 encryption on " << blk_device;
+    if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
+        LERROR << "Failed to run " TUNE2FS_BIN " to enable "
+               << "ext4 encryption on " << blk_device;
+        *fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED;
+    }
+}
+
+//
+// Prepare the filesystem on the given block device to be mounted.
+//
+// If the "check" option was given in the fstab record, or it seems that the
+// filesystem was uncleanly shut down, we'll run fsck on the filesystem.
+//
+// If needed, we'll also enable (or disable) filesystem features as specified by
+// the fstab record.
+//
+static int prepare_fs_for_mount(const char* blk_device, const struct fstab_rec* rec) {
+    int fs_stat = 0;
+
+    if (is_extfs(rec->fs_type)) {
+        struct ext4_super_block sb;
+
+        if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
+            if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
+                (sb.s_state & EXT4_VALID_FS) == 0) {
+                LINFO << "Filesystem on " << blk_device << " was not cleanly shutdown; "
+                      << "state flags: 0x" << std::hex << sb.s_state << ", "
+                      << "incompat feature flags: 0x" << std::hex << sb.s_feature_incompat;
+                fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
+            }
+
+            // Note: quotas should be enabled before running fsck.
+            tune_quota(blk_device, rec, &sb, &fs_stat);
         } else {
-            LINFO << "Running " << TUNE2FS_BIN << " on " << blk_device;
-
-            int status = 0;
-            int ret = 0;
-            unsigned long reserved_blocks = 0;
-            android::base::unique_fd fd(
-                TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
-            if (fd >= 0) {
-                struct ext4_super_block sb;
-                ret = read_super_block(fd, &sb);
-                if (ret < 0) {
-                    PERROR << "Can't read '" << blk_device << "' super block";
-                    return;
-                }
-                reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb);
-                unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02;
-                if (reserved_threshold < reserved_blocks) {
-                    LWARNING << "Reserved blocks " << reserved_blocks
-                             << " is too large";
-                    reserved_blocks = reserved_threshold;
-                }
-
-                if (ext4_r_blocks_count(&sb) == reserved_blocks) {
-                    LINFO << "Have reserved same blocks";
-                    return;
-                }
-            } else {
-                PERROR << "Failed to open '" << blk_device << "'";
-                return;
-            }
-
-            char buf[16] = {0};
-            snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks);
-            const char *tune2fs_argv[] = {
-                TUNE2FS_BIN,
-                buf,
-                blk_device,
-            };
-
-            ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv),
-                                          const_cast<char **>(tune2fs_argv),
-                                          &status, true, LOG_KLOG | LOG_FILE,
-                                          true, NULL, NULL, 0);
-
-            if (ret < 0) {
-                /* No need to check for error in fork, we can't really handle it now */
-                LERROR << "Failed trying to run " << TUNE2FS_BIN;
-                *fs_stat |= FS_STAT_TUNE2FS_FAILED;
-            }
+            return fs_stat;
         }
     }
+
+    if ((rec->fs_mgr_flags & MF_CHECK) ||
+        (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
+        check_fs(blk_device, rec->fs_type, rec->mount_point, &fs_stat);
+    }
+
+    if (is_extfs(rec->fs_type) && (rec->fs_mgr_flags & (MF_RESERVEDSIZE | MF_FILEENCRYPTION))) {
+        struct ext4_super_block sb;
+
+        if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
+            tune_reserved_size(blk_device, rec, &sb, &fs_stat);
+            tune_encrypt(blk_device, rec, &sb, &fs_stat);
+        }
+    }
+
+    return fs_stat;
 }
 
 static void remove_trailing_slashes(char *n)
@@ -457,6 +476,16 @@
     return rc;
 }
 
+// Orange state means the device is unlocked, see the following link for details.
+// https://source.android.com/security/verifiedboot/verified-boot#device_state
+bool fs_mgr_is_device_unlocked() {
+    std::string verified_boot_state;
+    if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
+        return verified_boot_state == "orange";
+    }
+    return false;
+}
+
 /*
  * __mount(): wrapper around the mount() system call which also
  * sets the underlying block device to read-only if the mount is read-only.
@@ -476,10 +505,11 @@
         if ((info.st_mode & S_IFMT) == S_IFLNK)
             unlink(target);
     mkdir(target, 0755);
+    errno = 0;
     ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
     save_errno = errno;
-    LINFO << __FUNCTION__ << "(source=" << source << ",target="
-          << target << ",type=" << rec->fs_type << ")=" << ret;
+    PINFO << __FUNCTION__ << "(source=" << source << ",target=" << target
+          << ",type=" << rec->fs_type << ")=" << ret;
     if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
         fs_mgr_set_blk_ro(source);
     }
@@ -559,10 +589,7 @@
                 continue;
             }
 
-            int fs_stat = 0;
-            int force_check = do_quota_with_shutdown_check(fstab->recs[i].blk_device,
-                                                           fstab->recs[i].fs_type,
-                                                           &fstab->recs[i], &fs_stat);
+            int fs_stat = prepare_fs_for_mount(fstab->recs[i].blk_device, &fstab->recs[i]);
             if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) {
                 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint="
                        << fstab->recs[i].mount_point << " rec[" << i
@@ -570,15 +597,6 @@
                 mount_errno = EINVAL;  // continue bootup for FDE
                 continue;
             }
-            if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
-                check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
-                         fstab->recs[i].mount_point, &fs_stat);
-            }
-
-            if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
-                do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
-                                 &fstab->recs[i], &fs_stat);
-            }
 
             int retry_count = 2;
             while (retry_count-- > 0) {
@@ -756,19 +774,6 @@
     }
 }
 
-// TODO: add ueventd notifiers if they don't exist.
-// This is just doing a wait_for_device for maximum of 1s
-int fs_mgr_test_access(const char *device) {
-    int tries = 25;
-    while (tries--) {
-        if (!access(device, F_OK) || errno != ENOENT) {
-            return 0;
-        }
-        usleep(40 * 1000);
-    }
-    return -1;
-}
-
 bool is_device_secure() {
     int ret = -1;
     char value[PROP_VALUE_MAX];
@@ -829,9 +834,7 @@
         }
 
         /* Translate LABEL= file system labels into block devices */
-        if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
-            !strcmp(fstab->recs[i].fs_type, "ext3") ||
-            !strcmp(fstab->recs[i].fs_type, "ext4")) {
+        if (is_extfs(fstab->recs[i].fs_type)) {
             int tret = translate_ext_labels(&fstab->recs[i]);
             if (tret < 0) {
                 LERROR << "Could not translate label to block device";
@@ -839,8 +842,10 @@
             }
         }
 
-        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
-            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
+        if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
+            !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
+            LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all";
+            continue;
         }
 
         if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
@@ -1047,22 +1052,12 @@
         }
 
         /* First check the filesystem if requested */
-        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
-            wait_for_file(n_blk_device, WAIT_TIMEOUT);
+        if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) {
+            LERROR << "Skipping mounting '" << n_blk_device << "'";
+            continue;
         }
 
-        int fs_stat = 0;
-        int force_check = do_quota_with_shutdown_check(n_blk_device, fstab->recs[i].fs_type,
-                                                       &fstab->recs[i], &fs_stat);
-
-        if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
-            check_fs(n_blk_device, fstab->recs[i].fs_type,
-                     fstab->recs[i].mount_point, &fs_stat);
-        }
-
-        if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
-            do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat);
-        }
+        int fs_stat = prepare_fs_for_mount(n_blk_device, &fstab->recs[i]);
 
         if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
             if (!avb_handle) {
@@ -1221,8 +1216,11 @@
             fclose(zram_fp);
         }
 
-        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
-            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
+        if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
+            !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
+            LERROR << "Skipping mkswap for '" << fstab->recs[i].blk_device << "'";
+            ret = -1;
+            continue;
         }
 
         /* Initialize the swap area */
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 2c99aa7..7824cfa 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -397,7 +397,7 @@
     fstab_entry->blk_device = strdup(verity_blk_name.c_str());
 
     // Makes sure we've set everything up properly.
-    if (wait_for_verity_dev && fs_mgr_test_access(verity_blk_name.c_str()) < 0) {
+    if (wait_for_verity_dev && !fs_mgr_wait_for_file(verity_blk_name, 1s)) {
         return false;
     }
 
@@ -473,16 +473,6 @@
     return true;
 }
 
-// Orange state means the device is unlocked, see the following link for details.
-// https://source.android.com/security/verifiedboot/verified-boot#device_state
-static inline bool IsDeviceUnlocked() {
-    std::string verified_boot_state;
-    if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
-        return verified_boot_state == "orange";
-    }
-    return false;
-}
-
 FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) {
     FsManagerAvbOps avb_ops(fstab);
     return DoOpen(&avb_ops);
@@ -498,7 +488,7 @@
 }
 
 FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) {
-    bool is_device_unlocked = IsDeviceUnlocked();
+    bool is_device_unlocked = fs_mgr_is_device_unlocked();
 
     FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle());
     if (!avb_handle) {
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index ba1262f..43879fe 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -142,10 +142,8 @@
     }
     std::string path = iter->second;
 
-    // Ensures the device path (a symlink created by init) is ready to
-    // access. fs_mgr_test_access() will test a few iterations if the
-    // path doesn't exist yet.
-    if (fs_mgr_test_access(path.c_str()) < 0) {
+    // Ensures the device path (a symlink created by init) is ready to access.
+    if (!fs_mgr_wait_for_file(path, 1s)) {
         return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
     }
 
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index ab5beed..9c5d3f3 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <string>
+
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
@@ -21,19 +23,11 @@
 
 #include "fs_mgr_priv.h"
 
-// Tries to get the boot config value in properties, kernel cmdline and
-// device tree (in that order).  returns 'true' if successfully found, 'false'
-// otherwise
-bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) {
+// Tries to get the given boot config value from kernel cmdline.
+// Returns true if successfully found, false otherwise.
+bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) {
     FS_MGR_CHECK(out_val != nullptr);
 
-    // first check if we have "ro.boot" property already
-    *out_val = android::base::GetProperty("ro.boot." + key, "");
-    if (!out_val->empty()) {
-        return true;
-    }
-
-    // fallback to kernel cmdline, properties may not be ready yet
     std::string cmdline;
     std::string cmdline_key("androidboot." + key);
     if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
@@ -48,12 +42,34 @@
         }
     }
 
+    return false;
+}
+
+// Tries to get the boot config value in properties, kernel cmdline and
+// device tree (in that order).  returns 'true' if successfully found, 'false'
+// otherwise
+bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) {
+    FS_MGR_CHECK(out_val != nullptr);
+
+    // first check if we have "ro.boot" property already
+    *out_val = android::base::GetProperty("ro.boot." + key, "");
+    if (!out_val->empty()) {
+        return true;
+    }
+
+    // fallback to kernel cmdline, properties may not be ready yet
+    if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) {
+        return true;
+    }
+
     // lastly, check the device tree
     if (is_dt_compatible()) {
-        std::string file_name = kAndroidDtDir + "/" + key;
-        // DT entries terminate with '\0' but so do the properties
+        std::string file_name = get_android_dt_dir() + "/" + key;
         if (android::base::ReadFileToString(file_name, out_val)) {
-            return true;
+            if (!out_val->empty()) {
+                out_val->pop_back();  // Trims the trailing '\0' out.
+                return true;
+            }
         }
     }
 
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index 75feee7..fc88217 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -38,7 +38,6 @@
 {
     uint64_t dev_sz;
     int fd, rc = 0;
-    int status;
 
     if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
         PERROR << "Cannot open block device";
@@ -62,7 +61,7 @@
     const char* const mke2fs_args[] = {
         "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
 
-    rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), &status,
+    rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
                                  true, LOG_KLOG, true, nullptr, nullptr, 0);
     if (rc) {
         LERROR << "mke2fs returned " << rc;
@@ -78,7 +77,7 @@
         nullptr};
 
     rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
-                                 &status, true, LOG_KLOG, true, nullptr, nullptr, 0);
+                                 NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
     if (rc) {
         LERROR << "e2fsdroid returned " << rc;
     }
@@ -88,10 +87,9 @@
 
 static int format_f2fs(char *fs_blkdev)
 {
-    int status;
     const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
 
-    return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), &status, true,
+    return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
                                    LOG_KLOG, true, nullptr, nullptr, 0);
 }
 
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 6c527c5..eeac697 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -29,6 +29,8 @@
 
 #include "fs_mgr_priv.h"
 
+const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android");
+
 struct fs_mgr_flag_values {
     char *key_loc;
     char* key_dir;
@@ -365,9 +367,26 @@
     return f;
 }
 
+static std::string init_android_dt_dir() {
+    std::string android_dt_dir;
+    // The platform may specify a custom Android DT path in kernel cmdline
+    if (!fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
+        // Fall back to the standard procfs-based path
+        android_dt_dir = kDefaultAndroidDtDir;
+    }
+    return android_dt_dir;
+}
+
+// FIXME: The same logic is duplicated in system/core/init/
+const std::string& get_android_dt_dir() {
+    // Set once and saves time for subsequent calls to this function
+    static const std::string kAndroidDtDir = init_android_dt_dir();
+    return kAndroidDtDir;
+}
+
 static bool is_dt_fstab_compatible() {
     std::string dt_value;
-    std::string file_name = kAndroidDtDir + "/fstab/compatible";
+    std::string file_name = get_android_dt_dir() + "/fstab/compatible";
     if (read_dt_file(file_name, &dt_value)) {
         if (dt_value == "android,fstab") {
             return true;
@@ -383,7 +402,7 @@
         return fstab;
     }
 
-    std::string fstabdir_name = kAndroidDtDir + "/fstab";
+    std::string fstabdir_name = get_android_dt_dir() + "/fstab";
     std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
     if (!fstabdir) return fstab;
 
@@ -446,7 +465,7 @@
 }
 
 bool is_dt_compatible() {
-    std::string file_name = kAndroidDtDir + "/compatible";
+    std::string file_name = get_android_dt_dir() + "/compatible";
     std::string dt_value;
     if (read_dt_file(file_name, &dt_value)) {
         if (dt_value == "android,firmware") {
@@ -864,32 +883,26 @@
     return fstab->fs_mgr_flags & MF_NOEMULATEDSD;
 }
 
-int fs_mgr_is_notrim(struct fstab_rec *fstab)
-{
+int fs_mgr_is_notrim(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & MF_NOTRIM;
 }
 
-int fs_mgr_is_formattable(struct fstab_rec *fstab)
-{
+int fs_mgr_is_formattable(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & (MF_FORMATTABLE);
 }
 
-int fs_mgr_is_slotselect(struct fstab_rec *fstab)
-{
+int fs_mgr_is_slotselect(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & MF_SLOTSELECT;
 }
 
-int fs_mgr_is_nofail(struct fstab_rec *fstab)
-{
+int fs_mgr_is_nofail(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & MF_NOFAIL;
 }
 
-int fs_mgr_is_latemount(struct fstab_rec *fstab)
-{
+int fs_mgr_is_latemount(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & MF_LATEMOUNT;
 }
 
-int fs_mgr_is_quota(struct fstab_rec *fstab)
-{
+int fs_mgr_is_quota(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & MF_QUOTA;
 }
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 3ca507b..0f62e18 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -17,8 +17,12 @@
 #ifndef __CORE_FS_MGR_PRIV_H
 #define __CORE_FS_MGR_PRIV_H
 
+#include <chrono>
+#include <string>
+
 #include <android-base/logging.h>
-#include <fs_mgr.h>
+
+#include "fs_mgr.h"
 #include "fs_mgr_priv_boot_config.h"
 
 /* The CHECK() in logging.h will use program invocation name as the tag.
@@ -43,8 +47,6 @@
 
 #define CRYPTO_TMPFS_OPTIONS "size=256m,mode=0771,uid=1000,gid=1000"
 
-#define WAIT_TIMEOUT 20
-
 /* fstab has the following format:
  *
  * Any line starting with a # is a comment and ignored
@@ -111,9 +113,14 @@
 
 #define DM_BUF_SIZE 4096
 
+using namespace std::chrono_literals;
+
 int fs_mgr_set_blk_ro(const char *blockdev);
-int fs_mgr_test_access(const char *device);
+bool fs_mgr_wait_for_file(const std::string& filename,
+                          const std::chrono::milliseconds relative_timeout);
 bool fs_mgr_update_for_slotselect(struct fstab *fstab);
+bool fs_mgr_is_device_unlocked();
+const std::string& get_android_dt_dir();
 bool is_dt_compatible();
 bool is_device_secure();
 int load_verity_state(struct fstab_rec* fstab, int* mode);
diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/fs_mgr_priv_boot_config.h
index 8773d33..d98dc02 100644
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/fs_mgr_priv_boot_config.h
@@ -20,8 +20,7 @@
 #include <sys/cdefs.h>
 #include <string>
 
-const std::string kAndroidDtDir("/proc/device-tree/firmware/android");
-
+bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val);
 bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);
 
 #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 8904995..7f8e1e2 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -348,10 +348,13 @@
 
 static int was_verity_restart()
 {
-    static const char *files[] = {
+    static const char* files[] = {
+        // clang-format off
+        "/sys/fs/pstore/console-ramoops-0",
         "/sys/fs/pstore/console-ramoops",
         "/proc/last_kmsg",
         NULL
+        // clang-format on
     };
     int i;
 
@@ -689,27 +692,55 @@
     return read_verity_state(fstab->verity_loc, offset, mode);
 }
 
-static void update_verity_table_blk_device(char *blk_device, char **table)
-{
-    std::string result, word;
+// Update the verity table using the actual block device path.
+// Two cases:
+// Case-1: verity table is shared for devices with different by-name prefix.
+// Example:
+//   verity table token:       /dev/block/bootdevice/by-name/vendor
+//   blk_device-1 (non-A/B):   /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
+//   blk_device-2 (A/B):       /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a
+//
+// Case-2: append A/B suffix in the verity table.
+// Example:
+//   verity table token: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
+//   blk_device:         /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor_a
+static void update_verity_table_blk_device(const std::string& blk_device, char** table,
+                                           bool slot_select) {
+    bool updated = false;
+    std::string result, ab_suffix;
     auto tokens = android::base::Split(*table, " ");
 
+    // If slot_select is set, it means blk_device is already updated with ab_suffix.
+    if (slot_select) ab_suffix = fs_mgr_get_slot_suffix();
+
     for (const auto& token : tokens) {
-        if (android::base::StartsWith(token, "/dev/block/") &&
-            android::base::StartsWith(blk_device, token.c_str())) {
-            word = blk_device;
+        std::string new_token;
+        if (android::base::StartsWith(token, "/dev/block/")) {
+            if (token == blk_device) return;  // no need to update if they're already the same.
+            std::size_t found1 = blk_device.find("by-name");
+            std::size_t found2 = token.find("by-name");
+            if (found1 != std::string::npos && found2 != std::string::npos &&
+                blk_device.substr(found1) == token.substr(found2) + ab_suffix) {
+                new_token = blk_device;
+            }
+        }
+
+        if (!new_token.empty()) {
+            updated = true;
+            LINFO << "Verity table: updated block device from '" << token << "' to '" << new_token
+                  << "'";
         } else {
-            word = token;
+            new_token = token;
         }
 
         if (result.empty()) {
-            result = word;
+            result = new_token;
         } else {
-            result += " " + word;
+            result += " " + new_token;
         }
     }
 
-    if (result.empty()) {
+    if (!updated) {
         return;
     }
 
@@ -751,8 +782,8 @@
     if (fec_verity_get_metadata(f, &verity) < 0) {
         PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'";
         // Allow verity disabled when the device is unlocked without metadata
-        if ("0" == android::base::GetProperty("ro.boot.flash.locked", "")) {
-            retval = FS_MGR_SETUP_VERITY_DISABLED;
+        if (fs_mgr_is_device_unlocked()) {
+            retval = FS_MGR_SETUP_VERITY_SKIPPED;
             LWARNING << "Allow invalid metadata when the device is unlocked";
         }
         goto out;
@@ -810,9 +841,15 @@
 
     // verify the signature on the table
     if (verify_verity_signature(verity) < 0) {
+        // Allow signature verification error when the device is unlocked
+        if (fs_mgr_is_device_unlocked()) {
+            retval = FS_MGR_SETUP_VERITY_SKIPPED;
+            LWARNING << "Allow signature verification error when the device is unlocked";
+            goto out;
+        }
         if (params.mode == VERITY_MODE_LOGGING) {
             // the user has been warned, allow mounting without dm-verity
-            retval = FS_MGR_SETUP_VERITY_SUCCESS;
+            retval = FS_MGR_SETUP_VERITY_SKIPPED;
             goto out;
         }
 
@@ -825,10 +862,9 @@
     LINFO << "Enabling dm-verity for " << mount_point.c_str()
           << " (mode " << params.mode << ")";
 
-    if (fstab->fs_mgr_flags & MF_SLOTSELECT) {
-        // Update the verity params using the actual block device path
-        update_verity_table_blk_device(fstab->blk_device, &params.table);
-    }
+    // Update the verity params using the actual block device path
+    update_verity_table_blk_device(fstab->blk_device, &params.table,
+                                   fstab->fs_mgr_flags & MF_SLOTSELECT);
 
     // load the verity mapping table
     if (load_verity_table(io, mount_point, verity.data_size, fd, &params,
@@ -899,7 +935,7 @@
     }
 
     // make sure we've set everything up properly
-    if (wait_for_verity_dev && fs_mgr_test_access(fstab->blk_device) < 0) {
+    if (wait_for_verity_dev && !fs_mgr_wait_for_file(fstab->blk_device, 1s)) {
         goto out;
     }
 
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index e033d47..c74f6c8 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -22,11 +22,7 @@
 #include <stdbool.h>
 #include <linux/dm-ioctl.h>
 
-// C++ only headers
-// TODO: move this into separate header files under include/fs_mgr/*.h
-#ifdef __cplusplus
-#include <string>
-#endif
+#include <fstab/fstab.h>
 
 // Magic number at start of verity metadata
 #define VERITY_METADATA_MAGIC_NUMBER 0xb001b001
@@ -53,49 +49,10 @@
     MOUNT_MODE_LATE = 2
 };
 
-/*
- * The entries must be kept in the same order as they were seen in the fstab.
- * Unless explicitly requested, a lookup on mount point should always
- * return the 1st one.
- */
-struct fstab {
-    int num_entries;
-    struct fstab_rec *recs;
-    char *fstab_filename;
-};
-
-struct fstab_rec {
-    char *blk_device;
-    char *mount_point;
-    char *fs_type;
-    unsigned long flags;
-    char *fs_options;
-    int fs_mgr_flags;
-    char *key_loc;
-    char* key_dir;
-    char *verity_loc;
-    long long length;
-    char *label;
-    int partnum;
-    int swap_prio;
-    int max_comp_streams;
-    unsigned int zram_size;
-    uint64_t reserved_size;
-    unsigned int file_contents_mode;
-    unsigned int file_names_mode;
-    unsigned int erase_blk_size;
-    unsigned int logical_blk_size;
-};
-
 // Callback function for verity status
 typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab,
         const char *mount_point, int mode, int status);
 
-struct fstab *fs_mgr_read_fstab_default();
-struct fstab *fs_mgr_read_fstab_dt();
-struct fstab *fs_mgr_read_fstab(const char *fstab_path);
-void fs_mgr_free_fstab(struct fstab *fstab);
-
 #define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7
 #define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6
 #define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
@@ -120,28 +77,6 @@
 void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size);
 bool fs_mgr_load_verity_state(int* mode);
 bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
-int fs_mgr_add_entry(struct fstab *fstab,
-                     const char *mount_point, const char *fs_type,
-                     const char *blk_device);
-struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path);
-int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab);
-int fs_mgr_is_nonremovable(const struct fstab_rec *fstab);
-int fs_mgr_is_verified(const struct fstab_rec *fstab);
-int fs_mgr_is_verifyatboot(const struct fstab_rec *fstab);
-int fs_mgr_is_avb(const struct fstab_rec *fstab);
-int fs_mgr_is_encryptable(const struct fstab_rec *fstab);
-int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab);
-void fs_mgr_get_file_encryption_modes(const struct fstab_rec *fstab,
-                                      const char **contents_mode_ret,
-                                      const char **filenames_mode_ret);
-int fs_mgr_is_convertible_to_fbe(const struct fstab_rec *fstab);
-int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab);
-int fs_mgr_is_notrim(struct fstab_rec *fstab);
-int fs_mgr_is_formattable(struct fstab_rec *fstab);
-int fs_mgr_is_slotselect(struct fstab_rec *fstab);
-int fs_mgr_is_nofail(struct fstab_rec *fstab);
-int fs_mgr_is_latemount(struct fstab_rec *fstab);
-int fs_mgr_is_quota(struct fstab_rec *fstab);
 int fs_mgr_swapon_all(struct fstab *fstab);
 
 int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
@@ -154,10 +89,4 @@
 
 __END_DECLS
 
-// C++ only functions
-// TODO: move this into separate header files under include/fs_mgr/*.h
-#ifdef __cplusplus
-std::string fs_mgr_get_slot_suffix();
-#endif
-
 #endif /* __CORE_FS_MGR_H */
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
new file mode 100644
index 0000000..15c8caf
--- /dev/null
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 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 __CORE_FS_TAB_H
+#define __CORE_FS_TAB_H
+
+#include <linux/dm-ioctl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// C++ only headers
+// TODO: move this into separate header files under include/fs_mgr/*.h
+#ifdef __cplusplus
+#include <string>
+#endif
+
+__BEGIN_DECLS
+
+/*
+ * The entries must be kept in the same order as they were seen in the fstab.
+ * Unless explicitly requested, a lookup on mount point should always
+ * return the 1st one.
+ */
+struct fstab {
+    int num_entries;
+    struct fstab_rec* recs;
+    char* fstab_filename;
+};
+
+struct fstab_rec {
+    char* blk_device;
+    char* mount_point;
+    char* fs_type;
+    unsigned long flags;
+    char* fs_options;
+    int fs_mgr_flags;
+    char* key_loc;
+    char* key_dir;
+    char* verity_loc;
+    long long length;
+    char* label;
+    int partnum;
+    int swap_prio;
+    int max_comp_streams;
+    unsigned int zram_size;
+    uint64_t reserved_size;
+    unsigned int file_contents_mode;
+    unsigned int file_names_mode;
+    unsigned int erase_blk_size;
+    unsigned int logical_blk_size;
+};
+
+struct fstab* fs_mgr_read_fstab_default();
+struct fstab* fs_mgr_read_fstab_dt();
+struct fstab* fs_mgr_read_fstab(const char* fstab_path);
+void fs_mgr_free_fstab(struct fstab* fstab);
+
+int fs_mgr_add_entry(struct fstab* fstab, const char* mount_point, const char* fs_type,
+                     const char* blk_device);
+struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const char* path);
+int fs_mgr_is_voldmanaged(const struct fstab_rec* fstab);
+int fs_mgr_is_nonremovable(const struct fstab_rec* fstab);
+int fs_mgr_is_verified(const struct fstab_rec* fstab);
+int fs_mgr_is_verifyatboot(const struct fstab_rec* fstab);
+int fs_mgr_is_avb(const struct fstab_rec* fstab);
+int fs_mgr_is_encryptable(const struct fstab_rec* fstab);
+int fs_mgr_is_file_encrypted(const struct fstab_rec* fstab);
+void fs_mgr_get_file_encryption_modes(const struct fstab_rec* fstab, const char** contents_mode_ret,
+                                      const char** filenames_mode_ret);
+int fs_mgr_is_convertible_to_fbe(const struct fstab_rec* fstab);
+int fs_mgr_is_noemulatedsd(const struct fstab_rec* fstab);
+int fs_mgr_is_notrim(const struct fstab_rec* fstab);
+int fs_mgr_is_formattable(const struct fstab_rec* fstab);
+int fs_mgr_is_slotselect(const struct fstab_rec* fstab);
+int fs_mgr_is_nofail(const struct fstab_rec* fstab);
+int fs_mgr_is_latemount(const struct fstab_rec* fstab);
+int fs_mgr_is_quota(const struct fstab_rec* fstab);
+
+__END_DECLS
+
+// C++ only functions
+// TODO: move this into separate header files under include/fs_mgr/*.h
+#ifdef __cplusplus
+std::string fs_mgr_get_slot_suffix();
+#endif
+
+#endif /* __CORE_FS_TAB_H */
diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk
index 0dfd9d8..28f0b07 100644
--- a/gatekeeperd/Android.mk
+++ b/gatekeeperd/Android.mk
@@ -21,8 +21,7 @@
 LOCAL_SRC_FILES := \
 	SoftGateKeeperDevice.cpp \
 	IGateKeeperService.cpp \
-	gatekeeperd.cpp \
-	IUserManager.cpp
+	gatekeeperd.cpp
 
 LOCAL_MODULE := gatekeeperd
 LOCAL_SHARED_LIBRARIES := \
diff --git a/gatekeeperd/IUserManager.cpp b/gatekeeperd/IUserManager.cpp
deleted file mode 100644
index 8167d19..0000000
--- a/gatekeeperd/IUserManager.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "IUserManager"
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-
-#include "IUserManager.h"
-
-namespace android {
-
-class BpUserManager : public BpInterface<IUserManager>
-{
-public:
-    explicit BpUserManager(const sp<IBinder>& impl) :
-            BpInterface<IUserManager>(impl) {
-    }
-    virtual int32_t getCredentialOwnerProfile(int32_t user_id) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IUserManager::getInterfaceDescriptor());
-        data.writeInt32(user_id);
-        status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0);
-        if (rc != NO_ERROR) {
-            ALOGE("%s: failed (%d)\n", __func__, rc);
-            return -1;
-        }
-
-        int32_t exception = reply.readExceptionCode();
-        if (exception != 0) {
-            ALOGE("%s: got exception (%d)\n", __func__, exception);
-            return -1;
-        }
-
-        return reply.readInt32();
-    }
-
-};
-
-IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager");
-
-}; // namespace android
-
diff --git a/gatekeeperd/IUserManager.h b/gatekeeperd/IUserManager.h
deleted file mode 100644
index 640e9b5..0000000
--- a/gatekeeperd/IUserManager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef IUSERMANAGER_H_
-#define IUSERMANAGER_H_
-
-#include <inttypes.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-/*
-* Communication channel to UserManager
-*/
-class IUserManager : public IInterface {
-    public:
-        // must be kept in sync with IUserManager.aidl
-        enum {
-            GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0,
-        };
-
-        virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0;
-
-        DECLARE_META_INTERFACE(UserManager);
-};
-
-}; // namespace android
-
-#endif // IUSERMANAGER_H_
-
diff --git a/gatekeeperd/SoftGateKeeper.h b/gatekeeperd/SoftGateKeeper.h
index cb02a6f..2f4f4d7 100644
--- a/gatekeeperd/SoftGateKeeper.h
+++ b/gatekeeperd/SoftGateKeeper.h
@@ -26,11 +26,11 @@
 }
 
 #include <android-base/memory.h>
-#include <UniquePtr.h>
 #include <gatekeeper/gatekeeper.h>
 
 #include <iostream>
 #include <unordered_map>
+#include <memory>
 
 namespace gatekeeper {
 
@@ -173,7 +173,7 @@
     typedef std::unordered_map<uint32_t, failure_record_t> FailureRecordMap;
     typedef std::unordered_map<uint64_t, fast_hash_t> FastHashMap;
 
-    UniquePtr<uint8_t[]> key_;
+    std::unique_ptr<uint8_t[]> key_;
     FailureRecordMap failure_map_;
     FastHashMap fast_hash_map_;
 };
diff --git a/gatekeeperd/SoftGateKeeperDevice.h b/gatekeeperd/SoftGateKeeperDevice.h
index 3463c29..e3dc068 100644
--- a/gatekeeperd/SoftGateKeeperDevice.h
+++ b/gatekeeperd/SoftGateKeeperDevice.h
@@ -19,7 +19,7 @@
 
 #include "SoftGateKeeper.h"
 
-#include <UniquePtr.h>
+#include <memory>
 
 using namespace gatekeeper;
 
@@ -68,7 +68,7 @@
             const uint8_t *provided_password, uint32_t provided_password_length,
             uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll);
 private:
-    UniquePtr<SoftGateKeeper> impl_;
+    std::unique_ptr<SoftGateKeeper> impl_;
 };
 
 } // namespace gatekeeper
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index c6369f9..61c8804 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -23,6 +23,7 @@
 #include <inttypes.h>
 #include <stdint.h>
 #include <unistd.h>
+#include <memory>
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -37,7 +38,6 @@
 #include <utils/String16.h>
 
 #include "SoftGateKeeperDevice.h"
-#include "IUserManager.h"
 
 #include <hidl/HidlSupport.h>
 #include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -334,23 +334,7 @@
         return ret;
     }
 
-    virtual uint64_t getSecureUserId(uint32_t uid) {
-        uint64_t sid = read_sid(uid);
-         if (sid == 0) {
-            // might be a work profile, look up the parent
-            sp<IServiceManager> sm = defaultServiceManager();
-            sp<IBinder> binder = sm->getService(String16("user"));
-            sp<IUserManager> um = interface_cast<IUserManager>(binder);
-            int32_t parent = um->getCredentialOwnerProfile(uid);
-            if (parent < 0) {
-                return 0;
-            } else if (parent != (int32_t) uid) {
-                return read_sid(parent);
-            }
-        }
-        return sid;
-
-    }
+    virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); }
 
     virtual void clearSecureUserId(uint32_t uid) {
         IPCThreadState* ipc = IPCThreadState::self();
@@ -400,7 +384,7 @@
 
 private:
     sp<IGatekeeper> hw_device;
-    UniquePtr<SoftGateKeeperDevice> soft_device;
+    std::unique_ptr<SoftGateKeeperDevice> soft_device;
 
     bool clear_state_if_needed_done;
 };
diff --git a/gatekeeperd/tests/gatekeeper_test.cpp b/gatekeeperd/tests/gatekeeper_test.cpp
index 47a8bfa..100375f 100644
--- a/gatekeeperd/tests/gatekeeper_test.cpp
+++ b/gatekeeperd/tests/gatekeeper_test.cpp
@@ -19,7 +19,6 @@
 
 #include <gtest/gtest.h>
 #include <hardware/hw_auth_token.h>
-#include <UniquePtr.h>
 
 #include "../SoftGateKeeper.h"
 
diff --git a/healthd/Android.bp b/healthd/Android.bp
new file mode 100644
index 0000000..56f5148
--- /dev/null
+++ b/healthd/Android.bp
@@ -0,0 +1,7 @@
+cc_library_headers {
+    name: "libhealthd_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+    header_libs: ["libbatteryservice_headers"],
+    export_header_lib_headers: ["libbatteryservice_headers"],
+}
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index d26530b..676ee41 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -116,6 +116,10 @@
         { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE },
         { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE },
         { "Cold", BATTERY_HEALTH_COLD },
+        // battery health values from JEITA spec
+        { "Warm", BATTERY_HEALTH_GOOD },
+        { "Cool", BATTERY_HEALTH_GOOD },
+        { "Hot", BATTERY_HEALTH_OVERHEAT },
         { NULL, 0 },
     };
 
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index e7f3eaf..6c6d738 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -32,6 +32,7 @@
 #include <functional>
 
 #include <android-base/file.h>
+#include <android-base/macros.h>
 
 #include <linux/netlink.h>
 #include <sys/socket.h>
@@ -72,8 +73,6 @@
 #define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC)
 #define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
 
-#define LAST_KMSG_PATH "/proc/last_kmsg"
-#define LAST_KMSG_PSTORE_PATH "/sys/fs/pstore/console-ramoops"
 #define LAST_KMSG_MAX_SZ (32 * 1024)
 
 #define LOGE(x...) KLOG_ERROR("charger", x);
@@ -205,14 +204,21 @@
     LOGW("\n");
     LOGW("*************** LAST KMSG ***************\n");
     LOGW("\n");
-    buf = (char*)load_file(LAST_KMSG_PSTORE_PATH, &sz);
+    const char* kmsg[] = {
+        // clang-format off
+        "/sys/fs/pstore/console-ramoops-0",
+        "/sys/fs/pstore/console-ramoops",
+        "/proc/last_kmsg",
+        // clang-format on
+    };
+    for (size_t i = 0; i < arraysize(kmsg); ++i) {
+        buf = (char*)load_file(kmsg[i], &sz);
+        if (buf && sz) break;
+    }
 
     if (!buf || !sz) {
-        buf = (char*)load_file(LAST_KMSG_PATH, &sz);
-        if (!buf || !sz) {
-            LOGW("last_kmsg not found. Cold reset?\n");
-            goto out;
-        }
+        LOGW("last_kmsg not found. Cold reset?\n");
+        goto out;
     }
 
     len = min(sz, LAST_KMSG_MAX_SZ);
diff --git a/include/private/fs_config.h b/include/private/fs_config.h
new file mode 100644
index 0000000..e9868a4
--- /dev/null
+++ b/include/private/fs_config.h
@@ -0,0 +1,4 @@
+// TODO(b/63135587) remove this file after the transitive dependency
+// from private/android_filesystem_config.h is resolved. All files that use
+// libcutils/include/private/fs_config.h should include the file directly, not
+// indirectly via private/android_filesystem_config.h.
diff --git a/init/Android.bp b/init/Android.bp
index 5d6d979..aaef7e9 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -18,9 +18,8 @@
     name: "init_defaults",
     cpp_std: "experimental",
     sanitize: {
-        misc_undefined: ["integer"],
+        misc_undefined: ["signed-integer-overflow"],
     },
-    tidy_checks: ["-misc-forwarding-reference-overload"],
     cppflags: [
         "-DLOG_UEVENTS=0",
         "-Wall",
@@ -158,6 +157,7 @@
         "init_test.cpp",
         "property_service_test.cpp",
         "service_test.cpp",
+        "ueventd_test.cpp",
         "util_test.cpp",
     ],
     shared_libs: [
diff --git a/init/Android.mk b/init/Android.mk
index bf75f5a..161256e 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -28,6 +28,10 @@
 
 init_options += -DLOG_UEVENTS=0
 
+ifeq ($(TARGET_USER_MODE_LINUX), true)
+    init_cflags += -DUSER_MODE_LINUX
+endif
+
 init_cflags += \
     $(init_options) \
     -Wall -Wextra \
@@ -38,8 +42,6 @@
 # --
 
 include $(CLEAR_VARS)
-# b/38002385, work around clang-tidy segmentation fault.
-LOCAL_TIDY_CHECKS := -misc-forwarding-reference-overload
 LOCAL_CPPFLAGS := $(init_cflags)
 LOCAL_SRC_FILES:= \
     bootchart.cpp \
@@ -94,6 +96,6 @@
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
 
-LOCAL_SANITIZE := integer
+LOCAL_SANITIZE := signed-integer-overflow
 LOCAL_CLANG := true
 include $(BUILD_EXECUTABLE)
diff --git a/init/README.md b/init/README.md
index 422fdad..f3b57bc 100644
--- a/init/README.md
+++ b/init/README.md
@@ -260,6 +260,18 @@
 > Sets the child's /proc/self/oom\_score\_adj to the specified value,
   which must range from -1000 to 1000.
 
+`memcg.swappiness <value>`
+> Sets the child's memory.swappiness to the specified value (only if memcg is mounted),
+  which must be equal or greater than 0.
+
+`memcg.soft_limit_in_bytes <value>`
+> Sets the child's memory.soft_limit_in_bytes to the specified value (only if memcg is mounted),
+  which must be equal or greater than 0.
+
+`memcg.limit_in_bytes <value>`
+> Sets the child's memory.limit_in_bytes to the specified value (only if memcg is mounted),
+  which must be equal or greater than 0.
+
 `shutdown <shutdown_behavior>`
 > Set shutdown behavior of the service process. When this is not specified,
   the service is killed during shutdown process by using SIGTERM and SIGKILL.
diff --git a/init/action.cpp b/init/action.cpp
index 41bd061..4ec5f17 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -16,15 +16,17 @@
 
 #include "action.h"
 
+#include <android-base/chrono_utils.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
-#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 
 #include "util.h"
 
 using android::base::Join;
-using android::base::StringPrintf;
+
+namespace android {
+namespace init {
 
 Command::Command(BuiltinFunction f, const std::vector<std::string>& args, int line)
     : func_(f), args_(args), line_(line) {}
@@ -89,19 +91,18 @@
 }
 
 void Action::ExecuteCommand(const Command& command) const {
-    Timer t;
+    android::base::Timer t;
     int result = command.InvokeFunc();
 
-    double duration_ms = t.duration_s() * 1000;
+    auto duration = t.duration();
     // Any action longer than 50ms will be warned to user as slow operation
-    if (duration_ms > 50.0 ||
-        android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
+    if (duration > 50ms || android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
         std::string trigger_name = BuildTriggersString();
         std::string cmd_str = command.BuildCommandString();
-        std::string source = StringPrintf(" (%s:%d)", filename_.c_str(), command.line());
 
-        LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << source
-                  << " returned " << result << " took " << duration_ms << "ms.";
+        LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << " (" << filename_
+                  << ":" << command.line() << ") returned " << result << " took "
+                  << duration.count() << "ms.";
     }
 }
 
@@ -358,3 +359,6 @@
         action_manager_->AddAction(std::move(action_));
     }
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/action.h b/init/action.h
index c04076a..ad15f3f 100644
--- a/init/action.h
+++ b/init/action.h
@@ -27,6 +27,9 @@
 #include "init_parser.h"
 #include "keyword_map.h"
 
+namespace android {
+namespace init {
+
 class Command {
   public:
     Command(BuiltinFunction f, const std::vector<std::string>& args, int line);
@@ -127,4 +130,7 @@
     std::unique_ptr<Action> action_;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/bootchart.cpp b/init/bootchart.cpp
index 825603a..4727f92 100644
--- a/init/bootchart.cpp
+++ b/init/bootchart.cpp
@@ -40,6 +40,9 @@
 using android::base::StringPrintf;
 using namespace std::chrono_literals;
 
+namespace android {
+namespace init {
+
 static std::thread* g_bootcharting_thread;
 
 static std::mutex g_bootcharting_finished_mutex;
@@ -192,3 +195,6 @@
   if (args[1] == "start") return do_bootchart_start();
   return do_bootchart_stop();
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/bootchart.h b/init/bootchart.h
index 0e3593d..e4f7b59 100644
--- a/init/bootchart.h
+++ b/init/bootchart.h
@@ -20,6 +20,12 @@
 #include <string>
 #include <vector>
 
+namespace android {
+namespace init {
+
 int do_bootchart(const std::vector<std::string>& args);
 
+}  // namespace init
+}  // namespace android
+
 #endif /* _BOOTCHART_H */
diff --git a/init/builtins.cpp b/init/builtins.cpp
index fcc6092..9e2efe2 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -39,11 +39,11 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
-#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <bootloader_message/bootloader_message.h>
 #include <cutils/android_reboot.h>
@@ -68,6 +68,9 @@
 
 #define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
 
+namespace android {
+namespace init {
+
 static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
 
 static int insmod(const char *filename, const char *options, int flags) {
@@ -259,7 +262,7 @@
                 "--prompt_and_wipe_data",
                 "--reason=set_policy_failed:"s + args[1]};
             reboot_into_recovery(options);
-            return -1;
+            return 0;
         }
     }
     return 0;
@@ -487,7 +490,8 @@
         /* Setup a wipe via recovery, and reboot into recovery */
         PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
         const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
-        ret = reboot_into_recovery(options);
+        reboot_into_recovery(options);
+        return 0;
         /* If reboot worked, there is no return. */
     } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
         if (e4crypt_install_keyring()) {
@@ -552,11 +556,10 @@
         }
     }
 
-    std::string prop_name = android::base::StringPrintf("ro.boottime.init.mount_all.%s",
-                                                        prop_post_fix);
-    Timer t;
+    std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
+    android::base::Timer t;
     int ret =  mount_fstab(fstabfile, mount_mode);
-    property_set(prop_name.c_str(), std::to_string(t.duration_ms()).c_str());
+    property_set(prop_name, std::to_string(t.duration().count()));
 
     if (import_rc) {
         /* Paths of .rc files are specified at the 2nd argument and beyond */
@@ -584,9 +587,7 @@
 }
 
 static int do_setprop(const std::vector<std::string>& args) {
-    const char* name = args[1].c_str();
-    const char* value = args[2].c_str();
-    property_set(name, value);
+    property_set(args[1], args[2]);
     return 0;
 }
 
@@ -669,8 +670,7 @@
 
 static void verity_update_property(fstab_rec *fstab, const char *mount_point,
                                    int mode, int status) {
-    property_set(android::base::StringPrintf("partition.%s.verified", mount_point).c_str(),
-                 android::base::StringPrintf("%d", mode).c_str());
+    property_set("partition."s + mount_point + ".verified", std::to_string(mode));
 }
 
 static int do_verity_update_state(const std::vector<std::string>& args) {
@@ -946,3 +946,6 @@
     // clang-format on
     return builtin_functions;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/builtins.h b/init/builtins.h
index e1f0567..b110f61 100644
--- a/init/builtins.h
+++ b/init/builtins.h
@@ -24,6 +24,9 @@
 
 #include "keyword_map.h"
 
+namespace android {
+namespace init {
+
 using BuiltinFunction = std::function<int(const std::vector<std::string>&)>;
 class BuiltinFunctionMap : public KeywordMap<BuiltinFunction> {
   public:
@@ -33,4 +36,7 @@
     const Map& map() const override;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/capabilities.cpp b/init/capabilities.cpp
index b8a9ec0..642a364 100644
--- a/init/capabilities.cpp
+++ b/init/capabilities.cpp
@@ -25,6 +25,9 @@
 
 #define CAP_MAP_ENTRY(cap) { #cap, CAP_##cap }
 
+namespace android {
+namespace init {
+
 static const std::map<std::string, int> cap_map = {
     CAP_MAP_ENTRY(CHOWN),
     CAP_MAP_ENTRY(DAC_OVERRIDE),
@@ -104,17 +107,15 @@
 }
 
 static bool SetProcCaps(const CapSet& to_keep, bool add_setpcap) {
-    cap_t caps = cap_init();
-    auto deleter = [](cap_t* p) { cap_free(*p); };
-    std::unique_ptr<cap_t, decltype(deleter)> ptr_caps(&caps, deleter);
+    ScopedCaps caps(cap_init());
 
-    cap_clear(caps);
+    cap_clear(caps.get());
     cap_value_t value[1];
     for (size_t cap = 0; cap < to_keep.size(); ++cap) {
         if (to_keep.test(cap)) {
             value[0] = cap;
-            if (cap_set_flag(caps, CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
-                cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
+            if (cap_set_flag(caps.get(), CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
+                cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
                 PLOG(ERROR) << "cap_set_flag(INHERITABLE|PERMITTED, " << cap << ") failed";
                 return false;
             }
@@ -123,14 +124,14 @@
 
     if (add_setpcap) {
         value[0] = CAP_SETPCAP;
-        if (cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
-            cap_set_flag(caps, CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
+        if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
+            cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
             PLOG(ERROR) << "cap_set_flag(PERMITTED|EFFECTIVE, " << CAP_SETPCAP << ") failed";
             return false;
         }
     }
 
-    if (cap_set_proc(caps) != 0) {
+    if (cap_set_proc(caps.get()) != 0) {
         PLOG(ERROR) << "cap_set_proc(" << to_keep.to_ulong() << ") failed";
         return false;
     }
@@ -192,3 +193,6 @@
     // See http://man7.org/linux/man-pages/man7/capabilities.7.html.
     return SetAmbientCaps(to_keep);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/capabilities.h b/init/capabilities.h
index abd7fb2..ede85c3 100644
--- a/init/capabilities.h
+++ b/init/capabilities.h
@@ -15,16 +15,28 @@
 #ifndef _INIT_CAPABILITIES_H
 #define _INIT_CAPABILITIES_H
 
-#include <linux/capability.h>
+#include <sys/capability.h>
 
 #include <bitset>
 #include <string>
+#include <type_traits>
+
+namespace android {
+namespace init {
+
+struct CapDeleter {
+    void operator()(cap_t caps) const { cap_free(caps); }
+};
 
 using CapSet = std::bitset<CAP_LAST_CAP + 1>;
+using ScopedCaps = std::unique_ptr<std::remove_pointer<cap_t>::type, CapDeleter>;
 
 int LookupCap(const std::string& cap_name);
 bool CapAmbientSupported();
 unsigned int GetLastValidCap();
 bool SetCapsForExec(const CapSet& to_keep);
 
+}  // namespace init
+}  // namespace android
+
 #endif  // _INIT_CAPABILITIES_H
diff --git a/init/descriptors.cpp b/init/descriptors.cpp
index 6f729a3..0cb639a 100644
--- a/init/descriptors.cpp
+++ b/init/descriptors.cpp
@@ -31,6 +31,9 @@
 #include "init.h"
 #include "util.h"
 
+namespace android {
+namespace init {
+
 DescriptorInfo::DescriptorInfo(const std::string& name, const std::string& type, uid_t uid,
                                gid_t gid, int perm, const std::string& context)
         : name_(name), type_(type), uid_(uid), gid_(gid), perm_(perm), context_(context) {
@@ -58,7 +61,7 @@
   std::for_each(publishedName.begin(), publishedName.end(),
                 [] (char& c) { c = isalnum(c) ? c : '_'; });
 
-  std::string val = android::base::StringPrintf("%d", fd);
+  std::string val = std::to_string(fd);
   add_environment(publishedName.c_str(), val.c_str());
 
   // make sure we don't close on exec
@@ -74,7 +77,8 @@
 }
 
 void SocketInfo::Clean() const {
-  unlink(android::base::StringPrintf(ANDROID_SOCKET_DIR "/%s", name().c_str()).c_str());
+    std::string path = android::base::StringPrintf("%s/%s", ANDROID_SOCKET_DIR, name().c_str());
+    unlink(path.c_str());
 }
 
 int SocketInfo::Create(const std::string& context) const {
@@ -125,3 +129,6 @@
 const std::string FileInfo::key() const {
   return ANDROID_FILE_ENV_PREFIX;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/descriptors.h b/init/descriptors.h
index ff276fb..3bdddfe 100644
--- a/init/descriptors.h
+++ b/init/descriptors.h
@@ -22,6 +22,9 @@
 
 #include <string>
 
+namespace android {
+namespace init {
+
 class DescriptorInfo {
  public:
   DescriptorInfo(const std::string& name, const std::string& type, uid_t uid,
@@ -75,4 +78,7 @@
   virtual const std::string key() const override;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/devices.cpp b/init/devices.cpp
index 2943fb7..13cf991 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -37,13 +37,23 @@
 #error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
 #endif
 
+using android::base::Basename;
+using android::base::Dirname;
+using android::base::Readlink;
+using android::base::Realpath;
+using android::base::StartsWith;
+using android::base::StringPrintf;
+
+namespace android {
+namespace init {
+
 /* Given a path that may start with a PCI device, populate the supplied buffer
  * with the PCI domain/bus number and the peripheral ID and return 0.
  * If it doesn't start with a PCI device, or there is some error, return -1 */
 static bool FindPciDevicePrefix(const std::string& path, std::string* result) {
     result->clear();
 
-    if (!android::base::StartsWith(path, "/devices/pci")) return false;
+    if (!StartsWith(path, "/devices/pci")) return false;
 
     /* Beginning of the prefix is the initial "pci" after "/devices/" */
     std::string::size_type start = 9;
@@ -74,7 +84,7 @@
 static bool FindVbdDevicePrefix(const std::string& path, std::string* result) {
     result->clear();
 
-    if (!android::base::StartsWith(path, "/devices/vbd-")) return false;
+    if (!StartsWith(path, "/devices/vbd-")) return false;
 
     /* Beginning of the prefix is the initial "vbd-" after "/devices/" */
     std::string::size_type start = 13;
@@ -116,14 +126,14 @@
 }
 
 bool Permissions::Match(const std::string& path) const {
-    if (prefix_) return android::base::StartsWith(path, name_.c_str());
+    if (prefix_) return StartsWith(path, name_.c_str());
     if (wildcard_) return fnmatch(name_.c_str(), path.c_str(), FNM_PATHNAME) == 0;
     return path == name_;
 }
 
 bool SysfsPermissions::MatchWithSubsystem(const std::string& path,
                                           const std::string& subsystem) const {
-    std::string path_basename = android::base::Basename(path);
+    std::string path_basename = Basename(path);
     if (name().find(subsystem) != std::string::npos) {
         if (Match("/sys/class/" + subsystem + "/" + path_basename)) return true;
         if (Match("/sys/bus/" + subsystem + "/devices/" + path_basename)) return true;
@@ -156,11 +166,11 @@
     // Uevents don't contain the mount point, so we need to add it here.
     path.insert(0, sysfs_mount_point_);
 
-    std::string directory = android::base::Dirname(path);
+    std::string directory = Dirname(path);
 
     while (directory != "/" && directory != ".") {
         std::string subsystem_link_path;
-        if (android::base::Realpath(directory + "/subsystem", &subsystem_link_path) &&
+        if (Realpath(directory + "/subsystem", &subsystem_link_path) &&
             subsystem_link_path == sysfs_mount_point_ + "/bus/platform") {
             // We need to remove the mount point that we added above before returning.
             directory.erase(0, sysfs_mount_point_.size());
@@ -172,7 +182,7 @@
         if (last_slash == std::string::npos) return false;
 
         path.erase(last_slash);
-        directory = android::base::Dirname(path);
+        directory = Dirname(path);
     }
 
     return false;
@@ -209,7 +219,7 @@
     return {0600, 0, 0};
 }
 
-void DeviceHandler::MakeDevice(const std::string& path, int block, int major, int minor,
+void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, int minor,
                                const std::vector<std::string>& links) const {
     auto[mode, uid, gid] = GetDevicePermissions(path, links);
     mode |= (block ? S_IFBLK : S_IFCHR);
@@ -269,45 +279,6 @@
     }
 }
 
-std::vector<std::string> DeviceHandler::GetCharacterDeviceSymlinks(const Uevent& uevent) const {
-    std::string parent_device;
-    if (!FindPlatformDevice(uevent.path, &parent_device)) return {};
-
-    // skip path to the parent driver
-    std::string path = uevent.path.substr(parent_device.length());
-
-    if (!android::base::StartsWith(path, "/usb")) return {};
-
-    // skip root hub name and device. use device interface
-    // skip 3 slashes, including the first / by starting the search at the 1st character, not 0th.
-    // then extract what comes between the 3rd and 4th slash
-    // e.g. "/usb/usb_device/name/tty2-1:1.0" -> "name"
-
-    std::string::size_type start = 0;
-    start = path.find('/', start + 1);
-    if (start == std::string::npos) return {};
-
-    start = path.find('/', start + 1);
-    if (start == std::string::npos) return {};
-
-    auto end = path.find('/', start + 1);
-    if (end == std::string::npos) return {};
-
-    start++;  // Skip the first '/'
-
-    auto length = end - start;
-    if (length == 0) return {};
-
-    auto name_string = path.substr(start, length);
-
-    std::vector<std::string> links;
-    links.emplace_back("/dev/usb/" + uevent.subsystem + name_string);
-
-    mkdir("/dev/usb", 0755);
-
-    return links;
-}
-
 // replaces any unacceptable characters with '_', the
 // length of the resulting string is equal to the input string
 void SanitizePartitionName(std::string* string) {
@@ -334,9 +305,9 @@
         static const std::string devices_platform_prefix = "/devices/platform/";
         static const std::string devices_prefix = "/devices/";
 
-        if (android::base::StartsWith(device, devices_platform_prefix.c_str())) {
+        if (StartsWith(device, devices_platform_prefix.c_str())) {
             device = device.substr(devices_platform_prefix.length());
-        } else if (android::base::StartsWith(device, devices_prefix.c_str())) {
+        } else if (StartsWith(device, devices_prefix.c_str())) {
             device = device.substr(devices_prefix.length());
         }
 
@@ -375,13 +346,13 @@
     return links;
 }
 
-void DeviceHandler::HandleDevice(const std::string& action, const std::string& devpath, int block,
+void DeviceHandler::HandleDevice(const std::string& action, const std::string& devpath, bool block,
                                  int major, int minor, const std::vector<std::string>& links) const {
     if (action == "add") {
         MakeDevice(devpath, block, major, minor, links);
         for (const auto& link : links) {
-            if (mkdir_recursive(android::base::Dirname(link), 0755, sehandle_)) {
-                PLOG(ERROR) << "Failed to create directory " << android::base::Dirname(link);
+            if (mkdir_recursive(Dirname(link), 0755, sehandle_)) {
+                PLOG(ERROR) << "Failed to create directory " << Dirname(link);
             }
 
             if (symlink(devpath.c_str(), link.c_str()) && errno != EEXIST) {
@@ -393,7 +364,7 @@
     if (action == "remove") {
         for (const auto& link : links) {
             std::string link_path;
-            if (android::base::Readlink(link, &link_path) && link_path == devpath) {
+            if (Readlink(link, &link_path) && link_path == devpath) {
                 unlink(link.c_str());
             }
         }
@@ -401,31 +372,26 @@
     }
 }
 
-void DeviceHandler::HandleBlockDeviceEvent(const Uevent& uevent) const {
-    // if it's not a /dev device, nothing to do
-    if (uevent.major < 0 || uevent.minor < 0) return;
-
-    const char* base = "/dev/block/";
-    make_dir(base, 0755, sehandle_);
-
-    std::string name = android::base::Basename(uevent.path);
-    std::string devpath = base + name;
-
-    std::vector<std::string> links;
-    if (android::base::StartsWith(uevent.path, "/devices")) {
-        links = GetBlockDeviceSymlinks(uevent);
+void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
+    if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
+        FixupSysPermissions(uevent.path, uevent.subsystem);
     }
 
-    HandleDevice(uevent.action, devpath, 1, uevent.major, uevent.minor, links);
-}
-
-void DeviceHandler::HandleGenericDeviceEvent(const Uevent& uevent) const {
     // if it's not a /dev device, nothing to do
     if (uevent.major < 0 || uevent.minor < 0) return;
 
     std::string devpath;
+    std::vector<std::string> links;
+    bool block = false;
 
-    if (android::base::StartsWith(uevent.subsystem, "usb")) {
+    if (uevent.subsystem == "block") {
+        block = true;
+        devpath = "/dev/block/" + Basename(uevent.path);
+
+        if (StartsWith(uevent.path, "/devices")) {
+            links = GetBlockDeviceSymlinks(uevent);
+        }
+    } else if (StartsWith(uevent.subsystem, "usb")) {
         if (uevent.subsystem == "usb") {
             if (!uevent.device_name.empty()) {
                 devpath = "/dev/" + uevent.device_name;
@@ -435,7 +401,7 @@
                 // Minors are broken up into groups of 128, starting at "001"
                 int bus_id = uevent.minor / 128 + 1;
                 int device_id = uevent.minor % 128 + 1;
-                devpath = android::base::StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
+                devpath = StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
             }
         } else {
             // ignore other USB events
@@ -446,26 +412,12 @@
                subsystem != subsystems_.cend()) {
         devpath = subsystem->ParseDevPath(uevent);
     } else {
-        devpath = "/dev/" + android::base::Basename(uevent.path);
+        devpath = "/dev/" + Basename(uevent.path);
     }
 
-    mkdir_recursive(android::base::Dirname(devpath), 0755, sehandle_);
+    mkdir_recursive(Dirname(devpath), 0755, sehandle_);
 
-    auto links = GetCharacterDeviceSymlinks(uevent);
-
-    HandleDevice(uevent.action, devpath, 0, uevent.major, uevent.minor, links);
-}
-
-void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
-    if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
-        FixupSysPermissions(uevent.path, uevent.subsystem);
-    }
-
-    if (uevent.subsystem == "block") {
-        HandleBlockDeviceEvent(uevent);
-    } else {
-        HandleGenericDeviceEvent(uevent);
-    }
+    HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links);
 }
 
 DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
@@ -481,3 +433,6 @@
 DeviceHandler::DeviceHandler()
     : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
                     std::vector<Subsystem>{}, false) {}
+
+}  // namespace init
+}  // namespace android
diff --git a/init/devices.h b/init/devices.h
index 362c38c..c64f5fb 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -29,6 +29,9 @@
 
 #include "uevent.h"
 
+namespace android {
+namespace init {
+
 class Permissions {
   public:
     Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid);
@@ -112,16 +115,12 @@
     bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
     std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
         const std::string& path, const std::vector<std::string>& links) const;
-    void MakeDevice(const std::string& path, int block, int major, int minor,
+    void MakeDevice(const std::string& path, bool block, int major, int minor,
                     const std::vector<std::string>& links) const;
-    std::vector<std::string> GetCharacterDeviceSymlinks(const Uevent& uevent) const;
-    void HandleDevice(const std::string& action, const std::string& devpath, int block, int major,
+    void HandleDevice(const std::string& action, const std::string& devpath, bool block, int major,
                       int minor, const std::vector<std::string>& links) const;
     void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
 
-    void HandleBlockDeviceEvent(const Uevent& uevent) const;
-    void HandleGenericDeviceEvent(const Uevent& uevent) const;
-
     std::vector<Permissions> dev_permissions_;
     std::vector<SysfsPermissions> sysfs_permissions_;
     std::vector<Subsystem> subsystems_;
@@ -133,4 +132,7 @@
 // Exposed for testing
 void SanitizePartitionName(std::string* string);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/devices_test.cpp b/init/devices_test.cpp
index e1e4e49..ac4ab9b 100644
--- a/init/devices_test.cpp
+++ b/init/devices_test.cpp
@@ -24,10 +24,13 @@
 
 using namespace std::string_literals;
 
+namespace android {
+namespace init {
+
 class DeviceHandlerTester {
   public:
     void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent,
-                         const std::vector<std::string> expected_links, bool block) {
+                         const std::vector<std::string> expected_links) {
         TemporaryDir fake_sys_root;
         device_handler_.sysfs_mount_point_ = fake_sys_root.path;
 
@@ -41,11 +44,7 @@
         mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777, nullptr);
 
         std::vector<std::string> result;
-        if (block) {
-            result = device_handler_.GetBlockDeviceSymlinks(uevent);
-        } else {
-            result = device_handler_.GetCharacterDeviceSymlinks(uevent);
-        }
+        result = device_handler_.GetBlockDeviceSymlinks(uevent);
 
         auto expected_size = expected_links.size();
         ASSERT_EQ(expected_size, result.size());
@@ -61,95 +60,6 @@
     DeviceHandler device_handler_;
 };
 
-TEST(device_handler, get_character_device_symlinks_success) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device/name/tty2-1:1.0",
-        .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result{"/dev/usb/ttyname"};
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_pdev_match) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/device/name/tty2-1:1.0", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_nothing_after_platform_device) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_usb_found) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/bad/bad/", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_roothub) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_usb_device) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device/", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_final_slash) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device/name", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_final_name) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device//", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
 TEST(device_handler, get_block_device_symlinks_success_platform) {
     // These are actual paths from bullhead
     const char* platform_device = "/devices/soc.0/f9824900.sdhci";
@@ -161,7 +71,7 @@
     std::vector<std::string> expected_result{"/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0"};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition) {
@@ -179,7 +89,7 @@
     };
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_num) {
@@ -195,7 +105,7 @@
     };
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_name) {
@@ -211,7 +121,7 @@
     };
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_pci) {
@@ -222,7 +132,7 @@
     std::vector<std::string> expected_result{"/dev/block/pci/pci0000:00/0000:00:1f.2/mmcblk0"};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_pci_bad_format) {
@@ -233,7 +143,7 @@
     std::vector<std::string> expected_result{};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_vbd) {
@@ -244,7 +154,7 @@
     std::vector<std::string> expected_result{"/dev/block/vbd/1234/mmcblk0"};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_vbd_bad_format) {
@@ -255,7 +165,7 @@
     std::vector<std::string> expected_result{};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_no_matches) {
@@ -268,7 +178,7 @@
     std::vector<std::string> expected_result;
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, sanitize_null) {
@@ -400,3 +310,6 @@
     EXPECT_EQ(0U, permissions.uid());
     EXPECT_EQ(1001U, permissions.gid());
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index 844c605..b686885 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -24,16 +24,22 @@
 #include <string>
 #include <thread>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 
-#include "util.h"
+using android::base::Timer;
+using android::base::unique_fd;
+using android::base::WriteFully;
+
+namespace android {
+namespace init {
 
 static void LoadFirmware(const Uevent& uevent, const std::string& root, int fw_fd, size_t fw_size,
                          int loading_fd, int data_fd) {
     // Start transfer.
-    android::base::WriteFully(loading_fd, "1", 1);
+    WriteFully(loading_fd, "1", 1);
 
     // Copy the firmware.
     int rc = sendfile(data_fd, fw_fd, nullptr, fw_size);
@@ -44,7 +50,7 @@
 
     // Tell the firmware whether to abort or commit.
     const char* response = (rc != -1) ? "0" : "-1";
-    android::base::WriteFully(loading_fd, response, strlen(response));
+    WriteFully(loading_fd, response, strlen(response));
 }
 
 static bool IsBooting() {
@@ -60,13 +66,13 @@
     std::string loading = root + "/loading";
     std::string data = root + "/data";
 
-    android::base::unique_fd loading_fd(open(loading.c_str(), O_WRONLY | O_CLOEXEC));
+    unique_fd loading_fd(open(loading.c_str(), O_WRONLY | O_CLOEXEC));
     if (loading_fd == -1) {
         PLOG(ERROR) << "couldn't open firmware loading fd for " << uevent.firmware;
         return;
     }
 
-    android::base::unique_fd data_fd(open(data.c_str(), O_WRONLY | O_CLOEXEC));
+    unique_fd data_fd(open(data.c_str(), O_WRONLY | O_CLOEXEC));
     if (data_fd == -1) {
         PLOG(ERROR) << "couldn't open firmware data fd for " << uevent.firmware;
         return;
@@ -78,7 +84,7 @@
 try_loading_again:
     for (size_t i = 0; i < arraysize(firmware_dirs); i++) {
         std::string file = firmware_dirs[i] + uevent.firmware;
-        android::base::unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
+        unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
         struct stat sb;
         if (fw_fd != -1 && fstat(fw_fd, &sb) != -1) {
             LoadFirmware(uevent, root, fw_fd, sb.st_size, loading_fd, data_fd);
@@ -104,29 +110,17 @@
     if (uevent.subsystem != "firmware" || uevent.action != "add") return;
 
     // Loading the firmware in a child means we can do that in parallel...
-    // We double fork instead of waiting for these processes.
-    pid_t pid = fork();
+    auto pid = fork();
     if (pid == -1) {
         PLOG(ERROR) << "could not fork to process firmware event for " << uevent.firmware;
-        return;
     }
-
     if (pid == 0) {
-        pid = fork();
-        if (pid == -1) {
-            PLOG(ERROR) << "could not fork a sceond time to process firmware event for "
-                        << uevent.firmware;
-            _exit(EXIT_FAILURE);
-        }
-        if (pid == 0) {
-            Timer t;
-            ProcessFirmwareEvent(uevent);
-            LOG(INFO) << "loading " << uevent.path << " took " << t;
-            _exit(EXIT_SUCCESS);
-        }
-
+        Timer t;
+        ProcessFirmwareEvent(uevent);
+        LOG(INFO) << "loading " << uevent.path << " took " << t;
         _exit(EXIT_SUCCESS);
     }
-
-    waitpid(pid, nullptr, 0);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/firmware_handler.h b/init/firmware_handler.h
index be9daae..e456ac4 100644
--- a/init/firmware_handler.h
+++ b/init/firmware_handler.h
@@ -19,6 +19,12 @@
 
 #include "uevent.h"
 
+namespace android {
+namespace init {
+
 void HandleFirmwareEvent(const Uevent& uevent);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/import_parser.cpp b/init/import_parser.cpp
index 99275e5..b9fa2ce 100644
--- a/init/import_parser.cpp
+++ b/init/import_parser.cpp
@@ -20,6 +20,9 @@
 
 #include "util.h"
 
+namespace android {
+namespace init {
+
 bool ImportParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                 int line, std::string* err) {
     if (args.size() != 2) {
@@ -50,3 +53,6 @@
         }
     }
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/import_parser.h b/init/import_parser.h
index 45cbfad..b774c57 100644
--- a/init/import_parser.h
+++ b/init/import_parser.h
@@ -22,6 +22,9 @@
 #include <string>
 #include <vector>
 
+namespace android {
+namespace init {
+
 class ImportParser : public SectionParser {
   public:
     ImportParser(Parser* parser) : parser_(parser) {}
@@ -37,4 +40,7 @@
     std::vector<std::pair<std::string, int>> imports_;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/init.cpp b/init/init.cpp
index 9652efa..f65bfe0 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -42,14 +42,12 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
-#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <keyutils.h>
 #include <libavb/libavb.h>
 #include <private/android_filesystem_config.h>
 #include <selinux/android.h>
-#include <selinux/label.h>
 #include <selinux/selinux.h>
 
 #include <fstream>
@@ -71,9 +69,14 @@
 #include "util.h"
 #include "watchdogd.h"
 
+using namespace std::string_literals;
+
 using android::base::boot_clock;
 using android::base::GetProperty;
-using android::base::StringPrintf;
+using android::base::Timer;
+
+namespace android {
+namespace init {
 
 struct selabel_handle *sehandle;
 struct selabel_handle *sehandle_prop;
@@ -93,6 +96,8 @@
 static std::string wait_prop_name;
 static std::string wait_prop_value;
 static bool shutting_down;
+static std::string shutdown_command;
+static bool do_shutdown = false;
 
 void DumpState() {
     ServiceManager::GetInstance().DumpState();
@@ -171,9 +176,16 @@
     // In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific
     // commands to be executed.
     if (name == "sys.powerctl") {
-        if (HandlePowerctlMessage(value)) {
-            shutting_down = true;
-        }
+        // Despite the above comment, we can't call HandlePowerctlMessage() in this function,
+        // because it modifies the contents of the action queue, which can cause the action queue
+        // to get into a bad state if this function is called from a command being executed by the
+        // action queue.  Instead we set this flag and ensure that shutdown happens before the next
+        // command is run in the main init loop.
+        // TODO: once property service is removed from init, this will never happen from a builtin,
+        // but rather from a callback from the property service socket, in which case this hack can
+        // go away.
+        shutdown_command = value;
+        do_shutdown = true;
     }
 
     if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value);
@@ -230,7 +242,7 @@
         panic();
     }
 
-    property_set("ro.boottime.init.cold_boot_wait", std::to_string(t.duration_ms()).c_str());
+    property_set("ro.boottime.init.cold_boot_wait", std::to_string(t.duration().count()));
     return 0;
 }
 
@@ -388,7 +400,10 @@
     int ret = -1;
 
     /* values are arch-dependent */
-#if defined(__aarch64__)
+#if defined(USER_MODE_LINUX)
+    /* uml does not support mmap_rnd_bits */
+    ret = 0;
+#elif defined(__aarch64__)
     /* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */
     if (set_mmap_rnd_bits_min(33, 24, false)
             && set_mmap_rnd_bits_min(16, 16, true)) {
@@ -460,14 +475,14 @@
 
     if (for_emulator) {
         // In the emulator, export any kernel option with the "ro.kernel." prefix.
-        property_set(StringPrintf("ro.kernel.%s", key.c_str()).c_str(), value.c_str());
+        property_set("ro.kernel." + key, value);
         return;
     }
 
     if (key == "qemu") {
         strlcpy(qemu, value.c_str(), sizeof(qemu));
     } else if (android::base::StartsWith(key, "androidboot.")) {
-        property_set(StringPrintf("ro.boot.%s", key.c_str() + 12).c_str(), value.c_str());
+        property_set("ro.boot." + key.substr(12), value);
     }
 }
 
@@ -498,7 +513,7 @@
     };
     for (size_t i = 0; i < arraysize(prop_map); i++) {
         std::string value = GetProperty(prop_map[i].src_prop, "");
-        property_set(prop_map[i].dst_prop, (!value.empty()) ? value.c_str() : prop_map[i].default_value);
+        property_set(prop_map[i].dst_prop, (!value.empty()) ? value : prop_map[i].default_value);
     }
 }
 
@@ -507,7 +522,7 @@
         return;
     }
 
-    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(kAndroidDtDir.c_str()), closedir);
+    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir);
     if (!dir) return;
 
     std::string dt_file;
@@ -517,13 +532,12 @@
             continue;
         }
 
-        std::string file_name = kAndroidDtDir + dp->d_name;
+        std::string file_name = get_android_dt_dir() + dp->d_name;
 
         android::base::ReadFileToString(file_name, &dt_file);
         std::replace(dt_file.begin(), dt_file.end(), ',', '.');
 
-        std::string property_name = StringPrintf("ro.boot.%s", dp->d_name);
-        property_set(property_name.c_str(), dt_file.c_str());
+        property_set("ro.boot."s + dp->d_name, dt_file);
     }
 }
 
@@ -802,13 +816,15 @@
         return false;
     }
     std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil");
+    const std::string version_as_string = std::to_string(max_policy_version);
+
     // clang-format off
     const char* compile_args[] = {
         "/system/bin/secilc",
         plat_policy_cil_file,
         "-M", "true", "-G", "-N",
         // Target the highest policy language version supported by the kernel
-        "-c", std::to_string(max_policy_version).c_str(),
+        "-c", version_as_string.c_str(),
         mapping_file.c_str(),
         "/vendor/etc/selinux/nonplat_sepolicy.cil",
         "-o", compiled_sepolicy,
@@ -887,7 +903,7 @@
         }
 
         // init's first stage can't set properties, so pass the time to the second stage.
-        setenv("INIT_SELINUX_TOOK", std::to_string(t.duration_ms()).c_str(), 1);
+        setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1);
     } else {
         selinux_init_all_handles();
     }
@@ -905,7 +921,6 @@
     selinux_android_restorecon("/dev/urandom", 0);
     selinux_android_restorecon("/dev/__properties__", 0);
 
-    selinux_android_restorecon("/file_contexts.bin", 0);
     selinux_android_restorecon("/plat_file_contexts", 0);
     selinux_android_restorecon("/nonplat_file_contexts", 0);
     selinux_android_restorecon("/plat_property_contexts", 0);
@@ -919,7 +934,6 @@
     selinux_android_restorecon("/sepolicy", 0);
     selinux_android_restorecon("/vndservice_contexts", 0);
 
-    selinux_android_restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
     selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE);
     selinux_android_restorecon("/dev/device-mapper", 0);
 
@@ -943,7 +957,7 @@
     }
 }
 
-static void install_reboot_signal_handlers() {
+static void InstallRebootSignalHandlers() {
     // Instead of panic'ing the kernel as is the default behavior when init crashes,
     // we prefer to reboot to bootloader on development builds, as this will prevent
     // boot looping bad configurations and allow both developers and test farms to easily
@@ -951,7 +965,13 @@
     struct sigaction action;
     memset(&action, 0, sizeof(action));
     sigfillset(&action.sa_mask);
-    action.sa_handler = [](int) {
+    action.sa_handler = [](int signal) {
+        // These signal handlers are also caught for processes forked from init, however we do not
+        // want them to trigger reboot, so we directly call _exit() for children processes here.
+        if (getpid() != 1) {
+            _exit(signal);
+        }
+
         // panic() reboots to bootloader
         panic();
     };
@@ -978,7 +998,7 @@
     }
 
     if (REBOOT_BOOTLOADER_ON_PANIC) {
-        install_reboot_signal_handlers();
+        InstallRebootSignalHandlers();
     }
 
     add_environment("PATH", _PATH_DEFPATH);
@@ -1036,7 +1056,7 @@
 
         static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
         uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
-        setenv("INIT_STARTED_AT", StringPrintf("%" PRIu64, start_ms).c_str(), 1);
+        setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
 
         char* path = argv[0];
         char* args[] = { path, nullptr };
@@ -1164,6 +1184,13 @@
         // By default, sleep until something happens.
         int epoll_timeout_ms = -1;
 
+        if (do_shutdown && !shutting_down) {
+            do_shutdown = false;
+            if (HandlePowerctlMessage(shutdown_command)) {
+                shutting_down = true;
+            }
+        }
+
         if (!(waiting_for_prop || sm.IsWaitingForExec())) {
             am.ExecuteOneCommand();
         }
@@ -1191,3 +1218,10 @@
 
     return 0;
 }
+
+}  // namespace init
+}  // namespace android
+
+int main(int argc, char** argv) {
+    android::init::main(argc, argv);
+}
diff --git a/init/init.h b/init/init.h
index 4024cfe..aaab523 100644
--- a/init/init.h
+++ b/init/init.h
@@ -19,6 +19,11 @@
 
 #include <string>
 
+#include <selinux/label.h>
+
+namespace android {
+namespace init {
+
 // Note: These globals are *only* valid in init, so they should not be used in ueventd,
 // watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp.
 // TODO: Have an Init class and remove all globals.
@@ -41,4 +46,7 @@
 
 void ResetWaitForProp();
 
+}  // namespace init
+}  // namespace android
+
 #endif  /* _INIT_INIT_H */
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index d72c3ac..0f7e38f 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -25,6 +25,7 @@
 #include <string>
 #include <vector>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
@@ -36,7 +37,10 @@
 #include "uevent_listener.h"
 #include "util.h"
 
-using namespace std::chrono_literals;
+using android::base::Timer;
+
+namespace android {
+namespace init {
 
 // Class Declarations
 // ------------------
@@ -508,3 +512,6 @@
     }
     setenv("INIT_AVB_VERSION", avb_handle->avb_version().c_str(), 1);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/init_first_stage.h b/init/init_first_stage.h
index 170a24c..c7a3867 100644
--- a/init/init_first_stage.h
+++ b/init/init_first_stage.h
@@ -17,7 +17,13 @@
 #ifndef _INIT_FIRST_STAGE_H
 #define _INIT_FIRST_STAGE_H
 
+namespace android {
+namespace init {
+
 bool DoFirstStageMount();
 void SetInitAvbVersionInRecovery();
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 1b31cf2..9f7089b 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -18,6 +18,7 @@
 
 #include <dirent.h>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
@@ -25,6 +26,9 @@
 #include "parser.h"
 #include "util.h"
 
+namespace android {
+namespace init {
+
 Parser::Parser() {
 }
 
@@ -108,7 +112,7 @@
 
 bool Parser::ParseConfigFile(const std::string& path) {
     LOG(INFO) << "Parsing file " << path << "...";
-    Timer t;
+    android::base::Timer t;
     std::string data;
     std::string err;
     if (!ReadFile(path, &data, &err)) {
@@ -159,3 +163,6 @@
     }
     return ParseConfigFile(path);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/init_parser.h b/init/init_parser.h
index 722ebb2..c07a699 100644
--- a/init/init_parser.h
+++ b/init/init_parser.h
@@ -45,6 +45,9 @@
 //    This function is called at the end of the file.
 //    It indicates that the parsing has completed and any relevant objects should be committed.
 
+namespace android {
+namespace init {
+
 class SectionParser {
   public:
     virtual ~SectionParser() {}
@@ -93,4 +96,7 @@
     bool is_odm_etc_init_loaded_ = false;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/init_parser_test.cpp b/init/init_parser_test.cpp
index 86d60d0..95f269a 100644
--- a/init/init_parser_test.cpp
+++ b/init/init_parser_test.cpp
@@ -16,13 +16,17 @@
 
 #include "init_parser.h"
 
-#include "init.h"
-#include "service.h"
+#include <string>
+#include <vector>
 
 #include <gtest/gtest.h>
 
-#include <string>
-#include <vector>
+#include "init.h"
+#include "service.h"
+#include "util.h"
+
+namespace android {
+namespace init {
 
 TEST(init_parser, make_exec_oneshot_service_invalid_syntax) {
     ServiceManager& sm = ServiceManager::GetInstance();
@@ -141,3 +145,6 @@
 TEST(init_parser, make_exec_oneshot_service_with_just_command_no_dash) {
     Test_make_exec_oneshot_service(false, false, false, false, false);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 7093ba9..0a4071b 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -27,6 +27,9 @@
 #include "keyword_map.h"
 #include "util.h"
 
+namespace android {
+namespace init {
+
 class TestFunctionMap : public KeywordMap<BuiltinFunction> {
   public:
     // Helper for argument-less functions
@@ -185,3 +188,6 @@
 
     EXPECT_EQ(6, num_executed);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/keychords.cpp b/init/keychords.cpp
index c572cee..a0d7cc5 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "keychords.h"
+
 #include <fcntl.h>
 #include <stdlib.h>
 #include <sys/stat.h>
@@ -25,7 +27,9 @@
 #include <android-base/properties.h>
 
 #include "init.h"
-#include "service.h"
+
+namespace android {
+namespace init {
 
 static struct input_keychord *keychords = 0;
 static int keychords_count = 0;
@@ -112,3 +116,6 @@
 
     register_epoll_handler(keychord_fd, handle_keychord);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/keychords.h b/init/keychords.h
index d2723b7..1c34098 100644
--- a/init/keychords.h
+++ b/init/keychords.h
@@ -17,9 +17,15 @@
 #ifndef _INIT_KEYCHORDS_H_
 #define _INIT_KEYCHORDS_H_
 
-struct service;
+#include "service.h"
 
-void add_service_keycodes(service*);
+namespace android {
+namespace init {
+
+void add_service_keycodes(Service* svc);
 void keychord_init();
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/keyword_map.h b/init/keyword_map.h
index 88bad01..481d637 100644
--- a/init/keyword_map.h
+++ b/init/keyword_map.h
@@ -22,6 +22,9 @@
 
 #include <android-base/stringprintf.h>
 
+namespace android {
+namespace init {
+
 template <typename Function>
 class KeywordMap {
   public:
@@ -79,4 +82,7 @@
     virtual const Map& map() const = 0;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/log.cpp b/init/log.cpp
index 0615730..1830077 100644
--- a/init/log.cpp
+++ b/init/log.cpp
@@ -23,6 +23,9 @@
 #include <android-base/logging.h>
 #include <selinux/selinux.h>
 
+namespace android {
+namespace init {
+
 void InitKernelLogging(char* argv[]) {
     // Make stdin/stdout/stderr all point to /dev/null.
     int fd = open("/sys/fs/selinux/null", O_RDWR);
@@ -55,3 +58,6 @@
     android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf);
     return 0;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/log.h b/init/log.h
index 29a27af..5a4eba6 100644
--- a/init/log.h
+++ b/init/log.h
@@ -19,8 +19,14 @@
 
 #include <sys/cdefs.h>
 
+namespace android {
+namespace init {
+
 void InitKernelLogging(char* argv[]);
 
 int selinux_klog_callback(int level, const char* fmt, ...) __printflike(2, 3);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/parser.cpp b/init/parser.cpp
index 0d13cfe..c0fa6d9 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -1,5 +1,8 @@
 #include "parser.h"
 
+namespace android {
+namespace init {
+
 int next_token(struct parse_state *state)
 {
     char *x = state->ptr;
@@ -116,3 +119,6 @@
     }
     return T_EOF;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/parser.h b/init/parser.h
index 3dcc566..86e4c57 100644
--- a/init/parser.h
+++ b/init/parser.h
@@ -21,6 +21,9 @@
 #define T_TEXT 1
 #define T_NEWLINE 2
 
+namespace android {
+namespace init {
+
 struct parse_state
 {
     char *ptr;
@@ -31,4 +34,7 @@
 
 int next_token(struct parse_state *state);
 
+}  // namespace init
+}  // namespace android
+
 #endif /* PARSER_H_ */
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 20f21a9..fd14bd6 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -39,12 +39,13 @@
 #include <sys/_system_properties.h>
 
 #include <memory>
+#include <queue>
 #include <vector>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
-#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <bootimg.h>
 #include <fs_mgr.h>
@@ -55,11 +56,14 @@
 #include "init.h"
 #include "util.h"
 
-using android::base::StringPrintf;
+using android::base::Timer;
 
 #define PERSISTENT_PROPERTY_DIR  "/data/property"
 #define RECOVERY_MOUNT_POINT "/recovery"
 
+namespace android {
+namespace init {
+
 static int persistent_properties_loaded = 0;
 
 static int property_set_fd = -1;
@@ -162,7 +166,7 @@
     return true;
 }
 
-uint32_t property_set(const std::string& name, const std::string& value) {
+static uint32_t PropertySetImpl(const std::string& name, const std::string& value) {
     size_t valuelen = value.size();
 
     if (!is_legal_property_name(name)) {
@@ -176,12 +180,6 @@
         return PROP_ERROR_INVALID_VALUE;
     }
 
-    if (name == "selinux.restorecon_recursive" && valuelen > 0) {
-        if (selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
-            LOG(ERROR) << "Failed to restorecon_recursive " << value;
-        }
-    }
-
     prop_info* pi = (prop_info*) __system_property_find(name.c_str());
     if (pi != nullptr) {
         // ro.* properties are actually "write-once".
@@ -210,6 +208,85 @@
     return PROP_SUCCESS;
 }
 
+typedef int (*PropertyAsyncFunc)(const std::string&, const std::string&);
+
+struct PropertyChildInfo {
+    pid_t pid;
+    PropertyAsyncFunc func;
+    std::string name;
+    std::string value;
+};
+
+static std::queue<PropertyChildInfo> property_children;
+
+static void PropertyChildLaunch() {
+    auto& info = property_children.front();
+    pid_t pid = fork();
+    if (pid < 0) {
+        LOG(ERROR) << "Failed to fork for property_set_async";
+        while (!property_children.empty()) {
+            property_children.pop();
+        }
+        return;
+    }
+    if (pid != 0) {
+        info.pid = pid;
+    } else {
+        if (info.func(info.name, info.value) != 0) {
+            LOG(ERROR) << "property_set_async(\"" << info.name << "\", \"" << info.value
+                       << "\") failed";
+        }
+        exit(0);
+    }
+}
+
+bool PropertyChildReap(pid_t pid) {
+    if (property_children.empty()) {
+        return false;
+    }
+    auto& info = property_children.front();
+    if (info.pid != pid) {
+        return false;
+    }
+    if (PropertySetImpl(info.name, info.value) != PROP_SUCCESS) {
+        LOG(ERROR) << "Failed to set async property " << info.name;
+    }
+    property_children.pop();
+    if (!property_children.empty()) {
+        PropertyChildLaunch();
+    }
+    return true;
+}
+
+static uint32_t PropertySetAsync(const std::string& name, const std::string& value,
+                                 PropertyAsyncFunc func) {
+    if (value.empty()) {
+        return PropertySetImpl(name, value);
+    }
+
+    PropertyChildInfo info;
+    info.func = func;
+    info.name = name;
+    info.value = value;
+    property_children.push(info);
+    if (property_children.size() == 1) {
+        PropertyChildLaunch();
+    }
+    return PROP_SUCCESS;
+}
+
+static int RestoreconRecursiveAsync(const std::string& name, const std::string& value) {
+    return selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE);
+}
+
+uint32_t property_set(const std::string& name, const std::string& value) {
+    if (name == "selinux.restorecon_recursive") {
+        return PropertySetAsync(name, value, RestoreconRecursiveAsync);
+    }
+
+    return PropertySetImpl(name, value);
+}
+
 class SocketConnection {
  public:
   SocketConnection(int socket, const struct ucred& cred)
@@ -276,7 +353,7 @@
     while (*timeout_ms > 0) {
       Timer timer;
       int nr = poll(ufds, 1, *timeout_ms);
-      uint64_t millis = timer.duration_ms();
+      uint64_t millis = timer.duration().count();
       *timeout_ms = (millis > *timeout_ms) ? 0 : *timeout_ms - millis;
 
       if (nr > 0) {
@@ -647,7 +724,7 @@
     boot_img_hdr hdr;
     if (android::base::ReadFully(fd, &hdr, sizeof(hdr))) {
         std::string hex = bytes_to_hex(reinterpret_cast<uint8_t*>(hdr.id), sizeof(hdr.id));
-        property_set("ro.recovery_id", hex.c_str());
+        property_set("ro.recovery_id", hex);
     } else {
         PLOG(ERROR) << "error reading /recovery";
     }
@@ -677,3 +754,6 @@
 
     register_epoll_handler(property_set_fd, handle_property_set_fd);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/property_service.h b/init/property_service.h
index 9a5b6f6..a55e79c 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -21,11 +21,16 @@
 
 #include <string>
 
+namespace android {
+namespace init {
+
 struct property_audit_data {
     ucred *cr;
     const char* name;
 };
 
+extern bool PropertyChildReap(pid_t pid);
+
 void property_init(void);
 void property_load_boot_defaults(void);
 void load_persist_props(void);
@@ -34,5 +39,7 @@
 uint32_t property_set(const std::string& name, const std::string& value);
 bool is_legal_property_name(const std::string& name);
 
+}  // namespace init
+}  // namespace android
 
 #endif  /* _INIT_PROPERTY_H */
diff --git a/init/property_service_test.cpp b/init/property_service_test.cpp
index 4d784aa..3a64e02 100644
--- a/init/property_service_test.cpp
+++ b/init/property_service_test.cpp
@@ -23,6 +23,9 @@
 
 #include <gtest/gtest.h>
 
+namespace android {
+namespace init {
+
 TEST(property_service, very_long_name_35166374) {
   // Connect to the property service directly...
   int fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
@@ -46,3 +49,6 @@
   ASSERT_EQ(static_cast<ssize_t>(sizeof(data)), send(fd, &data, sizeof(data), 0));
   ASSERT_EQ(0, close(fd));
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/reboot.cpp b/init/reboot.cpp
index cee5a72..5c7ddf1 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -20,7 +20,7 @@
 #include <fcntl.h>
 #include <linux/fs.h>
 #include <mntent.h>
-#include <selinux/selinux.h>
+#include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
@@ -35,6 +35,7 @@
 #include <thread>
 #include <vector>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/macros.h>
@@ -48,11 +49,16 @@
 #include <logwrap/logwrap.h>
 #include <private/android_filesystem_config.h>
 
+#include "capabilities.h"
 #include "init.h"
 #include "property_service.h"
 #include "service.h"
 
 using android::base::StringPrintf;
+using android::base::Timer;
+
+namespace android {
+namespace init {
 
 // represents umount status during reboot / shutdown.
 enum UmountStat {
@@ -78,8 +84,8 @@
           mnt_type_(entry.mnt_type),
           mnt_opts_(entry.mnt_opts) {}
 
-    bool Umount() {
-        int r = umount2(mnt_dir_.c_str(), 0);
+    bool Umount(bool force) {
+        int r = umount2(mnt_dir_.c_str(), force ? MNT_FORCE : 0);
         if (r == 0) {
             LOG(INFO) << "umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
             return true;
@@ -157,12 +163,42 @@
 }
 
 static void LogShutdownTime(UmountStat stat, Timer* t) {
-    LOG(WARNING) << "powerctl_shutdown_time_ms:" << std::to_string(t->duration_ms()) << ":" << stat;
+    LOG(WARNING) << "powerctl_shutdown_time_ms:" << std::to_string(t->duration().count()) << ":"
+                 << stat;
+}
+
+// Determines whether the system is capable of rebooting. This is conservative,
+// so if any of the attempts to determine this fail, it will still return true.
+static bool IsRebootCapable() {
+    if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
+        PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
+        return true;
+    }
+
+    ScopedCaps caps(cap_get_proc());
+    if (!caps) {
+        PLOG(WARNING) << "cap_get_proc() failed";
+        return true;
+    }
+
+    cap_flag_value_t value = CAP_SET;
+    if (cap_get_flag(caps.get(), CAP_SYS_BOOT, CAP_EFFECTIVE, &value) != 0) {
+        PLOG(WARNING) << "cap_get_flag(CAP_SYS_BOOT, EFFECTIVE) failed";
+        return true;
+    }
+    return value == CAP_SET;
 }
 
 static void __attribute__((noreturn))
 RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
     LOG(INFO) << "Reboot ending, jumping to kernel";
+
+    if (!IsRebootCapable()) {
+        // On systems where init does not have the capability of rebooting the
+        // device, just exit cleanly.
+        exit(0);
+    }
+
     switch (cmd) {
         case ANDROID_RB_POWEROFF:
             reboot(RB_POWER_OFF);
@@ -227,7 +263,7 @@
     }
 }
 
-static UmountStat UmountPartitions(int timeoutMs) {
+static UmountStat UmountPartitions(std::chrono::milliseconds timeout) {
     Timer t;
     UmountStat stat = UMOUNT_STAT_TIMEOUT;
     int retry = 0;
@@ -245,17 +281,17 @@
             stat = UMOUNT_STAT_SUCCESS;
             break;
         }
-        if ((timeoutMs < t.duration_ms()) && retry > 0) {  // try umount at least once
+        if ((timeout < t.duration()) && retry > 0) {  // try umount at least once
             stat = UMOUNT_STAT_TIMEOUT;
             break;
         }
         if (emulated_devices.size() > 0 &&
             std::all_of(emulated_devices.begin(), emulated_devices.end(),
-                        [](auto& entry) { return entry.Umount(); })) {
+                        [](auto& entry) { return entry.Umount(false); })) {
             sync();
         }
         for (auto& entry : block_devices) {
-            entry.Umount();
+            entry.Umount(timeout == 0ms);
         }
         retry++;
         std::this_thread::sleep_for(100ms);
@@ -274,7 +310,7 @@
  *
  * return true when umount was successful. false when timed out.
  */
-static UmountStat TryUmountAndFsck(bool runFsck, int timeoutMs) {
+static UmountStat TryUmountAndFsck(bool runFsck, std::chrono::milliseconds timeout) {
     Timer t;
     std::vector<MountEntry> block_devices;
     std::vector<MountEntry> emulated_devices;
@@ -285,13 +321,13 @@
         return UMOUNT_STAT_ERROR;
     }
 
-    UmountStat stat = UmountPartitions(timeoutMs - t.duration_ms());
+    UmountStat stat = UmountPartitions(timeout - t.duration());
     if (stat != UMOUNT_STAT_SUCCESS) {
         LOG(INFO) << "umount timeout, last resort, kill all and try";
         if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(true);
         KillAllProcesses();
         // even if it succeeds, still it is timeout and do not run fsck with all processes killed
-        UmountStat st = UmountPartitions(0);
+        UmountStat st = UmountPartitions(0ms);
         if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(false);
     }
 
@@ -319,19 +355,19 @@
         runFsck = false;
     }
 
-    unsigned int shutdown_timeout = 0;  // ms
+    auto shutdown_timeout = 0ms;
     if (!SHUTDOWN_ZERO_TIMEOUT) {
         if (is_thermal_shutdown) {
-            constexpr unsigned int thermal_shutdown_timeout = 1;  // sec
-            shutdown_timeout = thermal_shutdown_timeout * 1000;
+            constexpr unsigned int thermal_shutdown_timeout = 1;
+            shutdown_timeout = std::chrono::seconds(thermal_shutdown_timeout);
         } else {
-            constexpr unsigned int shutdown_timeout_default = 6;  // sec
+            constexpr unsigned int shutdown_timeout_default = 6;
             auto shutdown_timeout_property = android::base::GetUintProperty(
                 "ro.build.shutdown_timeout", shutdown_timeout_default);
-            shutdown_timeout = shutdown_timeout_property * 1000;
+            shutdown_timeout = std::chrono::seconds(shutdown_timeout_property);
         }
     }
-    LOG(INFO) << "Shutdown timeout: " << shutdown_timeout << " ms";
+    LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
 
     // keep debugging tools until non critical ones are all gone.
     const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
@@ -358,7 +394,7 @@
 
     // optional shutdown step
     // 1. terminate all services except shutdown critical ones. wait for delay to finish
-    if (shutdown_timeout > 0) {
+    if (shutdown_timeout > 0ms) {
         LOG(INFO) << "terminating init services";
 
         // Ask all services to terminate except shutdown critical ones.
@@ -369,7 +405,7 @@
         int service_count = 0;
         // Only wait up to half of timeout here
         auto termination_wait_timeout = shutdown_timeout / 2;
-        while (t.duration_ms() < termination_wait_timeout) {
+        while (t.duration() < termination_wait_timeout) {
             ServiceManager::GetInstance().ReapAnyOutstandingChildren();
 
             service_count = 0;
@@ -417,7 +453,7 @@
     });
     // 4. sync, try umount, and optionally run fsck for user shutdown
     sync();
-    UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration_ms());
+    UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
     // Follow what linux shutdown is doing: one more sync with little bit delay
     sync();
     if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
@@ -495,3 +531,6 @@
 
     return true;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/reboot.h b/init/reboot.h
index b304b3c..e559540 100644
--- a/init/reboot.h
+++ b/init/reboot.h
@@ -19,6 +19,9 @@
 
 #include <string>
 
+namespace android {
+namespace init {
+
 /* Reboot / shutdown the system.
  * cmd ANDROID_RB_* as defined in android_reboot.h
  * reason Reason string like "reboot", "userrequested"
@@ -32,4 +35,7 @@
 // Parses and handles a setprop sys.powerctl message.
 bool HandlePowerctlMessage(const std::string& command);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/service.cpp b/init/service.cpp
index 09ebc31..f5e54df 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -34,6 +34,7 @@
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
+#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <processgroup/processgroup.h>
@@ -45,10 +46,17 @@
 #include "util.h"
 
 using android::base::boot_clock;
+using android::base::GetProperty;
+using android::base::Join;
+using android::base::make_scope_guard;
 using android::base::ParseInt;
+using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::WriteStringToFile;
 
+namespace android {
+namespace init {
+
 static std::string ComputeContextFromExecutable(std::string& service_name,
                                                 const std::string& service_path) {
     std::string computed_context;
@@ -126,17 +134,21 @@
     }
 }
 
-static void ExpandArgs(const std::vector<std::string>& args, std::vector<char*>* strs) {
+static bool ExpandArgsAndExecve(const std::vector<std::string>& args) {
     std::vector<std::string> expanded_args;
+    std::vector<char*> c_strings;
+
     expanded_args.resize(args.size());
-    strs->push_back(const_cast<char*>(args[0].c_str()));
+    c_strings.push_back(const_cast<char*>(args[0].data()));
     for (std::size_t i = 1; i < args.size(); ++i) {
         if (!expand_props(args[i], &expanded_args[i])) {
             LOG(FATAL) << args[0] << ": cannot expand '" << args[i] << "'";
         }
-        strs->push_back(const_cast<char*>(expanded_args[i].c_str()));
+        c_strings.push_back(expanded_args[i].data());
     }
-    strs->push_back(nullptr);
+    c_strings.push_back(nullptr);
+
+    return execve(c_strings[0], c_strings.data(), (char**)ENV) == 0;
 }
 
 ServiceEnvironmentInfo::ServiceEnvironmentInfo() {
@@ -163,6 +175,9 @@
       ioprio_pri_(0),
       priority_(0),
       oom_score_adjust_(-1000),
+      swappiness_(-1),
+      soft_limit_in_bytes_(-1),
+      limit_in_bytes_(-1),
       args_(args) {
     onrestart_.InitSingleTrigger("onrestart");
 }
@@ -188,6 +203,9 @@
       ioprio_pri_(0),
       priority_(0),
       oom_score_adjust_(-1000),
+      swappiness_(-1),
+      soft_limit_in_bytes_(-1),
+      limit_in_bytes_(-1),
       args_(args) {
     onrestart_.InitSingleTrigger("onrestart");
 }
@@ -198,13 +216,12 @@
         return;
     }
 
-    std::string prop_name = StringPrintf("init.svc.%s", name_.c_str());
-    property_set(prop_name.c_str(), new_state.c_str());
+    std::string prop_name = "init.svc." + name_;
+    property_set(prop_name, new_state);
 
     if (new_state == "running") {
         uint64_t start_ns = time_started_.time_since_epoch().count();
-        property_set(StringPrintf("ro.boottime.%s", name_.c_str()).c_str(),
-                     StringPrintf("%" PRIu64, start_ns).c_str());
+        property_set("ro.boottime." + name_, std::to_string(start_ns));
     }
 }
 
@@ -230,8 +247,15 @@
 void Service::SetProcessAttributes() {
     // Keep capabilites on uid change.
     if (capabilities_.any() && uid_) {
-        if (prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED) != 0) {
-            PLOG(FATAL) << "prtcl(PR_SET_KEEPCAPS) failed for " << name_;
+        // If Android is running in a container, some securebits might already
+        // be locked, so don't change those.
+        unsigned long securebits = prctl(PR_GET_SECUREBITS);
+        if (securebits == -1UL) {
+            PLOG(FATAL) << "prctl(PR_GET_SECUREBITS) failed for " << name_;
+        }
+        securebits |= SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED;
+        if (prctl(PR_SET_SECUREBITS, securebits) != 0) {
+            PLOG(FATAL) << "prctl(PR_SET_SECUREBITS) failed for " << name_;
         }
     }
 
@@ -322,8 +346,8 @@
 
 void Service::DumpState() const {
     LOG(INFO) << "service " << name_;
-    LOG(INFO) << "  class '" << android::base::Join(classnames_, " ") << "'";
-    LOG(INFO) << "  exec "<< android::base::Join(args_, " ");
+    LOG(INFO) << "  class '" << Join(classnames_, " ") << "'";
+    LOG(INFO) << "  exec " << Join(args_, " ");
     std::for_each(descriptors_.begin(), descriptors_.end(),
                   [] (const auto& info) { LOG(INFO) << *info; });
 }
@@ -477,6 +501,30 @@
     return true;
 }
 
+bool Service::ParseMemcgSwappiness(const std::vector<std::string>& args, std::string* err) {
+    if (!ParseInt(args[1], &swappiness_, 0)) {
+        *err = "swappiness value must be equal or greater than 0";
+        return false;
+    }
+    return true;
+}
+
+bool Service::ParseMemcgLimitInBytes(const std::vector<std::string>& args, std::string* err) {
+    if (!ParseInt(args[1], &limit_in_bytes_, 0)) {
+        *err = "limit_in_bytes value must be equal or greater than 0";
+        return false;
+    }
+    return true;
+}
+
+bool Service::ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args, std::string* err) {
+    if (!ParseInt(args[1], &soft_limit_in_bytes_, 0)) {
+        *err = "soft_limit_in_bytes value must be equal or greater than 0";
+        return false;
+    }
+    return true;
+}
+
 bool Service::ParseSeclabel(const std::vector<std::string>& args, std::string* err) {
     seclabel_ = args[1];
     return true;
@@ -534,9 +582,8 @@
 
 // name type perm [ uid gid context ]
 bool Service::ParseSocket(const std::vector<std::string>& args, std::string* err) {
-    if (!android::base::StartsWith(args[2], "dgram") &&
-        !android::base::StartsWith(args[2], "stream") &&
-        !android::base::StartsWith(args[2], "seqpacket")) {
+    if (!StartsWith(args[2], "dgram") && !StartsWith(args[2], "stream") &&
+        !StartsWith(args[2], "seqpacket")) {
         *err = "socket type must be 'dgram', 'stream' or 'seqpacket'";
         return false;
     }
@@ -596,6 +643,12 @@
         {"onrestart",   {1,     kMax, &Service::ParseOnrestart}},
         {"oom_score_adjust",
                         {1,     1,    &Service::ParseOomScoreAdjust}},
+        {"memcg.swappiness",
+                        {1,     1,    &Service::ParseMemcgSwappiness}},
+        {"memcg.soft_limit_in_bytes",
+                        {1,     1,    &Service::ParseMemcgSoftLimitInBytes}},
+        {"memcg.limit_in_bytes",
+                        {1,     1,    &Service::ParseMemcgLimitInBytes}},
         {"namespace",   {1,     2,    &Service::ParseNamespace}},
         {"seclabel",    {1,     1,    &Service::ParseSeclabel}},
         {"setenv",      {2,     2,    &Service::ParseSetenv}},
@@ -620,10 +673,10 @@
     return (this->*parser)(args, err);
 }
 
-bool Service::ExecStart(std::unique_ptr<Timer>* exec_waiter) {
+bool Service::ExecStart(std::unique_ptr<android::base::Timer>* exec_waiter) {
     flags_ |= SVC_EXEC | SVC_ONESHOT;
 
-    exec_waiter->reset(new Timer);
+    exec_waiter->reset(new android::base::Timer);
 
     if (!Start()) {
         exec_waiter->reset();
@@ -705,13 +758,13 @@
 
         // See if there were "writepid" instructions to write to files under /dev/cpuset/.
         auto cpuset_predicate = [](const std::string& path) {
-            return android::base::StartsWith(path, "/dev/cpuset/");
+            return StartsWith(path, "/dev/cpuset/");
         };
         auto iter = std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
         if (iter == writepid_files_.end()) {
             // There were no "writepid" instructions for cpusets, check if the system default
             // cpuset is specified to be used for the process.
-            std::string default_cpuset = android::base::GetProperty("ro.cpuset.default", "");
+            std::string default_cpuset = GetProperty("ro.cpuset.default", "");
             if (!default_cpuset.empty()) {
                 // Make sure the cpuset name starts and ends with '/'.
                 // A single '/' means the 'root' cpuset.
@@ -725,7 +778,7 @@
                     StringPrintf("/dev/cpuset%stasks", default_cpuset.c_str()));
             }
         }
-        std::string pid_str = StringPrintf("%d", getpid());
+        std::string pid_str = std::to_string(getpid());
         for (const auto& file : writepid_files_) {
             if (!WriteStringToFile(pid_str, file)) {
                 PLOG(ERROR) << "couldn't write " << pid_str << " to " << file;
@@ -750,10 +803,8 @@
         // priority. Aborts on failure.
         SetProcessAttributes();
 
-        std::vector<char*> strs;
-        ExpandArgs(args_, &strs);
-        if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
-            PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
+        if (!ExpandArgsAndExecve(args_)) {
+            PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
         }
 
         _exit(127);
@@ -766,7 +817,7 @@
     }
 
     if (oom_score_adjust_ != -1000) {
-        std::string oom_str = StringPrintf("%d", oom_score_adjust_);
+        std::string oom_str = std::to_string(oom_score_adjust_);
         std::string oom_file = StringPrintf("/proc/%d/oom_score_adj", pid);
         if (!WriteStringToFile(oom_str, oom_file)) {
             PLOG(ERROR) << "couldn't write oom_score_adj: " << strerror(errno);
@@ -782,12 +833,30 @@
     if (errno != 0) {
         PLOG(ERROR) << "createProcessGroup(" << uid_ << ", " << pid_ << ") failed for service '"
                     << name_ << "'";
+    } else {
+        if (swappiness_ != -1) {
+            if (!setProcessGroupSwappiness(uid_, pid_, swappiness_)) {
+                PLOG(ERROR) << "setProcessGroupSwappiness failed";
+            }
+        }
+
+        if (soft_limit_in_bytes_ != -1) {
+            if (!setProcessGroupSoftLimit(uid_, pid_, soft_limit_in_bytes_)) {
+                PLOG(ERROR) << "setProcessGroupSoftLimit failed";
+            }
+        }
+
+        if (limit_in_bytes_ != -1) {
+            if (!setProcessGroupLimit(uid_, pid_, limit_in_bytes_)) {
+                PLOG(ERROR) << "setProcessGroupLimit failed";
+            }
+        }
     }
 
     if ((flags_ & SVC_EXEC) != 0) {
-        LOG(INFO) << android::base::StringPrintf(
-            "SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...", pid_, uid_, gid_,
-            supp_gids_.size(), !seclabel_.empty() ? seclabel_.c_str() : "default");
+        LOG(INFO) << "SVC_EXEC pid " << pid_ << " (uid " << uid_ << " gid " << gid_ << "+"
+                  << supp_gids_.size() << " context "
+                  << (!seclabel_.empty() ? seclabel_ : "default") << ") started; waiting...";
     }
 
     NotifyStateChange("running");
@@ -964,8 +1033,7 @@
     std::vector<std::string> str_args(args.begin() + command_arg, args.end());
 
     exec_count_++;
-    std::string name =
-        "exec " + std::to_string(exec_count_) + " (" + android::base::Join(str_args, " ") + ")";
+    std::string name = "exec " + std::to_string(exec_count_) + " (" + Join(str_args, " ") + ")";
 
     unsigned flags = SVC_EXEC | SVC_ONESHOT | SVC_TEMPORARY;
     CapSet no_capabilities;
@@ -1087,13 +1155,25 @@
 }
 
 bool ServiceManager::ReapOneProcess() {
-    int status;
-    pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
-    if (pid == 0) {
+    siginfo_t siginfo = {};
+    // This returns a zombie pid or informs us that there are no zombies left to be reaped.
+    // It does NOT reap the pid; that is done below.
+    if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) {
+        PLOG(ERROR) << "waitid failed";
         return false;
-    } else if (pid == -1) {
-        PLOG(ERROR) << "waitpid failed";
-        return false;
+    }
+
+    auto pid = siginfo.si_pid;
+    if (pid == 0) return false;
+
+    // At this point we know we have a zombie pid, so we use this scopeguard to reap the pid
+    // whenever the function returns from this point forward.
+    // We do NOT want to reap the zombie earlier as in Service::Reap(), we kill(-pid, ...) and we
+    // want the pid to remain valid throughout that (and potentially future) usages.
+    auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); });
+
+    if (PropertyChildReap(pid)) {
+        return true;
     }
 
     Service* svc = FindServiceByPid(pid);
@@ -1101,24 +1181,20 @@
     std::string name;
     std::string wait_string;
     if (svc) {
-        name = android::base::StringPrintf("Service '%s' (pid %d)",
-                                           svc->name().c_str(), pid);
+        name = StringPrintf("Service '%s' (pid %d)", svc->name().c_str(), pid);
         if (svc->flags() & SVC_EXEC) {
-            wait_string =
-                android::base::StringPrintf(" waiting took %f seconds", exec_waiter_->duration_s());
+            wait_string = StringPrintf(" waiting took %f seconds",
+                                       exec_waiter_->duration().count() / 1000.0f);
         }
     } else {
-        name = android::base::StringPrintf("Untracked pid %d", pid);
+        name = StringPrintf("Untracked pid %d", pid);
     }
 
+    auto status = siginfo.si_status;
     if (WIFEXITED(status)) {
         LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
     } else if (WIFSIGNALED(status)) {
         LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
-    } else if (WIFSTOPPED(status)) {
-        LOG(INFO) << name << " stopped by signal " << WSTOPSIG(status) << wait_string;
-    } else {
-        LOG(INFO) << name << " state changed" << wait_string;
     }
 
     if (!svc) {
@@ -1192,3 +1268,6 @@
     // the service name to the "ctl.start" and "ctl.stop" properties.)
     return is_legal_property_name("init.svc." + name) && name.size() <= PROP_VALUE_MAX;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/service.h b/init/service.h
index 25d1975..62a3299 100644
--- a/init/service.h
+++ b/init/service.h
@@ -32,7 +32,6 @@
 #include "descriptors.h"
 #include "init_parser.h"
 #include "keyword_map.h"
-#include "util.h"
 
 #define SVC_DISABLED 0x001        // do not autostart with class
 #define SVC_ONESHOT 0x002         // do not restart on exit
@@ -55,8 +54,8 @@
 
 #define NR_SVC_SUPP_GIDS 12    // twelve supplementary groups
 
-class Action;
-class ServiceManager;
+namespace android {
+namespace init {
 
 struct ServiceEnvironmentInfo {
     ServiceEnvironmentInfo();
@@ -76,7 +75,7 @@
 
     bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
     bool ParseLine(const std::vector<std::string>& args, std::string* err);
-    bool ExecStart(std::unique_ptr<Timer>* exec_waiter);
+    bool ExecStart(std::unique_ptr<android::base::Timer>* exec_waiter);
     bool Start();
     bool StartIfNotDisabled();
     bool Enable();
@@ -135,6 +134,9 @@
     bool ParseOneshot(const std::vector<std::string>& args, std::string* err);
     bool ParseOnrestart(const std::vector<std::string>& args, std::string* err);
     bool ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err);
+    bool ParseMemcgLimitInBytes(const std::vector<std::string>& args, std::string* err);
+    bool ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args, std::string* err);
+    bool ParseMemcgSwappiness(const std::vector<std::string>& args, std::string* err);
     bool ParseNamespace(const std::vector<std::string>& args, std::string* err);
     bool ParseSeclabel(const std::vector<std::string>& args, std::string* err);
     bool ParseSetenv(const std::vector<std::string>& args, std::string* err);
@@ -182,6 +184,10 @@
 
     int oom_score_adjust_;
 
+    int swappiness_;
+    int soft_limit_in_bytes_;
+    int limit_in_bytes_;
+
     bool process_cgroup_empty_ = false;
 
     std::vector<std::string> args_;
@@ -218,7 +224,7 @@
     bool ReapOneProcess();
 
     static int exec_count_; // Every service needs a unique name.
-    std::unique_ptr<Timer> exec_waiter_;
+    std::unique_ptr<android::base::Timer> exec_waiter_;
 
     std::vector<std::unique_ptr<Service>> services_;
 };
@@ -239,4 +245,7 @@
     std::unique_ptr<Service> service_;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/service_test.cpp b/init/service_test.cpp
index b9c4627..44f28a3 100644
--- a/init/service_test.cpp
+++ b/init/service_test.cpp
@@ -23,6 +23,9 @@
 
 #include <gtest/gtest.h>
 
+namespace android {
+namespace init {
+
 TEST(service, pod_initialized) {
     constexpr auto memory_size = sizeof(Service);
     alignas(alignof(Service)) char old_memory[memory_size];
@@ -67,3 +70,6 @@
     EXPECT_EQ(-1000, service_in_old_memory2->oom_score_adjust());
     EXPECT_FALSE(service_in_old_memory->process_cgroup_empty());
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index 4d56d84..db1bfcf 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -21,11 +21,13 @@
 #include <unistd.h>
 
 #include <android-base/logging.h>
-#include <android-base/stringprintf.h>
 
 #include "init.h"
 #include "service.h"
 
+namespace android {
+namespace init {
+
 static int signal_write_fd = -1;
 static int signal_read_fd = -1;
 
@@ -65,3 +67,6 @@
 
     register_epoll_handler(signal_read_fd, handle_signal);
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/signal_handler.h b/init/signal_handler.h
index 449b4af..f7881ab 100644
--- a/init/signal_handler.h
+++ b/init/signal_handler.h
@@ -17,6 +17,12 @@
 #ifndef _INIT_SIGNAL_HANDLER_H_
 #define _INIT_SIGNAL_HANDLER_H_
 
+namespace android {
+namespace init {
+
 void signal_handler_init(void);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/uevent.h b/init/uevent.h
index 1095665..c4fd945 100644
--- a/init/uevent.h
+++ b/init/uevent.h
@@ -19,6 +19,9 @@
 
 #include <string>
 
+namespace android {
+namespace init {
+
 struct Uevent {
     std::string action;
     std::string path;
@@ -31,4 +34,7 @@
     int minor;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp
index 923fa8e..ac1d7c7 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -26,6 +26,9 @@
 #include <android-base/logging.h>
 #include <cutils/uevent.h>
 
+namespace android {
+namespace init {
+
 static void ParseEvent(const char* msg, Uevent* uevent) {
     uevent->partition_num = -1;
     uevent->major = -1;
@@ -165,7 +168,7 @@
     return RegenerateUeventsForDir(d.get(), callback);
 }
 
-const char* kRegenerationPaths[] = {"/sys/class", "/sys/block", "/sys/devices"};
+static const char* kRegenerationPaths[] = {"/sys/class", "/sys/block", "/sys/devices"};
 
 void UeventListener::RegenerateUevents(const ListenerCallback& callback) const {
     for (const auto path : kRegenerationPaths) {
@@ -212,3 +215,6 @@
         }
     }
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/uevent_listener.h b/init/uevent_listener.h
index 1964688..5b453fe 100644
--- a/init/uevent_listener.h
+++ b/init/uevent_listener.h
@@ -29,6 +29,9 @@
 
 #define UEVENT_MSG_LEN 2048
 
+namespace android {
+namespace init {
+
 enum class ListenerAction {
     kStop = 0,  // Stop regenerating uevents as we've handled the one(s) we're interested in.
     kContinue,  // Continue regenerating uevents as we haven't seen the one(s) we're interested in.
@@ -36,8 +39,6 @@
 
 using ListenerCallback = std::function<ListenerAction(const Uevent&)>;
 
-extern const char* kRegenerationPaths[3];
-
 class UeventListener {
   public:
     UeventListener();
@@ -55,4 +56,7 @@
     android::base::unique_fd device_fd_;
 };
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index ff64e8e..c0eae1e 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -27,9 +27,9 @@
 #include <set>
 #include <thread>
 
+#include <android-base/chrono_utils.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
-#include <android-base/stringprintf.h>
 #include <selinux/android.h>
 #include <selinux/selinux.h>
 
@@ -100,6 +100,9 @@
 // the uevent listener resumes in polling mode and will handle the uevents that occurred during
 // coldboot.
 
+namespace android {
+namespace init {
+
 class ColdBoot {
   public:
     ColdBoot(UeventListener& uevent_listener, DeviceHandler& device_handler)
@@ -158,9 +161,7 @@
 }
 
 void ColdBoot::DoRestoreCon() {
-    for (const char* path : kRegenerationPaths) {
-        selinux_android_restorecon(path, SELINUX_ANDROID_RESTORECON_RECURSE);
-    }
+    selinux_android_restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
     device_handler_.set_skip_restorecon(false);
 }
 
@@ -198,7 +199,7 @@
 }
 
 void ColdBoot::Run() {
-    Timer cold_boot_timer;
+    android::base::Timer cold_boot_timer;
 
     RegenerateUevents();
 
@@ -209,7 +210,7 @@
     WaitForSubProcesses();
 
     close(open(COLDBOOT_DONE, O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
-    LOG(INFO) << "Coldboot took " << cold_boot_timer;
+    LOG(INFO) << "Coldboot took " << cold_boot_timer.duration().count() / 1000.0f << " seconds";
 }
 
 DeviceHandler CreateDeviceHandler() {
@@ -268,6 +269,13 @@
         cold_boot.Run();
     }
 
+    // We use waitpid() in ColdBoot, so we can't ignore SIGCHLD until now.
+    signal(SIGCHLD, SIG_IGN);
+    // Reap and pending children that exited between the last call to waitpid() and setting SIG_IGN
+    // for SIGCHLD above.
+    while (waitpid(-1, nullptr, WNOHANG) > 0) {
+    }
+
     uevent_listener.Poll([&device_handler](const Uevent& uevent) {
         HandleFirmwareEvent(uevent);
         device_handler.HandleDeviceEvent(uevent);
@@ -276,3 +284,6 @@
 
     return 0;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/ueventd.h b/init/ueventd.h
index 1f424d3..51775ec 100644
--- a/init/ueventd.h
+++ b/init/ueventd.h
@@ -17,6 +17,12 @@
 #ifndef _INIT_UEVENTD_H_
 #define _INIT_UEVENTD_H_
 
+namespace android {
+namespace init {
+
 int ueventd_main(int argc, char** argv);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 7156e76..02e0d42 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -21,6 +21,9 @@
 
 #include "keyword_map.h"
 
+namespace android {
+namespace init {
+
 bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
                           std::vector<SysfsPermissions>* out_sysfs_permissions,
                           std::vector<Permissions>* out_dev_permissions) {
@@ -143,3 +146,6 @@
 void SubsystemParser::EndSection() {
     subsystems_->emplace_back(std::move(subsystem_));
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index c1ce976..592df63 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -23,6 +23,9 @@
 #include "devices.h"
 #include "init_parser.h"
 
+namespace android {
+namespace init {
+
 class SubsystemParser : public SectionParser {
   public:
     SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
@@ -43,4 +46,7 @@
                           std::vector<SysfsPermissions>* out_sysfs_permissions,
                           std::vector<Permissions>* out_dev_permissions);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/ueventd_test.cpp b/init/ueventd_test.cpp
new file mode 100644
index 0000000..4d9a1fa
--- /dev/null
+++ b/init/ueventd_test.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <linux/futex.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <string>
+#include <thread>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/scopeguard.h>
+#include <android-base/test_utils.h>
+#include <gtest/gtest.h>
+#include <selinux/selinux.h>
+
+using namespace std::string_literals;
+
+template <typename T, typename F>
+void WriteFromMultipleThreads(std::vector<std::pair<std::string, T>>& files_and_parameters,
+                              F function) {
+    auto num_threads = files_and_parameters.size();
+    pthread_barrier_t barrier;
+    pthread_barrier_init(&barrier, nullptr, num_threads);
+    auto barrier_destroy =
+        android::base::make_scope_guard([&barrier]() { pthread_barrier_destroy(&barrier); });
+
+    auto make_thread_function = [&function, &barrier](const auto& file, const auto& parameter) {
+        return [&]() {
+            function(parameter);
+            pthread_barrier_wait(&barrier);
+            android::base::WriteStringToFile("<empty>", file);
+        };
+    };
+
+    std::vector<std::thread> threads;
+    // TODO(b/63712782): Structured bindings + templated containers are broken in clang :(
+    // for (const auto& [file, parameter] : files_and_parameters) {
+    for (const auto& pair : files_and_parameters) {
+        const auto& file = pair.first;
+        const auto& parameter = pair.second;
+        threads.emplace_back(std::thread(make_thread_function(file, parameter)));
+    }
+
+    for (auto& thread : threads) {
+        thread.join();
+    }
+}
+
+TEST(ueventd, setegid_IsPerThread) {
+    if (getuid() != 0) {
+        GTEST_LOG_(INFO) << "Skipping test, must be run as root.";
+        return;
+    }
+
+    TemporaryDir dir;
+
+    gid_t gid = 0;
+    std::vector<std::pair<std::string, gid_t>> files_and_gids;
+    std::generate_n(std::back_inserter(files_and_gids), 100, [&gid, &dir]() {
+        gid++;
+        return std::pair(dir.path + "/gid_"s + std::to_string(gid), gid);
+    });
+
+    WriteFromMultipleThreads(files_and_gids, [](gid_t gid) { EXPECT_EQ(0, setegid(gid)); });
+
+    for (const auto& [file, expected_gid] : files_and_gids) {
+        struct stat info;
+        ASSERT_EQ(0, stat(file.c_str(), &info));
+        EXPECT_EQ(expected_gid, info.st_gid);
+    }
+}
+
+TEST(ueventd, setfscreatecon_IsPerThread) {
+    if (getuid() != 0) {
+        GTEST_LOG_(INFO) << "Skipping test, must be run as root.";
+        return;
+    }
+    if (!is_selinux_enabled() || security_getenforce() == 1) {
+        GTEST_LOG_(INFO) << "Skipping test, SELinux must be enabled and in permissive mode.";
+        return;
+    }
+
+    const char* const contexts[] = {
+        "u:object_r:audio_device:s0",
+        "u:object_r:sensors_device:s0",
+        "u:object_r:video_device:s0"
+        "u:object_r:zero_device:s0",
+    };
+
+    TemporaryDir dir;
+    std::vector<std::pair<std::string, std::string>> files_and_contexts;
+    for (const char* context : contexts) {
+        files_and_contexts.emplace_back(dir.path + "/context_"s + context, context);
+    }
+
+    WriteFromMultipleThreads(files_and_contexts, [](const std::string& context) {
+        EXPECT_EQ(0, setfscreatecon(context.c_str()));
+    });
+
+    for (const auto& [file, expected_context] : files_and_contexts) {
+        char* file_context;
+        ASSERT_GT(getfilecon(file.c_str(), &file_context), 0);
+        EXPECT_EQ(expected_context, file_context);
+        freecon(file_context);
+    }
+}
diff --git a/init/util.cpp b/init/util.cpp
index dfdfeb4..fdcb22d 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -50,6 +50,11 @@
 using android::base::boot_clock;
 using namespace std::literals::string_literals;
 
+namespace android {
+namespace init {
+
+const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");
+
 // DecodeUid() - decodes and returns the given string, which can be either the
 // numeric or name representation, into the integer uid or gid. Returns
 // UINT_MAX on error.
@@ -371,15 +376,31 @@
     DoReboot(ANDROID_RB_RESTART2, "reboot", "bootloader", false);
 }
 
-std::ostream& operator<<(std::ostream& os, const Timer& t) {
-    os << t.duration_s() << " seconds";
-    return os;
+static std::string init_android_dt_dir() {
+    // Use the standard procfs-based path by default
+    std::string android_dt_dir = kDefaultAndroidDtDir;
+    // The platform may specify a custom Android DT path in kernel cmdline
+    import_kernel_cmdline(false,
+                          [&](const std::string& key, const std::string& value, bool in_qemu) {
+                              if (key == "androidboot.android_dt_dir") {
+                                  android_dt_dir = value;
+                              }
+                          });
+    LOG(INFO) << "Using Android DT directory " << android_dt_dir;
+    return android_dt_dir;
 }
 
-// Reads the content of device tree file under kAndroidDtDir directory.
+// FIXME: The same logic is duplicated in system/core/fs_mgr/
+const std::string& get_android_dt_dir() {
+    // Set once and saves time for subsequent calls to this function
+    static const std::string kAndroidDtDir = init_android_dt_dir();
+    return kAndroidDtDir;
+}
+
+// Reads the content of device tree file under the platform's Android DT directory.
 // Returns true if the read is success, false otherwise.
 bool read_android_dt_file(const std::string& sub_path, std::string* dt_content) {
-    const std::string file_name = kAndroidDtDir + sub_path;
+    const std::string file_name = get_android_dt_dir() + sub_path;
     if (android::base::ReadFileToString(file_name, dt_content)) {
         if (!dt_content->empty()) {
             dt_content->pop_back();  // Trims the trailing '\0' out.
@@ -398,3 +419,6 @@
     }
     return false;
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/util.h b/init/util.h
index 1ad6b77..29c10cb 100644
--- a/init/util.h
+++ b/init/util.h
@@ -30,37 +30,18 @@
 
 #define COLDBOOT_DONE "/dev/.coldboot_done"
 
-const std::string kAndroidDtDir("/proc/device-tree/firmware/android/");
-
 using android::base::boot_clock;
 using namespace std::chrono_literals;
 
+namespace android {
+namespace init {
+
 int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t uid, gid_t gid,
                  const char* socketcon, selabel_handle* sehandle);
 
 bool ReadFile(const std::string& path, std::string* content, std::string* err);
 bool WriteFile(const std::string& path, const std::string& content, std::string* err);
 
-class Timer {
-  public:
-    Timer() : start_(boot_clock::now()) {}
-
-    double duration_s() const {
-        typedef std::chrono::duration<double> double_duration;
-        return std::chrono::duration_cast<double_duration>(boot_clock::now() - start_).count();
-    }
-
-    int64_t duration_ms() const {
-        return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_)
-            .count();
-    }
-
-  private:
-    android::base::boot_clock::time_point start_;
-};
-
-std::ostream& operator<<(std::ostream& os, const Timer& t);
-
 bool DecodeUid(const std::string& name, uid_t* uid, std::string* err);
 
 int mkdir_recursive(const std::string& pathname, mode_t mode, selabel_handle* sehandle);
@@ -74,8 +55,14 @@
 
 void panic() __attribute__((__noreturn__));
 
-// Reads or compares the content of device tree file under kAndroidDtDir directory.
+// Returns the platform's Android DT directory as specified in the kernel cmdline.
+// If the platform does not configure a custom DT path, returns the standard one (based in procfs).
+const std::string& get_android_dt_dir();
+// Reads or compares the content of device tree file under the platform's Android DT directory.
 bool read_android_dt_file(const std::string& sub_path, std::string* dt_content);
 bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 4bb8a83..c16ab74 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -26,6 +26,9 @@
 
 using namespace std::literals::string_literals;
 
+namespace android {
+namespace init {
+
 TEST(util, ReadFile_ENOENT) {
     std::string s("hello");
     std::string err;
@@ -187,3 +190,6 @@
     std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
     EXPECT_TRUE(is_dir(path1.c_str()));
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/watchdogd.cpp b/init/watchdogd.cpp
index 7baa487..e0164b4 100644
--- a/init/watchdogd.cpp
+++ b/init/watchdogd.cpp
@@ -31,6 +31,9 @@
 
 #define DEV_NAME "/dev/watchdog"
 
+namespace android {
+namespace init {
+
 int watchdogd_main(int argc, char **argv) {
     InitKernelLogging(argv);
 
@@ -73,3 +76,6 @@
         sleep(interval);
     }
 }
+
+}  // namespace init
+}  // namespace android
diff --git a/init/watchdogd.h b/init/watchdogd.h
index 8b48ab8..73f77d5 100644
--- a/init/watchdogd.h
+++ b/init/watchdogd.h
@@ -17,6 +17,12 @@
 #ifndef _INIT_WATCHDOGD_H_
 #define _INIT_WATCHDOGD_H_
 
+namespace android {
+namespace init {
+
 int watchdogd_main(int argc, char **argv);
 
+}  // namespace init
+}  // namespace android
+
 #endif
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index 0792307..8b0c53e 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -179,7 +179,11 @@
         }
 
         const uint32_t opcode = buffer_.request.header.opcode;
-        LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode;
+        const uint64_t unique = buffer_.request.header.unique;
+        LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
+        if (unique == 0) {
+            return FuseBridgeState::kWaitToReadEither;
+        }
         switch (opcode) {
             case FUSE_FORGET:
                 // Do not reply to FUSE_FORGET.
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index 51d6051..0a28451 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -67,6 +67,7 @@
     memset(&request_, 0, sizeof(FuseRequest));
     request_.header.opcode = opcode;
     request_.header.len = sizeof(fuse_in_header);
+    request_.header.unique = 1;
     ASSERT_TRUE(request_.Write(dev_sockets_[0]));
 
     memset(&response_, 0, sizeof(FuseResponse));
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index a643a29..7eefc95 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -64,6 +64,10 @@
 cc_library {
     name: "libbacktrace",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     defaults: ["libbacktrace_common"],
     host_supported: true,
 
@@ -161,6 +165,7 @@
     shared_libs = [
         "libbase",
         "libunwind",
+        "libziparchive",
     ],
 }
 
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index e46d353..81f5e32 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -84,10 +84,8 @@
 }
 
 std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) {
-  uintptr_t relative_pc;
   std::string map_name;
   if (BacktraceMap::IsValid(frame->map)) {
-    relative_pc = BacktraceMap::GetRelativePc(frame->map, frame->pc);
     if (!frame->map.name.empty()) {
       map_name = frame->map.name.c_str();
       if (map_name[0] == '[' && map_name[map_name.size() - 1] == ']') {
@@ -99,10 +97,9 @@
     }
   } else {
     map_name = "<unknown>";
-    relative_pc = frame->pc;
   }
 
-  std::string line(StringPrintf("#%02zu pc %" PRIPTR "  ", frame->num, relative_pc));
+  std::string line(StringPrintf("#%02zu pc %" PRIPTR "  ", frame->num, frame->rel_pc));
   line += map_name;
   // Special handling for non-zero offset maps, we need to print that
   // information.
diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp
index 3c509e6..2c87fa8 100644
--- a/libbacktrace/UnwindCurrent.cpp
+++ b/libbacktrace/UnwindCurrent.cpp
@@ -133,6 +133,11 @@
           backtrace_frame_data_t* prev = &frames_.at(num_frames-1);
           prev->stack_size = frame->sp - prev->sp;
         }
+        if (BacktraceMap::IsValid(frame->map)) {
+          frame->rel_pc = frame->pc - frame->map.start + frame->map.load_bias;
+        } else {
+          frame->rel_pc = frame->pc;
+        }
         num_frames++;
       } else {
         num_ignore_frames--;
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index af79562..0b8232b 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -57,7 +57,7 @@
     map.start = unw_map.start;
     map.end = unw_map.end;
     map.offset = unw_map.offset;
-    map.load_base = unw_map.load_base;
+    map.load_bias = unw_map.load_base;
     map.flags = unw_map.flags;
     map.name = unw_map.path;
 
@@ -106,7 +106,7 @@
       map.start = unw_map.start;
       map.end = unw_map.end;
       map.offset = unw_map.offset;
-      map.load_base = unw_map.load_base;
+      map.load_bias = unw_map.load_base;
       map.flags = unw_map.flags;
       map.name = unw_map.path;
 
diff --git a/libbacktrace/UnwindPtrace.cpp b/libbacktrace/UnwindPtrace.cpp
index 42ac1bc..87282ef 100644
--- a/libbacktrace/UnwindPtrace.cpp
+++ b/libbacktrace/UnwindPtrace.cpp
@@ -135,6 +135,11 @@
       }
 
       FillInMap(frame->pc, &frame->map);
+      if (BacktraceMap::IsValid(frame->map)) {
+        frame->rel_pc = frame->pc - frame->map.start + frame->map.load_bias;
+      } else {
+        frame->rel_pc = frame->pc;
+      }
 
       frame->func_name = GetFunctionName(frame->pc, &frame->func_offset, &frame->map);
 
diff --git a/libbacktrace/backtrace_offline_test.cpp b/libbacktrace/backtrace_offline_test.cpp
index 465b3f9..16b1d79 100644
--- a/libbacktrace/backtrace_offline_test.cpp
+++ b/libbacktrace/backtrace_offline_test.cpp
@@ -167,9 +167,9 @@
   // 2. Dump maps
   for (auto it = map->begin(); it != map->end(); ++it) {
     testdata += android::base::StringPrintf(
-        "map: start: %" PRIxPTR " end: %" PRIxPTR " offset: %" PRIxPTR
-        " load_base: %" PRIxPTR " flags: %d name: %s\n",
-        it->start, it->end, it->offset, it->load_base, it->flags, it->name.c_str());
+        "map: start: %" PRIxPTR " end: %" PRIxPTR " offset: %" PRIxPTR " load_bias: %" PRIxPTR
+        " flags: %d name: %s\n",
+        it->start, it->end, it->offset, it->load_bias, it->flags, it->name.c_str());
   }
   // 3. Dump registers
   testdata += android::base::StringPrintf("registers: %zu ", sizeof(arg.unw_context));
@@ -246,9 +246,9 @@
       backtrace_map_t& map = testdata->maps.back();
       int pos;
       sscanf(line.c_str(),
-             "map: start: %" SCNxPTR " end: %" SCNxPTR " offset: %" SCNxPTR
-             " load_base: %" SCNxPTR " flags: %d name: %n",
-             &map.start, &map.end, &map.offset, &map.load_base, &map.flags, &pos);
+             "map: start: %" SCNxPTR " end: %" SCNxPTR " offset: %" SCNxPTR " load_bias: %" SCNxPTR
+             " flags: %d name: %n",
+             &map.start, &map.end, &map.offset, &map.load_bias, &map.flags, &pos);
       map.name = android::base::Trim(line.substr(pos));
     } else if (android::base::StartsWith(line, "registers:")) {
       size_t size;
@@ -392,8 +392,8 @@
   // The last frame is outside of libart.so
   ASSERT_EQ(testdata.symbols.size() + 1, backtrace->NumFrames());
   for (size_t i = 0; i + 1 < backtrace->NumFrames(); ++i) {
-    uintptr_t vaddr_in_file = backtrace->GetFrame(i)->pc - testdata.maps[0].start +
-        testdata.maps[0].load_base;
+    uintptr_t vaddr_in_file =
+        backtrace->GetFrame(i)->pc - testdata.maps[0].start + testdata.maps[0].load_bias;
     std::string name = FunctionNameForAddress(vaddr_in_file, testdata.symbols);
     ASSERT_EQ(name, testdata.symbols[i].name);
   }
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index fb463b0..1ec6a45 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -784,6 +784,7 @@
   backtrace_frame_data_t frame;
   frame.num = 1;
   frame.pc = 2;
+  frame.rel_pc = 2;
   frame.sp = 0;
   frame.stack_size = 0;
   frame.func_offset = 0;
@@ -799,9 +800,10 @@
 
   // Check map name empty, but exists.
   frame.pc = 0xb0020;
+  frame.rel_pc = 0x20;
   frame.map.start = 0xb0000;
   frame.map.end = 0xbffff;
-  frame.map.load_base = 0;
+  frame.map.load_bias = 0;
 #if defined(__LP64__)
   EXPECT_EQ("#01 pc 0000000000000020  <anonymous:00000000000b0000>",
 #else
@@ -813,7 +815,7 @@
   frame.pc = 0xc0020;
   frame.map.start = 0xc0000;
   frame.map.end = 0xcffff;
-  frame.map.load_base = 0;
+  frame.map.load_bias = 0;
   frame.map.name = "[anon:thread signal stack]";
 #if defined(__LP64__)
   EXPECT_EQ("#01 pc 0000000000000020  [anon:thread signal stack:00000000000c0000]",
@@ -824,6 +826,7 @@
 
   // Check relative pc is set and map name is set.
   frame.pc = 0x12345679;
+  frame.rel_pc = 0x12345678;
   frame.map.name = "MapFake";
   frame.map.start =  1;
   frame.map.end =  1;
@@ -852,9 +855,10 @@
 #endif
             backtrace->FormatFrameData(&frame));
 
-  // Check func_name is set, func offset is non-zero, and load_base is non-zero.
+  // Check func_name is set, func offset is non-zero, and load_bias is non-zero.
+  frame.rel_pc = 0x123456dc;
   frame.func_offset = 645;
-  frame.map.load_base = 100;
+  frame.map.load_bias = 100;
 #if defined(__LP64__)
   EXPECT_EQ("#01 pc 00000000123456dc  MapFake (ProcFake+645)",
 #else
@@ -1737,9 +1741,13 @@
   FinishRemoteProcess(pid);
 }
 
-TEST(libbacktrace, unwind_remote_through_signal_using_handler) { UnwindThroughSignal(false); }
+TEST(libbacktrace, unwind_remote_through_signal_using_handler) {
+  UnwindThroughSignal(false);
+}
 
-TEST(libbacktrace, unwind_remote_through_signal_using_action) { UnwindThroughSignal(true); }
+TEST(libbacktrace, unwind_remote_through_signal_using_action) {
+  UnwindThroughSignal(true);
+}
 
 #if defined(ENABLE_PSS_TESTS)
 #include "GetPss.h"
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h
index 4f73a65..b919e81 100644
--- a/libbacktrace/include/backtrace/Backtrace.h
+++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -55,6 +55,7 @@
 struct backtrace_frame_data_t {
   size_t num;             // The current fame number.
   uintptr_t pc;           // The absolute pc.
+  uintptr_t rel_pc;       // The relative pc.
   uintptr_t sp;           // The top of the stack.
   size_t stack_size;      // The size of the stack, zero indicate an unknown stack size.
   backtrace_map_t map;    // The map associated with the given pc.
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index 8ab0dfa..f7a55b8 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -41,7 +41,7 @@
   uintptr_t start = 0;
   uintptr_t end = 0;
   uintptr_t offset = 0;
-  uintptr_t load_base = 0;
+  uintptr_t load_bias = 0;
   int flags = 0;
   std::string name;
 };
@@ -89,20 +89,14 @@
   const_iterator begin() const { return maps_.begin(); }
   const_iterator end() const { return maps_.end(); }
 
+  size_t size() const { return maps_.size(); }
+
   virtual bool Build();
 
   static inline bool IsValid(const backtrace_map_t& map) {
     return map.end > 0;
   }
 
-  static uintptr_t GetRelativePc(const backtrace_map_t& map, uintptr_t pc) {
-    if (IsValid(map)) {
-      return pc - map.start + map.load_base;
-    } else {
-      return pc;
-    }
-  }
-
 protected:
   BacktraceMap(pid_t pid);
 
diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp
index 4a5f2a7..47de12a 100644
--- a/libcrypto_utils/Android.bp
+++ b/libcrypto_utils/Android.bp
@@ -17,6 +17,9 @@
 cc_library {
     name: "libcrypto_utils",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     host_supported: true,
     srcs: [
         "android_pubkey.c",
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 245deb1..d00ff5f 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -50,6 +50,10 @@
 cc_library {
     name: "libcutils",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     host_supported: true,
     srcs: [
         "config_utils.c",
@@ -150,6 +154,7 @@
         "libutils_headers",
     ],
     export_header_lib_headers: ["libcutils_headers"],
+    local_include_dirs: ["include"],
 
     cflags: [
         "-Werror",
diff --git a/libcutils/canned_fs_config.c b/libcutils/canned_fs_config.c
index 96ca566..819a846 100644
--- a/libcutils/canned_fs_config.c
+++ b/libcutils/canned_fs_config.c
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include <private/android_filesystem_config.h>
+#include <private/fs_config.h>
 #include <private/canned_fs_config.h>
 
 typedef struct {
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index c39071c..cc96ff8 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -267,14 +267,27 @@
     return false;
 }
 
+static inline bool prefix_cmp(bool partial, const char* prefix, size_t len, const char* path,
+                              size_t plen) {
+    return ((partial && plen >= len) || (plen == len)) && !strncmp(prefix, path, len);
+}
+
 // alias prefixes of "<partition>/<stuff>" to "system/<partition>/<stuff>" or
 // "system/<partition>/<stuff>" to "<partition>/<stuff>"
-static bool prefix_cmp(const char* prefix, const char* path, size_t len) {
-    if (!strncmp(prefix, path, len)) return true;
+static bool fs_config_cmp(bool partial, const char* prefix, size_t len, const char* path,
+                          size_t plen) {
+    // If name ends in * then allow partial matches.
+    if (!partial && prefix[len - 1] == '*') {
+        len--;
+        partial = true;
+    }
+
+    if (prefix_cmp(partial, prefix, len, path, plen)) return true;
 
     static const char system[] = "system/";
     if (!strncmp(path, system, strlen(system))) {
         path += strlen(system);
+        plen -= strlen(system);
     } else if (len <= strlen(system)) {
         return false;
     } else if (strncmp(prefix, system, strlen(system))) {
@@ -283,25 +296,11 @@
         prefix += strlen(system);
         len -= strlen(system);
     }
-    return is_partition(prefix, len) && !strncmp(prefix, path, len);
+    return is_partition(prefix, len) && prefix_cmp(partial, prefix, len, path, plen);
 }
-
-static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* path, size_t plen) {
-    if (dir) {
-        if (plen < len) {
-            return false;
-        }
-    } else {
-        // If name ends in * then allow partial matches.
-        if (prefix[len - 1] == '*') {
-            return prefix_cmp(prefix, path, len - 1);
-        }
-        if (plen != len) {
-            return false;
-        }
-    }
-    return prefix_cmp(prefix, path, len);
-}
+#ifndef __ANDROID_VNDK__
+auto __for_testing_only__fs_config_cmp = fs_config_cmp;
+#endif
 
 void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid,
                unsigned* mode, uint64_t* capabilities) {
diff --git a/libcutils/include/cutils/android_filesystem_config.h b/libcutils/include/cutils/android_filesystem_config.h
new file mode 120000
index 0000000..d2a92fe
--- /dev/null
+++ b/libcutils/include/cutils/android_filesystem_config.h
@@ -0,0 +1 @@
+../private/android_filesystem_config.h
\ No newline at end of file
diff --git a/libcutils/include/cutils/sched_policy.h b/libcutils/include/cutils/sched_policy.h
index 9683f91..4c1113b 100644
--- a/libcutils/include/cutils/sched_policy.h
+++ b/libcutils/include/cutils/sched_policy.h
@@ -34,7 +34,7 @@
  * Check if Linux kernel enables SCHEDTUNE feature (only available in Android
  * common kernel or Linaro LSK, not in mainline Linux as of v4.9)
  *
- * Return value: 1 if Linux kernel CONFIG_SCHEDTUNE=y; 0 otherwise.
+ * Return value: 1 if Linux kernel CONFIG_CGROUP_SCHEDTUNE=y; 0 otherwise.
  */
 extern bool schedboost_enabled();
 
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 02141d6..d4ba019 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -14,11 +14,6 @@
  * limitations under the License.
  */
 
-/* This file is used to define the properties of the filesystem
-** images generated by build tools (mkbootfs and mkyaffs2image) and
-** by the device side of adb.
-*/
-
 /*
  * This file is consumed by build/tools/fs_config and is used
  * for generating various files. Anything #define AID_<name>
@@ -49,18 +44,12 @@
 #ifndef _ANDROID_FILESYSTEM_CONFIG_H_
 #define _ANDROID_FILESYSTEM_CONFIG_H_
 
-#include <stdint.h>
-#include <sys/cdefs.h>
 #include <sys/types.h>
 
-#if defined(__BIONIC__)
-#include <linux/capability.h>
-#else
-#include "android_filesystem_capability.h"
+#if !defined(__ANDROID_VNDK__) && !defined(EXCLUDE_FS_CONFIG_STRUCTURES)
+#include <private/fs_config.h>
 #endif
 
-#define CAP_MASK_LONG(cap_name) (1ULL << (cap_name))
-
 /* This is the master Users and Groups config for the platform.
  * DO NOT EVER RENUMBER
  */
@@ -193,36 +182,4 @@
  * Also see build/tools/fs_config for more details.
  */
 
-#if !defined(EXCLUDE_FS_CONFIG_STRUCTURES)
-
-struct fs_path_config {
-    unsigned mode;
-    unsigned uid;
-    unsigned gid;
-    uint64_t capabilities;
-    const char* prefix;
-};
-
-/* Rules for directories and files has moved to system/code/libcutils/fs_config.c */
-
-__BEGIN_DECLS
-
-/*
- * Used in:
- *  build/tools/fs_config/fs_config.c
- *  build/tools/fs_get_stats/fs_get_stats.c
- *  system/extras/ext4_utils/make_ext4fs_main.c
- *  external/squashfs-tools/squashfs-tools/android.c
- *  system/core/cpio/mkbootfs.c
- *  system/core/adb/file_sync_service.cpp
- *  system/extras/ext4_utils/canned_fs_config.c
- */
-void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid,
-               unsigned* mode, uint64_t* capabilities);
-
-ssize_t fs_config_generate(char* buffer, size_t length, const struct fs_path_config* pc);
-
-__END_DECLS
-
-#endif
 #endif
diff --git a/libcutils/include/private/fs_config.h b/libcutils/include/private/fs_config.h
index 7dad668..aab5042 100644
--- a/libcutils/include/private/fs_config.h
+++ b/libcutils/include/private/fs_config.h
@@ -14,10 +14,24 @@
  * limitations under the License.
  */
 
+/* This file is used to define the properties of the filesystem
+** images generated by build tools (mkbootfs and mkyaffs2image) and
+** by the device side of adb.
+*/
+
 #ifndef _LIBS_CUTILS_PRIVATE_FS_CONFIG_H
 #define _LIBS_CUTILS_PRIVATE_FS_CONFIG_H
 
 #include <stdint.h>
+#include <sys/cdefs.h>
+
+#if defined(__BIONIC__)
+#include <linux/capability.h>
+#else  // defined(__BIONIC__)
+#include "android_filesystem_capability.h"
+#endif  // defined(__BIONIC__)
+
+#define CAP_MASK_LONG(cap_name) (1ULL << (cap_name))
 
 /*
  * binary format for the runtime <partition>/etc/fs_config_(dirs|files)
@@ -34,4 +48,33 @@
     char prefix[];
 } __attribute__((__aligned__(sizeof(uint64_t))));
 
+struct fs_path_config {
+    unsigned mode;
+    unsigned uid;
+    unsigned gid;
+    uint64_t capabilities;
+    const char* prefix;
+};
+
+/* Rules for directories and files has moved to system/code/libcutils/fs_config.c */
+
+__BEGIN_DECLS
+
+/*
+ * Used in:
+ *  build/tools/fs_config/fs_config.c
+ *  build/tools/fs_get_stats/fs_get_stats.c
+ *  system/extras/ext4_utils/make_ext4fs_main.c
+ *  external/squashfs-tools/squashfs-tools/android.c
+ *  system/core/cpio/mkbootfs.c
+ *  system/core/adb/file_sync_service.cpp
+ *  system/extras/ext4_utils/canned_fs_config.c
+ */
+void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid,
+               unsigned* mode, uint64_t* capabilities);
+
+ssize_t fs_config_generate(char* buffer, size_t length, const struct fs_path_config* pc);
+
+__END_DECLS
+
 #endif /* _LIBS_CUTILS_PRIVATE_FS_CONFIG_H */
diff --git a/libcutils/include_vndk/cutils/android_filesystem_config.h b/libcutils/include_vndk/cutils/android_filesystem_config.h
new file mode 120000
index 0000000..13a5a08
--- /dev/null
+++ b/libcutils/include_vndk/cutils/android_filesystem_config.h
@@ -0,0 +1 @@
+../../include/private/android_filesystem_config.h
\ No newline at end of file
diff --git a/libcutils/include_vndk/private b/libcutils/include_vndk/private
deleted file mode 120000
index 2245a85..0000000
--- a/libcutils/include_vndk/private
+++ /dev/null
@@ -1 +0,0 @@
-../include/private
\ No newline at end of file
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index 7170b48..b00fa85 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -28,13 +28,6 @@
 
 #define UNUSED __attribute__((__unused__))
 
-#ifndef SLOGE
-#define SLOGE ALOGE
-#endif
-#ifndef SLOGW
-#define SLOGW ALOGW
-#endif
-
 /* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged.
  * Call this any place a SchedPolicy is used as an input parameter.
  * Returns the possibly re-mapped policy.
@@ -124,11 +117,8 @@
     on where init.rc mounts cpuset. That's why we'd better require this
     configuration be set if CONFIG_CPUSETS is set.
 
-    With runtime check using the following function, build time
-    variables like ENABLE_CPUSETS (used in Android.mk) or cpusets (used
-    in Android.bp) are not needed.
+    In older releases, this was controlled by build-time configuration.
  */
-
 bool cpusets_enabled() {
     static bool enabled = (access("/dev/cpuset/tasks", F_OK) == 0);
 
@@ -137,15 +127,11 @@
 
 /*
     Similar to CONFIG_CPUSETS above, but with a different configuration
-    CONFIG_SCHEDTUNE that's in Android common Linux kernel and Linaro
+    CONFIG_CGROUP_SCHEDTUNE that's in Android common Linux kernel and Linaro
     Stable Kernel (LSK), but not in mainline Linux as of v4.9.
 
-    With runtime check using the following function, build time
-    variables like ENABLE_SCHEDBOOST (used in Android.mk) or schedboost
-    (used in Android.bp) are not needed.
-
+    In older releases, this was controlled by build-time configuration.
  */
-
 bool schedboost_enabled() {
     static bool enabled = (access("/dev/stune/tasks", F_OK) == 0);
 
@@ -343,7 +329,7 @@
     return 0;
 }
 
-static void set_timerslack_ns(int tid, unsigned long long slack) {
+static void set_timerslack_ns(int tid, unsigned long slack) {
     // v4.6+ kernels support the /proc/<tid>/timerslack_ns interface.
     // TODO: once we've backported this, log if the open(2) fails.
     if (__sys_supports_timerslack) {
@@ -351,7 +337,7 @@
         snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", tid);
         int fd = open(buf, O_WRONLY | O_CLOEXEC);
         if (fd != -1) {
-            int len = snprintf(buf, sizeof(buf), "%llu", slack);
+            int len = snprintf(buf, sizeof(buf), "%lu", slack);
             if (write(fd, buf, len) != len) {
                 SLOGE("set_timerslack_ns write failed: %s\n", strerror(errno));
             }
diff --git a/libcutils/tests/fs_config.cpp b/libcutils/tests/fs_config.cpp
index a62cd51..391adb6 100644
--- a/libcutils/tests/fs_config.cpp
+++ b/libcutils/tests/fs_config.cpp
@@ -29,12 +29,39 @@
 
 extern const fs_path_config* __for_testing_only__android_dirs;
 extern const fs_path_config* __for_testing_only__android_files;
+extern bool (*__for_testing_only__fs_config_cmp)(bool, const char*, size_t, const char*, size_t);
 
 // Maximum entries in system/core/libcutils/fs_config.cpp:android_* before we
 // hit a nullptr termination, before we declare the list is just too big or
 // could be missing the nullptr.
 static constexpr size_t max_idx = 4096;
 
+static const struct fs_config_cmp_test {
+    bool dir;
+    const char* prefix;
+    const char* path;
+    bool match;
+} fs_config_cmp_tests[] = {
+    // clang-format off
+    { true,  "system/lib",             "system/lib/hw",           true  },
+    { true,  "vendor/lib",             "system/vendor/lib/hw",    true  },
+    { true,  "system/vendor/lib",      "vendor/lib/hw",           true  },
+    { true,  "system/vendor/lib",      "system/vendor/lib/hw",    true  },
+    { false, "vendor/bin/wifi",        "system/vendor/bin/w",     false },
+    { false, "vendor/bin/wifi",        "system/vendor/bin/wifi",  true  },
+    { false, "vendor/bin/wifi",        "system/vendor/bin/wifi2", false },
+    { false, "system/vendor/bin/wifi", "system/vendor/bin/wifi",  true, },
+    { false, "odm/bin/wifi",           "system/odm/bin/wifi",     true  },
+    { false, "oem/bin/wifi",           "system/oem/bin/wifi",     true  },
+    { false, "data/bin/wifi",          "system/data/bin/wifi",    false },
+    { false, "system/bin/*",           "system/bin/wifi",         true  },
+    { false, "vendor/bin/*",           "system/vendor/bin/wifi",  true  },
+    { false, "system/bin/*",           "system/bin",              false },
+    { false, "system/vendor/bin/*",    "vendor/bin/wifi",         true  },
+    { false, NULL,                     NULL,                      false },
+    // clang-format on
+};
+
 static bool check_unique(std::vector<const char*>& paths, const std::string& config_name,
                          const std::string& prefix) {
     bool retval = false;
@@ -106,6 +133,22 @@
     return check_unique(paths_tmp, config, prefix) || retval;
 }
 
+static bool check_fs_config_cmp(const fs_config_cmp_test* tests) {
+    bool match, retval = false;
+    for (size_t idx = 0; tests[idx].prefix; ++idx) {
+        match = __for_testing_only__fs_config_cmp(tests[idx].dir, tests[idx].prefix,
+                                                  strlen(tests[idx].prefix), tests[idx].path,
+                                                  strlen(tests[idx].path));
+        if (match != tests[idx].match) {
+            GTEST_LOG_(ERROR) << tests[idx].path << (match ? " matched " : " didn't match ")
+                              << tests[idx].prefix;
+            retval = true;
+            break;
+        }
+    }
+    return retval;
+}
+
 #define endof(pointer, field) (offsetof(typeof(*(pointer)), field) + sizeof((pointer)->field))
 
 static bool check_unique(const std::string& config, const std::string& prefix) {
@@ -199,3 +242,7 @@
 TEST(fs_config, odm_files_alias) {
     check_two(__for_testing_only__android_files, "files", "odm/");
 }
+
+TEST(fs_config, system_alias) {
+    EXPECT_FALSE(check_fs_config_cmp(fs_config_cmp_tests));
+}
diff --git a/libdiskconfig/Android.bp b/libdiskconfig/Android.bp
index 088981a..23a5c79 100644
--- a/libdiskconfig/Android.bp
+++ b/libdiskconfig/Android.bp
@@ -1,6 +1,9 @@
 cc_library {
     name: "libdiskconfig",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     srcs: [
         "diskconfig.c",
         "diskutils.c",
diff --git a/libion/Android.bp b/libion/Android.bp
index 6f267e4..6d9fae0 100644
--- a/libion/Android.bp
+++ b/libion/Android.bp
@@ -1,7 +1,11 @@
 
 cc_library {
     name: "libion",
-		vendor_available: true,
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     srcs: ["ion.c"],
     shared_libs: ["liblog"],
     local_include_dirs: [
diff --git a/liblog/Android.bp b/liblog/Android.bp
index e74aa82..b98d18f 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -42,6 +42,24 @@
     "logd_writer.c",
 ]
 
+cc_library_headers {
+    name: "liblog_headers",
+    host_supported: true,
+    vendor_available: true,
+    export_include_dirs: ["include"],
+    target: {
+        windows: {
+            enabled: true,
+        },
+        linux_bionic: {
+            enabled: true,
+        },
+        vendor: {
+            export_include_dirs: ["include_vndk"],
+        },
+    },
+}
+
 // Shared and static library for host and device
 // ========================================================
 cc_library {
@@ -81,7 +99,8 @@
         },
     },
 
-    export_include_dirs: ["include"],
+    header_libs: ["liblog_headers"],
+    export_header_lib_headers: ["liblog_headers"],
 
     cflags: [
         "-Werror",
@@ -100,7 +119,7 @@
 }
 
 ndk_headers {
-    name: "liblog_headers",
+    name: "liblog_ndk_headers",
     from: "include/android",
     to: "android",
     srcs: ["include/android/log.h"],
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index 3a215e9..d01708d 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -161,7 +161,7 @@
 #endif
 
 #if __ANDROID_USE_LIBLOG_CLOCK_INTERFACE
-clockid_t android_log_clockid();
+clockid_t android_log_clockid(void);
 #endif
 
 #endif /* __linux__ */
@@ -185,7 +185,7 @@
  * May be used to clean up File descriptors after a Fork, the resources are
  * all O_CLOEXEC so wil self clean on exec().
  */
-void __android_log_close();
+void __android_log_close(void);
 #endif
 
 #ifndef __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE
diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h
index da16158..68c2e9a 100644
--- a/liblog/include/log/log_main.h
+++ b/liblog/include/log/log_main.h
@@ -18,10 +18,9 @@
 #define _LIBS_LOG_LOG_MAIN_H
 
 #include <android/log.h>
+#include <sys/cdefs.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*
  * Normally we strip the effects of ALOGV (VERBOSE messages),
@@ -385,8 +384,6 @@
 #pragma clang diagnostic pop
 #endif
 
-#ifdef __cplusplus
-}
-#endif
+__END_DECLS
 
 #endif /* _LIBS_LOG_LOG_MAIN_H */
diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h
index 3764faf..309f5d1 100644
--- a/liblog/include/log/log_time.h
+++ b/liblog/include/log/log_time.h
@@ -28,6 +28,10 @@
 #ifndef __struct_log_time_defined
 #define __struct_log_time_defined
 
+#define LOG_TIME_SEC(t) ((t)->tv_sec)
+/* next power of two after NS_PER_SEC */
+#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
+
 #ifdef __cplusplus
 
 /*
@@ -167,15 +171,15 @@
 #endif
 } __attribute__((__packed__));
 
-#else
+#else /* __cplusplus */
 
 typedef struct log_time {
   uint32_t tv_sec;
   uint32_t tv_nsec;
 } __attribute__((__packed__)) log_time;
 
-#endif
+#endif /* __cplusplus */
 
-#endif
+#endif /* __struct_log_time_defined */
 
 #endif /* _LIBS_LOG_LOG_TIME_H */
diff --git a/liblog/include_vndk/log/log.h b/liblog/include_vndk/log/log.h
index 01623df..a79beec 100644
--- a/liblog/include_vndk/log/log.h
+++ b/liblog/include_vndk/log/log.h
@@ -9,6 +9,7 @@
 #include <log/log_radio.h>
 #include <log/log_read.h>
 #include <log/log_safetynet.h>
+#include <log/log_system.h>
 #include <log/log_time.h>
 
 /*
diff --git a/liblog/include_vndk/log/log_system.h b/liblog/include_vndk/log/log_system.h
new file mode 120000
index 0000000..d0d3904
--- /dev/null
+++ b/liblog/include_vndk/log/log_system.h
@@ -0,0 +1 @@
+../../include/log/log_system.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_time.h b/liblog/include_vndk/log/log_time.h
deleted file mode 120000
index abfe439..0000000
--- a/liblog/include_vndk/log/log_time.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/log/log_time.h
\ No newline at end of file
diff --git a/liblog/include_vndk/log/log_time.h b/liblog/include_vndk/log/log_time.h
new file mode 100644
index 0000000..5a09959
--- /dev/null
+++ b/liblog/include_vndk/log/log_time.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005-2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_LOG_LOG_TIME_H
+#define _LIBS_LOG_LOG_TIME_H
+
+#include <stdint.h>
+
+/* struct log_time is a wire-format variant of struct timespec */
+#ifndef NS_PER_SEC
+#define NS_PER_SEC 1000000000ULL
+#endif
+#ifndef US_PER_SEC
+#define US_PER_SEC 1000000ULL
+#endif
+#ifndef MS_PER_SEC
+#define MS_PER_SEC 1000ULL
+#endif
+
+#ifndef __struct_log_time_defined
+#define __struct_log_time_defined
+
+#define LOG_TIME_SEC(t) ((t)->tv_sec)
+/* next power of two after NS_PER_SEC */
+#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
+
+typedef struct log_time {
+  uint32_t tv_sec;
+  uint32_t tv_nsec;
+} __attribute__((__packed__)) log_time;
+
+#endif
+
+#endif /* _LIBS_LOG_LOG_TIME_H */
diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c
index 600f4bb..603ba24 100644
--- a/liblog/logd_reader.c
+++ b/liblog/logd_reader.c
@@ -590,20 +590,30 @@
 
   memset(log_msg, 0, sizeof(*log_msg));
 
+  unsigned int new_alarm = 0;
   if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
+    if ((logger_list->mode & ANDROID_LOG_WRAP) &&
+        (logger_list->start.tv_sec || logger_list->start.tv_nsec)) {
+      /* b/64143705 */
+      new_alarm = (ANDROID_LOG_WRAP_DEFAULT_TIMEOUT * 11) / 10 + 10;
+      logger_list->mode &= ~ANDROID_LOG_WRAP;
+    } else {
+      new_alarm = 30;
+    }
+
     memset(&ignore, 0, sizeof(ignore));
     ignore.sa_handler = caught_signal;
     sigemptyset(&ignore.sa_mask);
     /* particularily useful if tombstone is reporting for logd */
     sigaction(SIGALRM, &ignore, &old_sigaction);
-    old_alarm = alarm(30);
+    old_alarm = alarm(new_alarm);
   }
 
   /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
   ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
   e = errno;
 
-  if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
+  if (new_alarm) {
     if ((ret == 0) || (e == EINTR)) {
       e = EAGAIN;
       ret = -1;
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index ab96429..39b52ac 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -54,7 +54,7 @@
     -Werror \
     -fno-builtin \
 
-test_src_files := \
+cts_src_files := \
     libc_test.cpp \
     liblog_test_default.cpp \
     liblog_test_local.cpp \
@@ -64,7 +64,11 @@
     log_radio_test.cpp \
     log_read_test.cpp \
     log_system_test.cpp \
-    log_time_test.cpp
+    log_time_test.cpp \
+    log_wrap_test.cpp
+
+test_src_files := \
+    $(cts_src_files) \
 
 # Build tests for the device (with .so). Run with:
 #   adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
@@ -81,15 +85,15 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := $(cts_executable)
 LOCAL_MODULE_TAGS := tests
-LOCAL_CFLAGS += $(test_c_flags)
-LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE
+LOCAL_SRC_FILES := $(cts_src_files)
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
 LOCAL_MULTILIB := both
 LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
 LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 LOCAL_CTS_TEST_PACKAGE := android.core.liblog
 include $(BUILD_CTS_EXECUTABLE)
 
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 46ec5ef..56dbf1f 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -116,6 +116,7 @@
   return ret;
 }
 
+#ifndef NO_PSTORE
 static bool isPmsgActive() {
   pid_t pid = getpid();
 
@@ -125,6 +126,7 @@
 
   return std::string::npos != myPidFds.find(" -> /dev/pmsg0");
 }
+#endif /* NO_PSTORE */
 
 static bool isLogdwActive() {
   std::string logdwSignature =
@@ -189,22 +191,25 @@
   EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
 #ifdef USING_LOGGER_DEFAULT
   // Check that we can close and reopen the logger
-  bool pmsgActiveAfter__android_log_btwrite;
   bool logdwActiveAfter__android_log_btwrite;
   if (getuid() == AID_ROOT) {
     tested__android_log_close = true;
-    pmsgActiveAfter__android_log_btwrite = isPmsgActive();
-    logdwActiveAfter__android_log_btwrite = isLogdwActive();
+#ifndef NO_PSTORE
+    bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
     EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+#endif /* NO_PSTORE */
+    logdwActiveAfter__android_log_btwrite = isLogdwActive();
     EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
   } else if (!tested__android_log_close) {
     fprintf(stderr, "WARNING: can not test __android_log_close()\n");
   }
   __android_log_close();
   if (getuid() == AID_ROOT) {
+#ifndef NO_PSTORE
     bool pmsgActiveAfter__android_log_close = isPmsgActive();
-    bool logdwActiveAfter__android_log_close = isLogdwActive();
     EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+#endif /* NO_PSTORE */
+    bool logdwActiveAfter__android_log_close = isLogdwActive();
     EXPECT_FALSE(logdwActiveAfter__android_log_close);
   }
 #endif
@@ -213,9 +218,11 @@
   EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
 #ifdef USING_LOGGER_DEFAULT
   if (getuid() == AID_ROOT) {
-    pmsgActiveAfter__android_log_btwrite = isPmsgActive();
-    logdwActiveAfter__android_log_btwrite = isLogdwActive();
+#ifndef NO_PSTORE
+    bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
     EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+#endif /* NO_PSTORE */
+    logdwActiveAfter__android_log_btwrite = isLogdwActive();
     EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
   }
 #endif
@@ -3036,12 +3043,15 @@
 
 #ifdef USING_LOGGER_DEFAULT  // Do not retest pmsg functionality
 #ifdef __ANDROID__
+#ifndef NO_PSTORE
 static const char __pmsg_file[] =
     "/data/william-shakespeare/MuchAdoAboutNothing.txt";
+#endif /* NO_PSTORE */
 #endif
 
 TEST(liblog, __android_log_pmsg_file_write) {
 #ifdef __ANDROID__
+#ifndef NO_PSTORE
   __android_log_close();
   if (getuid() == AID_ROOT) {
     tested__android_log_close = true;
@@ -3092,12 +3102,16 @@
     EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
     EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
   }
+#else  /* NO_PSTORE */
+  GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
+#endif /* NO_PSTORE */
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
 
 #ifdef __ANDROID__
+#ifndef NO_PSTORE
 static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
                          const char* buf, size_t len, void* arg) {
   EXPECT_TRUE(NULL == arg);
@@ -3118,10 +3132,12 @@
              ? -ENOEXEC
              : 1;
 }
+#endif /* NO_PSTORE */
 #endif
 
 TEST(liblog, __android_log_pmsg_file_read) {
 #ifdef __ANDROID__
+#ifndef NO_PSTORE
   signaled = 0;
 
   __android_log_close();
@@ -3155,6 +3171,9 @@
 
   EXPECT_LT(0, ret);
   EXPECT_EQ(1U, signaled);
+#else  /* NO_PSTORE */
+  GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
+#endif /* NO_PSTORE */
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp
new file mode 100644
index 0000000..ebf0b15
--- /dev/null
+++ b/liblog/tests/log_wrap_test.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013-2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <string>
+
+#include <android-base/chrono_utils.h>
+#include <android-base/stringprintf.h>
+#include <android/log.h>  // minimal logging API
+#include <gtest/gtest.h>
+#include <log/log_properties.h>
+#include <log/log_read.h>
+#include <log/log_time.h>
+#include <log/log_transport.h>
+
+#ifdef __ANDROID__
+static void read_with_wrap() {
+  android_set_log_transport(LOGGER_LOGD);
+
+  // Read the last line in the log to get a starting timestamp. We're assuming
+  // the log is not empty.
+  const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
+  struct logger_list* logger_list =
+      android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0);
+
+  ASSERT_NE(logger_list, nullptr);
+
+  log_msg log_msg;
+  int ret = android_logger_list_read(logger_list, &log_msg);
+  android_logger_list_close(logger_list);
+  ASSERT_GT(ret, 0);
+
+  log_time start(log_msg.entry.sec, log_msg.entry.nsec);
+  ASSERT_NE(start, log_time());
+
+  logger_list =
+      android_logger_list_alloc_time(mode | ANDROID_LOG_WRAP, start, 0);
+  ASSERT_NE(logger_list, nullptr);
+
+  struct logger* logger = android_logger_open(logger_list, LOG_ID_MAIN);
+  EXPECT_NE(logger, nullptr);
+  if (logger) {
+    android_logger_list_read(logger_list, &log_msg);
+  }
+
+  android_logger_list_close(logger_list);
+}
+
+static void caught_signal(int /* signum */) {
+}
+#endif
+
+// b/64143705 confirm fixed
+TEST(liblog, wrap_mode_blocks) {
+#ifdef __ANDROID__
+
+  android::base::Timer timer;
+
+  // The read call is expected to take up to 2 hours in the happy case.
+  // We only want to make sure it waits for longer than 30s, but we can't
+  // use an alarm as the implementation uses it. So we run the test in
+  // a separate process.
+  pid_t pid = fork();
+
+  if (pid == 0) {
+    // child
+    read_with_wrap();
+    _exit(0);
+  }
+
+  struct sigaction ignore, old_sigaction;
+  memset(&ignore, 0, sizeof(ignore));
+  ignore.sa_handler = caught_signal;
+  sigemptyset(&ignore.sa_mask);
+  sigaction(SIGALRM, &ignore, &old_sigaction);
+  alarm(45);
+
+  bool killed = false;
+  for (;;) {
+    siginfo_t info = {};
+    // This wait will succeed if the child exits, or fail with EINTR if the
+    // alarm goes off first - a loose approximation to a timed wait.
+    int ret = waitid(P_PID, pid, &info, WEXITED);
+    if (ret >= 0 || errno != EINTR) {
+      EXPECT_EQ(ret, 0);
+      if (!killed) {
+        EXPECT_EQ(info.si_status, 0);
+      }
+      break;
+    }
+    unsigned int alarm_left = alarm(0);
+    if (alarm_left > 0) {
+      alarm(alarm_left);
+    } else {
+      kill(pid, SIGTERM);
+      killed = true;
+    }
+  }
+
+  alarm(0);
+  EXPECT_GT(timer.duration(), std::chrono::seconds(40));
+#else
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
diff --git a/libmemtrack/Android.bp b/libmemtrack/Android.bp
index 68c580a..0955633 100644
--- a/libmemtrack/Android.bp
+++ b/libmemtrack/Android.bp
@@ -2,6 +2,10 @@
 
 cc_library_shared {
     name: "libmemtrack",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     srcs: ["memtrack.cpp"],
     export_include_dirs: ["include"],
     local_include_dirs: ["include"],
diff --git a/libmemunreachable/Allocator.cpp b/libmemunreachable/Allocator.cpp
index 6fe67a4..213be17 100644
--- a/libmemunreachable/Allocator.cpp
+++ b/libmemunreachable/Allocator.cpp
@@ -33,9 +33,11 @@
 
 #include "android-base/macros.h"
 
-#include "anon_vma_naming.h"
 #include "Allocator.h"
 #include "LinkedList.h"
+#include "anon_vma_naming.h"
+
+namespace android {
 
 // runtime interfaces used:
 // abort
@@ -57,10 +59,9 @@
 static constexpr size_t kUsableChunkSize = kChunkSize - kPageSize;
 static constexpr size_t kMaxBucketAllocationSize = kChunkSize / 4;
 static constexpr size_t kMinBucketAllocationSize = 8;
-static constexpr unsigned int kNumBuckets = const_log2(kMaxBucketAllocationSize)
-    - const_log2(kMinBucketAllocationSize) + 1;
-static constexpr unsigned int kUsablePagesPerChunk = kUsableChunkSize
-    / kPageSize;
+static constexpr unsigned int kNumBuckets =
+    const_log2(kMaxBucketAllocationSize) - const_log2(kMinBucketAllocationSize) + 1;
+static constexpr unsigned int kUsablePagesPerChunk = kUsableChunkSize / kPageSize;
 
 std::atomic<int> heap_count;
 
@@ -93,7 +94,7 @@
   void FreeLocked(void* ptr);
 
   struct MapAllocation {
-    void *ptr;
+    void* ptr;
     size_t size;
     MapAllocation* next;
   };
@@ -107,8 +108,7 @@
 }
 
 static inline unsigned int size_to_bucket(size_t size) {
-  if (size < kMinBucketAllocationSize)
-    return kMinBucketAllocationSize;
+  if (size < kMinBucketAllocationSize) return kMinBucketAllocationSize;
   return log2(size - 1) + 1 - const_log2(kMinBucketAllocationSize);
 }
 
@@ -140,8 +140,7 @@
 
   // Trim beginning
   if (aligned_ptr != ptr) {
-    ptrdiff_t extra = reinterpret_cast<uintptr_t>(aligned_ptr)
-        - reinterpret_cast<uintptr_t>(ptr);
+    ptrdiff_t extra = reinterpret_cast<uintptr_t>(aligned_ptr) - reinterpret_cast<uintptr_t>(ptr);
     munmap(ptr, extra);
     map_size -= extra;
     ptr = aligned_ptr;
@@ -151,14 +150,13 @@
   if (map_size != size) {
     assert(map_size > size);
     assert(ptr != NULL);
-    munmap(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + size),
-        map_size - size);
+    munmap(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + size), map_size - size);
   }
 
-#define PR_SET_VMA   0x53564d41
-#define PR_SET_VMA_ANON_NAME    0
-  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME,
-      reinterpret_cast<uintptr_t>(ptr), size, "leak_detector_malloc");
+#define PR_SET_VMA 0x53564d41
+#define PR_SET_VMA_ANON_NAME 0
+  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<uintptr_t>(ptr), size,
+        "leak_detector_malloc");
 
   return ptr;
 }
@@ -170,36 +168,31 @@
   Chunk(HeapImpl* heap, int bucket);
   ~Chunk() {}
 
-  void *Alloc();
+  void* Alloc();
   void Free(void* ptr);
   void Purge();
   bool Empty();
 
   static Chunk* ptr_to_chunk(void* ptr) {
-    return reinterpret_cast<Chunk*>(reinterpret_cast<uintptr_t>(ptr)
-        & ~(kChunkSize - 1));
+    return reinterpret_cast<Chunk*>(reinterpret_cast<uintptr_t>(ptr) & ~(kChunkSize - 1));
   }
   static bool is_chunk(void* ptr) {
     return (reinterpret_cast<uintptr_t>(ptr) & (kChunkSize - 1)) != 0;
   }
 
-  unsigned int free_count() {
-    return free_count_;
-  }
-  HeapImpl* heap() {
-    return heap_;
-  }
-  LinkedList<Chunk*> node_; // linked list sorted by minimum free count
+  unsigned int free_count() { return free_count_; }
+  HeapImpl* heap() { return heap_; }
+  LinkedList<Chunk*> node_;  // linked list sorted by minimum free count
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Chunk);
   HeapImpl* heap_;
   unsigned int bucket_;
-  unsigned int allocation_size_; // size of allocations in chunk, min 8 bytes
-  unsigned int max_allocations_; // maximum number of allocations in the chunk
-  unsigned int first_free_bitmap_; // index into bitmap for first non-full entry
-  unsigned int free_count_; // number of available allocations
-  unsigned int frees_since_purge_; // number of calls to Free since last Purge
+  unsigned int allocation_size_;    // size of allocations in chunk, min 8 bytes
+  unsigned int max_allocations_;    // maximum number of allocations in the chunk
+  unsigned int first_free_bitmap_;  // index into bitmap for first non-full entry
+  unsigned int free_count_;         // number of available allocations
+  unsigned int frees_since_purge_;  // number of calls to Free since last Purge
 
   // bitmap of pages that have been dirtied
   uint32_t dirty_pages_[div_round_up(kUsablePagesPerChunk, 32)];
@@ -210,13 +203,10 @@
   char data_[0];
 
   unsigned int ptr_to_n(void* ptr) {
-    ptrdiff_t offset = reinterpret_cast<uintptr_t>(ptr)
-        - reinterpret_cast<uintptr_t>(data_);
+    ptrdiff_t offset = reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(data_);
     return offset / allocation_size_;
   }
-  void* n_to_ptr(unsigned int n) {
-    return data_ + n * allocation_size_;
-  }
+  void* n_to_ptr(unsigned int n) { return data_ + n * allocation_size_; }
 };
 static_assert(sizeof(Chunk) <= kPageSize, "header must fit in page");
 
@@ -225,23 +215,27 @@
   assert(count == sizeof(Chunk));
   void* mem = MapAligned(kChunkSize, kChunkSize);
   if (!mem) {
-    abort(); //throw std::bad_alloc;
+    abort();  // throw std::bad_alloc;
   }
 
   return mem;
 }
 
 // Override new operator on chunk to use mmap to allocate kChunkSize
-void Chunk::operator delete(void *ptr) {
+void Chunk::operator delete(void* ptr) {
   assert(reinterpret_cast<Chunk*>(ptr) == ptr_to_chunk(ptr));
   munmap(ptr, kChunkSize);
 }
 
-Chunk::Chunk(HeapImpl* heap, int bucket) :
-    node_(this), heap_(heap), bucket_(bucket), allocation_size_(
-        bucket_to_size(bucket)), max_allocations_(
-        kUsableChunkSize / allocation_size_), first_free_bitmap_(0), free_count_(
-        max_allocations_), frees_since_purge_(0) {
+Chunk::Chunk(HeapImpl* heap, int bucket)
+    : node_(this),
+      heap_(heap),
+      bucket_(bucket),
+      allocation_size_(bucket_to_size(bucket)),
+      max_allocations_(kUsableChunkSize / allocation_size_),
+      first_free_bitmap_(0),
+      free_count_(max_allocations_),
+      frees_since_purge_(0) {
   memset(dirty_pages_, 0, sizeof(dirty_pages_));
   memset(free_bitmap_, 0xff, sizeof(free_bitmap_));
 }
@@ -254,8 +248,7 @@
   assert(free_count_ > 0);
 
   unsigned int i = first_free_bitmap_;
-  while (free_bitmap_[i] == 0)
-    i++;
+  while (free_bitmap_[i] == 0) i++;
   assert(i < arraysize(free_bitmap_));
   unsigned int bit = __builtin_ffs(free_bitmap_[i]) - 1;
   assert(free_bitmap_[i] & (1U << bit));
@@ -306,38 +299,35 @@
 void Chunk::Purge() {
   frees_since_purge_ = 0;
 
-  //unsigned int allocsPerPage = kPageSize / allocation_size_;
+  // unsigned int allocsPerPage = kPageSize / allocation_size_;
 }
 
 // Override new operator on HeapImpl to use mmap to allocate a page
-void* HeapImpl::operator new(std::size_t count __attribute__((unused)))
-    noexcept {
+void* HeapImpl::operator new(std::size_t count __attribute__((unused))) noexcept {
   assert(count == sizeof(HeapImpl));
   void* mem = MapAligned(kPageSize, kPageSize);
   if (!mem) {
-    abort(); //throw std::bad_alloc;
+    abort();  // throw std::bad_alloc;
   }
 
   heap_count++;
   return mem;
 }
 
-void HeapImpl::operator delete(void *ptr) {
+void HeapImpl::operator delete(void* ptr) {
   munmap(ptr, kPageSize);
 }
 
-HeapImpl::HeapImpl() :
-    free_chunks_(), full_chunks_(), map_allocation_list_(NULL) {
-}
+HeapImpl::HeapImpl() : free_chunks_(), full_chunks_(), map_allocation_list_(NULL) {}
 
 bool HeapImpl::Empty() {
   for (unsigned int i = 0; i < kNumBuckets; i++) {
-    for (LinkedList<Chunk*> *it = free_chunks_[i].next(); it->data() != NULL; it = it->next()) {
+    for (LinkedList<Chunk*>* it = free_chunks_[i].next(); it->data() != NULL; it = it->next()) {
       if (!it->data()->Empty()) {
         return false;
       }
     }
-    for (LinkedList<Chunk*> *it = full_chunks_[i].next(); it->data() != NULL; it = it->next()) {
+    for (LinkedList<Chunk*>* it = full_chunks_[i].next(); it->data() != NULL; it = it->next()) {
       if (!it->data()->Empty()) {
         return false;
       }
@@ -350,12 +340,12 @@
 HeapImpl::~HeapImpl() {
   for (unsigned int i = 0; i < kNumBuckets; i++) {
     while (!free_chunks_[i].empty()) {
-      Chunk *chunk = free_chunks_[i].next()->data();
+      Chunk* chunk = free_chunks_[i].next()->data();
       chunk->node_.remove();
       delete chunk;
     }
     while (!full_chunks_[i].empty()) {
-      Chunk *chunk = full_chunks_[i].next()->data();
+      Chunk* chunk = full_chunks_[i].next()->data();
       chunk->node_.remove();
       delete chunk;
     }
@@ -373,18 +363,18 @@
   }
   int bucket = size_to_bucket(size);
   if (free_chunks_[bucket].empty()) {
-    Chunk *chunk = new Chunk(this, bucket);
+    Chunk* chunk = new Chunk(this, bucket);
     free_chunks_[bucket].insert(chunk->node_);
   }
   return free_chunks_[bucket].next()->data()->Alloc();
 }
 
-void HeapImpl::Free(void *ptr) {
+void HeapImpl::Free(void* ptr) {
   std::lock_guard<std::mutex> lk(m_);
   FreeLocked(ptr);
 }
 
-void HeapImpl::FreeLocked(void *ptr) {
+void HeapImpl::FreeLocked(void* ptr) {
   if (!Chunk::is_chunk(ptr)) {
     HeapImpl::MapFree(ptr);
   } else {
@@ -397,12 +387,11 @@
 void* HeapImpl::MapAlloc(size_t size) {
   size = (size + kPageSize - 1) & ~(kPageSize - 1);
 
-  MapAllocation* allocation = reinterpret_cast<MapAllocation*>(AllocLocked(
-      sizeof(MapAllocation)));
+  MapAllocation* allocation = reinterpret_cast<MapAllocation*>(AllocLocked(sizeof(MapAllocation)));
   void* ptr = MapAligned(size, kChunkSize);
   if (!ptr) {
     FreeLocked(allocation);
-    abort(); //throw std::bad_alloc;
+    abort();  // throw std::bad_alloc;
   }
   allocation->ptr = ptr;
   allocation->size = size;
@@ -412,10 +401,9 @@
   return ptr;
 }
 
-void HeapImpl::MapFree(void *ptr) {
-  MapAllocation **allocation = &map_allocation_list_;
-  while (*allocation && (*allocation)->ptr != ptr)
-    allocation = &(*allocation)->next;
+void HeapImpl::MapFree(void* ptr) {
+  MapAllocation** allocation = &map_allocation_list_;
+  while (*allocation && (*allocation)->ptr != ptr) allocation = &(*allocation)->next;
 
   assert(*allocation != nullptr);
 
@@ -425,22 +413,22 @@
   *allocation = (*allocation)->next;
 }
 
-void HeapImpl::MoveToFreeList(Chunk *chunk, int bucket) {
+void HeapImpl::MoveToFreeList(Chunk* chunk, int bucket) {
   MoveToList(chunk, &free_chunks_[bucket]);
 }
 
-void HeapImpl::MoveToFullList(Chunk *chunk, int bucket) {
+void HeapImpl::MoveToFullList(Chunk* chunk, int bucket) {
   MoveToList(chunk, &full_chunks_[bucket]);
 }
 
-void HeapImpl::MoveToList(Chunk *chunk, LinkedList<Chunk*>* head) {
+void HeapImpl::MoveToList(Chunk* chunk, LinkedList<Chunk*>* head) {
   // Remove from old list
   chunk->node_.remove();
 
-  LinkedList<Chunk*> *node = head;
+  LinkedList<Chunk*>* node = head;
   // Insert into new list, sorted by lowest free count
-  while (node->next() != head && node->data() != nullptr
-      && node->data()->free_count() < chunk->free_count())
+  while (node->next() != head && node->data() != nullptr &&
+         node->data()->free_count() < chunk->free_count())
     node = node->next();
 
   node->insert(chunk->node_);
@@ -469,10 +457,12 @@
   impl_->Free(ptr);
 }
 
-void Heap::deallocate(HeapImpl*impl, void* ptr) {
+void Heap::deallocate(HeapImpl* impl, void* ptr) {
   impl->Free(ptr);
 }
 
 bool Heap::empty() {
   return impl_->Empty();
 }
+
+}  // namespace android
diff --git a/libmemunreachable/Allocator.h b/libmemunreachable/Allocator.h
index 5390739..837a12b 100644
--- a/libmemunreachable/Allocator.h
+++ b/libmemunreachable/Allocator.h
@@ -27,18 +27,20 @@
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
+
+namespace android {
+
 extern std::atomic<int> heap_count;
 
 class HeapImpl;
 
-template<typename T>
+template <typename T>
 class Allocator;
 
-
 // Non-templated class that implements wraps HeapImpl to keep
 // implementation out of the header file
 class Heap {
-public:
+ public:
   Heap();
   ~Heap();
 
@@ -59,110 +61,99 @@
   static void deallocate(HeapImpl* impl, void* ptr);
 
   // Allocate a class of type T
-  template<class T>
+  template <class T>
   T* allocate() {
     return reinterpret_cast<T*>(allocate(sizeof(T)));
   }
 
   // Comparators, copied objects will be equal
-  bool operator ==(const Heap& other) const {
-    return impl_ == other.impl_;
-  }
-  bool operator !=(const Heap& other) const {
-    return !(*this == other);
-  }
+  bool operator==(const Heap& other) const { return impl_ == other.impl_; }
+  bool operator!=(const Heap& other) const { return !(*this == other); }
 
   // std::unique_ptr wrapper that allocates using allocate and deletes using
   // deallocate
-  template<class T>
+  template <class T>
   using unique_ptr = std::unique_ptr<T, std::function<void(void*)>>;
 
-  template<class T, class... Args>
+  template <class T, class... Args>
   unique_ptr<T> make_unique(Args&&... args) {
     HeapImpl* impl = impl_;
-    return unique_ptr<T>(new (allocate<T>()) T(std::forward<Args>(args)...),
-        [impl](void* ptr) {
-          reinterpret_cast<T*>(ptr)->~T();
-          deallocate(impl, ptr);
-        });
+    return unique_ptr<T>(new (allocate<T>()) T(std::forward<Args>(args)...), [impl](void* ptr) {
+      reinterpret_cast<T*>(ptr)->~T();
+      deallocate(impl, ptr);
+    });
   }
 
   // std::unique_ptr wrapper that allocates using allocate and deletes using
   // deallocate
-  template<class T>
+  template <class T>
   using shared_ptr = std::shared_ptr<T>;
 
-  template<class T, class... Args>
+  template <class T, class... Args>
   shared_ptr<T> make_shared(Args&&... args);
 
-protected:
+ protected:
   HeapImpl* impl_;
   bool owns_impl_;
 };
 
 // STLAllocator implements the std allocator interface on top of a Heap
-template<typename T>
+template <typename T>
 class STLAllocator {
-public:
+ public:
   using value_type = T;
-  ~STLAllocator() {
-  }
+  ~STLAllocator() {}
 
   // Construct an STLAllocator on top of a Heap
-  STLAllocator(const Heap& heap) :  // NOLINT, implicit
-      heap_(heap) {
-  }
+  STLAllocator(const Heap& heap)
+      :  // NOLINT, implicit
+        heap_(heap) {}
 
   // Rebind an STLAllocator from an another STLAllocator
-  template<typename U>
-  STLAllocator(const STLAllocator<U>& other) :  // NOLINT, implicit
-      heap_(other.heap_) {
-  }
+  template <typename U>
+  STLAllocator(const STLAllocator<U>& other)
+      :  // NOLINT, implicit
+        heap_(other.heap_) {}
 
   STLAllocator(const STLAllocator&) = default;
   STLAllocator<T>& operator=(const STLAllocator<T>&) = default;
 
-  T* allocate(std::size_t n) {
-    return reinterpret_cast<T*>(heap_.allocate(n * sizeof(T)));
-  }
+  T* allocate(std::size_t n) { return reinterpret_cast<T*>(heap_.allocate(n * sizeof(T))); }
 
-  void deallocate(T* ptr, std::size_t) {
-    heap_.deallocate(ptr);
-  }
+  void deallocate(T* ptr, std::size_t) { heap_.deallocate(ptr); }
 
-  template<typename U>
-  bool operator ==(const STLAllocator<U>& other) const {
+  template <typename U>
+  bool operator==(const STLAllocator<U>& other) const {
     return heap_ == other.heap_;
   }
-  template<typename U>
-  inline bool operator !=(const STLAllocator<U>& other) const {
+  template <typename U>
+  inline bool operator!=(const STLAllocator<U>& other) const {
     return !(this == other);
   }
 
-  template<typename U>
+  template <typename U>
   friend class STLAllocator;
 
-protected:
+ protected:
   Heap heap_;
 };
 
-
 // Allocator extends STLAllocator with some convenience methods for allocating
 // a single object and for constructing unique_ptr and shared_ptr objects with
 // appropriate deleters.
-template<class T>
+template <class T>
 class Allocator : public STLAllocator<T> {
  public:
   ~Allocator() {}
 
-  Allocator(const Heap& other) : // NOLINT, implicit
-      STLAllocator<T>(other) {
-  }
+  Allocator(const Heap& other)
+      :  // NOLINT, implicit
+        STLAllocator<T>(other) {}
 
-  template<typename U>
-  Allocator(const STLAllocator<U>& other) :  // NOLINT, implicit
-      STLAllocator<T>(other) {
-  }
+  template <typename U>
+  Allocator(const STLAllocator<U>& other)
+      :  // NOLINT, implicit
+        STLAllocator<T>(other) {}
 
   Allocator(const Allocator&) = default;
   Allocator<T>& operator=(const Allocator<T>&) = default;
@@ -171,24 +162,20 @@
   using STLAllocator<T>::deallocate;
   using STLAllocator<T>::heap_;
 
-  T* allocate() {
-    return STLAllocator<T>::allocate(1);
-  }
-  void deallocate(void* ptr) {
-    heap_.deallocate(ptr);
-  }
+  T* allocate() { return STLAllocator<T>::allocate(1); }
+  void deallocate(void* ptr) { heap_.deallocate(ptr); }
 
   using shared_ptr = Heap::shared_ptr<T>;
 
-  template<class... Args>
-  shared_ptr make_shared(Args&& ...args) {
+  template <class... Args>
+  shared_ptr make_shared(Args&&... args) {
     return heap_.template make_shared<T>(std::forward<Args>(args)...);
   }
 
   using unique_ptr = Heap::unique_ptr<T>;
 
-  template<class... Args>
-  unique_ptr make_unique(Args&& ...args) {
+  template <class... Args>
+  unique_ptr make_unique(Args&&... args) {
     return heap_.template make_unique<T>(std::forward<Args>(args)...);
   }
 };
@@ -196,33 +183,36 @@
 // std::unique_ptr wrapper that allocates using allocate and deletes using
 // deallocate.  Implemented outside class definition in order to pass
 // Allocator<T> to shared_ptr.
-template<class T, class... Args>
+template <class T, class... Args>
 inline Heap::shared_ptr<T> Heap::make_shared(Args&&... args) {
   return std::allocate_shared<T, Allocator<T>, Args...>(Allocator<T>(*this),
-      std::forward<Args>(args)...);
+                                                        std::forward<Args>(args)...);
 }
 
 namespace allocator {
 
-template<class T>
+template <class T>
 using vector = std::vector<T, Allocator<T>>;
 
-template<class T>
+template <class T>
 using list = std::list<T, Allocator<T>>;
 
-template<class Key, class T, class Compare = std::less<Key>>
+template <class Key, class T, class Compare = std::less<Key>>
 using map = std::map<Key, T, Compare, Allocator<std::pair<const Key, T>>>;
 
-template<class Key, class T, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
-using unordered_map = std::unordered_map<Key, T, Hash, KeyEqual, Allocator<std::pair<const Key, T>>>;
+template <class Key, class T, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
+using unordered_map =
+    std::unordered_map<Key, T, Hash, KeyEqual, Allocator<std::pair<const Key, T>>>;
 
-template<class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
+template <class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
 using unordered_set = std::unordered_set<Key, Hash, KeyEqual, Allocator<Key>>;
 
-template<class Key, class Compare = std::less<Key>>
+template <class Key, class Compare = std::less<Key>>
 using set = std::set<Key, Compare, Allocator<Key>>;
 
 using string = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
 }
 
+}  // namespace android
+
 #endif
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index cdac76b..826a576 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -26,6 +26,7 @@
     defaults: ["libmemunreachable_defaults"],
     srcs: [
         "Allocator.cpp",
+        "Binder.cpp",
         "HeapWalker.cpp",
         "LeakFolding.cpp",
         "LeakPipe.cpp",
@@ -84,3 +85,18 @@
         },
     },
 }
+
+cc_test {
+    name: "memunreachable_binder_test",
+    defaults: ["libmemunreachable_defaults"],
+    srcs: [
+        "tests/Binder_test.cpp",
+        "tests/MemUnreachable_test.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libhwbinder",
+        "libmemunreachable",
+        "libutils",
+    ],
+}
diff --git a/libmemunreachable/Binder.cpp b/libmemunreachable/Binder.cpp
new file mode 100644
index 0000000..60512a3
--- /dev/null
+++ b/libmemunreachable/Binder.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/cdefs.h>
+#include <unistd.h>
+
+#include <functional>
+
+#include "Binder.h"
+#include "log.h"
+
+__BEGIN_DECLS
+
+// Weak undefined references to the symbols in libbinder and libhwbinder
+// so that libmemunreachable can call them in processes that have them
+// loaded without requiring libmemunreachable to have dependencies on them.
+ssize_t __attribute__((weak)) getBinderKernelReferences(size_t, uintptr_t*);
+ssize_t __attribute__((weak)) getHWBinderKernelReferences(size_t, uintptr_t*);
+
+__END_DECLS
+
+namespace android {
+
+static bool BinderReferencesToVector(allocator::vector<uintptr_t>& refs,
+                                     std::function<ssize_t(size_t, uintptr_t*)> fn) {
+  if (fn == nullptr) {
+    return true;
+  }
+
+  size_t size = refs.size();
+
+  do {
+    refs.resize(size);
+
+    ssize_t ret = fn(refs.size(), refs.data());
+    if (ret < 0) {
+      return false;
+    }
+
+    size = ret;
+  } while (size > refs.size());
+
+  refs.resize(size);
+  return true;
+}
+
+bool BinderReferences(allocator::vector<uintptr_t>& refs) {
+  refs.clear();
+
+  allocator::vector<uintptr_t> binder_refs{refs.get_allocator()};
+  if (BinderReferencesToVector(refs, getBinderKernelReferences)) {
+    refs.insert(refs.end(), binder_refs.begin(), binder_refs.end());
+  } else {
+    MEM_ALOGE("getBinderKernelReferences failed");
+  }
+
+  allocator::vector<uintptr_t> hwbinder_refs{refs.get_allocator()};
+  if (BinderReferencesToVector(hwbinder_refs, getHWBinderKernelReferences)) {
+    refs.insert(refs.end(), hwbinder_refs.begin(), hwbinder_refs.end());
+  } else {
+    MEM_ALOGE("getHWBinderKernelReferences failed");
+  }
+
+  return true;
+}
+
+}  // namespace android
diff --git a/libunwindstack/Log.h b/libmemunreachable/Binder.h
similarity index 65%
copy from libunwindstack/Log.h
copy to libmemunreachable/Binder.h
index 2d01aa8..bf4fd3e 100644
--- a/libunwindstack/Log.h
+++ b/libmemunreachable/Binder.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,15 @@
  * limitations under the License.
  */
 
-#ifndef _LIBUNWINDSTACK_LOG_H
-#define _LIBUNWINDSTACK_LOG_H
+#ifndef LIBMEMUNREACHABLE_BINDER_H_
+#define LIBMEMUNREACHABLE_BINDER_H_
 
-#include <stdint.h>
+#include "Allocator.h"
 
-void log_to_stdout(bool enable);
-void log(uint8_t indent, const char* format, ...);
+namespace android {
 
-#endif  // _LIBUNWINDSTACK_LOG_H
+bool BinderReferences(allocator::vector<uintptr_t>& refs);
+
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_BINDER_H_
diff --git a/libmemunreachable/HeapWalker.cpp b/libmemunreachable/HeapWalker.cpp
index c365ae5..2403ad0 100644
--- a/libmemunreachable/HeapWalker.cpp
+++ b/libmemunreachable/HeapWalker.cpp
@@ -28,6 +28,8 @@
 #include "ScopedSignalHandler.h"
 #include "log.h"
 
+namespace android {
+
 bool HeapWalker::Allocation(uintptr_t begin, uintptr_t end) {
   if (end == begin) {
     end = begin + 1;
@@ -114,8 +116,8 @@
   return true;
 }
 
-bool HeapWalker::Leaked(allocator::vector<Range>& leaked, size_t limit,
-    size_t* num_leaks_out, size_t* leak_bytes_out) {
+bool HeapWalker::Leaked(allocator::vector<Range>& leaked, size_t limit, size_t* num_leaks_out,
+                        size_t* leak_bytes_out) {
   leaked.clear();
 
   size_t num_leaks = 0;
@@ -148,9 +150,9 @@
 
 static bool MapOverPage(void* addr) {
   const size_t page_size = sysconf(_SC_PAGE_SIZE);
-  void *page = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & ~(page_size-1));
+  void* page = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & ~(page_size - 1));
 
-  void* ret = mmap(page, page_size, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
+  void* ret = mmap(page, page_size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
   if (ret == MAP_FAILED) {
     MEM_ALOGE("failed to map page at %p: %s", page, strerror(errno));
     return false;
@@ -159,7 +161,8 @@
   return true;
 }
 
-void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginfo_t* si, void* /*uctx*/) {
+void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginfo_t* si,
+                                void* /*uctx*/) {
   uintptr_t addr = reinterpret_cast<uintptr_t>(si->si_addr);
   if (addr != walking_ptr_) {
     handler.reset();
@@ -172,3 +175,5 @@
 }
 
 ScopedSignalHandler::SignalFn ScopedSignalHandler::handler_;
+
+}  // namespace android
diff --git a/libmemunreachable/HeapWalker.h b/libmemunreachable/HeapWalker.h
index b25696f..5c7ec13 100644
--- a/libmemunreachable/HeapWalker.h
+++ b/libmemunreachable/HeapWalker.h
@@ -25,6 +25,8 @@
 #include "ScopedSignalHandler.h"
 #include "Tarjan.h"
 
+namespace android {
+
 // A range [begin, end)
 struct Range {
   uintptr_t begin;
@@ -34,31 +36,31 @@
   bool operator==(const Range& other) const {
     return this->begin == other.begin && this->end == other.end;
   }
-  bool operator!=(const Range& other) const {
-    return !(*this == other);
-  }
+  bool operator!=(const Range& other) const { return !(*this == other); }
 };
 
 // Comparator for Ranges that returns equivalence for overlapping ranges
 struct compare_range {
-  bool operator()(const Range& a, const Range& b) const {
-    return a.end <= b.begin;
-  }
+  bool operator()(const Range& a, const Range& b) const { return a.end <= b.begin; }
 };
 
 class HeapWalker {
  public:
-  explicit HeapWalker(Allocator<HeapWalker> allocator) : allocator_(allocator),
-    allocations_(allocator), allocation_bytes_(0),
-	roots_(allocator), root_vals_(allocator),
-	segv_handler_(allocator), walking_ptr_(0) {
+  explicit HeapWalker(Allocator<HeapWalker> allocator)
+      : allocator_(allocator),
+        allocations_(allocator),
+        allocation_bytes_(0),
+        roots_(allocator),
+        root_vals_(allocator),
+        segv_handler_(allocator),
+        walking_ptr_(0) {
     valid_allocations_range_.end = 0;
     valid_allocations_range_.begin = ~valid_allocations_range_.end;
 
-    segv_handler_.install(SIGSEGV,
-        [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
+    segv_handler_.install(
+        SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
           this->HandleSegFault(handler, signal, siginfo, uctx);
-      });
+        });
   }
 
   ~HeapWalker() {}
@@ -68,15 +70,14 @@
 
   bool DetectLeaks();
 
-  bool Leaked(allocator::vector<Range>&, size_t limit, size_t* num_leaks,
-      size_t* leak_bytes);
+  bool Leaked(allocator::vector<Range>&, size_t limit, size_t* num_leaks, size_t* leak_bytes);
   size_t Allocations();
   size_t AllocationBytes();
 
-  template<class F>
+  template <class F>
   void ForEachPtrInRange(const Range& range, F&& f);
 
-  template<class F>
+  template <class F>
   void ForEachAllocation(F&& f);
 
   struct AllocationInfo {
@@ -84,7 +85,6 @@
   };
 
  private:
-
   void RecurseRoot(const Range& root);
   bool WordContainsAllocationPtr(uintptr_t ptr, Range* range, AllocationInfo** info);
   void HandleSegFault(ScopedSignalHandler&, int, siginfo_t*, void*);
@@ -103,7 +103,7 @@
   uintptr_t walking_ptr_;
 };
 
-template<class F>
+template <class F>
 inline void HeapWalker::ForEachPtrInRange(const Range& range, F&& f) {
   uintptr_t begin = (range.begin + (sizeof(uintptr_t) - 1)) & ~(sizeof(uintptr_t) - 1);
   // TODO(ccross): we might need to consider a pointer to the end of a buffer
@@ -118,7 +118,7 @@
   }
 }
 
-template<class F>
+template <class F>
 inline void HeapWalker::ForEachAllocation(F&& f) {
   for (auto& it : allocations_) {
     const Range& range = it.first;
@@ -127,4 +127,6 @@
   }
 }
 
+}  // namespace android
+
 #endif
diff --git a/libmemunreachable/Leak.h b/libmemunreachable/Leak.h
index eaeeea7..de64b64 100644
--- a/libmemunreachable/Leak.h
+++ b/libmemunreachable/Leak.h
@@ -26,9 +26,9 @@
 // as a key in std::unordered_map.
 namespace std {
 
-template<>
-struct hash<Leak::Backtrace> {
-  std::size_t operator()(const Leak::Backtrace& key) const {
+template <>
+struct hash<android::Leak::Backtrace> {
+  std::size_t operator()(const android::Leak::Backtrace& key) const {
     std::size_t seed = 0;
 
     hash_combine(seed, key.num_frames);
@@ -40,7 +40,7 @@
   }
 
  private:
-  template<typename T>
+  template <typename T>
   inline void hash_combine(std::size_t& seed, const T& v) const {
     std::hash<T> hasher;
     seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
@@ -49,9 +49,12 @@
 
 }  // namespace std
 
+namespace android {
+
 static bool operator==(const Leak::Backtrace& lhs, const Leak::Backtrace& rhs) {
   return (lhs.num_frames == rhs.num_frames) &&
-      memcmp(lhs.frames, rhs.frames, lhs.num_frames * sizeof(lhs.frames[0])) == 0;
+         memcmp(lhs.frames, rhs.frames, lhs.num_frames * sizeof(lhs.frames[0])) == 0;
+}
 }
 
 #endif
diff --git a/libmemunreachable/LeakFolding.cpp b/libmemunreachable/LeakFolding.cpp
index be4d20c..69f320c 100644
--- a/libmemunreachable/LeakFolding.cpp
+++ b/libmemunreachable/LeakFolding.cpp
@@ -22,6 +22,8 @@
 #include "Tarjan.h"
 #include "log.h"
 
+namespace android {
+
 // Converts possibly cyclic graph of leaks to a DAG by combining
 // strongly-connected components into a object, stored in the scc pointer
 // of each node in the component.
@@ -31,11 +33,11 @@
 
   Allocator<SCCInfo> scc_allocator = allocator_;
 
-  for (auto& scc_nodes: scc_list) {
+  for (auto& scc_nodes : scc_list) {
     Allocator<SCCInfo>::unique_ptr leak_scc;
     leak_scc = scc_allocator.make_unique(scc_allocator);
 
-    for (auto& node: scc_nodes) {
+    for (auto& node : scc_nodes) {
       node->ptr->scc = leak_scc.get();
       leak_scc->count++;
       leak_scc->size += node->ptr->range.size();
@@ -46,7 +48,7 @@
 
   for (auto& it : leak_map_) {
     LeakInfo& leak = it.second;
-    for (auto& ref: leak.node.references_out) {
+    for (auto& ref : leak.node.references_out) {
       if (leak.scc != ref->ptr->scc) {
         leak.scc->node.Edge(&ref->ptr->scc->node);
       }
@@ -55,17 +57,14 @@
 }
 
 void LeakFolding::AccumulateLeaks(SCCInfo* dominator) {
-  std::function<void(SCCInfo*)> walk(std::allocator_arg, allocator_,
-      [&](SCCInfo* scc) {
-        if (scc->accumulator != dominator) {
-          scc->accumulator = dominator;
-          dominator->cuumulative_size += scc->size;
-          dominator->cuumulative_count += scc->count;
-          scc->node.Foreach([&](SCCInfo* ref) {
-            walk(ref);
-          });
-        }
-      });
+  std::function<void(SCCInfo*)> walk(std::allocator_arg, allocator_, [&](SCCInfo* scc) {
+    if (scc->accumulator != dominator) {
+      scc->accumulator = dominator;
+      dominator->cuumulative_size += scc->size;
+      dominator->cuumulative_count += scc->count;
+      scc->node.Foreach([&](SCCInfo* ref) { walk(ref); });
+    }
+  });
   walk(dominator);
 }
 
@@ -73,27 +72,25 @@
   Allocator<LeakInfo> leak_allocator = allocator_;
 
   // Find all leaked allocations insert them into leak_map_ and leak_graph_
-  heap_walker_.ForEachAllocation(
-      [&](const Range& range, HeapWalker::AllocationInfo& allocation) {
-        if (!allocation.referenced_from_root) {
-          auto it = leak_map_.emplace(std::piecewise_construct,
-              std::forward_as_tuple(range),
-              std::forward_as_tuple(range, allocator_));
-          LeakInfo& leak = it.first->second;
-          leak_graph_.push_back(&leak.node);
-        }
-      });
+  heap_walker_.ForEachAllocation([&](const Range& range, HeapWalker::AllocationInfo& allocation) {
+    if (!allocation.referenced_from_root) {
+      auto it = leak_map_.emplace(std::piecewise_construct, std::forward_as_tuple(range),
+                                  std::forward_as_tuple(range, allocator_));
+      LeakInfo& leak = it.first->second;
+      leak_graph_.push_back(&leak.node);
+    }
+  });
 
   // Find references between leaked allocations and connect them in leak_graph_
   for (auto& it : leak_map_) {
     LeakInfo& leak = it.second;
     heap_walker_.ForEachPtrInRange(leak.range,
-        [&](Range& ptr_range, HeapWalker::AllocationInfo* ptr_info) {
-          if (!ptr_info->referenced_from_root) {
-            LeakInfo* ptr_leak = &leak_map_.at(ptr_range);
-            leak.node.Edge(&ptr_leak->node);
-          }
-        });
+                                   [&](Range& ptr_range, HeapWalker::AllocationInfo* ptr_info) {
+                                     if (!ptr_info->referenced_from_root) {
+                                       LeakInfo* ptr_leak = &leak_map_.at(ptr_range);
+                                       leak.node.Edge(&ptr_leak->node);
+                                     }
+                                   });
   }
 
   // Convert the cyclic graph to a DAG by grouping strongly connected components
@@ -110,8 +107,8 @@
   return true;
 }
 
-bool LeakFolding::Leaked(allocator::vector<LeakFolding::Leak>& leaked,
-    size_t* num_leaks_out, size_t* leak_bytes_out) {
+bool LeakFolding::Leaked(allocator::vector<LeakFolding::Leak>& leaked, size_t* num_leaks_out,
+                         size_t* leak_bytes_out) {
   size_t num_leaks = 0;
   size_t leak_bytes = 0;
   for (auto& it : leak_map_) {
@@ -123,9 +120,8 @@
   for (auto& it : leak_map_) {
     const LeakInfo& leak = it.second;
     if (leak.scc->dominator) {
-      leaked.emplace_back(Leak{leak.range,
-        leak.scc->cuumulative_count - 1,
-        leak.scc->cuumulative_size - leak.range.size()});
+      leaked.emplace_back(Leak{leak.range, leak.scc->cuumulative_count - 1,
+                               leak.scc->cuumulative_size - leak.range.size()});
     }
   }
 
@@ -138,3 +134,5 @@
 
   return true;
 }
+
+}  // namespace android
diff --git a/libmemunreachable/LeakFolding.h b/libmemunreachable/LeakFolding.h
index 9c6a525..09affac 100644
--- a/libmemunreachable/LeakFolding.h
+++ b/libmemunreachable/LeakFolding.h
@@ -19,11 +19,16 @@
 
 #include "HeapWalker.h"
 
+namespace android {
+
 class LeakFolding {
  public:
   LeakFolding(Allocator<void> allocator, HeapWalker& heap_walker)
-   : allocator_(allocator), heap_walker_(heap_walker),
-     leak_map_(allocator), leak_graph_(allocator), leak_scc_(allocator) {}
+      : allocator_(allocator),
+        heap_walker_(heap_walker),
+        leak_map_(allocator),
+        leak_graph_(allocator),
+        leak_scc_(allocator) {}
 
   bool FoldLeaks();
 
@@ -33,8 +38,7 @@
     size_t referenced_size;
   };
 
-  bool Leaked(allocator::vector<Leak>& leaked,
-      size_t* num_leaks_out, size_t* leak_bytes_out);
+  bool Leaked(allocator::vector<Leak>& leaked, size_t* num_leaks_out, size_t* leak_bytes_out);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(LeakFolding);
@@ -54,9 +58,15 @@
     bool dominator;
     SCCInfo* accumulator;
 
-    explicit SCCInfo(Allocator<SCCInfo> allocator) : node(this, allocator),
-        count(0), size(0), cuumulative_count(0), cuumulative_size(0),
-        dominator(false), accumulator(nullptr) {}
+    explicit SCCInfo(Allocator<SCCInfo> allocator)
+        : node(this, allocator),
+          count(0),
+          size(0),
+          cuumulative_count(0),
+          cuumulative_size(0),
+          dominator(false),
+          accumulator(nullptr) {}
+
    private:
     SCCInfo(SCCInfo&&) = delete;
     DISALLOW_COPY_AND_ASSIGN(SCCInfo);
@@ -71,8 +81,7 @@
     SCCInfo* scc;
 
     LeakInfo(const Range& range, Allocator<LeakInfo> allocator)
-        : node(this, allocator), range(range),
-          scc(nullptr) {}
+        : node(this, allocator), range(range), scc(nullptr) {}
 
    private:
     DISALLOW_COPY_AND_ASSIGN(LeakInfo);
@@ -86,4 +95,6 @@
   allocator::vector<Allocator<SCCInfo>::unique_ptr> leak_scc_;
 };
 
-#endif // LIBMEMUNREACHABLE_LEAK_FOLDING_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_LEAK_FOLDING_H_
diff --git a/libmemunreachable/LeakPipe.cpp b/libmemunreachable/LeakPipe.cpp
index 78117e2..8ea9ad6 100644
--- a/libmemunreachable/LeakPipe.cpp
+++ b/libmemunreachable/LeakPipe.cpp
@@ -21,9 +21,11 @@
 
 #include "log.h"
 
+namespace android {
+
 bool LeakPipe::SendFd(int sock, int fd) {
-  struct msghdr hdr{};
-  struct iovec iov{};
+  struct msghdr hdr {};
+  struct iovec iov {};
   unsigned int data = 0xfdfdfdfd;
   alignas(struct cmsghdr) char cmsgbuf[CMSG_SPACE(sizeof(int))];
 
@@ -56,8 +58,8 @@
 }
 
 int LeakPipe::ReceiveFd(int sock) {
-  struct msghdr hdr{};
-  struct iovec iov{};
+  struct msghdr hdr {};
+  struct iovec iov {};
   unsigned int data;
   alignas(struct cmsghdr) char cmsgbuf[CMSG_SPACE(sizeof(int))];
 
@@ -87,3 +89,5 @@
 
   return *(int*)CMSG_DATA(cmsg);
 }
+
+}  // namespace android
diff --git a/libmemunreachable/LeakPipe.h b/libmemunreachable/LeakPipe.h
index 3ea2d8f..94d4aa4 100644
--- a/libmemunreachable/LeakPipe.h
+++ b/libmemunreachable/LeakPipe.h
@@ -26,6 +26,8 @@
 #include "ScopedPipe.h"
 #include "log.h"
 
+namespace android {
+
 // LeakPipe implements a pipe that can transfer vectors of simple objects
 // between processes.  The pipe is created in the sending process and
 // transferred over a socketpair that was created before forking.  This ensures
@@ -34,15 +36,13 @@
 class LeakPipe {
  public:
   LeakPipe() {
-    int ret = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, sv_);
+    int ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv_);
     if (ret < 0) {
       MEM_LOG_ALWAYS_FATAL("failed to create socketpair: %s", strerror(errno));
     }
   }
 
-  ~LeakPipe() {
-    Close();
-  }
+  ~LeakPipe() { Close(); }
 
   void Close() {
     close(sv_[0]);
@@ -77,13 +77,9 @@
    public:
     LeakPipeBase() : fd_(-1) {}
 
-    ~LeakPipeBase() {
-      Close();
-    }
+    ~LeakPipeBase() { Close(); }
 
-    void SetFd(int fd) {
-      fd_ = fd;
-    }
+    void SetFd(int fd) { fd_ = fd; }
 
     void Close() {
       close(fd_);
@@ -101,7 +97,7 @@
    public:
     using LeakPipeBase::LeakPipeBase;
 
-    template<typename T>
+    template <typename T>
     bool Send(const T& value) {
       ssize_t ret = TEMP_FAILURE_RETRY(write(fd_, &value, sizeof(T)));
       if (ret < 0) {
@@ -115,7 +111,7 @@
       return true;
     }
 
-    template<class T, class Alloc = std::allocator<T>>
+    template <class T, class Alloc = std::allocator<T>>
     bool SendVector(const std::vector<T, Alloc>& vector) {
       size_t size = vector.size() * sizeof(T);
       if (!Send(size)) {
@@ -139,7 +135,7 @@
    public:
     using LeakPipeBase::LeakPipeBase;
 
-    template<typename T>
+    template <typename T>
     bool Receive(T* value) {
       ssize_t ret = TEMP_FAILURE_RETRY(read(fd_, reinterpret_cast<void*>(value), sizeof(T)));
       if (ret < 0) {
@@ -153,7 +149,7 @@
       return true;
     }
 
-    template<class T, class Alloc = std::allocator<T>>
+    template <class T, class Alloc = std::allocator<T>>
     bool ReceiveVector(std::vector<T, Alloc>& vector) {
       size_t size = 0;
       if (!Receive(&size)) {
@@ -178,16 +174,11 @@
 
       return true;
     }
-
   };
 
-  LeakPipeReceiver& Receiver() {
-    return receiver_;
-  }
+  LeakPipeReceiver& Receiver() { return receiver_; }
 
-  LeakPipeSender& Sender() {
-    return sender_;
-  }
+  LeakPipeSender& Sender() { return sender_; }
 
  private:
   LeakPipeReceiver receiver_;
@@ -198,4 +189,6 @@
   int sv_[2];
 };
 
-#endif // LIBMEMUNREACHABLE_LEAK_PIPE_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_LEAK_PIPE_H_
diff --git a/libmemunreachable/LineBuffer.cpp b/libmemunreachable/LineBuffer.cpp
index d3580c0..4ea0542 100644
--- a/libmemunreachable/LineBuffer.cpp
+++ b/libmemunreachable/LineBuffer.cpp
@@ -23,8 +23,10 @@
 
 #include "LineBuffer.h"
 
-LineBuffer::LineBuffer(int fd, char* buffer, size_t buffer_len) : fd_(fd), buffer_(buffer), buffer_len_(buffer_len) {
-}
+namespace android {
+
+LineBuffer::LineBuffer(int fd, char* buffer, size_t buffer_len)
+    : fd_(fd), buffer_(buffer), buffer_len_(buffer_len) {}
 
 bool LineBuffer::GetLine(char** line, size_t* line_len) {
   while (true) {
@@ -60,3 +62,5 @@
     bytes_ += bytes;
   }
 }
+
+}  // namespace android
diff --git a/libmemunreachable/LineBuffer.h b/libmemunreachable/LineBuffer.h
index a015c46..cc6cd0c 100644
--- a/libmemunreachable/LineBuffer.h
+++ b/libmemunreachable/LineBuffer.h
@@ -19,6 +19,8 @@
 
 #include <stdint.h>
 
+namespace android {
+
 class LineBuffer {
  public:
   LineBuffer(int fd, char* buffer, size_t buffer_len);
@@ -33,4 +35,6 @@
   size_t bytes_ = 0;
 };
 
-#endif // _LIBMEMUNREACHABLE_LINE_BUFFER_H
+}  // namespace android
+
+#endif  // _LIBMEMUNREACHABLE_LINE_BUFFER_H
diff --git a/libmemunreachable/LinkedList.h b/libmemunreachable/LinkedList.h
index 132842d..36fe9fd 100644
--- a/libmemunreachable/LinkedList.h
+++ b/libmemunreachable/LinkedList.h
@@ -17,44 +17,47 @@
 #ifndef LIBMEMUNREACHABLE_LINKED_LIST_H_
 #define LIBMEMUNREACHABLE_LINKED_LIST_H_
 
-template<class T>
+namespace android {
+
+template <class T>
 class LinkedList {
-public:
-    LinkedList() : next_(this), prev_(this), data_() {}
-    explicit LinkedList(T data) : LinkedList() {
-        data_ = data;
-    }
-    ~LinkedList() {}
-    void insert(LinkedList<T>& node) {
-        assert(node.empty());
-        node.next_ = this->next_;
-        node.next_->prev_ = &node;
-        this->next_ = &node;
-        node.prev_ = this;
-    }
-    void remove() {
-        this->next_->prev_ = this->prev_;
-        this->prev_->next_ = this->next_;
-        this->next_ = this;
-        this->prev_ = this;
-    }
-    T data() { return data_; }
-    bool empty() { return next_ == this && prev_ == this; }
-    LinkedList<T> *next() { return next_; }
-private:
-    LinkedList<T> *next_;
-    LinkedList<T> *prev_;
-    T data_;
+ public:
+  LinkedList() : next_(this), prev_(this), data_() {}
+  explicit LinkedList(T data) : LinkedList() { data_ = data; }
+  ~LinkedList() {}
+  void insert(LinkedList<T>& node) {
+    assert(node.empty());
+    node.next_ = this->next_;
+    node.next_->prev_ = &node;
+    this->next_ = &node;
+    node.prev_ = this;
+  }
+  void remove() {
+    this->next_->prev_ = this->prev_;
+    this->prev_->next_ = this->next_;
+    this->next_ = this;
+    this->prev_ = this;
+  }
+  T data() { return data_; }
+  bool empty() { return next_ == this && prev_ == this; }
+  LinkedList<T>* next() { return next_; }
+
+ private:
+  LinkedList<T>* next_;
+  LinkedList<T>* prev_;
+  T data_;
 };
 
-template<class T>
+template <class T>
 class LinkedListHead {
-public:
-    LinkedListHead() : node_() {}
-    ~LinkedListHead() {}
+ public:
+  LinkedListHead() : node_() {}
+  ~LinkedListHead() {}
 
-private:
-    LinkedList<T> node_;
+ private:
+  LinkedList<T> node_;
 };
 
+}  // namespace android
+
 #endif
diff --git a/libmemunreachable/MemUnreachable.cpp b/libmemunreachable/MemUnreachable.cpp
index 1c84744..5e062fd 100644
--- a/libmemunreachable/MemUnreachable.cpp
+++ b/libmemunreachable/MemUnreachable.cpp
@@ -15,18 +15,20 @@
  */
 
 #include <inttypes.h>
+#include <string.h>
 
 #include <functional>
 #include <iomanip>
 #include <mutex>
-#include <string>
 #include <sstream>
+#include <string>
 #include <unordered_map>
 
-#include <backtrace.h>
 #include <android-base/macros.h>
+#include <backtrace.h>
 
 #include "Allocator.h"
+#include "Binder.h"
 #include "HeapWalker.h"
 #include "Leak.h"
 #include "LeakFolding.h"
@@ -37,30 +39,34 @@
 #include "Semaphore.h"
 #include "ThreadCapture.h"
 
-#include "memunreachable/memunreachable.h"
 #include "bionic.h"
 #include "log.h"
-
-const size_t Leak::contents_length;
+#include "memunreachable/memunreachable.h"
 
 using namespace std::chrono_literals;
 
+namespace android {
+
+const size_t Leak::contents_length;
+
 class MemUnreachable {
  public:
-  MemUnreachable(pid_t pid, Allocator<void> allocator) : pid_(pid), allocator_(allocator),
-      heap_walker_(allocator_) {}
+  MemUnreachable(pid_t pid, Allocator<void> allocator)
+      : pid_(pid), allocator_(allocator), heap_walker_(allocator_) {}
   bool CollectAllocations(const allocator::vector<ThreadInfo>& threads,
-      const allocator::vector<Mapping>& mappings);
-  bool GetUnreachableMemory(allocator::vector<Leak>& leaks, size_t limit,
-      size_t* num_leaks, size_t* leak_bytes);
+                          const allocator::vector<Mapping>& mappings,
+                          const allocator::vector<uintptr_t>& refs);
+  bool GetUnreachableMemory(allocator::vector<Leak>& leaks, size_t limit, size_t* num_leaks,
+                            size_t* leak_bytes);
   size_t Allocations() { return heap_walker_.Allocations(); }
   size_t AllocationBytes() { return heap_walker_.AllocationBytes(); }
+
  private:
   bool ClassifyMappings(const allocator::vector<Mapping>& mappings,
-      allocator::vector<Mapping>& heap_mappings,
-      allocator::vector<Mapping>& anon_mappings,
-      allocator::vector<Mapping>& globals_mappings,
-      allocator::vector<Mapping>& stack_mappings);
+                        allocator::vector<Mapping>& heap_mappings,
+                        allocator::vector<Mapping>& anon_mappings,
+                        allocator::vector<Mapping>& globals_mappings,
+                        allocator::vector<Mapping>& stack_mappings);
   DISALLOW_COPY_AND_ASSIGN(MemUnreachable);
   pid_t pid_;
   Allocator<void> allocator_;
@@ -68,16 +74,18 @@
 };
 
 static void HeapIterate(const Mapping& heap_mapping,
-    const std::function<void(uintptr_t, size_t)>& func) {
+                        const std::function<void(uintptr_t, size_t)>& func) {
   malloc_iterate(heap_mapping.begin, heap_mapping.end - heap_mapping.begin,
-      [](uintptr_t base, size_t size, void* arg) {
-    auto f = reinterpret_cast<const std::function<void(uintptr_t, size_t)>*>(arg);
-    (*f)(base, size);
-  }, const_cast<void*>(reinterpret_cast<const void*>(&func)));
+                 [](uintptr_t base, size_t size, void* arg) {
+                   auto f = reinterpret_cast<const std::function<void(uintptr_t, size_t)>*>(arg);
+                   (*f)(base, size);
+                 },
+                 const_cast<void*>(reinterpret_cast<const void*>(&func)));
 }
 
 bool MemUnreachable::CollectAllocations(const allocator::vector<ThreadInfo>& threads,
-    const allocator::vector<Mapping>& mappings) {
+                                        const allocator::vector<Mapping>& mappings,
+                                        const allocator::vector<uintptr_t>& refs) {
   MEM_ALOGI("searching process %d for allocations", pid_);
   allocator::vector<Mapping> heap_mappings{mappings};
   allocator::vector<Mapping> anon_mappings{mappings};
@@ -113,13 +121,15 @@
     heap_walker_.Root(thread_it->regs);
   }
 
+  heap_walker_.Root(refs);
+
   MEM_ALOGI("searching done");
 
   return true;
 }
 
-bool MemUnreachable::GetUnreachableMemory(allocator::vector<Leak>& leaks,
-    size_t limit, size_t* num_leaks, size_t* leak_bytes) {
+bool MemUnreachable::GetUnreachableMemory(allocator::vector<Leak>& leaks, size_t limit,
+                                          size_t* num_leaks, size_t* leak_bytes) {
   MEM_ALOGI("sweeping process %d for unreachable memory", pid_);
   leaks.clear();
 
@@ -127,7 +137,6 @@
     return false;
   }
 
-
   allocator::vector<Range> leaked1{allocator_};
   heap_walker_.Leaked(leaked1, 0, num_leaks, leak_bytes);
 
@@ -152,12 +161,12 @@
   // in backtrace_map.
   leaks.reserve(leaked.size());
 
-  for (auto& it: leaked) {
+  for (auto& it : leaked) {
     leaks.emplace_back();
     Leak* leak = &leaks.back();
 
-    ssize_t num_backtrace_frames = malloc_backtrace(reinterpret_cast<void*>(it.range.begin),
-        leak->backtrace.frames, leak->backtrace.max_frames);
+    ssize_t num_backtrace_frames = malloc_backtrace(
+        reinterpret_cast<void*>(it.range.begin), leak->backtrace.frames, leak->backtrace.max_frames);
     if (num_backtrace_frames > 0) {
       leak->backtrace.num_frames = num_backtrace_frames;
 
@@ -183,14 +192,13 @@
     leak->referenced_size = it.referenced_size;
     leak->total_size = leak->size + leak->referenced_size;
     memcpy(leak->contents, reinterpret_cast<void*>(it.range.begin),
-        std::min(leak->size, Leak::contents_length));
+           std::min(leak->size, Leak::contents_length));
   }
 
   MEM_ALOGI("folding done");
 
-  std::sort(leaks.begin(), leaks.end(), [](const Leak& a, const Leak& b) {
-    return a.total_size > b.total_size;
-  });
+  std::sort(leaks.begin(), leaks.end(),
+            [](const Leak& a, const Leak& b) { return a.total_size > b.total_size; });
 
   if (leaks.size() > limit) {
     leaks.resize(limit);
@@ -205,11 +213,10 @@
 }
 
 bool MemUnreachable::ClassifyMappings(const allocator::vector<Mapping>& mappings,
-    allocator::vector<Mapping>& heap_mappings,
-    allocator::vector<Mapping>& anon_mappings,
-    allocator::vector<Mapping>& globals_mappings,
-    allocator::vector<Mapping>& stack_mappings)
-{
+                                      allocator::vector<Mapping>& heap_mappings,
+                                      allocator::vector<Mapping>& anon_mappings,
+                                      allocator::vector<Mapping>& globals_mappings,
+                                      allocator::vector<Mapping>& stack_mappings) {
   heap_mappings.clear();
   anon_mappings.clear();
   globals_mappings.clear();
@@ -245,7 +252,8 @@
       stack_mappings.emplace_back(*it);
     } else if (mapping_name.size() == 0) {
       globals_mappings.emplace_back(*it);
-    } else if (has_prefix(mapping_name, "[anon:") && mapping_name != "[anon:leak_detector_malloc]") {
+    } else if (has_prefix(mapping_name, "[anon:") &&
+               mapping_name != "[anon:leak_detector_malloc]") {
       // TODO(ccross): it would be nice to treat named anonymous mappings as
       // possible leaks, but naming something in a .bss or .data section makes
       // it impossible to distinguish them from mmaped and then named mappings.
@@ -256,7 +264,7 @@
   return true;
 }
 
-template<typename T>
+template <typename T>
 static inline const char* plural(T val) {
   return (val == 1) ? "" : "s";
 }
@@ -279,6 +287,7 @@
     ThreadCapture thread_capture(parent_pid, heap);
     allocator::vector<ThreadInfo> thread_info(heap);
     allocator::vector<Mapping> mappings(heap);
+    allocator::vector<uintptr_t> refs(heap);
 
     // ptrace all the threads
     if (!thread_capture.CaptureThreads()) {
@@ -298,6 +307,11 @@
       return 1;
     }
 
+    if (!BinderReferences(refs)) {
+      continue_parent_sem.Post();
+      return 1;
+    }
+
     // malloc must be enabled to call fork, at_fork handlers take the same
     // locks as ScopedDisableMalloc.  All threads are paused in ptrace, so
     // memory state is still consistent.  Unfreeze the original thread so it
@@ -323,7 +337,7 @@
 
       MemUnreachable unreachable{parent_pid, heap};
 
-      if (!unreachable.CollectAllocations(thread_info, mappings)) {
+      if (!unreachable.CollectAllocations(thread_info, mappings, refs)) {
         _exit(2);
       }
       size_t num_allocations = unreachable.Allocations();
@@ -403,7 +417,6 @@
 }
 
 std::string Leak::ToString(bool log_contents) const {
-
   std::ostringstream oss;
 
   oss << "  " << std::dec << size;
@@ -492,8 +505,8 @@
   oss << std::endl;
 
   for (auto it = leaks.begin(); it != leaks.end(); it++) {
-      oss << it->ToString(log_contents);
-      oss << std::endl;
+    oss << it->ToString(log_contents);
+    oss << std::endl;
   }
 
   return oss.str();
@@ -511,9 +524,11 @@
   return info.ToString(log_contents);
 }
 
+}  // namespace android
+
 bool LogUnreachableMemory(bool log_contents, size_t limit) {
-  UnreachableMemoryInfo info;
-  if (!GetUnreachableMemory(info, limit)) {
+  android::UnreachableMemoryInfo info;
+  if (!android::GetUnreachableMemory(info, limit)) {
     return false;
   }
 
@@ -523,10 +538,9 @@
   return true;
 }
 
-
 bool NoLeaks() {
-  UnreachableMemoryInfo info;
-  if (!GetUnreachableMemory(info, 0)) {
+  android::UnreachableMemoryInfo info;
+  if (!android::GetUnreachableMemory(info, 0)) {
     return false;
   }
 
diff --git a/libmemunreachable/ProcessMappings.cpp b/libmemunreachable/ProcessMappings.cpp
index 57b2321..9a06870 100644
--- a/libmemunreachable/ProcessMappings.cpp
+++ b/libmemunreachable/ProcessMappings.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <inttypes.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -25,6 +25,8 @@
 #include "ProcessMappings.h"
 #include "log.h"
 
+namespace android {
+
 // This function is not re-entrant since it uses a static buffer for
 // the line data.
 bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings) {
@@ -42,8 +44,8 @@
     int name_pos;
     char perms[5];
     Mapping mapping{};
-    if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %*x %*x:%*x %*d %n",
-        &mapping.begin, &mapping.end, perms, &name_pos) == 3) {
+    if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %*x %*x:%*x %*d %n", &mapping.begin,
+               &mapping.end, perms, &name_pos) == 3) {
       if (perms[0] == 'r') {
         mapping.read = true;
       }
@@ -64,3 +66,5 @@
   }
   return true;
 }
+
+}  // namespace android
diff --git a/libmemunreachable/ProcessMappings.h b/libmemunreachable/ProcessMappings.h
index d3b7496..a0e97e9 100644
--- a/libmemunreachable/ProcessMappings.h
+++ b/libmemunreachable/ProcessMappings.h
@@ -19,6 +19,8 @@
 
 #include "Allocator.h"
 
+namespace android {
+
 struct Mapping {
   uintptr_t begin;
   uintptr_t end;
@@ -33,4 +35,6 @@
 // the line data.
 bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings);
 
-#endif // LIBMEMUNREACHABLE_PROCESS_MAPPING_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_PROCESS_MAPPING_H_
diff --git a/libmemunreachable/PtracerThread.cpp b/libmemunreachable/PtracerThread.cpp
index 73b0493..aca2a82 100644
--- a/libmemunreachable/PtracerThread.cpp
+++ b/libmemunreachable/PtracerThread.cpp
@@ -23,17 +23,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <sys/mman.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 #include "android-base/macros.h"
 
+#include "PtracerThread.h"
 #include "anon_vma_naming.h"
 #include "log.h"
-#include "PtracerThread.h"
+
+namespace android {
 
 class Stack {
  public:
@@ -41,7 +43,7 @@
     int prot = PROT_READ | PROT_WRITE;
     int flags = MAP_PRIVATE | MAP_ANONYMOUS;
     page_size_ = sysconf(_SC_PAGE_SIZE);
-    size_ += page_size_*2; // guard pages
+    size_ += page_size_ * 2;  // guard pages
     base_ = mmap(NULL, size_, prot, flags, -1, 0);
     if (base_ == MAP_FAILED) {
       base_ = NULL;
@@ -52,22 +54,20 @@
     mprotect(base_, page_size_, PROT_NONE);
     mprotect(top(), page_size_, PROT_NONE);
   };
-  ~Stack() {
-    munmap(base_, size_);
-  };
+  ~Stack() { munmap(base_, size_); };
   void* top() {
     return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(base_) + size_ - page_size_);
   };
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Stack);
 
-  void *base_;
+  void* base_;
   size_t size_;
   size_t page_size_;
 };
 
-PtracerThread::PtracerThread(const std::function<int()>& func) :
-    child_pid_(0) {
+PtracerThread::PtracerThread(const std::function<int()>& func) : child_pid_(0) {
   stack_ = std::make_unique<Stack>(PTHREAD_STACK_MIN);
   if (stack_->top() == nullptr) {
     MEM_LOG_ALWAYS_FATAL("failed to mmap child stack: %s", strerror(errno));
@@ -93,14 +93,13 @@
   std::unique_lock<std::mutex> lk(m_);
 
   // Convert from void(*)(void*) to lambda with captures
-  auto proxy = [](void *arg) -> int {
+  auto proxy = [](void* arg) -> int {
     prctl(PR_SET_NAME, "libmemunreachable ptrace thread");
     return (*reinterpret_cast<std::function<int()>*>(arg))();
   };
 
-  child_pid_ = clone(proxy, stack_->top(),
-       CLONE_VM|CLONE_FS|CLONE_FILES/*|CLONE_UNTRACED*/,
-       reinterpret_cast<void*>(&func_));
+  child_pid_ = clone(proxy, stack_->top(), CLONE_VM | CLONE_FS | CLONE_FILES /*|CLONE_UNTRACED*/,
+                     reinterpret_cast<void*>(&func_));
   if (child_pid_ < 0) {
     MEM_ALOGE("failed to clone child: %s", strerror(errno));
     return false;
@@ -151,3 +150,5 @@
 void PtracerThread::ClearTracer() {
   prctl(PR_SET_PTRACER, 0);
 }
+
+}  // namespace android
diff --git a/libmemunreachable/PtracerThread.h b/libmemunreachable/PtracerThread.h
index f88b599..4f9c420 100644
--- a/libmemunreachable/PtracerThread.h
+++ b/libmemunreachable/PtracerThread.h
@@ -24,6 +24,8 @@
 
 #include "Allocator.h"
 
+namespace android {
+
 class Stack;
 
 // PtracerThread is similar to std::thread, except that it creates a "thread"
@@ -36,6 +38,7 @@
   ~PtracerThread();
   bool Start();
   int Join();
+
  private:
   void SetTracer(pid_t);
   void ClearTracer();
@@ -47,4 +50,6 @@
   pid_t child_pid_;
 };
 
-#endif // LIBMEMUNREACHABLE_PTRACER_THREAD_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_PTRACER_THREAD_H_
diff --git a/libmemunreachable/ScopedAlarm.h b/libmemunreachable/ScopedAlarm.h
index 287f479..bb50b9e 100644
--- a/libmemunreachable/ScopedAlarm.h
+++ b/libmemunreachable/ScopedAlarm.h
@@ -23,15 +23,15 @@
 #include <chrono>
 #include <functional>
 
+namespace android {
+
 class ScopedAlarm {
  public:
   ScopedAlarm(std::chrono::microseconds us, std::function<void()> func) {
     func_ = func;
-    struct sigaction oldact{};
-    struct sigaction act{};
-    act.sa_handler = [](int) {
-      ScopedAlarm::func_();
-    };
+    struct sigaction oldact {};
+    struct sigaction act {};
+    act.sa_handler = [](int) { ScopedAlarm::func_(); };
     sigaction(SIGALRM, &act, &oldact);
 
     std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(us);
@@ -43,11 +43,15 @@
   ~ScopedAlarm() {
     itimerval t = itimerval{};
     setitimer(ITIMER_REAL, &t, NULL);
-    struct sigaction act{};
+    struct sigaction act {};
     act.sa_handler = SIG_DFL;
     sigaction(SIGALRM, &act, NULL);
   }
+
  private:
   static std::function<void()> func_;
 };
+
+}  // namespace android
+
 #endif
diff --git a/libmemunreachable/ScopedDisableMalloc.h b/libmemunreachable/ScopedDisableMalloc.h
index 758d317..655e826 100644
--- a/libmemunreachable/ScopedDisableMalloc.h
+++ b/libmemunreachable/ScopedDisableMalloc.h
@@ -21,16 +21,16 @@
 
 #include "android-base/macros.h"
 
+#include "ScopedAlarm.h"
 #include "bionic.h"
 #include "log.h"
-#include "ScopedAlarm.h"
 
-class DisableMallocGuard{
+namespace android {
+
+class DisableMallocGuard {
  public:
-  DisableMallocGuard() : disabled_(false){}
-  ~DisableMallocGuard() {
-    Enable();
-  }
+  DisableMallocGuard() : disabled_(false) {}
+  ~DisableMallocGuard() { Enable(); }
 
   void Disable() {
     if (!disabled_) {
@@ -45,6 +45,7 @@
       disabled_ = false;
     }
   }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(DisableMallocGuard);
   bool disabled_;
@@ -59,13 +60,9 @@
 // here.
 class ScopedDisableMalloc {
  public:
-  ScopedDisableMalloc() {
-    disable_malloc_.Disable();
-  }
+  ScopedDisableMalloc() { disable_malloc_.Disable(); }
 
-  ~ScopedDisableMalloc() {
-    disable_malloc_.Enable();
-  }
+  ~ScopedDisableMalloc() { disable_malloc_.Enable(); }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ScopedDisableMalloc);
@@ -74,18 +71,15 @@
 
 class ScopedDisableMallocTimeout {
  public:
-  explicit ScopedDisableMallocTimeout(std::chrono::milliseconds timeout = std::chrono::milliseconds(2000)) :
-    timeout_(timeout), timed_out_(false), disable_malloc_() {
+  explicit ScopedDisableMallocTimeout(
+      std::chrono::milliseconds timeout = std::chrono::milliseconds(2000))
+      : timeout_(timeout), timed_out_(false), disable_malloc_() {
     Disable();
   }
 
-  ~ScopedDisableMallocTimeout() {
-    Enable();
-  }
+  ~ScopedDisableMallocTimeout() { Enable(); }
 
-  bool timed_out() {
-    return timed_out_;
-  }
+  bool timed_out() { return timed_out_; }
 
   void Enable() {
     disable_malloc_.Enable();
@@ -110,4 +104,6 @@
   DisableMallocGuard disable_malloc_;
 };
 
-#endif // LIBMEMUNREACHABLE_SCOPED_DISABLE_MALLOC_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_SCOPED_DISABLE_MALLOC_H_
diff --git a/libmemunreachable/ScopedPipe.h b/libmemunreachable/ScopedPipe.h
index 7f44953..adabfd8 100644
--- a/libmemunreachable/ScopedPipe.h
+++ b/libmemunreachable/ScopedPipe.h
@@ -21,6 +21,8 @@
 
 #include "log.h"
 
+namespace android {
+
 class ScopedPipe {
  public:
   ScopedPipe() : pipefd_{-1, -1} {
@@ -29,28 +31,22 @@
       MEM_LOG_ALWAYS_FATAL("failed to open pipe");
     }
   }
-  ~ScopedPipe() {
-    Close();
-  }
+  ~ScopedPipe() { Close(); }
 
   ScopedPipe(ScopedPipe&& other) {
     SetReceiver(other.ReleaseReceiver());
     SetSender(other.ReleaseSender());
   }
 
-  ScopedPipe& operator = (ScopedPipe&& other) {
+  ScopedPipe& operator=(ScopedPipe&& other) {
     SetReceiver(other.ReleaseReceiver());
     SetSender(other.ReleaseSender());
     return *this;
   }
 
-  void CloseReceiver() {
-    close(ReleaseReceiver());
-  }
+  void CloseReceiver() { close(ReleaseReceiver()); }
 
-  void CloseSender() {
-    close(ReleaseSender());
-  }
+  void CloseSender() { close(ReleaseSender()); }
 
   void Close() {
     CloseReceiver();
@@ -78,4 +74,7 @@
 
   int pipefd_[2];
 };
+
+}  // namespace android
+
 #endif
diff --git a/libmemunreachable/ScopedSignalHandler.h b/libmemunreachable/ScopedSignalHandler.h
index ada2ae4..ff53fad 100644
--- a/libmemunreachable/ScopedSignalHandler.h
+++ b/libmemunreachable/ScopedSignalHandler.h
@@ -26,18 +26,18 @@
 
 #include "log.h"
 
+namespace android {
+
 class ScopedSignalHandler {
  public:
   using Fn = std::function<void(ScopedSignalHandler&, int, siginfo_t*, void*)>;
 
   explicit ScopedSignalHandler(Allocator<Fn> allocator) : allocator_(allocator), signal_(-1) {}
-  ~ScopedSignalHandler() {
-    reset();
-  }
+  ~ScopedSignalHandler() { reset(); }
 
   template <class F>
   void install(int signal, F&& f) {
-    MEM_LOG_ALWAYS_FATAL_IF(signal_ != -1, "ScopedSignalHandler already installed");
+    if (signal_ != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed");
 
     handler_ = SignalFn(std::allocator_arg, allocator_,
                         [=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
@@ -65,7 +65,6 @@
     }
   }
 
-
  private:
   using SignalFn = std::function<void(int, siginfo_t*, void*)>;
   DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler);
@@ -77,4 +76,6 @@
   static SignalFn handler_;
 };
 
-#endif // LIBMEMUNREACHABLE_SCOPED_SIGNAL_HANDLER_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_SCOPED_SIGNAL_HANDLER_H_
diff --git a/libmemunreachable/Semaphore.h b/libmemunreachable/Semaphore.h
index 6bcf4ea..cd73972 100644
--- a/libmemunreachable/Semaphore.h
+++ b/libmemunreachable/Semaphore.h
@@ -22,6 +22,8 @@
 
 #include "android-base/macros.h"
 
+namespace android {
+
 class Semaphore {
  public:
   explicit Semaphore(int count = 0) : count_(count) {}
@@ -29,7 +31,7 @@
 
   void Wait(std::chrono::milliseconds ms) {
     std::unique_lock<std::mutex> lk(m_);
-    cv_.wait_for(lk, ms, [&]{
+    cv_.wait_for(lk, ms, [&] {
       if (count_ > 0) {
         count_--;
         return true;
@@ -44,6 +46,7 @@
     }
     cv_.notify_one();
   }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Semaphore);
 
@@ -52,5 +55,6 @@
   std::condition_variable cv_;
 };
 
+}  // namespace android
 
-#endif // LIBMEMUNREACHABLE_SEMAPHORE_H_
+#endif  // LIBMEMUNREACHABLE_SEMAPHORE_H_
diff --git a/libmemunreachable/Tarjan.h b/libmemunreachable/Tarjan.h
index 2546341..355679f 100644
--- a/libmemunreachable/Tarjan.h
+++ b/libmemunreachable/Tarjan.h
@@ -24,7 +24,9 @@
 
 #include "Allocator.h"
 
-template<class T>
+namespace android {
+
+template <class T>
 class Node {
  public:
   allocator::set<Node<T>*> references_in;
@@ -34,39 +36,41 @@
 
   T* ptr;
 
-  Node(T* ptr, Allocator<Node> allocator) : references_in(allocator), references_out(allocator),
-      ptr(ptr) {};
+  Node(T* ptr, Allocator<Node> allocator)
+      : references_in(allocator), references_out(allocator), ptr(ptr){};
   Node(Node&& rhs) = default;
   void Edge(Node<T>* ref) {
     references_out.emplace(ref);
     ref->references_in.emplace(this);
   }
-  template<class F>
+  template <class F>
   void Foreach(F&& f) {
-    for (auto& node: references_out) {
+    for (auto& node : references_out) {
       f(node->ptr);
     }
   }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Node<T>);
 };
 
-template<class T>
+template <class T>
 using Graph = allocator::vector<Node<T>*>;
 
-template<class T>
+template <class T>
 using SCC = allocator::vector<Node<T>*>;
 
-template<class T>
+template <class T>
 using SCCList = allocator::vector<SCC<T>>;
 
-template<class T>
+template <class T>
 class TarjanAlgorithm {
  public:
-  explicit TarjanAlgorithm(Allocator<void> allocator) : index_(0),
-    stack_(allocator), components_(allocator) {}
+  explicit TarjanAlgorithm(Allocator<void> allocator)
+      : index_(0), stack_(allocator), components_(allocator) {}
 
   void Execute(Graph<T>& graph, SCCList<T>& out);
+
  private:
   static constexpr size_t UNDEFINED_INDEX = static_cast<size_t>(-1);
   void Tarjan(Node<T>* vertex, Graph<T>& graph);
@@ -76,17 +80,17 @@
   SCCList<T> components_;
 };
 
-template<class T>
+template <class T>
 void TarjanAlgorithm<T>::Execute(Graph<T>& graph, SCCList<T>& out) {
   stack_.clear();
   components_.clear();
   index_ = 0;
-  for (auto& it: graph) {
+  for (auto& it : graph) {
     it->index = UNDEFINED_INDEX;
     it->lowlink = UNDEFINED_INDEX;
   }
 
-  for (auto& it: graph) {
+  for (auto& it : graph) {
     if (it->index == UNDEFINED_INDEX) {
       Tarjan(it, graph);
     }
@@ -94,14 +98,14 @@
   out.swap(components_);
 }
 
-template<class T>
+template <class T>
 void TarjanAlgorithm<T>::Tarjan(Node<T>* vertex, Graph<T>& graph) {
   assert(vertex->index == UNDEFINED_INDEX);
   vertex->index = index_;
   vertex->lowlink = index_;
   index_++;
   stack_.push_back(vertex);
-  for (auto& it: vertex->references_out) {
+  for (auto& it : vertex->references_out) {
     Node<T>* vertex_next = it;
     if (vertex_next->index == UNDEFINED_INDEX) {
       Tarjan(vertex_next, graph);
@@ -123,10 +127,12 @@
   }
 }
 
-template<class T>
+template <class T>
 void Tarjan(Graph<T>& graph, SCCList<T>& out) {
   TarjanAlgorithm<T> tarjan{graph.get_allocator()};
   tarjan.Execute(graph, out);
 }
 
-#endif // LIBMEMUNREACHABLE_TARJAN_H_
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_TARJAN_H_
diff --git a/libmemunreachable/ThreadCapture.cpp b/libmemunreachable/ThreadCapture.cpp
index 3891f2d..45eb55d 100644
--- a/libmemunreachable/ThreadCapture.cpp
+++ b/libmemunreachable/ThreadCapture.cpp
@@ -21,13 +21,13 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sys/ptrace.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 #include <map>
 #include <memory>
@@ -39,6 +39,8 @@
 #include "Allocator.h"
 #include "log.h"
 
+namespace android {
+
 // bionic interfaces used:
 // atoi
 // strlcat
@@ -50,12 +52,12 @@
 // Convert a pid > 0 to a string.  sprintf might allocate, so we can't use it.
 // Returns a pointer somewhere in buf to a null terminated string, or NULL
 // on error.
-static char *pid_to_str(char *buf, size_t len, pid_t pid) {
+static char* pid_to_str(char* buf, size_t len, pid_t pid) {
   if (pid <= 0) {
     return nullptr;
   }
 
-  char *ptr = buf + len - 1;
+  char* ptr = buf + len - 1;
   *ptr = 0;
   while (pid > 0) {
     ptr--;
@@ -79,6 +81,7 @@
   bool ReleaseThread(pid_t tid);
   bool CapturedThreadInfo(ThreadInfoList& threads);
   void InjectTestFunc(std::function<void(pid_t)>&& f) { inject_test_func_ = f; }
+
  private:
   int CaptureThread(pid_t tid);
   bool ReleaseThread(pid_t tid, unsigned int signal);
@@ -92,9 +95,8 @@
   std::function<void(pid_t)> inject_test_func_;
 };
 
-ThreadCaptureImpl::ThreadCaptureImpl(pid_t pid, Allocator<ThreadCaptureImpl>& allocator) :
-    captured_threads_(allocator), allocator_(allocator), pid_(pid) {
-}
+ThreadCaptureImpl::ThreadCaptureImpl(pid_t pid, Allocator<ThreadCaptureImpl>& allocator)
+    : captured_threads_(allocator), allocator_(allocator), pid_(pid) {}
 
 bool ThreadCaptureImpl::ListThreads(TidList& tids) {
   tids.clear();
@@ -115,11 +117,11 @@
   }
 
   struct linux_dirent64 {
-    uint64_t  d_ino;
-    int64_t   d_off;
-    uint16_t  d_reclen;
-    char      d_type;
-    char      d_name[];
+    uint64_t d_ino;
+    int64_t d_off;
+    uint16_t d_reclen;
+    char d_type;
+    char d_name[];
   } __attribute((packed));
   char dirent_buf[4096];
   ssize_t nread;
@@ -209,7 +211,7 @@
 bool ThreadCaptureImpl::PtraceThreadInfo(pid_t tid, ThreadInfo& thread_info) {
   thread_info.tid = tid;
 
-  const unsigned int max_num_regs = 128; // larger than number of registers on any device
+  const unsigned int max_num_regs = 128;  // larger than number of registers on any device
   uintptr_t regs[max_num_regs];
   struct iovec iovec;
   iovec.iov_base = &regs;
@@ -243,7 +245,7 @@
 
   thread_info.stack = std::pair<uintptr_t, uintptr_t>(regs[sp], 0);
 
-   return true;
+  return true;
 }
 
 int ThreadCaptureImpl::CaptureThread(pid_t tid) {
@@ -266,7 +268,7 @@
 
   unsigned int resume_signal = 0;
 
-  unsigned int signal =  WSTOPSIG(status);
+  unsigned int signal = WSTOPSIG(status);
   if ((status >> 16) == PTRACE_EVENT_STOP) {
     switch (signal) {
       case SIGSTOP:
@@ -307,7 +309,7 @@
 
 bool ThreadCaptureImpl::ReleaseThreads() {
   bool ret = true;
-  for (auto it = captured_threads_.begin(); it != captured_threads_.end(); ) {
+  for (auto it = captured_threads_.begin(); it != captured_threads_.end();) {
     if (ReleaseThread(it->first, it->second)) {
       it = captured_threads_.erase(it);
     } else {
@@ -361,3 +363,5 @@
 void ThreadCapture::InjectTestFunc(std::function<void(pid_t)>&& f) {
   impl_->InjectTestFunc(std::forward<std::function<void(pid_t)>>(f));
 }
+
+}  // namespace android
diff --git a/libmemunreachable/ThreadCapture.h b/libmemunreachable/ThreadCapture.h
index 1022cad..961cb60 100644
--- a/libmemunreachable/ThreadCapture.h
+++ b/libmemunreachable/ThreadCapture.h
@@ -21,6 +21,8 @@
 
 #include "Allocator.h"
 
+namespace android {
+
 struct ThreadInfo {
   pid_t tid;
   allocator::vector<uintptr_t> regs;
@@ -33,7 +35,7 @@
 class ThreadCaptureImpl;
 
 class ThreadCapture {
-public:
+ public:
   ThreadCapture(pid_t pid, Allocator<ThreadCapture> allocator);
   ~ThreadCapture();
 
@@ -44,11 +46,13 @@
   bool CapturedThreadInfo(ThreadInfoList& threads);
   void InjectTestFunc(std::function<void(pid_t)>&& f);
 
-private:
+ private:
   ThreadCapture(const ThreadCapture&) = delete;
   void operator=(const ThreadCapture&) = delete;
 
   Allocator<ThreadCaptureImpl>::unique_ptr impl_;
 };
 
+}  // namespace android
+
 #endif
diff --git a/libmemunreachable/anon_vma_naming.h b/libmemunreachable/anon_vma_naming.h
index 1e4ade1..fb31e41 100644
--- a/libmemunreachable/anon_vma_naming.h
+++ b/libmemunreachable/anon_vma_naming.h
@@ -19,7 +19,7 @@
 
 #include <sys/prctl.h>
 
-#define PR_SET_VMA            0x53564d41
-#define  PR_SET_VMA_ANON_NAME 0
+#define PR_SET_VMA 0x53564d41
+#define PR_SET_VMA_ANON_NAME 0
 
-#endif // LIBMEMUNREACHABLE_ANON_VMA_NAMING_H_
+#endif  // LIBMEMUNREACHABLE_ANON_VMA_NAMING_H_
diff --git a/libmemunreachable/bionic.h b/libmemunreachable/bionic.h
index 83d07a8..dd1ec79 100644
--- a/libmemunreachable/bionic.h
+++ b/libmemunreachable/bionic.h
@@ -17,9 +17,9 @@
 #ifndef LIBMEMUNREACHABLE_BIONIC_H_
 #define LIBMEMUNREACHABLE_BIONIC_H_
 
-#include <sys/cdefs.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <sys/cdefs.h>
 
 __BEGIN_DECLS
 
@@ -27,9 +27,9 @@
 extern void malloc_disable();
 extern void malloc_enable();
 extern int malloc_iterate(uintptr_t base, size_t size,
-    void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
+                          void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
 extern ssize_t malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count);
 
 __END_DECLS
 
-#endif // LIBMEMUNREACHABLE_BIONIC_H_
+#endif  // LIBMEMUNREACHABLE_BIONIC_H_
diff --git a/libmemunreachable/include/memunreachable/memunreachable.h b/libmemunreachable/include/memunreachable/memunreachable.h
index 9b227fd..438fcaf 100644
--- a/libmemunreachable/include/memunreachable/memunreachable.h
+++ b/libmemunreachable/include/memunreachable/memunreachable.h
@@ -17,12 +17,15 @@
 #ifndef LIBMEMUNREACHABLE_MEMUNREACHABLE_H_
 #define LIBMEMUNREACHABLE_MEMUNREACHABLE_H_
 
+#include <string.h>
 #include <sys/cdefs.h>
 
 #ifdef __cplusplus
 
-#include <vector>
 #include <string>
+#include <vector>
+
+namespace android {
 
 struct Leak {
   uintptr_t begin;
@@ -73,6 +76,8 @@
 
 std::string GetUnreachableMemoryString(bool log_contents = false, size_t limit = 100);
 
+}  // namespace android
+
 #endif
 
 __BEGIN_DECLS
@@ -83,4 +88,4 @@
 
 __END_DECLS
 
-#endif // LIBMEMUNREACHABLE_MEMUNREACHABLE_H_
+#endif  // LIBMEMUNREACHABLE_MEMUNREACHABLE_H_
diff --git a/libmemunreachable/log.h b/libmemunreachable/log.h
index 1725c53..44c5f85 100644
--- a/libmemunreachable/log.h
+++ b/libmemunreachable/log.h
@@ -26,13 +26,21 @@
 #define MEM_ALOGE(...) async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, ##__VA_ARGS__)
 #define MEM_ALOGW(...) async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, ##__VA_ARGS__)
 #define MEM_ALOGI(...) async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG, ##__VA_ARGS__)
-#define MEM_ALOGV(...) async_safe_format_log(ANDROID_LOG_VERBOSE, LOG_TAG, ##__VA_ARGS__)
+#define MEM_ALOGV_IMPL(...) async_safe_format_log(ANDROID_LOG_VERBOSE, LOG_TAG, ##__VA_ARGS__)
+
+#ifdef NDEBUG
+#define MEM_ALOGV(...)             \
+  do {                             \
+    if (0) {                       \
+      MEM_ALOGV_IMPL(__VA_ARGS__); \
+    }                              \
+  } while (0)
+#else
+#define MEM_ALOGV(...) MEM_ALOGV_IMPL(__VA_ARGS__)
+#endif
 
 #define MEM_LOG_ALWAYS_FATAL(...) async_safe_fatal(__VA_ARGS__)
 
-#define MEM_LOG_ALWAYS_FATAL_IF(cond, ...) \
-  ((__predict_false(cond)) ? async_safe_fatal(__VA_ARGS__) : (void)0)
-
 #else
 
 #include <log/log.h>
@@ -43,8 +51,7 @@
 #define MEM_ALOGI ALOGI
 
 #define MEM_LOG_ALWAYS_FATAL LOG_ALWAYS_FATAL
-#define MEM_LOG_ALWAYS_FATAL_IF LOG_ALWAYS_FATAL_IF
 
 #endif
 
-#endif // LIBMEMUNREACHABLE_LOG_H_
+#endif  // LIBMEMUNREACHABLE_LOG_H_
diff --git a/libmemunreachable/tests/Allocator_test.cpp b/libmemunreachable/tests/Allocator_test.cpp
index 21c8218..8991a7b 100644
--- a/libmemunreachable/tests/Allocator_test.cpp
+++ b/libmemunreachable/tests/Allocator_test.cpp
@@ -16,44 +16,44 @@
 
 #include <Allocator.h>
 
-#include <gtest/gtest.h>
 #include <ScopedDisableMalloc.h>
+#include <gtest/gtest.h>
 
+namespace android {
 
 std::function<void()> ScopedAlarm::func_;
 
 class AllocatorTest : public testing::Test {
  protected:
   AllocatorTest() : heap(), disable_malloc_() {}
-  virtual void SetUp() {
-    heap_count = 0;
-  }
+  virtual void SetUp() { heap_count = 0; }
   virtual void TearDown() {
     ASSERT_EQ(heap_count, 0);
     ASSERT_TRUE(heap.empty());
     ASSERT_FALSE(disable_malloc_.timed_out());
   }
   Heap heap;
+
  private:
   ScopedDisableMallocTimeout disable_malloc_;
 };
 
 TEST_F(AllocatorTest, simple) {
   Allocator<char[100]> allocator(heap);
-  void *ptr = allocator.allocate();
+  void* ptr = allocator.allocate();
   ASSERT_TRUE(ptr != NULL);
   allocator.deallocate(ptr);
 }
 
 TEST_F(AllocatorTest, multiple) {
   Allocator<char[100]> allocator(heap);
-  void *ptr1 = allocator.allocate();
+  void* ptr1 = allocator.allocate();
   ASSERT_TRUE(ptr1 != NULL);
-  void *ptr2 = allocator.allocate();
+  void* ptr2 = allocator.allocate();
   ASSERT_TRUE(ptr2 != NULL);
   ASSERT_NE(ptr1, ptr2);
   allocator.deallocate(ptr1);
-  void *ptr3 = allocator.allocate();
+  void* ptr3 = allocator.allocate();
   ASSERT_EQ(ptr1, ptr3);
   allocator.deallocate(ptr3);
   allocator.deallocate(ptr2);
@@ -63,7 +63,7 @@
   const int num = 4096;
   const int size = 128;
   Allocator<char[size]> allocator(heap);
-  void *ptr[num];
+  void* ptr[num];
   for (int i = 0; i < num; i++) {
     ptr[i] = allocator.allocate();
     memset(ptr[i], 0xaa, size);
@@ -87,7 +87,7 @@
 TEST_F(AllocatorTest, large) {
   const size_t size = 1024 * 1024;
   Allocator<char[size]> allocator(heap);
-  void *ptr = allocator.allocate();
+  void* ptr = allocator.allocate();
   memset(ptr, 0xaa, size);
   allocator.deallocate(ptr);
 }
@@ -96,7 +96,7 @@
   const int num = 128;
   const int size = 1024 * 1024;
   Allocator<char[size]> allocator(heap);
-  void *ptr[num];
+  void* ptr[num];
   for (int i = 0; i < num; i++) {
     ptr[i] = allocator.allocate();
     memset(ptr[i], 0xaa, size);
@@ -172,3 +172,5 @@
 
   ASSERT_NE(ptr, nullptr);
 }
+
+}  // namespace android
diff --git a/libmemunreachable/tests/AndroidTest.xml b/libmemunreachable/tests/AndroidTest.xml
new file mode 100644
index 0000000..604c0ec
--- /dev/null
+++ b/libmemunreachable/tests/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for memunreachable_test">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="memunreachable_test->/data/local/tmp/memunreachable_test" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="memunreachable_test" />
+    </test>
+</configuration>
diff --git a/libmemunreachable/tests/Binder_test.cpp b/libmemunreachable/tests/Binder_test.cpp
new file mode 100644
index 0000000..6e85d5a
--- /dev/null
+++ b/libmemunreachable/tests/Binder_test.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <binder/Binder.h>
+#include <binder/IBinder.h>
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/ProcessState.h>
+
+#include <gtest/gtest.h>
+
+#include "Allocator.h"
+#include "Binder.h"
+
+namespace android {
+
+static const String16 service_name("test.libmemunreachable_binder");
+
+class BinderService : public BBinder {
+ public:
+  BinderService() = default;
+  virtual ~BinderService() = default;
+
+  virtual status_t onTransact(uint32_t /*code*/, const Parcel& data, Parcel* reply,
+                              uint32_t /*flags*/ = 0) {
+    reply->writeStrongBinder(ref);
+    ref = data.readStrongBinder();
+    return 0;
+  }
+
+ private:
+  sp<IBinder> ref;
+};
+
+class BinderObject : public BBinder {
+ public:
+  BinderObject() = default;
+  ~BinderObject() = default;
+};
+
+class ServiceProcess {
+ public:
+  ServiceProcess() : child_(0) {}
+  ~ServiceProcess() { Stop(); }
+
+  bool Run() {
+    pid_t ret = fork();
+    if (ret < 0) {
+      return false;
+    } else if (ret == 0) {
+      // child
+      _exit(Service());
+    } else {
+      // parent
+      child_ = ret;
+      return true;
+    }
+  }
+
+  bool Stop() {
+    if (child_ > 0) {
+      if (kill(child_, SIGTERM)) {
+        return false;
+      }
+      int status = 0;
+      if (TEMP_FAILURE_RETRY(waitpid(child_, &status, 0)) != child_) {
+        return false;
+      }
+      child_ = 0;
+      return WIFEXITED(status) && WEXITSTATUS(status) == 0;
+    }
+
+    return true;
+  }
+
+  int Service() {
+    sp<ProcessState> proc{ProcessState::self()};
+    sp<IServiceManager> sm = defaultServiceManager();
+    if (sm == nullptr) {
+      fprintf(stderr, "Failed to get service manager\n");
+      return 1;
+    }
+    if (sm->addService(service_name, new BinderService()) != OK) {
+      fprintf(stderr, "Failed to add test service\n");
+      return 1;
+    }
+    proc->startThreadPool();
+    pause();
+    return 0;
+  }
+
+ private:
+  pid_t child_;
+};
+
+class BinderTest : public ::testing::Test {
+ protected:
+  ServiceProcess service_process_;
+};
+
+TEST_F(BinderTest, binder) {
+  ServiceProcess service_process;
+  ASSERT_TRUE(service_process.Run());
+
+  sp<IServiceManager> sm = defaultServiceManager();
+  ASSERT_TRUE(sm != nullptr);
+
+  // A small sleep allows the service to start, which
+  // prevents a longer sleep in getService.
+  usleep(100000);
+
+  sp<IBinder> service = sm->getService(service_name);
+  ASSERT_TRUE(service != nullptr);
+
+  sp<IBinder> binder{new BinderObject()};
+
+  Parcel send;
+  Parcel reply;
+
+  send.writeStrongBinder(binder);
+  status_t rv = service->transact(0, send, &reply);
+  ASSERT_EQ(static_cast<status_t>(OK), rv);
+
+  Heap heap;
+  allocator::vector<uintptr_t> refs{heap};
+
+  ASSERT_TRUE(BinderReferences(refs));
+
+  bool found_ref = false;
+  for (auto ref : refs) {
+    if (ref == reinterpret_cast<uintptr_t>(binder.get())) {
+      found_ref = true;
+    }
+  }
+
+  ASSERT_TRUE(found_ref);
+}
+
+}  // namespace android
diff --git a/libmemunreachable/tests/DisableMalloc_test.cpp b/libmemunreachable/tests/DisableMalloc_test.cpp
index 4e6155b..c630049 100644
--- a/libmemunreachable/tests/DisableMalloc_test.cpp
+++ b/libmemunreachable/tests/DisableMalloc_test.cpp
@@ -19,11 +19,13 @@
 #include <chrono>
 #include <functional>
 
-#include <gtest/gtest.h>
 #include <ScopedDisableMalloc.h>
+#include <gtest/gtest.h>
 
 using namespace std::chrono_literals;
 
+namespace android {
+
 class DisableMallocTest : public ::testing::Test {
  protected:
   void alarm(std::chrono::microseconds us) {
@@ -36,75 +38,83 @@
 };
 
 TEST_F(DisableMallocTest, reenable) {
-  ASSERT_EXIT({
-    alarm(100ms);
-    void *ptr1 = malloc(128);
-    ASSERT_NE(ptr1, nullptr);
-    free(ptr1);
-    {
-      ScopedDisableMalloc disable_malloc;
-    }
-    void *ptr2 = malloc(128);
-    ASSERT_NE(ptr2, nullptr);
-    free(ptr2);
-    _exit(1);
-  }, ::testing::ExitedWithCode(1), "");
+  ASSERT_EXIT(
+      {
+        alarm(100ms);
+        void* ptr1 = malloc(128);
+        ASSERT_NE(ptr1, nullptr);
+        free(ptr1);
+        { ScopedDisableMalloc disable_malloc; }
+        void* ptr2 = malloc(128);
+        ASSERT_NE(ptr2, nullptr);
+        free(ptr2);
+        _exit(1);
+      },
+      ::testing::ExitedWithCode(1), "");
 }
 
 TEST_F(DisableMallocTest, deadlock_allocate) {
-  ASSERT_DEATH({
-    void *ptr = malloc(128);
-    ASSERT_NE(ptr, nullptr);
-    free(ptr);
-    {
-      alarm(100ms);
-      ScopedDisableMalloc disable_malloc;
-      void* ptr = malloc(128);
-      ASSERT_NE(ptr, nullptr);
-      free(ptr);
-    }
-  }, "");
+  ASSERT_DEATH(
+      {
+        void* ptr = malloc(128);
+        ASSERT_NE(ptr, nullptr);
+        free(ptr);
+        {
+          alarm(100ms);
+          ScopedDisableMalloc disable_malloc;
+          void* ptr = malloc(128);
+          ASSERT_NE(ptr, nullptr);
+          free(ptr);
+        }
+      },
+      "");
 }
 
 TEST_F(DisableMallocTest, deadlock_new) {
-  ASSERT_DEATH({
-    char* ptr = new(char);
-    ASSERT_NE(ptr, nullptr);
-    delete(ptr);
-    {
-      alarm(100ms);
-      ScopedDisableMalloc disable_malloc;
-      char* ptr = new (std::nothrow)(char);
-      ASSERT_NE(ptr, nullptr);
-      delete(ptr);
-    }
-  }, "");
+  ASSERT_DEATH(
+      {
+        char* ptr = new (char);
+        ASSERT_NE(ptr, nullptr);
+        delete (ptr);
+        {
+          alarm(100ms);
+          ScopedDisableMalloc disable_malloc;
+          char* ptr = new (std::nothrow)(char);
+          ASSERT_NE(ptr, nullptr);
+          delete (ptr);
+        }
+      },
+      "");
 }
 
 TEST_F(DisableMallocTest, deadlock_delete) {
-  ASSERT_DEATH({
-    char* ptr = new(char);
-    ASSERT_NE(ptr, nullptr);
-    {
-      alarm(250ms);
-      ScopedDisableMalloc disable_malloc;
-      delete(ptr);
-      // Force ptr usage or this code gets optimized away by the arm64 compiler.
-      ASSERT_NE(ptr, nullptr);
-    }
-  }, "");
+  ASSERT_DEATH(
+      {
+        char* ptr = new (char);
+        ASSERT_NE(ptr, nullptr);
+        {
+          alarm(250ms);
+          ScopedDisableMalloc disable_malloc;
+          delete (ptr);
+          // Force ptr usage or this code gets optimized away by the arm64 compiler.
+          ASSERT_NE(ptr, nullptr);
+        }
+      },
+      "");
 }
 
 TEST_F(DisableMallocTest, deadlock_free) {
-  ASSERT_DEATH({
-    void *ptr = malloc(128);
-    ASSERT_NE(ptr, nullptr);
-    {
-      alarm(100ms);
-      ScopedDisableMalloc disable_malloc;
-      free(ptr);
-    }
-  }, "");
+  ASSERT_DEATH(
+      {
+        void* ptr = malloc(128);
+        ASSERT_NE(ptr, nullptr);
+        {
+          alarm(100ms);
+          ScopedDisableMalloc disable_malloc;
+          free(ptr);
+        }
+      },
+      "");
 }
 
 TEST_F(DisableMallocTest, deadlock_fork) {
@@ -113,6 +123,8 @@
       alarm(100ms);
       ScopedDisableMalloc disable_malloc;
       fork();
-    }
-  }, "");
 }
+}, "");
+}
+
+}  // namespace android
diff --git a/libmemunreachable/tests/HeapWalker_test.cpp b/libmemunreachable/tests/HeapWalker_test.cpp
index 98e4aa1..84a0ec6 100644
--- a/libmemunreachable/tests/HeapWalker_test.cpp
+++ b/libmemunreachable/tests/HeapWalker_test.cpp
@@ -19,10 +19,12 @@
 
 #include "HeapWalker.h"
 
-#include <gtest/gtest.h>
 #include <ScopedDisableMalloc.h>
+#include <gtest/gtest.h>
 #include "Allocator.h"
 
+namespace android {
+
 class HeapWalkerTest : public ::testing::Test {
  public:
   HeapWalkerTest() : disable_malloc_(), heap_() {}
@@ -172,20 +174,20 @@
   ASSERT_EQ(true, heap_walker.Leaked(leaked, 100, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(2U, num_leaks);
-  EXPECT_EQ(2*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(2 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(2U, leaked.size());
 }
 
 TEST_F(HeapWalkerTest, segv) {
   const size_t page_size = sysconf(_SC_PAGE_SIZE);
-  void* buffer1 = mmap(NULL, page_size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+  void* buffer1 = mmap(NULL, page_size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   ASSERT_NE(buffer1, nullptr);
   void* buffer2;
 
   buffer2 = &buffer1;
 
   HeapWalker heap_walker(heap_);
-  heap_walker.Allocation(buffer_begin(buffer1), buffer_begin(buffer1)+page_size);
+  heap_walker.Allocation(buffer_begin(buffer1), buffer_begin(buffer1) + page_size);
   heap_walker.Root(buffer_begin(buffer2), buffer_end(buffer2));
 
   ASSERT_EQ(true, heap_walker.DetectLeaks());
@@ -199,3 +201,5 @@
   EXPECT_EQ(0U, leaked_bytes);
   ASSERT_EQ(0U, leaked.size());
 }
+
+}  // namespace android
diff --git a/libmemunreachable/tests/HostMallocStub.cpp b/libmemunreachable/tests/HostMallocStub.cpp
index a7e3f07..0ef0487 100644
--- a/libmemunreachable/tests/HostMallocStub.cpp
+++ b/libmemunreachable/tests/HostMallocStub.cpp
@@ -16,8 +16,6 @@
 
 #include "bionic.h"
 
-void malloc_disable() {
-}
+void malloc_disable() {}
 
-void malloc_enable() {
-}
+void malloc_enable() {}
diff --git a/libmemunreachable/tests/LeakFolding_test.cpp b/libmemunreachable/tests/LeakFolding_test.cpp
index e85df5f..f5b3631 100644
--- a/libmemunreachable/tests/LeakFolding_test.cpp
+++ b/libmemunreachable/tests/LeakFolding_test.cpp
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-#include "HeapWalker.h"
 #include "LeakFolding.h"
+#include "HeapWalker.h"
 
-#include <gtest/gtest.h>
 #include <ScopedDisableMalloc.h>
+#include <gtest/gtest.h>
 #include "Allocator.h"
 
+namespace android {
+
 class LeakFoldingTest : public ::testing::Test {
  public:
   LeakFoldingTest() : disable_malloc_(), heap_() {}
@@ -84,7 +86,7 @@
   ASSERT_EQ(true, folding.Leaked(leaked, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(2U, num_leaks);
-  EXPECT_EQ(2*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(2 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(2U, leaked.size());
   EXPECT_EQ(0U, leaked[0].referenced_count);
   EXPECT_EQ(0U, leaked[0].referenced_size);
@@ -113,7 +115,7 @@
   ASSERT_EQ(true, folding.Leaked(leaked, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(2U, num_leaks);
-  EXPECT_EQ(2*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(2 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(1U, leaked.size());
   EXPECT_EQ(1U, leaked[0].referenced_count);
   EXPECT_EQ(sizeof(uintptr_t), leaked[0].referenced_size);
@@ -144,10 +146,10 @@
   ASSERT_EQ(true, folding.Leaked(leaked, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(3U, num_leaks);
-  EXPECT_EQ(3*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(3 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(1U, leaked.size());
   EXPECT_EQ(2U, leaked[0].referenced_count);
-  EXPECT_EQ(2*sizeof(uintptr_t), leaked[0].referenced_size);
+  EXPECT_EQ(2 * sizeof(uintptr_t), leaked[0].referenced_size);
 }
 
 TEST_F(LeakFoldingTest, dominator_cycle) {
@@ -175,13 +177,13 @@
   ASSERT_EQ(true, folding.Leaked(leaked, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(3U, num_leaks);
-  EXPECT_EQ(5*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(5 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(2U, leaked.size());
 
   EXPECT_EQ(2U, leaked[0].referenced_count);
-  EXPECT_EQ(3*sizeof(uintptr_t), leaked[0].referenced_size);
+  EXPECT_EQ(3 * sizeof(uintptr_t), leaked[0].referenced_size);
   EXPECT_EQ(2U, leaked[1].referenced_count);
-  EXPECT_EQ(3*sizeof(uintptr_t), leaked[1].referenced_size);
+  EXPECT_EQ(3 * sizeof(uintptr_t), leaked[1].referenced_size);
 }
 
 TEST_F(LeakFoldingTest, two_cycles) {
@@ -218,12 +220,12 @@
   ASSERT_EQ(true, folding.Leaked(leaked, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(6U, num_leaks);
-  EXPECT_EQ(6*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(6 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(2U, leaked.size());
   EXPECT_EQ(2U, leaked[0].referenced_count);
-  EXPECT_EQ(2*sizeof(uintptr_t), leaked[0].referenced_size);
+  EXPECT_EQ(2 * sizeof(uintptr_t), leaked[0].referenced_size);
   EXPECT_EQ(2U, leaked[1].referenced_count);
-  EXPECT_EQ(2*sizeof(uintptr_t), leaked[1].referenced_size);
+  EXPECT_EQ(2 * sizeof(uintptr_t), leaked[1].referenced_size);
 }
 
 TEST_F(LeakFoldingTest, two_dominator_cycles) {
@@ -254,7 +256,7 @@
   ASSERT_EQ(true, folding.Leaked(leaked, &num_leaks, &leaked_bytes));
 
   EXPECT_EQ(4U, num_leaks);
-  EXPECT_EQ(4*sizeof(uintptr_t), leaked_bytes);
+  EXPECT_EQ(4 * sizeof(uintptr_t), leaked_bytes);
   ASSERT_EQ(4U, leaked.size());
   EXPECT_EQ(1U, leaked[0].referenced_count);
   EXPECT_EQ(sizeof(uintptr_t), leaked[0].referenced_size);
@@ -272,13 +274,13 @@
 
   HeapWalker heap_walker(heap_);
 
-  for (size_t i = 0; i < n; i ++) {
+  for (size_t i = 0; i < n; i++) {
     ASSERT_TRUE(heap_walker.Allocation(reinterpret_cast<uintptr_t>(&buffer[i]),
-        reinterpret_cast<uintptr_t>(&buffer[i+1])));
+                                       reinterpret_cast<uintptr_t>(&buffer[i + 1])));
   }
 
   for (size_t i = 0; i < n - 1; i++) {
-    buffer[i] = &buffer[i+1];
+    buffer[i] = &buffer[i + 1];
   }
   buffer[n - 1] = &buffer[0];
 
@@ -306,15 +308,15 @@
   HeapWalker heap_walker(heap_);
 
   for (size_t i = 0; i < n - 1; i++) {
-    buffer[i] = &buffer[i+1];
+    buffer[i] = &buffer[i + 1];
   }
   buffer[n - 1] = &buffer[0];
 
   buffer1[0] = &buffer[0];
 
-  for (size_t i = 0; i < n; i ++) {
+  for (size_t i = 0; i < n; i++) {
     ASSERT_TRUE(heap_walker.Allocation(reinterpret_cast<uintptr_t>(&buffer[i]),
-        reinterpret_cast<uintptr_t>(&buffer[i+1])));
+                                       reinterpret_cast<uintptr_t>(&buffer[i + 1])));
   }
 
   ALLOCATION(heap_walker, buffer1);
@@ -425,3 +427,5 @@
   EXPECT_EQ(3U, leaked[3].referenced_count);
   EXPECT_EQ(6 * sizeof(uintptr_t), leaked[3].referenced_size);
 }
+
+}  // namespace android
diff --git a/libmemunreachable/tests/MemUnreachable_test.cpp b/libmemunreachable/tests/MemUnreachable_test.cpp
index 71da365..ec89388 100644
--- a/libmemunreachable/tests/MemUnreachable_test.cpp
+++ b/libmemunreachable/tests/MemUnreachable_test.cpp
@@ -16,36 +16,32 @@
 
 #include <fcntl.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sys/prctl.h>
+#include <unistd.h>
 
 #include <gtest/gtest.h>
 
 #include <memunreachable/memunreachable.h>
 
+namespace android {
+
 class HiddenPointer {
  public:
-  explicit HiddenPointer(size_t size = 256) {
-    Set(malloc(size));
-  }
-  ~HiddenPointer() {
-    Free();
-  }
-  void* Get() {
-    return reinterpret_cast<void*>(~ptr_);
-  }
+  explicit HiddenPointer(size_t size = 256) { Set(malloc(size)); }
+  ~HiddenPointer() { Free(); }
+  void* Get() { return reinterpret_cast<void*>(~ptr_); }
   void Free() {
     free(Get());
     Set(nullptr);
   }
+
  private:
-  void Set(void* ptr) {
-    ptr_ = ~reinterpret_cast<uintptr_t>(ptr);
-  }
+  void Set(void* ptr) { ptr_ = ~reinterpret_cast<uintptr_t>(ptr); }
   volatile uintptr_t ptr_;
 };
 
-static void Ref(void* ptr) {
+// Trick the compiler into thinking a value on the stack is still referenced.
+static void Ref(void** ptr) {
   write(0, ptr, 0);
 }
 
@@ -63,14 +59,14 @@
 
   {
     void* ptr = hidden_ptr.Get();
-    Ref(ptr);
+    Ref(&ptr);
 
     UnreachableMemoryInfo info;
 
     ASSERT_TRUE(GetUnreachableMemory(info));
     ASSERT_EQ(0U, info.leaks.size());
 
-    Ref(ptr);
+    ptr = nullptr;
   }
 
   {
@@ -216,3 +212,5 @@
 
   ASSERT_TRUE(LogUnreachableMemory(true, 100));
 }
+
+}  // namespace android
diff --git a/libmemunreachable/tests/ThreadCapture_test.cpp b/libmemunreachable/tests/ThreadCapture_test.cpp
index 44aabd7..4fbf729 100644
--- a/libmemunreachable/tests/ThreadCapture_test.cpp
+++ b/libmemunreachable/tests/ThreadCapture_test.cpp
@@ -34,6 +34,8 @@
 
 using namespace std::chrono_literals;
 
+namespace android {
+
 class ThreadListTest : public ::testing::TestWithParam<int> {
  public:
   ThreadListTest() : stop_(false) {}
@@ -45,12 +47,10 @@
     WaitForThreads();
   }
 
-  virtual void TearDown() {
-    ASSERT_TRUE(heap.empty());
-  }
+  virtual void TearDown() { ASSERT_TRUE(heap.empty()); }
 
  protected:
-  template<class Function>
+  template <class Function>
   void StartThreads(unsigned int threads, Function&& func) {
     threads_.reserve(threads);
     tids_.reserve(threads);
@@ -68,14 +68,14 @@
 
         {
           std::unique_lock<std::mutex> lk(m_);
-          cv_stop_.wait(lk, [&] {return stop_;});
+          cv_stop_.wait(lk, [&] { return stop_; });
         }
       });
     }
 
     {
       std::unique_lock<std::mutex> lk(m_);
-      cv_start_.wait(lk, [&]{ return tids_.size() == threads; });
+      cv_start_.wait(lk, [&] { return tids_.size() == threads; });
     }
   }
 
@@ -93,9 +93,7 @@
     tids_.clear();
   }
 
-  std::vector<pid_t>& tids() {
-    return tids_;
-  }
+  std::vector<pid_t>& tids() { return tids_; }
 
   Heap heap;
 
@@ -143,7 +141,7 @@
 TEST_P(ThreadListTest, list_some) {
   const unsigned int threads = GetParam() - 1;
 
-  StartThreads(threads, [](){});
+  StartThreads(threads, []() {});
   std::vector<pid_t> expected_tids = tids();
   expected_tids.push_back(getpid());
 
@@ -176,10 +174,8 @@
  public:
   ThreadCaptureTest() {}
   ~ThreadCaptureTest() {}
-  void Fork(std::function<void()>&& child_init,
-      std::function<void()>&& child_cleanup,
-      std::function<void(pid_t)>&& parent) {
-
+  void Fork(std::function<void()>&& child_init, std::function<void()>&& child_cleanup,
+            std::function<void(pid_t)>&& parent) {
     ScopedPipe start_pipe;
     ScopedPipe stop_pipe;
 
@@ -211,39 +207,40 @@
 TEST_P(ThreadCaptureTest, capture_some) {
   const unsigned int threads = GetParam();
 
-  Fork([&](){
-    // child init
-    StartThreads(threads - 1, [](){});
-  },
-  [&](){
-    // child cleanup
-    StopThreads();
-  },
-  [&](pid_t child){
-    // parent
-    ASSERT_GT(child, 0);
+  Fork(
+      [&]() {
+        // child init
+        StartThreads(threads - 1, []() {});
+      },
+      [&]() {
+        // child cleanup
+        StopThreads();
+      },
+      [&](pid_t child) {
+        // parent
+        ASSERT_GT(child, 0);
 
-    {
-      ScopedDisableMallocTimeout disable_malloc;
+        {
+          ScopedDisableMallocTimeout disable_malloc;
 
-      ThreadCapture thread_capture(child, heap);
-      auto list_tids = allocator::vector<pid_t>(heap);
+          ThreadCapture thread_capture(child, heap);
+          auto list_tids = allocator::vector<pid_t>(heap);
 
-      ASSERT_TRUE(thread_capture.ListThreads(list_tids));
-      ASSERT_EQ(threads, list_tids.size());
+          ASSERT_TRUE(thread_capture.ListThreads(list_tids));
+          ASSERT_EQ(threads, list_tids.size());
 
-      ASSERT_TRUE(thread_capture.CaptureThreads());
+          ASSERT_TRUE(thread_capture.CaptureThreads());
 
-      auto thread_info = allocator::vector<ThreadInfo>(heap);
-      ASSERT_TRUE(thread_capture.CapturedThreadInfo(thread_info));
-      ASSERT_EQ(threads, thread_info.size());
-      ASSERT_TRUE(thread_capture.ReleaseThreads());
+          auto thread_info = allocator::vector<ThreadInfo>(heap);
+          ASSERT_TRUE(thread_capture.CapturedThreadInfo(thread_info));
+          ASSERT_EQ(threads, thread_info.size());
+          ASSERT_TRUE(thread_capture.ReleaseThreads());
 
-      if (!HasFailure()) {
-        ASSERT_FALSE(disable_malloc.timed_out());
-      }
-}
-  });
+          if (!HasFailure()) {
+            ASSERT_FALSE(disable_malloc.timed_out());
+          }
+        }
+      });
 }
 
 INSTANTIATE_TEST_CASE_P(ThreadCaptureTest, ThreadCaptureTest, ::testing::Values(1, 2, 10, 1024));
@@ -262,7 +259,7 @@
       ScopedDisableMallocTimeout disable_malloc;
 
       ThreadCapture thread_capture(ret, heap);
-      thread_capture.InjectTestFunc([&](pid_t tid){
+      thread_capture.InjectTestFunc([&](pid_t tid) {
         syscall(SYS_tgkill, ret, tid, SIGKILL);
         usleep(10000);
       });
@@ -288,62 +285,65 @@
   // For signal handler
   static ScopedPipe* g_pipe;
 
-  Fork([&](){
-    // child init
-    pipe.CloseReceiver();
+  Fork(
+      [&]() {
+        // child init
+        pipe.CloseReceiver();
 
-    g_pipe = &pipe;
+        g_pipe = &pipe;
 
-    struct sigaction act{};
-    act.sa_handler = [](int){
-      char buf = '+';
-      write(g_pipe->Sender(), &buf, 1);
-      g_pipe->CloseSender();
-    };
-    sigaction(sig, &act, NULL);
-    sigset_t set;
-    sigemptyset(&set);
-    sigaddset(&set, sig);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-  },
-  [&](){
-    // child cleanup
-    g_pipe = nullptr;
-    pipe.Close();
-  },
-  [&](pid_t child){
-    // parent
-    ASSERT_GT(child, 0);
-    pipe.CloseSender();
+        struct sigaction act {};
+        act.sa_handler = [](int) {
+          char buf = '+';
+          write(g_pipe->Sender(), &buf, 1);
+          g_pipe->CloseSender();
+        };
+        sigaction(sig, &act, NULL);
+        sigset_t set;
+        sigemptyset(&set);
+        sigaddset(&set, sig);
+        pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+      },
+      [&]() {
+        // child cleanup
+        g_pipe = nullptr;
+        pipe.Close();
+      },
+      [&](pid_t child) {
+        // parent
+        ASSERT_GT(child, 0);
+        pipe.CloseSender();
 
-    {
-      ScopedDisableMallocTimeout disable_malloc;
+        {
+          ScopedDisableMallocTimeout disable_malloc;
 
-      ThreadCapture thread_capture(child, heap);
-      thread_capture.InjectTestFunc([&](pid_t tid){
-        syscall(SYS_tgkill, child, tid, sig);
-        usleep(10000);
+          ThreadCapture thread_capture(child, heap);
+          thread_capture.InjectTestFunc([&](pid_t tid) {
+            syscall(SYS_tgkill, child, tid, sig);
+            usleep(10000);
+          });
+          auto list_tids = allocator::vector<pid_t>(heap);
+
+          ASSERT_TRUE(thread_capture.ListThreads(list_tids));
+          ASSERT_EQ(1U, list_tids.size());
+
+          ASSERT_TRUE(thread_capture.CaptureThreads());
+
+          auto thread_info = allocator::vector<ThreadInfo>(heap);
+          ASSERT_TRUE(thread_capture.CapturedThreadInfo(thread_info));
+          ASSERT_EQ(1U, thread_info.size());
+          ASSERT_TRUE(thread_capture.ReleaseThreads());
+
+          usleep(100000);
+          char buf;
+          ASSERT_EQ(1, TEMP_FAILURE_RETRY(read(pipe.Receiver(), &buf, 1)));
+          ASSERT_EQ(buf, '+');
+
+          if (!HasFailure()) {
+            ASSERT_FALSE(disable_malloc.timed_out());
+          }
+        }
       });
-      auto list_tids = allocator::vector<pid_t>(heap);
-
-      ASSERT_TRUE(thread_capture.ListThreads(list_tids));
-      ASSERT_EQ(1U, list_tids.size());
-
-      ASSERT_TRUE(thread_capture.CaptureThreads());
-
-      auto thread_info = allocator::vector<ThreadInfo>(heap);
-      ASSERT_TRUE(thread_capture.CapturedThreadInfo(thread_info));
-      ASSERT_EQ(1U, thread_info.size());
-      ASSERT_TRUE(thread_capture.ReleaseThreads());
-
-      usleep(100000);
-      char buf;
-      ASSERT_EQ(1, TEMP_FAILURE_RETRY(read(pipe.Receiver(), &buf, 1)));
-      ASSERT_EQ(buf, '+');
-
-      if (!HasFailure()) {
-        ASSERT_FALSE(disable_malloc.timed_out());
-      }
-    }
-  });
 }
+
+}  // namespace android
diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp
index 38859d1..e292403 100644
--- a/libmetricslogger/Android.bp
+++ b/libmetricslogger/Android.bp
@@ -20,10 +20,11 @@
         "-Wextra",
         "-Werror",
 
-        // 524291 corresponds to sysui_histogram, from
-        // frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags
-        "-DHISTOGRAM_LOG_TAG=524292",
-        "-DCOUNT_LOG_TAG=524290",
+        // The following define maps the sysui_multi_action logtag ID as represented by:
+        //   frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags
+        //
+        // TODO(jhawkins): Query this value at runtime.
+        "-DMULTI_ACTION_LOG_TAG=524292",
     ],
 }
 
@@ -31,7 +32,6 @@
 // -----------------------------------------------------------------------------
 cc_library_shared {
     name: "libmetricslogger",
-    vendor_available: true,
     srcs: metricslogger_lib_src_files,
     defaults: ["metricslogger_defaults"],
 }
diff --git a/libmetricslogger/include/metricslogger/metrics_logger.h b/libmetricslogger/include/metricslogger/metrics_logger.h
index 36e124d..189bc4b 100644
--- a/libmetricslogger/include/metricslogger/metrics_logger.h
+++ b/libmetricslogger/include/metricslogger/metrics_logger.h
@@ -28,14 +28,26 @@
 // log buffer.
 void LogCounter(const std::string& name, int32_t val);
 
+// Logs a Tron multi_action with category|category| containing the string
+// |value| in the field |field|.
+void LogMultiAction(int32_t category, int32_t field, const std::string& value);
+
 // TODO: replace these with the metric_logger.proto definitions
 enum {
     LOGBUILDER_CATEGORY = 757,
+    LOGBUILDER_TYPE = 758,
     LOGBUILDER_NAME = 799,
     LOGBUILDER_BUCKET = 801,
     LOGBUILDER_VALUE = 802,
     LOGBUILDER_COUNTER = 803,
     LOGBUILDER_HISTOGRAM = 804,
+
+    ACTION_BOOT = 1098,
+    FIELD_PLATFORM_REASON = 1099,
+};
+
+enum {
+    TYPE_ACTION = 4,
 };
 
 }  // namespace metricslogger
diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp
index 6f65e10..0ca024d 100644
--- a/libmetricslogger/metrics_logger.cpp
+++ b/libmetricslogger/metrics_logger.cpp
@@ -25,17 +25,24 @@
 
 // Mirror com.android.internal.logging.MetricsLogger#histogram().
 void LogHistogram(const std::string& event, int32_t data) {
-    android_log_event_list log(HISTOGRAM_LOG_TAG);
+    android_log_event_list log(MULTI_ACTION_LOG_TAG);
     log << LOGBUILDER_CATEGORY << LOGBUILDER_HISTOGRAM << LOGBUILDER_NAME << event
         << LOGBUILDER_BUCKET << data << LOGBUILDER_VALUE << 1 << LOG_ID_EVENTS;
 }
 
 // Mirror com.android.internal.logging.MetricsLogger#count().
 void LogCounter(const std::string& name, int32_t val) {
-    android_log_event_list log(COUNT_LOG_TAG);
+    android_log_event_list log(MULTI_ACTION_LOG_TAG);
     log << LOGBUILDER_CATEGORY << LOGBUILDER_COUNTER << LOGBUILDER_NAME << name << LOGBUILDER_VALUE
         << val << LOG_ID_EVENTS;
 }
 
+// Mirror com.android.internal.logging.MetricsLogger#action().
+void LogMultiAction(int32_t category, int32_t field, const std::string& value) {
+    android_log_event_list log(MULTI_ACTION_LOG_TAG);
+    log << LOGBUILDER_CATEGORY << category << LOGBUILDER_TYPE << TYPE_ACTION
+        << field << value << LOG_ID_EVENTS;
+}
+
 }  // namespace metricslogger
 }  // namespace android
diff --git a/libnativebridge/Android.bp b/libnativebridge/Android.bp
index 377b7dd..1cea4cd 100644
--- a/libnativebridge/Android.bp
+++ b/libnativebridge/Android.bp
@@ -1,4 +1,11 @@
 
+cc_library_headers {
+    name: "libnativebridge-dummy-headers",
+
+    host_supported: true,
+    export_include_dirs=["include"],
+}
+
 cc_library {
     name: "libnativebridge",
 
@@ -7,6 +14,8 @@
     shared_libs: ["liblog"],
     clang: true,
 
+    export_include_dirs=["include"],
+
     cflags: [
         "-Werror",
         "-Wall",
@@ -23,4 +32,4 @@
     },
 }
 
-subdirs = ["tests"]
\ No newline at end of file
+subdirs = ["tests"]
diff --git a/include/nativebridge/native_bridge.h b/libnativebridge/include/nativebridge/native_bridge.h
similarity index 100%
rename from include/nativebridge/native_bridge.h
rename to libnativebridge/include/nativebridge/native_bridge.h
diff --git a/libnativebridge/tests/Android.bp b/libnativebridge/tests/Android.bp
index efd3978..e31dae0 100644
--- a/libnativebridge/tests/Android.bp
+++ b/libnativebridge/tests/Android.bp
@@ -23,6 +23,7 @@
         "-Wextra",
         "-Werror",
     ],
+    header_libs: ["libnativebridge-dummy-headers"],
     cppflags: ["-fvisibility=protected"],
     target: {
         android: {
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index 99ae3a7..3563fc1 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -34,6 +34,7 @@
                                    int32_t target_sdk_version,
                                    jobject class_loader,
                                    bool is_shared,
+                                   bool is_for_vendor,
                                    jstring library_path,
                                    jstring permitted_path);
 
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 36a2e44..5d160ee 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -15,7 +15,7 @@
  */
 
 #include "nativeloader/native_loader.h"
-#include "ScopedUtfChars.h"
+#include <nativehelper/ScopedUtfChars.h>
 
 #include <dlfcn.h>
 #ifdef __ANDROID__
@@ -82,6 +82,11 @@
                                   "/etc/public.libraries.txt";
 static constexpr const char* kPublicNativeLibrariesVendorConfig =
                                   "/vendor/etc/public.libraries.txt";
+static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
+                                  "/etc/llndk.libraries.txt";
+static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
+                                  "/etc/vndksp.libraries.txt";
+
 
 // The device may be configured to have the vendor libraries loaded to a separate namespace.
 // For historical reasons this namespace was named sphal but effectively it is intended
@@ -89,6 +94,11 @@
 // vendor and system namespaces.
 static constexpr const char* kVendorNamespaceName = "sphal";
 
+static constexpr const char* kVndkNamespaceName = "vndk";
+
+static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
+static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
+
 // (http://b/27588281) This is a workaround for apps using custom classloaders and calling
 // System.load() with an absolute path which is outside of the classloader library search path.
 // This list includes all directories app is allowed to access this way.
@@ -108,6 +118,7 @@
               uint32_t target_sdk_version,
               jobject class_loader,
               bool is_shared,
+              bool is_for_vendor,
               jstring java_library_path,
               jstring java_permitted_path,
               NativeLoaderNamespace* ns,
@@ -163,9 +174,39 @@
       is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str());
     }
 
+    std::string system_exposed_libraries = system_public_libraries_;
+    const char* namespace_name = kClassloaderNamespaceName;
+    android_namespace_t* vndk_ns = nullptr;
+    if (is_for_vendor && !is_shared) {
+      LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
+
+      // For vendor apks, give access to the vendor lib even though
+      // they are treated as unbundled; the libs and apks are still bundled
+      // together in the vendor partition.
+#if defined(__LP64__)
+      std::string vendor_lib_path = "/vendor/lib64";
+#else
+      std::string vendor_lib_path = "/vendor/lib";
+#endif
+      library_path = library_path + ":" + vendor_lib_path.c_str();
+      permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
+
+      // Also give access to LLNDK libraries since they are available to vendors
+      system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
+
+      // Give access to VNDK-SP libraries from the 'vndk' namespace.
+      vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
+      LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
+                          "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
+
+      // Different name is useful for debugging
+      namespace_name = kVendorClassloaderNamespaceName;
+      ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
+    }
+
     NativeLoaderNamespace native_loader_ns;
     if (!is_native_bridge) {
-      android_namespace_t* ns = android_create_namespace("classloader-namespace",
+      android_namespace_t* ns = android_create_namespace(namespace_name,
                                                          nullptr,
                                                          library_path.c_str(),
                                                          namespace_type,
@@ -181,11 +222,19 @@
       // which is expected behavior in this case.
       android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
 
-      if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) {
+      if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
         *error_msg = dlerror();
         return false;
       }
 
+      if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) {
+        // vendor apks are allowed to use VNDK-SP libraries.
+        if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) {
+          *error_msg = dlerror();
+          return false;
+        }
+      }
+
       if (!vendor_public_libraries_.empty()) {
         if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
           *error_msg = dlerror();
@@ -195,7 +244,7 @@
 
       native_loader_ns = NativeLoaderNamespace(ns);
     } else {
-      native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace",
+      native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
                                                                   nullptr,
                                                                   library_path.c_str(),
                                                                   namespace_type,
@@ -209,7 +258,7 @@
 
       native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
 
-      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) {
+      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
         *error_msg = NativeBridgeGetError();
         return false;
       }
@@ -259,6 +308,10 @@
     std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
     std::string public_native_libraries_system_config =
             root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
+    std::string llndk_native_libraries_system_config =
+            root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
+    std::string vndksp_native_libraries_system_config =
+            root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
 
     std::string error_msg;
     LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
@@ -294,6 +347,14 @@
     system_public_libraries_ = base::Join(sonames, ':');
 
     sonames.clear();
+    ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames);
+    system_llndk_libraries_ = base::Join(sonames, ':');
+
+    sonames.clear();
+    ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames);
+    system_vndksp_libraries_ = base::Join(sonames, ':');
+
+    sonames.clear();
     // This file is optional, quietly ignore if the file does not exist.
     ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
 
@@ -404,6 +465,8 @@
   std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
   std::string system_public_libraries_;
   std::string vendor_public_libraries_;
+  std::string system_llndk_libraries_;
+  std::string system_vndksp_libraries_;
 
   DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
 };
@@ -430,6 +493,7 @@
                                    int32_t target_sdk_version,
                                    jobject class_loader,
                                    bool is_shared,
+                                   bool is_for_vendor,
                                    jstring library_path,
                                    jstring permitted_path) {
 #if defined(__ANDROID__)
@@ -441,6 +505,7 @@
                                       target_sdk_version,
                                       class_loader,
                                       is_shared,
+                                      is_for_vendor,
                                       library_path,
                                       permitted_path,
                                       &ns,
@@ -449,7 +514,7 @@
     return env->NewStringUTF(error_msg.c_str());
   }
 #else
-  UNUSED(env, target_sdk_version, class_loader, is_shared,
+  UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
          library_path, permitted_path);
 #endif
   return nullptr;
@@ -478,7 +543,8 @@
     if (!g_namespaces->Create(env,
                               target_sdk_version,
                               class_loader,
-                              false,
+                              false /* is_shared */,
+                              false /* is_for_vendor */,
                               library_path,
                               nullptr,
                               &ns,
diff --git a/libnetutils/Android.bp b/libnetutils/Android.bp
index 9967ef8..1d43775 100644
--- a/libnetutils/Android.bp
+++ b/libnetutils/Android.bp
@@ -1,6 +1,9 @@
 cc_library_shared {
     name: "libnetutils",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "dhcpclient.c",
diff --git a/libpixelflinger/codeflinger/mips64_disassem.c b/libpixelflinger/codeflinger/mips64_disassem.c
index f28d726..1856e5c 100644
--- a/libpixelflinger/codeflinger/mips64_disassem.c
+++ b/libpixelflinger/codeflinger/mips64_disassem.c
@@ -555,6 +555,7 @@
     } else {
         vprintf(fmt, argp);
     }
+    va_end(argp);
 }
 
 /*
diff --git a/libpixelflinger/codeflinger/mips_disassem.c b/libpixelflinger/codeflinger/mips_disassem.c
index 3007b15..83a9740 100644
--- a/libpixelflinger/codeflinger/mips_disassem.c
+++ b/libpixelflinger/codeflinger/mips_disassem.c
@@ -562,6 +562,7 @@
     } else {
         vprintf(fmt, argp);
     }
+    va_end(argp);
 }
 
 
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index f0c3795..9fa4154 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -33,6 +33,10 @@
 
 int createProcessGroup(uid_t uid, int initialPid);
 
+bool setProcessGroupSwappiness(uid_t uid, int initialPid, int swappiness);
+bool setProcessGroupSoftLimit(uid_t uid, int initialPid, int64_t softLimitInBytes);
+bool setProcessGroupLimit(uid_t uid, int initialPid, int64_t limitInBytes);
+
 void removeAllProcessGroups(void);
 
 __END_DECLS
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index f5d4e1c..8526b3a 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -35,16 +35,16 @@
 #include <set>
 #include <thread>
 
+#include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 #include <private/android_filesystem_config.h>
 
 #include <processgroup/processgroup.h>
 
-using namespace std::chrono_literals;
+using android::base::WriteStringToFile;
 
-// Uncomment line below use memory cgroups for keeping track of (forked) PIDs
-// #define USE_MEMCG 1
+using namespace std::chrono_literals;
 
 #define MEM_CGROUP_PATH "/dev/memcg/apps"
 #define MEM_CGROUP_TASKS "/dev/memcg/apps/tasks"
@@ -91,7 +91,6 @@
 };
 
 static const char* getCgroupRootPath() {
-#ifdef USE_MEMCG
     static const char* cgroup_root_path = NULL;
     std::call_once(init_path_flag, [&]() {
             // Check if mem cgroup is mounted, only then check for write-access to avoid
@@ -100,9 +99,6 @@
                     ACCT_CGROUP_PATH : MEM_CGROUP_PATH;
             });
     return cgroup_root_path;
-#else
-    return ACCT_CGROUP_PATH;
-#endif
 }
 
 static int convertUidToPath(char *path, size_t size, uid_t uid)
@@ -409,22 +405,40 @@
 
     strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
 
-    int fd = open(path, O_WRONLY);
-    if (fd == -1) {
-        int ret = -errno;
-        PLOG(ERROR) << "Failed to open " << path;
-        return ret;
-    }
-
-    char pid[PROCESSGROUP_MAX_PID_LEN + 1] = {0};
-    int len = snprintf(pid, sizeof(pid), "%d", initialPid);
-
     int ret = 0;
-    if (write(fd, pid, len) < 0) {
+    if (!WriteStringToFile(std::to_string(initialPid), path)) {
         ret = -errno;
-        PLOG(ERROR) << "Failed to write '" << pid << "' to " << path;
+        PLOG(ERROR) << "Failed to write '" << initialPid << "' to " << path;
     }
 
-    close(fd);
     return ret;
 }
+
+static bool setProcessGroupValue(uid_t uid, int pid, const char* fileName, int64_t value) {
+    char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
+    if (strcmp(getCgroupRootPath(), MEM_CGROUP_PATH)) {
+        PLOG(ERROR) << "Memcg is not mounted." << path;
+        return false;
+    }
+
+    convertUidPidToPath(path, sizeof(path), uid, pid);
+    strlcat(path, fileName, sizeof(path));
+
+    if (!WriteStringToFile(std::to_string(value), path)) {
+        PLOG(ERROR) << "Failed to write '" << value << "' to " << path;
+        return false;
+    }
+    return true;
+}
+
+bool setProcessGroupSwappiness(uid_t uid, int pid, int swappiness) {
+    return setProcessGroupValue(uid, pid, "/memory.swappiness", swappiness);
+}
+
+bool setProcessGroupSoftLimit(uid_t uid, int pid, int64_t soft_limit_in_bytes) {
+    return setProcessGroupValue(uid, pid, "/memory.soft_limit_in_bytes", soft_limit_in_bytes);
+}
+
+bool setProcessGroupLimit(uid_t uid, int pid, int64_t limit_in_bytes) {
+    return setProcessGroupValue(uid, pid, "/memory.limit_in_bytes", limit_in_bytes);
+}
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index aedaa38..b568ee5 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -23,6 +23,9 @@
 cc_library {
     name: "libprocinfo",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     host_supported: true,
     srcs: [
         "process.cpp",
diff --git a/libprocinfo/include/procinfo/process.h b/libprocinfo/include/procinfo/process.h
index fb140ff..db56fc1 100644
--- a/libprocinfo/include/procinfo/process.h
+++ b/libprocinfo/include/procinfo/process.h
@@ -35,8 +35,18 @@
 
 #if defined(__linux__)
 
+enum ProcessState {
+  kProcessStateUnknown,
+  kProcessStateRunning,
+  kProcessStateSleeping,
+  kProcessStateUninterruptibleWait,
+  kProcessStateStopped,
+  kProcessStateZombie,
+};
+
 struct ProcessInfo {
   std::string name;
+  ProcessState state;
   pid_t tid;
   pid_t pid;
   pid_t ppid;
diff --git a/libprocinfo/process.cpp b/libprocinfo/process.cpp
index c513e16..6e5be6e 100644
--- a/libprocinfo/process.cpp
+++ b/libprocinfo/process.cpp
@@ -44,6 +44,24 @@
   return GetProcessInfoFromProcPidFd(dirfd.get(), process_info);
 }
 
+static ProcessState parse_state(const char* state) {
+  switch (*state) {
+    case 'R':
+      return kProcessStateRunning;
+    case 'S':
+      return kProcessStateSleeping;
+    case 'D':
+      return kProcessStateUninterruptibleWait;
+    case 'T':
+      return kProcessStateStopped;
+    case 'Z':
+      return kProcessStateZombie;
+    default:
+      LOG(ERROR) << "unknown process state: " << *state;
+      return kProcessStateUnknown;
+  }
+}
+
 bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info) {
   int status_fd = openat(fd, "status", O_RDONLY | O_CLOEXEC);
 
@@ -60,7 +78,7 @@
   }
 
   int field_bitmap = 0;
-  static constexpr int finished_bitmap = 127;
+  static constexpr int finished_bitmap = 255;
   char* line = nullptr;
   size_t len = 0;
 
@@ -98,6 +116,9 @@
     } else if (header == "Gid:") {
       process_info->gid = atoi(tab + 1);
       field_bitmap |= 64;
+    } else if (header == "State:") {
+      process_info->state = parse_state(tab + 1);
+      field_bitmap |= 128;
     }
   }
 
diff --git a/libprocinfo/process_test.cpp b/libprocinfo/process_test.cpp
index 5ffd236..9da9278 100644
--- a/libprocinfo/process_test.cpp
+++ b/libprocinfo/process_test.cpp
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <chrono>
 #include <set>
 #include <thread>
 #include <vector>
@@ -29,6 +30,8 @@
 
 #include <android-base/stringprintf.h>
 
+using namespace std::chrono_literals;
+
 #if !defined(__BIONIC__)
 #include <syscall.h>
 static pid_t gettid() {
@@ -82,3 +85,34 @@
     }
   }).join();
 }
+
+TEST(process_info, process_state) {
+  int pipefd[2];
+  ASSERT_EQ(0, pipe2(pipefd, O_CLOEXEC));
+  pid_t forkpid = fork();
+
+  ASSERT_NE(-1, forkpid);
+  if (forkpid == 0) {
+    close(pipefd[1]);
+    char buf;
+    TEMP_FAILURE_RETRY(read(pipefd[0], &buf, 1));
+    _exit(0);
+  }
+
+  // Give the child some time to get to the read.
+  std::this_thread::sleep_for(100ms);
+
+  android::procinfo::ProcessInfo procinfo;
+  ASSERT_TRUE(android::procinfo::GetProcessInfo(forkpid, &procinfo));
+  ASSERT_EQ(android::procinfo::kProcessStateSleeping, procinfo.state);
+
+  ASSERT_EQ(0, kill(forkpid, SIGKILL));
+
+  // Give the kernel some time to kill the child.
+  std::this_thread::sleep_for(100ms);
+
+  ASSERT_TRUE(android::procinfo::GetProcessInfo(forkpid, &procinfo));
+  ASSERT_EQ(android::procinfo::kProcessStateZombie, procinfo.state);
+
+  ASSERT_EQ(forkpid, waitpid(forkpid, nullptr, 0));
+}
diff --git a/libsuspend/Android.bp b/libsuspend/Android.bp
index 130800e..32f1e1f 100644
--- a/libsuspend/Android.bp
+++ b/libsuspend/Android.bp
@@ -3,6 +3,9 @@
 cc_library {
     name: "libsuspend",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "autosuspend.c",
diff --git a/libsync/Android.bp b/libsync/Android.bp
index 257d42d..ce9e84a 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -22,10 +22,15 @@
 
 cc_library_shared {
     name: "libsync",
-    vendor_available: true,
     defaults: ["libsync_defaults"],
 }
 
+llndk_library {
+    name: "libsync",
+    symbol_file: "libsync.map.txt",
+    export_include_dirs: ["include"],
+}
+
 // libsync_recovery is only intended for the recovery binary.
 // Future versions of the kernel WILL require an updated libsync, and will break
 // anything statically linked against the current libsync.
diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt
index daa28ae..53bb07a 100644
--- a/libsync/libsync.map.txt
+++ b/libsync/libsync.map.txt
@@ -17,16 +17,12 @@
 LIBSYNC {
   global:
     sync_merge; # introduced=26
-    sync_get_fence_info; # introduced=26
-    sync_free_fence_info; # introduced=26
+    sync_file_info; # introduced=26
+    sync_file_info_free; # introduced=26
+    sync_wait; # vndk
+    sync_fence_info; # vndk
+    sync_pt_info; # vndk
+    sync_fence_info_free; # vndk
   local:
     *;
 };
-
-LIBSYNC_PLATFORM {
-  global:
-    sync_wait;
-    sync_fence_info;
-    sync_pt_info;
-    sync_fence_info_free;
-} LIBSYNC_PLATFORM;
diff --git a/libsync/sync.c b/libsync/sync.c
index baeccda..0950082 100644
--- a/libsync/sync.c
+++ b/libsync/sync.c
@@ -217,6 +217,8 @@
                   local_info.num_fences * sizeof(struct sync_fence_info));
     if (!info)
         return NULL;
+
+    info->num_fences = local_info.num_fences;
     info->sync_fence_info = (__u64)(uintptr_t)(info + 1);
 
     err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
diff --git a/libsystem/include/system/thread_defs.h b/libsystem/include/system/thread_defs.h
index 377a48c..80d1160 100644
--- a/libsystem/include/system/thread_defs.h
+++ b/libsystem/include/system/thread_defs.h
@@ -55,6 +55,9 @@
     /* ui service treads might want to run at a urgent display (uncommon) */
     ANDROID_PRIORITY_URGENT_DISPLAY =  HAL_PRIORITY_URGENT_DISPLAY,
 
+    /* all normal video threads */
+    ANDROID_PRIORITY_VIDEO          = -10,
+
     /* all normal audio threads */
     ANDROID_PRIORITY_AUDIO          = -16,
 
diff --git a/libsysutils/Android.bp b/libsysutils/Android.bp
index 550ef42..d076a1a 100644
--- a/libsysutils/Android.bp
+++ b/libsysutils/Android.bp
@@ -1,6 +1,9 @@
 cc_library_shared {
     name: "libsysutils",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "src/SocketListener.cpp",
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index 1b6076f..87e2684 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -68,7 +68,7 @@
         android_errorWriteLog(0x534e4554, "29831647");
         c->sendMsg(500, "Command too large for buffer", false);
         mSkipToNextNullByte = true;
-        return false;
+        return true;
     }
 
     int offset = 0;
@@ -211,7 +211,6 @@
     return;
 
 overflow:
-    LOG_EVENT_INT(78001, cli->getUid());
     cli->sendMsg(500, "Command too long", false);
     goto out;
 }
diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp
index 896dad3..aad0394 100644
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -57,8 +57,6 @@
     count = TEMP_FAILURE_RETRY(uevent_kernel_recv(socket,
             mBuffer, sizeof(mBuffer), require_group, &uid));
     if (count < 0) {
-        if (uid > 0)
-            LOG_EVENT_INT(65537, uid);
         SLOGE("recvmsg failed (%s)", strerror(errno));
         return false;
     }
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index eb2b902..04c4cfa 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -31,23 +31,26 @@
         },
     },
 
-    multilib: {
-        lib32: {
-            suffix: "32",
+    arch: {
+        mips: {
+            enabled: false,
         },
-        lib64: {
-            suffix: "64",
+        mips64: {
+            enabled: false,
         },
     },
 }
 
-cc_defaults {
-    name: "libunwindstack_common",
+cc_library {
+    name: "libunwindstack",
     defaults: ["libunwindstack_flags"],
+    export_include_dirs: ["include"],
 
     srcs: [
         "ArmExidx.cpp",
         "DwarfCfa.cpp",
+        "DwarfDebugFrame.cpp",
+        "DwarfEhFrame.cpp",
         "DwarfMemory.cpp",
         "DwarfOp.cpp",
         "DwarfSection.cpp",
@@ -55,40 +58,34 @@
         "ElfInterface.cpp",
         "ElfInterfaceArm.cpp",
         "Log.cpp",
-        "Regs.cpp",
         "MapInfo.cpp",
         "Maps.cpp",
         "Memory.cpp",
+        "Regs.cpp",
         "Symbols.cpp",
     ],
 
+    arch: {
+        x86: {
+            srcs: ["AsmGetRegsX86.S"],
+        },
+        x86_64: {
+            srcs: ["AsmGetRegsX86_64.S"],
+        },
+    },
+
     shared_libs: [
         "libbase",
         "liblog",
-    ],
-}
-
-cc_library {
-    name: "libunwindstack",
-    defaults: ["libunwindstack_common"],
-}
-
-cc_library {
-    name: "libunwindstack_debug",
-    defaults: ["libunwindstack_common"],
-
-    cflags: [
-        "-UNDEBUG",
-        "-O0",
-        "-g",
+        "liblzma",
     ],
 }
 
 //-------------------------------------------------------------------------
 // Unit Tests
 //-------------------------------------------------------------------------
-cc_defaults {
-    name: "libunwindstack_test_common",
+cc_test {
+    name: &quo