Merge "liblog: display valid utf8 characters with 'printable' log format"
diff --git a/adb/Android.bp b/adb/Android.bp
index f2f4018..eec1335 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -26,7 +26,6 @@
         "-Wvla",
         "-DADB_HOST=1",         // overridden by adbd_defaults
         "-DALLOW_ADBD_ROOT=0",  // overridden by adbd_defaults
-        "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION=1",
     ],
     cpp_std: "experimental",
 
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index bdb8efa..f5cdcb5 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -34,7 +34,7 @@
 #include "adb_utils.h"
 #include "sysdeps.h"
 
-bool SendProtocolString(borrowed_fd fd, std::string_view s) {
+bool SendProtocolString(int fd, std::string_view s) {
     unsigned int length = s.size();
     if (length > MAX_PAYLOAD - 4) {
         errno = EMSGSIZE;
@@ -47,7 +47,7 @@
     return WriteFdExactly(fd, str);
 }
 
-bool ReadProtocolString(borrowed_fd fd, std::string* s, std::string* error) {
+bool ReadProtocolString(int fd, std::string* s, std::string* error) {
     char buf[5];
     if (!ReadFdExactly(fd, buf, 4)) {
         *error = perror_str("protocol fault (couldn't read status length)");
@@ -65,57 +65,57 @@
     return true;
 }
 
-bool SendOkay(borrowed_fd fd) {
+bool SendOkay(int fd) {
     return WriteFdExactly(fd, "OKAY", 4);
 }
 
-bool SendFail(borrowed_fd fd, std::string_view reason) {
+bool SendFail(int fd, std::string_view reason) {
     return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
 }
 
-bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len) {
+bool ReadFdExactly(int fd, void* buf, size_t len) {
     char* p = reinterpret_cast<char*>(buf);
 
     size_t len0 = len;
 
-    D("readx: fd=%d wanted=%zu", fd.get(), len);
+    D("readx: fd=%d wanted=%zu", fd, len);
     while (len > 0) {
         int r = adb_read(fd, p, len);
         if (r > 0) {
             len -= r;
             p += r;
         } else if (r == -1) {
-            D("readx: fd=%d error %d: %s", fd.get(), errno, strerror(errno));
+            D("readx: fd=%d error %d: %s", fd, errno, strerror(errno));
             return false;
         } else {
-            D("readx: fd=%d disconnected", fd.get());
+            D("readx: fd=%d disconnected", fd);
             errno = 0;
             return false;
         }
     }
 
-    VLOG(RWX) << "readx: fd=" << fd.get() << " wanted=" << len0 << " got=" << (len0 - len) << " "
-              << dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
+    VLOG(RWX) << "readx: fd=" << fd << " wanted=" << len0 << " got=" << (len0 - len)
+              << " " << dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
 
     return true;
 }
 
-bool WriteFdExactly(borrowed_fd fd, const void* buf, size_t len) {
+bool WriteFdExactly(int fd, const void* buf, size_t len) {
     const char* p = reinterpret_cast<const char*>(buf);
     int r;
 
-    VLOG(RWX) << "writex: fd=" << fd.get() << " len=" << len << " "
-              << dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
+    VLOG(RWX) << "writex: fd=" << fd << " len=" << len
+              << " " << dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
 
     while (len > 0) {
         r = adb_write(fd, p, len);
         if (r == -1) {
-            D("writex: fd=%d error %d: %s", fd.get(), errno, strerror(errno));
+            D("writex: fd=%d error %d: %s", fd, errno, strerror(errno));
             if (errno == EAGAIN) {
                 std::this_thread::yield();
                 continue;
             } else if (errno == EPIPE) {
-                D("writex: fd=%d disconnected", fd.get());
+                D("writex: fd=%d disconnected", fd);
                 errno = 0;
                 return false;
             } else {
@@ -129,15 +129,15 @@
     return true;
 }
 
-bool WriteFdExactly(borrowed_fd fd, const char* str) {
+bool WriteFdExactly(int fd, const char* str) {
     return WriteFdExactly(fd, str, strlen(str));
 }
 
-bool WriteFdExactly(borrowed_fd fd, const std::string& str) {
+bool WriteFdExactly(int fd, const std::string& str) {
     return WriteFdExactly(fd, str.c_str(), str.size());
 }
 
-bool WriteFdFmt(borrowed_fd fd, const char* fmt, ...) {
+bool WriteFdFmt(int fd, const char* fmt, ...) {
     std::string str;
 
     va_list ap;
@@ -148,7 +148,7 @@
     return WriteFdExactly(fd, str);
 }
 
-bool ReadOrderlyShutdown(borrowed_fd fd) {
+bool ReadOrderlyShutdown(int fd) {
     char buf[16];
 
     // Only call this function if you're sure that the peer does
@@ -178,7 +178,7 @@
         // data. We don't repeatedly call adb_read() until we get zero because
         // we don't know how long that would take, but we do know that the
         // caller wants to close the socket soon.
-        VLOG(RWX) << "ReadOrderlyShutdown(" << fd.get() << ") unexpectedly read "
+        VLOG(RWX) << "ReadOrderlyShutdown(" << fd << ") unexpectedly read "
                   << dump_hex(buf, result);
         // Shutdown the socket to prevent the caller from reading or writing to
         // it which doesn't make sense if we just read and discarded some data.
diff --git a/adb/adb_io.h b/adb/adb_io.h
index 9628946..d6e65d8 100644
--- a/adb/adb_io.h
+++ b/adb/adb_io.h
@@ -25,16 +25,16 @@
 #include "adb_unique_fd.h"
 
 // Sends the protocol "OKAY" message.
-bool SendOkay(borrowed_fd fd);
+bool SendOkay(int fd);
 
 // Sends the protocol "FAIL" message, with the given failure reason.
-bool SendFail(borrowed_fd fd, std::string_view reason);
+bool SendFail(int fd, std::string_view reason);
 
 // Writes a protocol-format string; a four hex digit length followed by the string data.
-bool SendProtocolString(borrowed_fd fd, std::string_view s);
+bool SendProtocolString(int fd, std::string_view s);
 
 // Reads a protocol-format string; a four hex digit length followed by the string data.
-bool ReadProtocolString(borrowed_fd fd, std::string* s, std::string* error);
+bool ReadProtocolString(int fd, std::string* s, std::string* error);
 
 // Reads exactly len bytes from fd into buf.
 //
@@ -42,7 +42,7 @@
 // were read. If EOF was found, errno will be set to 0.
 //
 // If this function fails, the contents of buf are undefined.
-bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len);
+bool ReadFdExactly(int fd, void* buf, size_t len);
 
 // Given a client socket, wait for orderly/graceful shutdown. Call this:
 //
@@ -60,19 +60,19 @@
 // connect()s from the client to fail with WSAEADDRINUSE on Windows.
 // Returns true if it is sure that orderly/graceful shutdown has occurred with
 // no additional data read from the server.
-bool ReadOrderlyShutdown(borrowed_fd fd);
+bool ReadOrderlyShutdown(int fd);
 
 // Writes exactly len bytes from buf to fd.
 //
 // Returns false if there is an error or if the fd was closed before the write
 // completed. If the other end of the fd (such as in a socket, pipe, or fifo),
 // is closed, errno will be set to 0.
-bool WriteFdExactly(borrowed_fd fd, const void* buf, size_t len);
+bool WriteFdExactly(int fd, const void* buf, size_t len);
 
 // Same as above, but for strings.
-bool WriteFdExactly(borrowed_fd fd, const char* s);
-bool WriteFdExactly(borrowed_fd fd, const std::string& s);
+bool WriteFdExactly(int fd, const char* s);
+bool WriteFdExactly(int fd, const std::string& s);
 
 // Same as above, but formats the string to send.
-bool WriteFdFmt(borrowed_fd fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
+bool WriteFdFmt(int fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
 #endif /* ADB_IO_H */
diff --git a/adb/adb_unique_fd.h b/adb/adb_unique_fd.h
index b6c910a..d47213d 100644
--- a/adb/adb_unique_fd.h
+++ b/adb/adb_unique_fd.h
@@ -32,8 +32,6 @@
 using unique_fd = android::base::unique_fd;
 #endif
 
-using android::base::borrowed_fd;
-
 template <typename T>
 int adb_close(const android::base::unique_fd_impl<T>&)
         __attribute__((__unavailable__("adb_close called on unique_fd")));
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index cf5fbc8..9791769 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -234,15 +234,15 @@
 
 #if !defined(_WIN32)
 // Windows version provided in sysdeps_win32.cpp
-bool set_file_block_mode(borrowed_fd fd, bool block) {
-    int flags = fcntl(fd.get(), F_GETFL, 0);
+bool set_file_block_mode(int fd, bool block) {
+    int flags = fcntl(fd, F_GETFL, 0);
     if (flags == -1) {
-        PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd.get();
+        PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd;
         return false;
     }
     flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
-    if (fcntl(fd.get(), F_SETFL, flags) != 0) {
-        PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd.get() << ", flags " << flags;
+    if (fcntl(fd, F_SETFL, flags) != 0) {
+        PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd << ", flags " << flags;
         return false;
     }
     return true;
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 2988034..5800a62 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -26,7 +26,6 @@
 #include <android-base/macros.h>
 
 #include "adb.h"
-#include "adb_unique_fd.h"
 
 void close_stdin();
 
@@ -52,7 +51,7 @@
 [[noreturn]] void error_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
 [[noreturn]] void perror_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
 
-bool set_file_block_mode(borrowed_fd fd, bool block);
+bool set_file_block_mode(int fd, bool block);
 
 // Given forward/reverse targets, returns true if they look sane. If an error is found, fills
 // |error| and returns false.
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index cdca3aa..bd676c2 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -149,13 +149,13 @@
 TEST(adb_utils, set_file_block_mode) {
     unique_fd fd(adb_open("/dev/null", O_RDWR | O_APPEND));
     ASSERT_GE(fd, 0);
-    int flags = fcntl(fd.get(), F_GETFL, 0);
+    int flags = fcntl(fd, F_GETFL, 0);
     ASSERT_EQ(O_RDWR | O_APPEND, (flags & (O_RDWR | O_APPEND)));
     ASSERT_TRUE(set_file_block_mode(fd, false));
-    int new_flags = fcntl(fd.get(), F_GETFL, 0);
+    int new_flags = fcntl(fd, F_GETFL, 0);
     ASSERT_EQ(flags | O_NONBLOCK, new_flags);
     ASSERT_TRUE(set_file_block_mode(fd, true));
-    new_flags = fcntl(fd.get(), F_GETFL, 0);
+    new_flags = fcntl(fd, F_GETFL, 0);
     ASSERT_EQ(flags, new_flags);
 }
 #endif
diff --git a/adb/client/adb_client.cpp b/adb/client/adb_client.cpp
index 7e408a8..5a7bc8d 100644
--- a/adb/client/adb_client.cpp
+++ b/adb/client/adb_client.cpp
@@ -128,7 +128,7 @@
     return result;
 }
 
-bool adb_status(borrowed_fd fd, std::string* error) {
+bool adb_status(int fd, std::string* error) {
     char buf[5];
     if (!ReadFdExactly(fd, buf, 4)) {
         *error = perror_str("protocol fault (couldn't read status)");
diff --git a/adb/client/adb_client.h b/adb/client/adb_client.h
index fe1e584..8d32c93 100644
--- a/adb/client/adb_client.h
+++ b/adb/client/adb_client.h
@@ -16,14 +16,13 @@
 
 #pragma once
 
-#include <optional>
-#include <string>
-
 #include "adb.h"
-#include "adb_unique_fd.h"
 #include "sysdeps.h"
 #include "transport.h"
 
+#include <optional>
+#include <string>
+
 // Explicitly check the adb server version.
 // All of the commands below do this implicitly.
 // Only the first invocation of this function will check the server version.
@@ -65,7 +64,7 @@
 
 // Reads a standard adb status response (OKAY|FAIL) and returns true in the
 // event of OKAY, false in the event of FAIL or protocol error.
-bool adb_status(borrowed_fd fd, std::string* _Nonnull error);
+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);
diff --git a/adb/client/auth.cpp b/adb/client/auth.cpp
index 3eee426..ed6a9a8 100644
--- a/adb/client/auth.cpp
+++ b/adb/client/auth.cpp
@@ -53,6 +53,25 @@
     *new std::map<std::string, std::shared_ptr<RSA>>;
 static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;
 
+static std::string get_user_info() {
+    std::string hostname;
+    if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
+#if !defined(_WIN32)
+    char buf[64];
+    if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
+#endif
+    if (hostname.empty()) hostname = "unknown";
+
+    std::string username;
+    if (getenv("LOGNAME")) username = getenv("LOGNAME");
+#if !defined(_WIN32)
+    if (username.empty() && getlogin()) username = getlogin();
+#endif
+    if (username.empty()) hostname = "unknown";
+
+    return " " + username + "@" + hostname;
+}
+
 static bool calculate_public_key(std::string* out, RSA* private_key) {
     uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
     if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
@@ -70,6 +89,7 @@
     size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
                                            sizeof(binary_key_data));
     out->resize(actual_length);
+    out->append(get_user_info());
     return true;
 }
 
@@ -79,6 +99,7 @@
     mode_t old_mask;
     FILE *f = nullptr;
     int ret = 0;
+    std::string pubkey;
 
     EVP_PKEY* pkey = EVP_PKEY_new();
     BIGNUM* exponent = BN_new();
@@ -92,6 +113,11 @@
     RSA_generate_key_ex(rsa, 2048, exponent, nullptr);
     EVP_PKEY_set1_RSA(pkey, rsa);
 
+    if (!calculate_public_key(&pubkey, rsa)) {
+        LOG(ERROR) << "failed to calculate public key";
+        goto out;
+    }
+
     old_mask = umask(077);
 
     f = fopen(file.c_str(), "w");
@@ -104,7 +130,12 @@
     umask(old_mask);
 
     if (!PEM_write_PrivateKey(f, pkey, nullptr, nullptr, 0, nullptr, nullptr)) {
-        D("Failed to write key");
+        LOG(ERROR) << "Failed to write key";
+        goto out;
+    }
+
+    if (!android::base::WriteStringToFile(pubkey, file + ".pub")) {
+        PLOG(ERROR) << "failed to write public key";
         goto out;
     }
 
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index d1b798b..e2a17c5 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -262,7 +262,7 @@
 // stdout/stderr are routed independently and the remote exit code will be
 // returned.
 // if |callback| is non-null, stdout/stderr output will be handled by it.
-int read_and_dump(borrowed_fd fd, bool use_shell_protocol = false,
+int read_and_dump(int fd, bool use_shell_protocol = false,
                   StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK) {
     int exit_code = 0;
     if (fd < 0) return exit_code;
@@ -305,9 +305,9 @@
             }
             length = protocol->data_length();
         } else {
-            D("read_and_dump(): pre adb_read(fd=%d)", fd.get());
+            D("read_and_dump(): pre adb_read(fd=%d)", fd);
             length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
-            D("read_and_dump(): post adb_read(fd=%d): length=%d", fd.get(), length);
+            D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
             if (length <= 0) {
                 break;
             }
@@ -887,7 +887,7 @@
             return -1;
         }
         fprintf(stderr, "adb: trying pre-KitKat sideload method...\n");
-        return adb_sideload_legacy(filename, package_fd.get(), static_cast<int>(sb.st_size));
+        return adb_sideload_legacy(filename, package_fd, static_cast<int>(sb.st_size));
     }
 
     int opt = SIDELOAD_HOST_BLOCK_SIZE;
@@ -904,12 +904,12 @@
         }
         buf[8] = '\0';
 
-        if (strcmp(kSideloadServiceExitSuccess, buf) == 0 ||
-            strcmp(kSideloadServiceExitFailure, buf) == 0) {
+        if (strcmp(kMinadbdServicesExitSuccess, buf) == 0 ||
+            strcmp(kMinadbdServicesExitFailure, buf) == 0) {
             printf("\rTotal xfer: %.2fx%*s\n",
                    static_cast<double>(xfer) / (sb.st_size ? sb.st_size : 1),
                    static_cast<int>(strlen(filename) + 10), "");
-            if (strcmp(kSideloadServiceExitFailure, buf) == 0) {
+            if (strcmp(kMinadbdServicesExitFailure, buf) == 0) {
                 return 1;
             }
             return 0;
@@ -961,6 +961,33 @@
     }
 }
 
+static int adb_wipe_devices() {
+    auto wipe_devices_message_size = strlen(kMinadbdServicesExitSuccess);
+    std::string error;
+    unique_fd fd(adb_connect(
+            android::base::StringPrintf("rescue-wipe:userdata:%zu", wipe_devices_message_size),
+            &error));
+    if (fd < 0) {
+        fprintf(stderr, "adb: wipe device connection failed: %s\n", error.c_str());
+        return 1;
+    }
+
+    std::string message(wipe_devices_message_size, '\0');
+    if (!ReadFdExactly(fd, message.data(), wipe_devices_message_size)) {
+        fprintf(stderr, "adb: failed to read wipe result: %s\n", strerror(errno));
+        return 1;
+    }
+
+    if (message == kMinadbdServicesExitSuccess) {
+        return 0;
+    }
+
+    if (message != kMinadbdServicesExitFailure) {
+        fprintf(stderr, "adb: got unexpected message from rescue wipe %s\n", message.c_str());
+    }
+    return 1;
+}
+
 /**
  * Run ppp in "notty" mode against a resource listed as the first parameter
  * eg:
@@ -1180,14 +1207,14 @@
     return send_shell_command(cmd);
 }
 
-static void write_zeros(int bytes, borrowed_fd fd) {
+static void write_zeros(int bytes, int fd) {
     int old_stdin_mode = -1;
     int old_stdout_mode = -1;
     std::vector<char> buf(bytes);
 
-    D("write_zeros(%d) -> %d", bytes, fd.get());
+    D("write_zeros(%d) -> %d", bytes, fd);
 
-    stdinout_raw_prologue(-1, fd.get(), old_stdin_mode, old_stdout_mode);
+    stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
 
     if (fd == STDOUT_FILENO) {
         fwrite(buf.data(), 1, bytes, stdout);
@@ -1196,7 +1223,7 @@
         adb_write(fd, buf.data(), bytes);
     }
 
-    stdinout_raw_prologue(-1, fd.get(), old_stdin_mode, old_stdout_mode);
+    stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
 
     D("write_zeros() finished");
 }
@@ -1643,6 +1670,7 @@
     } else if (!strcmp(argv[0], "rescue")) {
         // adb rescue getprop <prop>
         // adb rescue install <filename>
+        // adb rescue wipe userdata
         if (argc != 3) error_exit("rescue requires two arguments");
         if (!strcmp(argv[1], "getprop")) {
             return adb_connect_command(android::base::StringPrintf("rescue-getprop:%s", argv[2]));
@@ -1650,6 +1678,8 @@
             if (adb_sideload_install(argv[2], true /* rescue_mode */) != 0) {
                 return 1;
             }
+        } else if (!strcmp(argv[1], "wipe") && !strcmp(argv[2], "userdata")) {
+            return adb_wipe_devices();
         } else {
             error_exit("invalid rescue argument");
         }
diff --git a/adb/daemon/abb.cpp b/adb/daemon/abb.cpp
index 87ee8aa..eeac41a 100644
--- a/adb/daemon/abb.cpp
+++ b/adb/daemon/abb.cpp
@@ -28,11 +28,11 @@
 
 class AdbFdTextOutput : public android::TextOutput {
   public:
-    explicit AdbFdTextOutput(borrowed_fd fd) : fd_(fd) {}
+    explicit AdbFdTextOutput(int fd) : mFD(fd) {}
 
   private:
     android::status_t print(const char* txt, size_t len) override {
-        return WriteFdExactly(fd_, txt, len) ? android::OK : -errno;
+        return WriteFdExactly(mFD, txt, len) ? android::OK : -errno;
     }
     void moveIndent(int delta) override { /*not implemented*/
     }
@@ -43,7 +43,7 @@
     }
 
   private:
-    borrowed_fd fd_;
+    int mFD;
 };
 
 std::vector<std::string_view> parseCmdArgs(std::string_view args) {
@@ -67,11 +67,10 @@
 
 }  // namespace
 
-static int execCmd(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err) {
+static int execCmd(std::string_view args, int in, int out, int err) {
     AdbFdTextOutput oin(out);
     AdbFdTextOutput oerr(err);
-    return cmdMain(parseCmdArgs(args), oin, oerr, in.get(), out.get(), err.get(),
-                   RunMode::kLibrary);
+    return cmdMain(parseCmdArgs(args), oin, oerr, in, out, err, RunMode::kLibrary);
 }
 
 int main(int argc, char* const argv[]) {
diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp
index 9d50151..e82a51f 100644
--- a/adb/daemon/file_sync_service.cpp
+++ b/adb/daemon/file_sync_service.cpp
@@ -235,8 +235,8 @@
 
     unique_fd fd(adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode));
 
-    if (posix_fadvise(fd.get(), 0, 0,
-                      POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) < 0) {
+    if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) <
+        0) {
         D("[ Failed to fadvise: %d ]", errno);
     }
 
@@ -464,9 +464,8 @@
         return false;
     }
 
-    int rc = posix_fadvise(fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
-    if (rc != 0) {
-        D("[ Failed to fadvise: %d ]", rc);
+    if (posix_fadvise(fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE) < 0) {
+        D("[ Failed to fadvise: %d ]", errno);
     }
 
     syncmsg msg;
diff --git a/adb/daemon/jdwp_service.cpp b/adb/daemon/jdwp_service.cpp
index cd9b669..66bfc0d 100644
--- a/adb/daemon/jdwp_service.cpp
+++ b/adb/daemon/jdwp_service.cpp
@@ -325,12 +325,12 @@
 
     addrlen = pathlen + sizeof(addr.sun_family);
 
-    if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
+    if (bind(s, reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
         D("could not bind vm debug control socket: %d: %s", errno, strerror(errno));
         return -1;
     }
 
-    if (listen(s.get(), 4) < 0) {
+    if (listen(s, 4) < 0) {
         D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno));
         return -1;
     }
diff --git a/adb/daemon/reboot_service.cpp b/adb/daemon/reboot_service.cpp
index 13398af..a5a11b8 100644
--- a/adb/daemon/reboot_service.cpp
+++ b/adb/daemon/reboot_service.cpp
@@ -58,7 +58,7 @@
 
         sockaddr_un addr = {.sun_family = AF_UNIX};
         strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1);
-        if (connect(sock.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
+        if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
             WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno));
             PLOG(ERROR) << "Couldn't connect to recovery socket";
             return;
diff --git a/adb/daemon/set_verity_enable_state_service.cpp b/adb/daemon/set_verity_enable_state_service.cpp
index da99665..889229f 100644
--- a/adb/daemon/set_verity_enable_state_service.cpp
+++ b/adb/daemon/set_verity_enable_state_service.cpp
@@ -58,7 +58,7 @@
     }
 
     int OFF = 0;
-    bool result = (ioctl(fd.get(), BLKROSET, &OFF) != -1);
+    bool result = (ioctl(fd, BLKROSET, &OFF) != -1);
     return result;
 }
 
@@ -194,7 +194,7 @@
         }
 
         if (!android::base::GetBoolProperty("ro.secure", false)) {
-            overlayfs_setup(fd.get(), enable);
+            overlayfs_setup(fd, enable);
             WriteFdExactly(fd.get(), "verity not enabled - ENG build\n");
             return;
         }
@@ -239,7 +239,7 @@
             }
         }
     }
-    if (!any_changed) any_changed = overlayfs_setup(fd.get(), enable);
+    if (!any_changed) any_changed = overlayfs_setup(fd, enable);
 
     if (any_changed) {
         WriteFdExactly(fd.get(), "Now reboot your device for settings to take effect\n");
diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp
index de97068..3c8f393 100644
--- a/adb/daemon/shell_service.cpp
+++ b/adb/daemon/shell_service.cpp
@@ -114,7 +114,7 @@
 namespace {
 
 // Reads from |fd| until close or failure.
-std::string ReadAll(borrowed_fd fd) {
+std::string ReadAll(int fd) {
     char buffer[512];
     std::string received;
 
@@ -317,10 +317,9 @@
             child_stdinout_sfd.reset(OpenPtyChildFd(pts_name, &child_error_sfd));
         }
 
-        dup2(child_stdinout_sfd.get(), STDIN_FILENO);
-        dup2(child_stdinout_sfd.get(), STDOUT_FILENO);
-        dup2(child_stderr_sfd != -1 ? child_stderr_sfd.get() : child_stdinout_sfd.get(),
-             STDERR_FILENO);
+        dup2(child_stdinout_sfd, STDIN_FILENO);
+        dup2(child_stdinout_sfd, STDOUT_FILENO);
+        dup2(child_stderr_sfd != -1 ? child_stderr_sfd : child_stdinout_sfd, STDERR_FILENO);
 
         // exec doesn't trigger destructors, close the FDs manually.
         stdinout_sfd_.reset(-1);
@@ -416,7 +415,7 @@
         }
     } else {
         // Raw protocol doesn't support multiple output streams, so combine stdout and stderr.
-        child_stderr_sfd.reset(dup(child_stdinout_sfd.get()));
+        child_stderr_sfd.reset(dup(child_stdinout_sfd));
     }
 
     D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
@@ -538,7 +537,7 @@
     FD_ZERO(&master_write_set);
     for (unique_fd* sfd : {&protocol_sfd_, &stdinout_sfd_, &stderr_sfd_}) {
         if (*sfd != -1) {
-            FD_SET(sfd->get(), &master_read_set);
+            FD_SET(*sfd, &master_read_set);
         }
     }
 
@@ -548,8 +547,8 @@
         unique_fd* dead_sfd = SelectLoop(&master_read_set, &master_write_set);
         if (dead_sfd) {
             D("closing FD %d", dead_sfd->get());
-            FD_CLR(dead_sfd->get(), &master_read_set);
-            FD_CLR(dead_sfd->get(), &master_write_set);
+            FD_CLR(*dead_sfd, &master_read_set);
+            FD_CLR(*dead_sfd, &master_write_set);
             if (dead_sfd == &protocol_sfd_) {
                 // Using SIGHUP is a decent general way to indicate that the
                 // controlling process is going away. If specific signals are
@@ -574,7 +573,7 @@
 namespace {
 
 inline bool ValidAndInSet(const unique_fd& sfd, fd_set* set) {
-    return sfd != -1 && FD_ISSET(sfd.get(), set);
+    return sfd != -1 && FD_ISSET(sfd, set);
 }
 
 }   // namespace
@@ -582,8 +581,7 @@
 unique_fd* Subprocess::SelectLoop(fd_set* master_read_set_ptr,
                                   fd_set* master_write_set_ptr) {
     fd_set read_set, write_set;
-    int select_n =
-            std::max(std::max(protocol_sfd_.get(), stdinout_sfd_.get()), stderr_sfd_.get()) + 1;
+    int select_n = std::max(std::max(protocol_sfd_, stdinout_sfd_), stderr_sfd_) + 1;
     unique_fd* dead_sfd = nullptr;
 
     // Keep calling select() and passing data until an FD closes/errors.
@@ -616,8 +614,8 @@
             dead_sfd = PassInput();
             // If we didn't finish writing, block on stdin write.
             if (input_bytes_left_) {
-                FD_CLR(protocol_sfd_.get(), master_read_set_ptr);
-                FD_SET(stdinout_sfd_.get(), master_write_set_ptr);
+                FD_CLR(protocol_sfd_, master_read_set_ptr);
+                FD_SET(stdinout_sfd_, master_write_set_ptr);
             }
         }
 
@@ -626,8 +624,8 @@
             dead_sfd = PassInput();
             // If we finished writing, go back to blocking on protocol read.
             if (!input_bytes_left_) {
-                FD_SET(protocol_sfd_.get(), master_read_set_ptr);
-                FD_CLR(stdinout_sfd_.get(), master_write_set_ptr);
+                FD_SET(protocol_sfd_, master_read_set_ptr);
+                FD_CLR(stdinout_sfd_, master_write_set_ptr);
             }
         }
     }  // while (!dead_sfd)
@@ -641,7 +639,7 @@
         if (!input_->Read()) {
             // Read() uses ReadFdExactly() which sets errno to 0 on EOF.
             if (errno != 0) {
-                PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_.get();
+                PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_;
             }
             return &protocol_sfd_;
         }
@@ -657,7 +655,7 @@
                         ws.ws_col = cols;
                         ws.ws_xpixel = x_pixels;
                         ws.ws_ypixel = y_pixels;
-                        ioctl(stdinout_sfd_.get(), TIOCSWINSZ, &ws);
+                        ioctl(stdinout_sfd_, TIOCSWINSZ, &ws);
                     }
                     break;
                 case ShellProtocol::kIdStdin:
@@ -668,7 +666,8 @@
                         if (adb_shutdown(stdinout_sfd_, SHUT_WR) == 0) {
                             return nullptr;
                         }
-                        PLOG(ERROR) << "failed to shutdown writes to FD " << stdinout_sfd_.get();
+                        PLOG(ERROR) << "failed to shutdown writes to FD "
+                                    << stdinout_sfd_;
                         return &stdinout_sfd_;
                     } else {
                         // PTYs can't close just input, so rather than close the
@@ -689,7 +688,7 @@
         int bytes = adb_write(stdinout_sfd_, input_->data() + index, input_bytes_left_);
         if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
             if (bytes < 0) {
-                PLOG(ERROR) << "error reading stdin FD " << stdinout_sfd_.get();
+                PLOG(ERROR) << "error reading stdin FD " << stdinout_sfd_;
             }
             // stdin is done, mark this packet as finished and we'll just start
             // dumping any further data received from the protocol FD.
@@ -709,14 +708,14 @@
         // read() returns EIO if a PTY closes; don't report this as an error,
         // it just means the subprocess completed.
         if (bytes < 0 && !(type_ == SubprocessType::kPty && errno == EIO)) {
-            PLOG(ERROR) << "error reading output FD " << sfd->get();
+            PLOG(ERROR) << "error reading output FD " << *sfd;
         }
         return sfd;
     }
 
     if (bytes > 0 && !output_->Write(id, bytes)) {
         if (errno != 0) {
-            PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_.get();
+            PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_;
         }
         return &protocol_sfd_;
     }
diff --git a/adb/daemon/shell_service.h b/adb/daemon/shell_service.h
index 030228c..3abd958 100644
--- a/adb/daemon/shell_service.h
+++ b/adb/daemon/shell_service.h
@@ -48,7 +48,7 @@
 // Sets up in/out and error streams to emulate shell-like behavior.
 //
 // Returns an open FD connected to the thread or -1 on failure.
-using Command = int(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err);
+using Command = int(std::string_view args, int in, int out, int err);
 unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol);
 
 // Create a pipe containing the error.
diff --git a/adb/daemon/shell_service_test.cpp b/adb/daemon/shell_service_test.cpp
index cdd8dbe..dc79d12 100644
--- a/adb/daemon/shell_service_test.cpp
+++ b/adb/daemon/shell_service_test.cpp
@@ -77,7 +77,7 @@
 namespace {
 
 // Reads raw data from |fd| until it closes or errors.
-std::string ReadRaw(borrowed_fd fd) {
+std::string ReadRaw(int fd) {
     char buffer[1024];
     char *cur_ptr = buffer, *end_ptr = buffer + sizeof(buffer);
 
@@ -93,12 +93,12 @@
 // Reads shell protocol data from |fd| until it closes or errors. Fills
 // |stdout| and |stderr| with their respective data, and returns the exit code
 // read from the protocol or -1 if an exit code packet was not received.
-int ReadShellProtocol(borrowed_fd fd, std::string* stdout, std::string* stderr) {
+int ReadShellProtocol(int fd, std::string* stdout, std::string* stderr) {
     int exit_code = -1;
     stdout->clear();
     stderr->clear();
 
-    auto protocol = std::make_unique<ShellProtocol>(fd.get());
+    auto protocol = std::make_unique<ShellProtocol>(fd);
     while (protocol->Read()) {
         switch (protocol->id()) {
             case ShellProtocol::kIdStdout:
diff --git a/adb/services.h b/adb/services.h
index 8f3919b..6fc89d7 100644
--- a/adb/services.h
+++ b/adb/services.h
@@ -23,9 +23,10 @@
 constexpr char kShellServiceArgPty[] = "pty";
 constexpr char kShellServiceArgShellProtocol[] = "v2";
 
-// Special flags sent by minadbd that indicate the end of sideload transfer and install result.
-constexpr char kSideloadServiceExitSuccess[] = "DONEDONE";
-constexpr char kSideloadServiceExitFailure[] = "FAILFAIL";
+// Special flags sent by minadbd. They indicate the end of sideload transfer and the result of
+// installation or wipe.
+constexpr char kMinadbdServicesExitSuccess[] = "DONEDONE";
+constexpr char kMinadbdServicesExitFailure[] = "FAILFAIL";
 
 unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func);
 #endif  // SERVICES_H_
diff --git a/adb/shell_protocol.h b/adb/shell_protocol.h
index 4aab813..2c82689 100644
--- a/adb/shell_protocol.h
+++ b/adb/shell_protocol.h
@@ -21,7 +21,6 @@
 #include <android-base/macros.h>
 
 #include "adb.h"
-#include "adb_unique_fd.h"
 
 // Class to send and receive shell protocol packets.
 //
@@ -61,7 +60,7 @@
     // should be dynamically allocated on the heap instead.
     //
     // |fd| is an open file descriptor to be used to send or receive packets.
-    explicit ShellProtocol(borrowed_fd fd);
+    explicit ShellProtocol(int fd);
     virtual ~ShellProtocol();
 
     // Returns a pointer to the data buffer.
@@ -104,7 +103,7 @@
         kHeaderSize = sizeof(Id) + sizeof(length_t)
     };
 
-    borrowed_fd fd_;
+    int fd_;
     char buffer_[kBufferSize];
     size_t data_length_ = 0, bytes_left_ = 0;
 
diff --git a/adb/shell_service_protocol.cpp b/adb/shell_service_protocol.cpp
index 95afaff..13b66ec 100644
--- a/adb/shell_service_protocol.cpp
+++ b/adb/shell_service_protocol.cpp
@@ -22,7 +22,7 @@
 
 #include "adb_io.h"
 
-ShellProtocol::ShellProtocol(borrowed_fd fd) : fd_(fd) {
+ShellProtocol::ShellProtocol(int fd) : fd_(fd) {
     buffer_[0] = kIdInvalid;
 }
 
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index 1333724..de4fff9 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -314,14 +314,14 @@
         addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port;
         addr.svm_cid = VMADDR_CID_ANY;
         socklen_t addr_len = sizeof(addr);
-        if (bind(serverfd.get(), reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
+        if (bind(serverfd, reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
             return -1;
         }
-        if (listen(serverfd.get(), 4)) {
+        if (listen(serverfd, 4)) {
             return -1;
         }
         if (serverfd >= 0 && resolved_port) {
-            if (getsockname(serverfd.get(), reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
+            if (getsockname(serverfd, reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
                 *resolved_port = addr.svm_port;
             } else {
                 return -1;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 78abba5..15247e7 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -36,7 +36,6 @@
 #include <android-base/unique_fd.h>
 #include <android-base/utf8.h>
 
-#include "adb_unique_fd.h"
 #include "sysdeps/errno.h"
 #include "sysdeps/network.h"
 #include "sysdeps/stat.h"
@@ -77,40 +76,42 @@
 
 extern int adb_thread_setname(const std::string& name);
 
-static __inline__ void close_on_exec(borrowed_fd fd) {
+static __inline__ void  close_on_exec(int  fd)
+{
     /* nothing really */
 }
 
-extern int adb_unlink(const char* path);
-#undef unlink
-#define unlink ___xxx_unlink
+extern int  adb_unlink(const char*  path);
+#undef  unlink
+#define unlink  ___xxx_unlink
 
 extern int adb_mkdir(const std::string& path, int mode);
-#undef mkdir
-#define mkdir ___xxx_mkdir
+#undef   mkdir
+#define  mkdir  ___xxx_mkdir
 
 // See the comments for the !defined(_WIN32) versions of adb_*().
 extern int adb_open(const char* path, int options);
 extern int adb_creat(const char* path, int mode);
-extern int adb_read(borrowed_fd fd, void* buf, int len);
-extern int adb_write(borrowed_fd fd, const void* buf, int len);
-extern int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where);
-extern int adb_shutdown(borrowed_fd fd, int direction = SHUT_RDWR);
+extern int adb_read(int fd, void* buf, int len);
+extern int adb_write(int fd, const void* buf, int len);
+extern int64_t adb_lseek(int fd, int64_t pos, int where);
+extern int adb_shutdown(int fd, int direction = SHUT_RDWR);
 extern int adb_close(int fd);
 extern int adb_register_socket(SOCKET s);
 
 // See the comments for the !defined(_WIN32) version of unix_close().
-static __inline__ int unix_close(int fd) {
+static __inline__ int  unix_close(int fd)
+{
     return close(fd);
 }
-#undef close
-#define close ____xxx_close
+#undef   close
+#define  close   ____xxx_close
 
 // Like unix_read(), but may return EINTR.
-extern int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len);
+extern int  unix_read_interruptible(int  fd, void*  buf, size_t  len);
 
 // See the comments for the !defined(_WIN32) version of unix_read().
-static __inline__ int unix_read(borrowed_fd fd, void* buf, size_t len) {
+static __inline__ int unix_read(int fd, void* buf, size_t len) {
     return TEMP_FAILURE_RETRY(unix_read_interruptible(fd, buf, len));
 }
 
@@ -118,21 +119,23 @@
 #define  read  ___xxx_read
 
 // See the comments for the !defined(_WIN32) version of unix_write().
-static __inline__ int unix_write(borrowed_fd fd, const void* buf, size_t len) {
-    return write(fd.get(), buf, len);
+static __inline__  int  unix_write(int  fd, const void*  buf, size_t  len)
+{
+    return write(fd, buf, len);
 }
 #undef   write
 #define  write  ___xxx_write
 
 // See the comments for the !defined(_WIN32) version of unix_lseek().
-static __inline__ int unix_lseek(borrowed_fd fd, int pos, int where) {
-    return lseek(fd.get(), pos, where);
+static __inline__ int unix_lseek(int fd, int pos, int where) {
+    return lseek(fd, pos, where);
 }
 #undef lseek
 #define lseek ___xxx_lseek
 
 // See the comments for the !defined(_WIN32) version of adb_open_mode().
-static __inline__ int adb_open_mode(const char* path, int options, int mode) {
+static __inline__ int  adb_open_mode(const char* path, int options, int mode)
+{
     return adb_open(path, options);
 }
 
@@ -149,7 +152,7 @@
 // with |fd| must have GENERIC_READ access (which console FDs have by default).
 // Returns 1 if |fd| is a console FD, 0 otherwise. The value of errno after
 // calling this function is unreliable and should not be used.
-int unix_isatty(borrowed_fd fd);
+int unix_isatty(int fd);
 #define  isatty  ___xxx_isatty
 
 int network_inaddr_any_server(int port, int type, std::string* error);
@@ -165,21 +168,20 @@
 int network_connect(const std::string& host, int port, int type, int timeout,
                     std::string* error);
 
-extern int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen);
+extern int  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen);
 
 #undef   accept
 #define  accept  ___xxx_accept
 
 // Returns the local port number of a bound socket, or -1 on failure.
-int adb_socket_get_local_port(borrowed_fd fd);
+int adb_socket_get_local_port(int fd);
 
-extern int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval,
-                          socklen_t optlen);
+extern int  adb_setsockopt(int  fd, int  level, int  optname, const void*  optval, socklen_t  optlen);
 
 #undef   setsockopt
 #define  setsockopt  ___xxx_setsockopt
 
-extern int adb_socketpair(int sv[2]);
+extern int  adb_socketpair( int  sv[2] );
 
 struct adb_pollfd {
     int fd;
@@ -212,7 +214,8 @@
 extern int adb_fputc(int ch, FILE* stream);
 extern int adb_putchar(int ch);
 extern int adb_puts(const char* buf);
-extern size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
+extern size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb,
+                         FILE* stream);
 
 extern FILE* adb_fopen(const char* f, const char* m);
 
@@ -341,8 +344,9 @@
     return c == '/';
 }
 
-static __inline__ void close_on_exec(borrowed_fd fd) {
-    fcntl(fd.get(), F_SETFD, FD_CLOEXEC);
+static __inline__ void  close_on_exec(int  fd)
+{
+    fcntl( fd, F_SETFD, FD_CLOEXEC );
 }
 
 // Open a file and return a file descriptor that may be used with unix_read(),
@@ -370,10 +374,12 @@
 
 // Similar to the two-argument adb_open(), but takes a mode parameter for file
 // creation. See adb_open() for more info.
-static __inline__ int adb_open_mode(const char* pathname, int options, int mode) {
-    return TEMP_FAILURE_RETRY(open(pathname, options, mode));
+static __inline__ int  adb_open_mode( const char*  pathname, int  options, int  mode )
+{
+    return TEMP_FAILURE_RETRY( open( pathname, options, mode ) );
 }
 
+
 // Open a file and return a file descriptor that may be used with adb_read(),
 // adb_write(), adb_close(), but not unix_read(), unix_write(), unix_close().
 //
@@ -381,21 +387,23 @@
 // sysdeps_win32.cpp) uses Windows native file I/O and bypasses the C Runtime
 // and its CR/LF translation. The returned file descriptor should be used with
 // adb_read(), adb_write(), adb_close(), etc.
-static __inline__ int adb_open(const char* pathname, int options) {
-    int fd = TEMP_FAILURE_RETRY(open(pathname, options));
-    if (fd < 0) return -1;
-    close_on_exec(fd);
+static __inline__ int  adb_open( const char*  pathname, int  options )
+{
+    int  fd = TEMP_FAILURE_RETRY( open( pathname, options ) );
+    if (fd < 0)
+        return -1;
+    close_on_exec( fd );
     return fd;
 }
-#undef open
-#define open ___xxx_open
+#undef   open
+#define  open    ___xxx_open
 
-static __inline__ int adb_shutdown(borrowed_fd fd, int direction = SHUT_RDWR) {
-    return shutdown(fd.get(), direction);
+static __inline__ int adb_shutdown(int fd, int direction = SHUT_RDWR) {
+    return shutdown(fd, direction);
 }
 
-#undef shutdown
-#define shutdown ____xxx_shutdown
+#undef   shutdown
+#define  shutdown   ____xxx_shutdown
 
 // Closes a file descriptor that came from adb_open() or adb_open_mode(), but
 // not designed to take a file descriptor from unix_open(). See the comments
@@ -403,76 +411,81 @@
 __inline__ int adb_close(int fd) {
     return close(fd);
 }
-#undef close
-#define close ____xxx_close
+#undef   close
+#define  close   ____xxx_close
 
 // On Windows, ADB has an indirection layer for file descriptors. If we get a
 // Win32 SOCKET object from an external library, we have to map it in to that
 // indirection layer, which this does.
-__inline__ int adb_register_socket(int s) {
+__inline__ int  adb_register_socket(int s) {
     return s;
 }
 
-static __inline__ int adb_read(borrowed_fd fd, void* buf, size_t len) {
-    return TEMP_FAILURE_RETRY(read(fd.get(), buf, len));
+static __inline__  int  adb_read(int  fd, void*  buf, size_t  len)
+{
+    return TEMP_FAILURE_RETRY( read( fd, buf, len ) );
 }
 
 // Like unix_read(), but does not handle EINTR.
-static __inline__ int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len) {
-    return read(fd.get(), buf, len);
+static __inline__ int unix_read_interruptible(int fd, void* buf, size_t len) {
+    return read(fd, buf, len);
 }
 
-#undef read
-#define read ___xxx_read
+#undef   read
+#define  read  ___xxx_read
 
-static __inline__ int adb_write(borrowed_fd fd, const void* buf, size_t len) {
-    return TEMP_FAILURE_RETRY(write(fd.get(), buf, len));
+static __inline__  int  adb_write(int  fd, const void*  buf, size_t  len)
+{
+    return TEMP_FAILURE_RETRY( write( fd, buf, len ) );
 }
 #undef   write
 #define  write  ___xxx_write
 
-static __inline__ int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) {
+static __inline__ int64_t adb_lseek(int fd, int64_t pos, int where) {
 #if defined(__APPLE__)
-    return lseek(fd.get(), pos, where);
+    return lseek(fd, pos, where);
 #else
-    return lseek64(fd.get(), pos, where);
+    return lseek64(fd, pos, where);
 #endif
 }
 #undef lseek
 #define lseek ___xxx_lseek
 
-static __inline__ int adb_unlink(const char* path) {
-    return unlink(path);
+static __inline__  int    adb_unlink(const char*  path)
+{
+    return  unlink(path);
 }
-#undef unlink
-#define unlink ___xxx_unlink
+#undef  unlink
+#define unlink  ___xxx_unlink
 
-static __inline__ int adb_creat(const char* path, int mode) {
-    int fd = TEMP_FAILURE_RETRY(creat(path, mode));
+static __inline__  int  adb_creat(const char*  path, int  mode)
+{
+    int  fd = TEMP_FAILURE_RETRY( creat( path, mode ) );
 
-    if (fd < 0) return -1;
+    if ( fd < 0 )
+        return -1;
 
     close_on_exec(fd);
     return fd;
 }
-#undef creat
-#define creat ___xxx_creat
+#undef   creat
+#define  creat  ___xxx_creat
 
-static __inline__ int unix_isatty(borrowed_fd fd) {
-    return isatty(fd.get());
+static __inline__ int unix_isatty(int fd) {
+    return isatty(fd);
 }
-#define isatty ___xxx_isatty
+#define  isatty  ___xxx_isatty
 
 // Helper for network_* functions.
 inline int _fd_set_error_str(int fd, std::string* error) {
-    if (fd == -1) {
-        *error = strerror(errno);
-    }
-    return fd;
+  if (fd == -1) {
+    *error = strerror(errno);
+  }
+  return fd;
 }
 
 inline int network_inaddr_any_server(int port, int type, std::string* error) {
-    return _fd_set_error_str(socket_inaddr_any_server(port, type), error);
+  return _fd_set_error_str(socket_inaddr_any_server(port, type), error);
 }
 
 inline int network_local_client(const char* name, int namespace_id, int type, std::string* error) {
@@ -485,21 +498,22 @@
 
 int network_connect(const std::string& host, int port, int type, int timeout, std::string* error);
 
-static __inline__ int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr,
-                                        socklen_t* addrlen) {
+static __inline__ int  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen)
+{
     int fd;
 
-    fd = TEMP_FAILURE_RETRY(accept(serverfd.get(), addr, addrlen));
-    if (fd >= 0) close_on_exec(fd);
+    fd = TEMP_FAILURE_RETRY( accept( serverfd, addr, addrlen ) );
+    if (fd >= 0)
+        close_on_exec(fd);
 
     return fd;
 }
 
-#undef accept
-#define accept ___xxx_accept
+#undef   accept
+#define  accept  ___xxx_accept
 
-inline int adb_socket_get_local_port(borrowed_fd fd) {
-    return socket_get_local_port(fd.get());
+inline int adb_socket_get_local_port(int fd) {
+    return socket_get_local_port(fd);
 }
 
 // Operate on a file descriptor returned from unix_open() or a well-known file
@@ -510,10 +524,10 @@
 // Windows implementations (in the ifdef above and in sysdeps_win32.cpp) call
 // into the C Runtime and its configurable CR/LF translation (which is settable
 // via _setmode()).
-#define unix_read adb_read
-#define unix_write adb_write
+#define  unix_read   adb_read
+#define  unix_write  adb_write
 #define unix_lseek adb_lseek
-#define unix_close adb_close
+#define  unix_close  adb_close
 
 static __inline__ int adb_thread_setname(const std::string& name) {
 #ifdef __APPLE__
@@ -528,31 +542,34 @@
 #endif
 }
 
-static __inline__ int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval,
-                                     socklen_t optlen) {
-    return setsockopt(fd.get(), level, optname, optval, optlen);
+static __inline__ int  adb_setsockopt( int  fd, int  level, int  optname, const void*  optval, socklen_t  optlen )
+{
+    return setsockopt( fd, level, optname, optval, optlen );
 }
 
-#undef setsockopt
-#define setsockopt ___xxx_setsockopt
+#undef   setsockopt
+#define  setsockopt  ___xxx_setsockopt
 
-static __inline__ int unix_socketpair(int d, int type, int protocol, int sv[2]) {
-    return socketpair(d, type, protocol, sv);
+static __inline__ int  unix_socketpair( int  d, int  type, int  protocol, int sv[2] )
+{
+    return socketpair( d, type, protocol, sv );
 }
 
-static __inline__ int adb_socketpair(int sv[2]) {
-    int rc;
+static __inline__ int  adb_socketpair( int  sv[2] )
+{
+    int  rc;
 
-    rc = unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
-    if (rc < 0) return -1;
+    rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
+    if (rc < 0)
+        return -1;
 
-    close_on_exec(sv[0]);
-    close_on_exec(sv[1]);
+    close_on_exec( sv[0] );
+    close_on_exec( sv[1] );
     return 0;
 }
 
-#undef socketpair
-#define socketpair ___xxx_socketpair
+#undef   socketpair
+#define  socketpair   ___xxx_socketpair
 
 typedef struct pollfd adb_pollfd;
 static __inline__ int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) {
@@ -561,12 +578,13 @@
 
 #define poll ___xxx_poll
 
-static __inline__ int adb_mkdir(const std::string& path, int mode) {
+static __inline__ int  adb_mkdir(const std::string& path, int mode)
+{
     return mkdir(path.c_str(), mode);
 }
 
-#undef mkdir
-#define mkdir ___xxx_mkdir
+#undef   mkdir
+#define  mkdir  ___xxx_mkdir
 
 static __inline__ int adb_is_absolute_host_path(const char* path) {
     return path[0] == '/';
@@ -574,15 +592,15 @@
 
 #endif /* !_WIN32 */
 
-static inline void disable_tcp_nagle(borrowed_fd fd) {
+static inline void disable_tcp_nagle(int fd) {
     int off = 1;
-    adb_setsockopt(fd.get(), IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
+    adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
 }
 
 // Sets TCP socket |fd| to send a keepalive TCP message every |interval_sec| seconds. Set
 // |interval_sec| to 0 to disable keepalives. If keepalives are enabled, the connection will be
 // configured to drop after 10 missed keepalives. Returns true on success.
-bool set_tcp_keepalive(borrowed_fd fd, int interval_sec);
+bool set_tcp_keepalive(int fd, int interval_sec);
 
 #if defined(_WIN32)
 // Win32 defines ERROR, which we don't need, but which conflicts with google3 logging.
diff --git a/adb/sysdeps/posix/network.cpp b/adb/sysdeps/posix/network.cpp
index c5c2275..4de240e 100644
--- a/adb/sysdeps/posix/network.cpp
+++ b/adb/sysdeps/posix/network.cpp
@@ -104,13 +104,13 @@
     socklen_t addrlen = sizeof(addr_storage);
     sockaddr* addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, port);
 
-    if (bind(s.get(), addr, addrlen) != 0) {
+    if (bind(s, addr, addrlen) != 0) {
         set_error(error);
         return -1;
     }
 
     if (type == SOCK_STREAM || type == SOCK_SEQPACKET) {
-        if (listen(s.get(), SOMAXCONN) != 0) {
+        if (listen(s, SOMAXCONN) != 0) {
             set_error(error);
             return -1;
         }
diff --git a/adb/sysdeps/uio.h b/adb/sysdeps/uio.h
index ced884b..d06ef89 100644
--- a/adb/sysdeps/uio.h
+++ b/adb/sysdeps/uio.h
@@ -18,8 +18,6 @@
 
 #include <sys/types.h>
 
-#include "adb_unique_fd.h"
-
 #if defined(_WIN32)
 
 // Layout of this struct must match struct WSABUF (verified via static assert in sysdeps_win32.cpp)
@@ -28,15 +26,13 @@
     void* iov_base;
 };
 
-ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt);
+ssize_t adb_writev(int fd, const adb_iovec* iov, int iovcnt);
 
 #else
 
 #include <sys/uio.h>
 using adb_iovec = struct iovec;
-inline ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt) {
-    return writev(fd.get(), iov, iovcnt);
-}
+#define adb_writev writev
 
 #endif
 
diff --git a/adb/sysdeps_unix.cpp b/adb/sysdeps_unix.cpp
index 3fdc917..4445a44 100644
--- a/adb/sysdeps_unix.cpp
+++ b/adb/sysdeps_unix.cpp
@@ -16,7 +16,7 @@
 
 #include "sysdeps.h"
 
-bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) {
+bool set_tcp_keepalive(int fd, int interval_sec) {
     int enable = (interval_sec > 0);
     if (adb_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable))) {
         return false;
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 886ded4..4c5d8cb 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -145,14 +145,16 @@
 static  FHRec        _win32_fhs[ WIN32_MAX_FHS ];
 static  int          _win32_fh_next;  // where to start search for free FHRec
 
-static FH _fh_from_int(borrowed_fd bfd, const char* func) {
-    FH f;
+static FH
+_fh_from_int( int   fd, const char*   func )
+{
+    FH  f;
 
-    int fd = bfd.get();
     fd -= WIN32_FH_BASE;
 
     if (fd < 0 || fd >= WIN32_MAX_FHS) {
-        D("_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE, func);
+        D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
+           func );
         errno = EBADF;
         return nullptr;
     }
@@ -160,7 +162,8 @@
     f = &_win32_fhs[fd];
 
     if (f->used == 0) {
-        D("_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE, func);
+        D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
+           func );
         errno = EBADF;
         return nullptr;
     }
@@ -168,15 +171,20 @@
     return f;
 }
 
-static int _fh_to_int(FH f) {
+
+static int
+_fh_to_int( FH  f )
+{
     if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
         return (int)(f - _win32_fhs) + WIN32_FH_BASE;
 
     return -1;
 }
 
-static FH _fh_alloc(FHClass clazz) {
-    FH f = nullptr;
+static FH
+_fh_alloc( FHClass  clazz )
+{
+    FH   f = nullptr;
 
     std::lock_guard<std::mutex> lock(_win32_lock);
 
@@ -198,7 +206,10 @@
     return nullptr;
 }
 
-static int _fh_close(FH f) {
+
+static int
+_fh_close( FH   f )
+{
     // Use lock so that closing only happens once and so that _fh_alloc can't
     // allocate a FH that we're in the middle of closing.
     std::lock_guard<std::mutex> lock(_win32_lock);
@@ -445,7 +456,7 @@
     return _fh_to_int(f);
 }
 
-int adb_read(borrowed_fd fd, void* buf, int len) {
+int adb_read(int fd, void* buf, int len) {
     FH f = _fh_from_int(fd, __func__);
 
     if (f == nullptr) {
@@ -456,7 +467,7 @@
     return f->clazz->_fh_read(f, buf, len);
 }
 
-int adb_write(borrowed_fd fd, const void* buf, int len) {
+int adb_write(int fd, const void* buf, int len) {
     FH f = _fh_from_int(fd, __func__);
 
     if (f == nullptr) {
@@ -467,7 +478,7 @@
     return f->clazz->_fh_write(f, buf, len);
 }
 
-ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt) {
+ssize_t adb_writev(int fd, const adb_iovec* iov, int iovcnt) {
     FH f = _fh_from_int(fd, __func__);
 
     if (f == nullptr) {
@@ -478,7 +489,7 @@
     return f->clazz->_fh_writev(f, iov, iovcnt);
 }
 
-int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) {
+int64_t adb_lseek(int fd, int64_t pos, int where) {
     FH f = _fh_from_int(fd, __func__);
     if (!f) {
         errno = EBADF;
@@ -962,11 +973,11 @@
 }
 
 #undef accept
-int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen) {
+int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t* addrlen) {
     FH serverfh = _fh_from_int(serverfd, __func__);
 
     if (!serverfh || serverfh->clazz != &_fh_socket_class) {
-        D("adb_socket_accept: invalid fd %d", serverfd.get());
+        D("adb_socket_accept: invalid fd %d", serverfd);
         errno = EBADF;
         return -1;
     }
@@ -981,7 +992,7 @@
     fh->fh_socket = accept(serverfh->fh_socket, addr, addrlen);
     if (fh->fh_socket == INVALID_SOCKET) {
         const DWORD err = WSAGetLastError();
-        LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd.get()
+        LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd
                    << " failed: " + android::base::SystemErrorCodeToString(err);
         _socket_set_errno(err);
         return -1;
@@ -989,16 +1000,16 @@
 
     const int fd = _fh_to_int(fh.get());
     snprintf(fh->name, sizeof(fh->name), "%d(accept:%s)", fd, serverfh->name);
-    D("adb_socket_accept on fd %d returns fd %d", serverfd.get(), fd);
+    D("adb_socket_accept on fd %d returns fd %d", serverfd, fd);
     fh.release();
     return fd;
 }
 
-int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval, socklen_t optlen) {
+int adb_setsockopt(int fd, int level, int optname, const void* optval, socklen_t optlen) {
     FH fh = _fh_from_int(fd, __func__);
 
     if (!fh || fh->clazz != &_fh_socket_class) {
-        D("adb_setsockopt: invalid fd %d", fd.get());
+        D("adb_setsockopt: invalid fd %d", fd);
         errno = EBADF;
         return -1;
     }
@@ -1011,7 +1022,7 @@
         setsockopt(fh->fh_socket, level, optname, reinterpret_cast<const char*>(optval), optlen);
     if (result == SOCKET_ERROR) {
         const DWORD err = WSAGetLastError();
-        D("adb_setsockopt: setsockopt on fd %d level %d optname %d failed: %s\n", fd.get(), level,
+        D("adb_setsockopt: setsockopt on fd %d level %d optname %d failed: %s\n", fd, level,
           optname, android::base::SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         result = -1;
@@ -1019,11 +1030,11 @@
     return result;
 }
 
-static int adb_getsockname(borrowed_fd fd, struct sockaddr* sockaddr, socklen_t* optlen) {
+int adb_getsockname(int fd, struct sockaddr* sockaddr, socklen_t* optlen) {
     FH fh = _fh_from_int(fd, __func__);
 
     if (!fh || fh->clazz != &_fh_socket_class) {
-        D("adb_getsockname: invalid fd %d", fd.get());
+        D("adb_getsockname: invalid fd %d", fd);
         errno = EBADF;
         return -1;
     }
@@ -1031,7 +1042,7 @@
     int result = getsockname(fh->fh_socket, sockaddr, optlen);
     if (result == SOCKET_ERROR) {
         const DWORD err = WSAGetLastError();
-        D("adb_getsockname: setsockopt on fd %d failed: %s\n", fd.get(),
+        D("adb_getsockname: setsockopt on fd %d failed: %s\n", fd,
           android::base::SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         result = -1;
@@ -1039,7 +1050,7 @@
     return result;
 }
 
-int adb_socket_get_local_port(borrowed_fd fd) {
+int adb_socket_get_local_port(int fd) {
     sockaddr_storage addr_storage;
     socklen_t addr_len = sizeof(addr_storage);
 
@@ -1057,11 +1068,11 @@
     return ntohs(reinterpret_cast<sockaddr_in*>(&addr_storage)->sin_port);
 }
 
-int adb_shutdown(borrowed_fd fd, int direction) {
+int adb_shutdown(int fd, int direction) {
     FH f = _fh_from_int(fd, __func__);
 
     if (!f || f->clazz != &_fh_socket_class) {
-        D("adb_shutdown: invalid fd %d", fd.get());
+        D("adb_shutdown: invalid fd %d", fd);
         errno = EBADF;
         return -1;
     }
@@ -1069,7 +1080,7 @@
     D("adb_shutdown: %s", f->name);
     if (shutdown(f->fh_socket, direction) == SOCKET_ERROR) {
         const DWORD err = WSAGetLastError();
-        D("socket shutdown fd %d failed: %s", fd.get(),
+        D("socket shutdown fd %d failed: %s", fd,
           android::base::SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         return -1;
@@ -1127,12 +1138,12 @@
     return -1;
 }
 
-bool set_file_block_mode(borrowed_fd fd, bool block) {
+bool set_file_block_mode(int fd, bool block) {
     FH fh = _fh_from_int(fd, __func__);
 
     if (!fh || !fh->used) {
         errno = EBADF;
-        D("Setting nonblocking on bad file descriptor %d", fd.get());
+        D("Setting nonblocking on bad file descriptor %d", fd);
         return false;
     }
 
@@ -1141,22 +1152,22 @@
         if (ioctlsocket(fh->u.socket, FIONBIO, &x) != 0) {
             int error = WSAGetLastError();
             _socket_set_errno(error);
-            D("Setting %d nonblocking failed (%d)", fd.get(), error);
+            D("Setting %d nonblocking failed (%d)", fd, error);
             return false;
         }
         return true;
     } else {
         errno = ENOTSOCK;
-        D("Setting nonblocking on non-socket %d", fd.get());
+        D("Setting nonblocking on non-socket %d", fd);
         return false;
     }
 }
 
-bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) {
+bool set_tcp_keepalive(int fd, int interval_sec) {
     FH fh = _fh_from_int(fd, __func__);
 
     if (!fh || fh->clazz != &_fh_socket_class) {
-        D("set_tcp_keepalive(%d) failed: invalid fd", fd.get());
+        D("set_tcp_keepalive(%d) failed: invalid fd", fd);
         errno = EBADF;
         return false;
     }
@@ -1170,7 +1181,7 @@
     if (WSAIoctl(fh->fh_socket, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), nullptr, 0,
                  &bytes_returned, nullptr, nullptr) != 0) {
         const DWORD err = WSAGetLastError();
-        D("set_tcp_keepalive(%d) failed: %s", fd.get(),
+        D("set_tcp_keepalive(%d) failed: %s", fd,
           android::base::SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         return false;
@@ -1217,12 +1228,12 @@
 // Returns a console HANDLE if |fd| is a console, otherwise returns nullptr.
 // If a valid HANDLE is returned and |mode| is not null, |mode| is also filled
 // with the console mode. Requires GENERIC_READ access to the underlying HANDLE.
-static HANDLE _get_console_handle(borrowed_fd fd, DWORD* mode = nullptr) {
+static HANDLE _get_console_handle(int fd, DWORD* mode=nullptr) {
     // First check isatty(); this is very fast and eliminates most non-console
     // FDs, but returns 1 for both consoles and character devices like NUL.
 #pragma push_macro("isatty")
 #undef isatty
-    if (!isatty(fd.get())) {
+    if (!isatty(fd)) {
         return nullptr;
     }
 #pragma pop_macro("isatty")
@@ -1230,7 +1241,7 @@
     // To differentiate between character devices and consoles we need to get
     // the underlying HANDLE and use GetConsoleMode(), which is what requires
     // GENERIC_READ permissions.
-    const intptr_t intptr_handle = _get_osfhandle(fd.get());
+    const intptr_t intptr_handle = _get_osfhandle(fd);
     if (intptr_handle == -1) {
         return nullptr;
     }
@@ -1254,7 +1265,7 @@
     return _get_console_handle(fd);
 }
 
-int unix_isatty(borrowed_fd fd) {
+int unix_isatty(int fd) {
     return _get_console_handle(fd) ? 1 : 0;
 }
 
@@ -1634,7 +1645,7 @@
 
 // Prefix the len bytes in buf with the escape character, and then return the
 // new buffer length.
-static size_t _escape_prefix(char* const buf, const size_t len) {
+size_t _escape_prefix(char* const buf, const size_t len) {
     // If nothing to prefix, don't do anything. We might be called with
     // len == 0, if alt was held down with a dead key which produced nothing.
     if (len == 0) {
@@ -2062,7 +2073,7 @@
 }
 
 // Called by 'adb shell' and 'adb exec-in' (via unix_read()) to read from stdin.
-int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len) {
+int unix_read_interruptible(int fd, void* buf, size_t len) {
     if ((fd == STDIN_FILENO) && (_console_handle != nullptr)) {
         // If it is a request to read from stdin, and stdin_raw_init() has been
         // called, and it successfully configured the console, then read from
@@ -2082,7 +2093,7 @@
         // plain read() in favor of unix_read() or adb_read().
 #pragma push_macro("read")
 #undef read
-        return read(fd.get(), buf, len);
+        return read(fd, buf, len);
 #pragma pop_macro("read")
     }
 }
diff --git a/base/cmsg.cpp b/base/cmsg.cpp
index 1fa873c..42866f8 100644
--- a/base/cmsg.cpp
+++ b/base/cmsg.cpp
@@ -29,7 +29,7 @@
 namespace android {
 namespace base {
 
-ssize_t SendFileDescriptorVector(borrowed_fd sockfd, const void* data, size_t len,
+ssize_t SendFileDescriptorVector(int sockfd, const void* data, size_t len,
                                  const std::vector<int>& fds) {
   size_t cmsg_space = CMSG_SPACE(sizeof(int) * fds.size());
   size_t cmsg_len = CMSG_LEN(sizeof(int) * fds.size());
@@ -67,10 +67,10 @@
   int flags = 0;
 #endif
 
-  return TEMP_FAILURE_RETRY(sendmsg(sockfd.get(), &msg, flags));
+  return TEMP_FAILURE_RETRY(sendmsg(sockfd, &msg, flags));
 }
 
-ssize_t ReceiveFileDescriptorVector(borrowed_fd sockfd, void* data, size_t len, size_t max_fds,
+ssize_t ReceiveFileDescriptorVector(int sockfd, void* data, size_t len, size_t max_fds,
                                     std::vector<unique_fd>* fds) {
   fds->clear();
 
@@ -98,7 +98,7 @@
   flags |= MSG_CMSG_CLOEXEC | MSG_NOSIGNAL;
 #endif
 
-  ssize_t rc = TEMP_FAILURE_RETRY(recvmsg(sockfd.get(), &msg, flags));
+  ssize_t rc = TEMP_FAILURE_RETRY(recvmsg(sockfd, &msg, flags));
 
   if (rc == -1) {
     return -1;
diff --git a/base/file.cpp b/base/file.cpp
index 3dfcfbb..adc8984 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -176,20 +176,20 @@
 // Versions of standard library APIs that support UTF-8 strings.
 using namespace android::base::utf8;
 
-bool ReadFdToString(borrowed_fd fd, std::string* content) {
+bool ReadFdToString(int fd, std::string* content) {
   content->clear();
 
   // Although original we had small files in mind, this code gets used for
   // very large files too, where the std::string growth heuristics might not
   // be suitable. https://code.google.com/p/android/issues/detail?id=258500.
   struct stat sb;
-  if (fstat(fd.get(), &sb) != -1 && sb.st_size > 0) {
+  if (fstat(fd, &sb) != -1 && sb.st_size > 0) {
     content->reserve(sb.st_size);
   }
 
   char buf[BUFSIZ];
   ssize_t n;
-  while ((n = TEMP_FAILURE_RETRY(read(fd.get(), &buf[0], sizeof(buf)))) > 0) {
+  while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
     content->append(buf, n);
   }
   return (n == 0) ? true : false;
@@ -206,11 +206,11 @@
   return ReadFdToString(fd, content);
 }
 
-bool WriteStringToFd(const std::string& content, borrowed_fd fd) {
+bool WriteStringToFd(const std::string& content, int fd) {
   const char* p = content.data();
   size_t left = content.size();
   while (left > 0) {
-    ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, left));
+    ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, left));
     if (n == -1) {
       return false;
     }
@@ -269,11 +269,11 @@
   return WriteStringToFd(content, fd) || CleanUpAfterFailedWrite(path);
 }
 
-bool ReadFully(borrowed_fd fd, void* data, size_t byte_count) {
+bool ReadFully(int fd, void* data, size_t byte_count) {
   uint8_t* p = reinterpret_cast<uint8_t*>(data);
   size_t remaining = byte_count;
   while (remaining > 0) {
-    ssize_t n = TEMP_FAILURE_RETRY(read(fd.get(), p, remaining));
+    ssize_t n = TEMP_FAILURE_RETRY(read(fd, p, remaining));
     if (n <= 0) return false;
     p += n;
     remaining -= n;
@@ -284,14 +284,14 @@
 #if defined(_WIN32)
 // Windows implementation of pread. Note that this DOES move the file descriptors read position,
 // but it does so atomically.
-static ssize_t pread(borrowed_fd fd, void* data, size_t byte_count, off64_t offset) {
+static ssize_t pread(int fd, void* data, size_t byte_count, off64_t offset) {
   DWORD bytes_read;
   OVERLAPPED overlapped;
   memset(&overlapped, 0, sizeof(OVERLAPPED));
   overlapped.Offset = static_cast<DWORD>(offset);
   overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
-  if (!ReadFile(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), data,
-                static_cast<DWORD>(byte_count), &bytes_read, &overlapped)) {
+  if (!ReadFile(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), data, static_cast<DWORD>(byte_count),
+                &bytes_read, &overlapped)) {
     // In case someone tries to read errno (since this is masquerading as a POSIX call)
     errno = EIO;
     return -1;
@@ -300,10 +300,10 @@
 }
 #endif
 
-bool ReadFullyAtOffset(borrowed_fd fd, void* data, size_t byte_count, off64_t offset) {
+bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset) {
   uint8_t* p = reinterpret_cast<uint8_t*>(data);
   while (byte_count > 0) {
-    ssize_t n = TEMP_FAILURE_RETRY(pread(fd.get(), p, byte_count, offset));
+    ssize_t n = TEMP_FAILURE_RETRY(pread(fd, p, byte_count, offset));
     if (n <= 0) return false;
     p += n;
     byte_count -= n;
@@ -312,11 +312,11 @@
   return true;
 }
 
-bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count) {
+bool WriteFully(int fd, const void* data, size_t byte_count) {
   const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
   size_t remaining = byte_count;
   while (remaining > 0) {
-    ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, remaining));
+    ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining));
     if (n == -1) return false;
     p += n;
     remaining -= n;
diff --git a/base/include/android-base/cmsg.h b/base/include/android-base/cmsg.h
index e4197b1..7f93ddc 100644
--- a/base/include/android-base/cmsg.h
+++ b/base/include/android-base/cmsg.h
@@ -51,20 +51,20 @@
 // Note that the write can return short if the socket type is SOCK_STREAM. When
 // this happens, file descriptors are still sent to the other end, but with
 // truncated data. For this reason, using SOCK_SEQPACKET or SOCK_DGRAM is recommended.
-ssize_t SendFileDescriptorVector(borrowed_fd sock, const void* data, size_t len,
+ssize_t SendFileDescriptorVector(int sock, const void* data, size_t len,
                                  const std::vector<int>& fds);
 
 // Receive file descriptors from a Unix domain socket.
 //
 // If more FDs (or bytes, for datagram sockets) are received than expected,
 // -1 is returned with errno set to EMSGSIZE, and all received FDs are thrown away.
-ssize_t ReceiveFileDescriptorVector(borrowed_fd sock, void* data, size_t len, size_t max_fds,
+ssize_t ReceiveFileDescriptorVector(int sock, void* data, size_t len, size_t max_fds,
                                     std::vector<android::base::unique_fd>* fds);
 
 // Helper for SendFileDescriptorVector that constructs a std::vector for you, e.g.:
 //   SendFileDescriptors(sock, "foo", 3, std::move(fd1), std::move(fd2))
 template <typename... Args>
-ssize_t SendFileDescriptors(borrowed_fd sock, const void* data, size_t len, Args&&... sent_fds) {
+ssize_t SendFileDescriptors(int sock, const void* data, size_t len, Args&&... sent_fds) {
   // Do not allow implicit conversion to int: people might try to do something along the lines of:
   //   SendFileDescriptors(..., std::move(a_unique_fd))
   // and be surprised when the unique_fd isn't closed afterwards.
@@ -79,7 +79,7 @@
 // If fewer file descriptors are received than requested, -1 is returned with errno set to ENOMSG.
 // In both cases, all arguments are cleared and any received FDs are thrown away.
 template <typename... Args>
-ssize_t ReceiveFileDescriptors(borrowed_fd sock, void* data, size_t len, Args&&... received_fds) {
+ssize_t ReceiveFileDescriptors(int sock, void* data, size_t len, Args&&... received_fds) {
   std::vector<unique_fd*> fds;
   Append(fds, std::forward<Args>(received_fds)...);
 
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 44b9335..f8748b5 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -21,8 +21,7 @@
 
 #include <string>
 
-#include "android-base/macros.h"
-#include "android-base/unique_fd.h"
+#include <android-base/macros.h>
 #include "android-base/off64_t.h"
 
 #if !defined(_WIN32) && !defined(O_BINARY)
@@ -78,13 +77,13 @@
 namespace android {
 namespace base {
 
-bool ReadFdToString(borrowed_fd fd, std::string* content);
+bool ReadFdToString(int fd, std::string* content);
 bool ReadFileToString(const std::string& path, std::string* content,
                       bool follow_symlinks = false);
 
 bool WriteStringToFile(const std::string& content, const std::string& path,
                        bool follow_symlinks = false);
-bool WriteStringToFd(const std::string& content, borrowed_fd fd);
+bool WriteStringToFd(const std::string& content, int fd);
 
 #if !defined(_WIN32)
 bool WriteStringToFile(const std::string& content, const std::string& path,
@@ -92,7 +91,7 @@
                        bool follow_symlinks = false);
 #endif
 
-bool ReadFully(borrowed_fd fd, void* data, size_t byte_count);
+bool ReadFully(int fd, void* data, size_t byte_count);
 
 // Reads `byte_count` bytes from the file descriptor at the specified offset.
 // Returns false if there was an IO error or EOF was reached before reading `byte_count` bytes.
@@ -102,9 +101,9 @@
 // get modified. This means that ReadFullyAtOffset can be used concurrently with other calls to the
 // same function, but concurrently seeking or reading incrementally can lead to unexpected
 // behavior.
-bool ReadFullyAtOffset(borrowed_fd fd, void* data, size_t byte_count, off64_t offset);
+bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset);
 
-bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count);
+bool WriteFully(int fd, const void* data, size_t byte_count);
 
 bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);
 
diff --git a/base/include/android-base/mapped_file.h b/base/include/android-base/mapped_file.h
index b719646..80513b1 100644
--- a/base/include/android-base/mapped_file.h
+++ b/base/include/android-base/mapped_file.h
@@ -16,14 +16,13 @@
 
 #pragma once
 
+#include "android-base/macros.h"
+#include "android-base/off64_t.h"
+
 #include <sys/types.h>
 
 #include <memory>
 
-#include "android-base/macros.h"
-#include "android-base/off64_t.h"
-#include "android-base/unique_fd.h"
-
 #if defined(_WIN32)
 #include <windows.h>
 #define PROT_READ 1
@@ -45,8 +44,7 @@
    * `offset` does not need to be page-aligned. If `PROT_WRITE` is set in `prot`, the mapping
    * will be writable, otherwise it will be read-only. Mappings are always `MAP_SHARED`.
    */
-  static std::unique_ptr<MappedFile> FromFd(borrowed_fd fd, off64_t offset, size_t length,
-                                            int prot);
+  static std::unique_ptr<MappedFile> FromFd(int fd, off64_t offset, size_t length, int prot);
 
   /**
    * Removes the mapping.
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index 3a02cff..3fa3bea 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -103,17 +103,7 @@
   void reset(int new_value = -1) { reset(new_value, nullptr); }
 
   int get() const { return fd_; }
-
-#if !defined(ANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION)
-  // unique_fd's operator int is dangerous, but we have way too much code that
-  // depends on it, so make this opt-in at first.
   operator int() const { return get(); }  // NOLINT
-#endif
-
-  bool operator>=(int rhs) const { return get() >= rhs; }
-  bool operator<(int rhs) const { return get() < rhs; }
-  bool operator==(int rhs) const { return get() == rhs; }
-  bool operator!=(int rhs) const { return get() != rhs; }
 
   // Catch bogus error checks (i.e.: "!fd" instead of "fd != -1").
   bool operator!() const = delete;
@@ -256,22 +246,6 @@
 
 #endif  // !defined(_WIN32)
 
-// A wrapper type that can be implicitly constructed from either int or unique_fd.
-struct borrowed_fd {
-  /* implicit */ borrowed_fd(int fd) : fd_(fd) {}
-  template <typename T>
-  /* implicit */ borrowed_fd(const unique_fd_impl<T>& ufd) : fd_(ufd.get()) {}
-
-  int get() const { return fd_; }
-
-  bool operator>=(int rhs) const { return get() >= rhs; }
-  bool operator<(int rhs) const { return get() < rhs; }
-  bool operator==(int rhs) const { return get() == rhs; }
-  bool operator!=(int rhs) const { return get() != rhs; }
-
- private:
-  int fd_ = -1;
-};
 }  // namespace base
 }  // namespace android
 
diff --git a/base/mapped_file.cpp b/base/mapped_file.cpp
index f689bfa..7c65dc3 100644
--- a/base/mapped_file.cpp
+++ b/base/mapped_file.cpp
@@ -18,8 +18,6 @@
 
 #include <errno.h>
 
-#include "android-base/unique_fd.h"
-
 namespace android {
 namespace base {
 
@@ -33,8 +31,7 @@
 #endif
 }
 
-std::unique_ptr<MappedFile> MappedFile::FromFd(borrowed_fd fd, off64_t offset, size_t length,
-                                               int prot) {
+std::unique_ptr<MappedFile> MappedFile::FromFd(int fd, off64_t offset, size_t length, int prot) {
   static off64_t page_size = InitPageSize();
   size_t slop = offset % page_size;
   off64_t file_offset = offset - slop;
@@ -42,7 +39,7 @@
 
 #if defined(_WIN32)
   HANDLE handle =
-      CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), nullptr,
+      CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), nullptr,
                         (prot & PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, 0, 0, nullptr);
   if (handle == nullptr) {
     // http://b/119818070 "app crashes when reading asset of zero length".
@@ -61,7 +58,7 @@
   return std::unique_ptr<MappedFile>(
       new MappedFile{static_cast<char*>(base), length, slop, handle});
 #else
-  void* base = mmap(nullptr, file_length, prot, MAP_SHARED, fd.get(), file_offset);
+  void* base = mmap(nullptr, file_length, prot, MAP_SHARED, fd, file_offset);
   if (base == MAP_FAILED) {
     // http://b/119818070 "app crashes when reading asset of zero length".
     // mmap fails with EINVAL for a zero length region.
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/types.h b/debuggerd/libdebuggerd/include/libdebuggerd/types.h
index 70583af..eb4b1b8 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/types.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/types.h
@@ -23,6 +23,9 @@
 
 struct ThreadInfo {
   std::unique_ptr<unwindstack::Regs> registers;
+
+  pid_t uid;
+
   pid_t tid;
   std::string thread_name;
 
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index 3196ce8..88c206f 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -343,6 +343,16 @@
   ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
 }
 
+TEST_F(TombstoneTest, dump_thread_info_uid) {
+  dump_thread_info(&log_, ThreadInfo{.uid = 1,
+                                     .pid = 2,
+                                     .tid = 3,
+                                     .thread_name = "some_thread",
+                                     .process_name = "some_process"});
+  std::string expected = "pid: 2, tid: 3, name: some_thread  >>> some_process <<<\nuid: 1\n";
+  ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
+}
+
 TEST_F(TombstoneTest, dump_timestamp) {
   setenv("TZ", "UTC", 1);
   tzset();
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index d1726cd..d246722 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -151,6 +151,7 @@
 
   _LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s  >>> %s <<<\n", thread_info.pid,
        thread_info.tid, thread_info.thread_name.c_str(), thread_info.process_name.c_str());
+  _LOG(log, logtype::HEADER, "uid: %d\n", thread_info.uid);
 }
 
 static void dump_stack_segment(log_t* log, unwindstack::Maps* maps, unwindstack::Memory* memory,
@@ -615,6 +616,7 @@
 
 void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, siginfo_t* siginfo,
                                 ucontext_t* ucontext) {
+  pid_t uid = getuid();
   pid_t pid = getpid();
   pid_t tid = gettid();
 
@@ -636,6 +638,7 @@
   std::map<pid_t, ThreadInfo> threads;
   threads[gettid()] = ThreadInfo{
       .registers = std::move(regs),
+      .uid = uid,
       .tid = tid,
       .thread_name = thread_name,
       .pid = pid,
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 5b90969..0966b6c 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -19,13 +19,14 @@
 #include <dirent.h>
 #include <fcntl.h>
 #include <linux/fs.h>
-#include <mntent.h>
 #include <linux/loop.h>
+#include <mntent.h>
+#include <semaphore.h>
 #include <sys/cdefs.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
-#include <sys/swap.h>
 #include <sys/stat.h>
+#include <sys/swap.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -57,11 +58,14 @@
 #include "service.h"
 #include "sigchld_handler.h"
 
+#define PROC_SYSRQ "/proc/sysrq-trigger"
+
 using android::base::GetBoolProperty;
 using android::base::Split;
 using android::base::StringPrintf;
 using android::base::Timer;
 using android::base::unique_fd;
+using android::base::WriteStringToFile;
 
 namespace android {
 namespace init {
@@ -207,8 +211,8 @@
     }
     FindPartitionsToUmount(nullptr, nullptr, true);
     // dump current CPU stack traces and uninterruptible tasks
-    android::base::WriteStringToFile("l", "/proc/sysrq-trigger");
-    android::base::WriteStringToFile("w", "/proc/sysrq-trigger");
+    WriteStringToFile("l", PROC_SYSRQ);
+    WriteStringToFile("w", PROC_SYSRQ);
 }
 
 static UmountStat UmountPartitions(std::chrono::milliseconds timeout) {
@@ -248,7 +252,91 @@
     }
 }
 
-static void KillAllProcesses() { android::base::WriteStringToFile("i", "/proc/sysrq-trigger"); }
+static void KillAllProcesses() {
+    WriteStringToFile("i", PROC_SYSRQ);
+}
+
+// Create reboot/shutdwon monitor thread
+void RebootMonitorThread(unsigned int cmd, const std::string& rebootTarget, sem_t* reboot_semaphore,
+                         std::chrono::milliseconds shutdown_timeout, bool* reboot_monitor_run) {
+    unsigned int remaining_shutdown_time = 0;
+
+    // 30 seconds more than the timeout passed to the thread as there is a final Umount pass
+    // after the timeout is reached.
+    constexpr unsigned int shutdown_watchdog_timeout_default = 30;
+    auto shutdown_watchdog_timeout = android::base::GetUintProperty(
+            "ro.build.shutdown.watchdog.timeout", shutdown_watchdog_timeout_default);
+    remaining_shutdown_time = shutdown_watchdog_timeout + shutdown_timeout.count() / 1000;
+
+    while (*reboot_monitor_run == true) {
+        if (TEMP_FAILURE_RETRY(sem_wait(reboot_semaphore)) == -1) {
+            LOG(ERROR) << "sem_wait failed and exit RebootMonitorThread()";
+            return;
+        }
+
+        timespec shutdown_timeout_timespec;
+        if (clock_gettime(CLOCK_MONOTONIC, &shutdown_timeout_timespec) == -1) {
+            LOG(ERROR) << "clock_gettime() fail! exit RebootMonitorThread()";
+            return;
+        }
+
+        // If there are some remaining shutdown time left from previous round, we use
+        // remaining time here.
+        shutdown_timeout_timespec.tv_sec += remaining_shutdown_time;
+
+        LOG(INFO) << "shutdown_timeout_timespec.tv_sec: " << shutdown_timeout_timespec.tv_sec;
+
+        int sem_return = 0;
+        while ((sem_return = sem_timedwait_monotonic_np(reboot_semaphore,
+                                                        &shutdown_timeout_timespec)) == -1 &&
+               errno == EINTR) {
+        }
+
+        if (sem_return == -1) {
+            LOG(ERROR) << "Reboot thread timed out";
+
+            if (android::base::GetBoolProperty("ro.debuggable", false) == true) {
+                LOG(INFO) << "Try to dump init process call trace:";
+                const char* vdc_argv[] = {"/system/bin/debuggerd", "-b", "1"};
+                int status;
+                android_fork_execvp_ext(arraysize(vdc_argv), (char**)vdc_argv, &status, true,
+                                        LOG_KLOG, true, nullptr, nullptr, 0);
+
+                LOG(INFO) << "Show stack for all active CPU:";
+                WriteStringToFile("l", PROC_SYSRQ);
+
+                LOG(INFO) << "Show tasks that are in disk sleep(uninterruptable sleep), which are "
+                             "like "
+                             "blocked in mutex or hardware register access:";
+                WriteStringToFile("w", PROC_SYSRQ);
+            }
+
+            // In shutdown case,notify kernel to sync and umount fs to read-only before shutdown.
+            if (cmd == ANDROID_RB_POWEROFF || cmd == ANDROID_RB_THERMOFF) {
+                WriteStringToFile("s", PROC_SYSRQ);
+
+                WriteStringToFile("u", PROC_SYSRQ);
+
+                RebootSystem(cmd, rebootTarget);
+            }
+
+            LOG(ERROR) << "Trigger crash at last!";
+            WriteStringToFile("c", PROC_SYSRQ);
+        } else {
+            timespec current_time_timespec;
+
+            if (clock_gettime(CLOCK_MONOTONIC, &current_time_timespec) == -1) {
+                LOG(ERROR) << "clock_gettime() fail! exit RebootMonitorThread()";
+                return;
+            }
+
+            remaining_shutdown_time =
+                    shutdown_timeout_timespec.tv_sec - current_time_timespec.tv_sec;
+
+            LOG(INFO) << "remaining_shutdown_time: " << remaining_shutdown_time;
+        }
+    }
+}
 
 /* Try umounting all emulated file systems R/W block device cfile systems.
  * This will just try umount and give it up if it fails.
@@ -259,7 +347,8 @@
  *
  * return true when umount was successful. false when timed out.
  */
-static UmountStat TryUmountAndFsck(bool runFsck, std::chrono::milliseconds timeout) {
+static UmountStat TryUmountAndFsck(unsigned int cmd, const std::string& rebootTarget, bool runFsck,
+                                   std::chrono::milliseconds timeout, sem_t* reboot_semaphore) {
     Timer t;
     std::vector<MountEntry> block_devices;
     std::vector<MountEntry> emulated_devices;
@@ -279,11 +368,17 @@
     }
 
     if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
+        LOG(INFO) << "Pause reboot monitor thread before fsck";
+        sem_post(reboot_semaphore);
+
         // fsck part is excluded from timeout check. It only runs for user initiated shutdown
         // and should not affect reboot time.
         for (auto& entry : block_devices) {
             entry.DoFsck();
         }
+
+        LOG(INFO) << "Resume reboot monitor thread after fsck";
+        sem_post(reboot_semaphore);
     }
     return stat;
 }
@@ -311,7 +406,7 @@
     }
     LOG(INFO) << "swapoff() took " << swap_timer;;
 
-    if (!android::base::WriteStringToFile("1", ZRAM_RESET)) {
+    if (!WriteStringToFile("1", ZRAM_RESET)) {
         LOG(ERROR) << "zram_backing_dev: reset (" << backing_dev << ")" << " failed";
         return;
     }
@@ -369,6 +464,23 @@
     }
     LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
 
+    sem_t reboot_semaphore;
+    if (sem_init(&reboot_semaphore, false, 0) == -1) {
+        // These should never fail, but if they do, skip the graceful reboot and reboot immediately.
+        LOG(ERROR) << "sem_init() fail and RebootSystem() return!";
+        RebootSystem(cmd, rebootTarget);
+    }
+
+    // Start a thread to monitor init shutdown process
+    LOG(INFO) << "Create reboot monitor thread.";
+    bool reboot_monitor_run = true;
+    std::thread reboot_monitor_thread(&RebootMonitorThread, cmd, rebootTarget, &reboot_semaphore,
+                                      shutdown_timeout, &reboot_monitor_run);
+    reboot_monitor_thread.detach();
+
+    // Start reboot monitor thread
+    sem_post(&reboot_semaphore);
+
     // keep debugging tools until non critical ones are all gone.
     const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
     // watchdogd is a vendor specific component but should be alive to complete shutdown safely.
@@ -497,7 +609,8 @@
     // 5. drop caches and disable zram backing device, if exist
     KillZramBackingDevice();
 
-    UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
+    UmountStat stat = TryUmountAndFsck(cmd, rebootTarget, runFsck, shutdown_timeout - t.duration(),
+                                       &reboot_semaphore);
     // Follow what linux shutdown is doing: one more sync with little bit delay
     {
         Timer sync_timer;
@@ -507,6 +620,11 @@
     }
     if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
     LogShutdownTime(stat, &t);
+
+    // Send signal to terminate reboot monitor thread.
+    reboot_monitor_run = false;
+    sem_post(&reboot_semaphore);
+
     // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
     RebootSystem(cmd, rebootTarget);
     abort();
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 5cc0857..1012ea0 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -126,7 +126,7 @@
 // classloader, the classloader-namespace namespace associated with that
 // classloader is selected for dlopen. The namespace is configured so that its
 // search path is set to the app-local JNI directory and it is linked to the
-// default namespace with the names of libs listed in the public.libraries.txt.
+// platform namespace with the names of libs listed in the public.libraries.txt.
 // This way an app can only load its own JNI libraries along with the public libs.
 static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
 // Same thing for vendor APKs.
@@ -220,7 +220,9 @@
       }
     }
 
-    if (!initialized_ && !InitPublicNamespace(library_path.c_str(), error_msg)) {
+    // Initialize the anonymous namespace with the first non-empty library path.
+    if (!library_path.empty() && !initialized_ &&
+        !InitPublicNamespace(library_path.c_str(), error_msg)) {
       return nullptr;
     }
 
@@ -307,21 +309,24 @@
       }
     }
 
-    std::string runtime_exposed_libraries = base::Join(kRuntimePublicLibraries, ":");
+    std::string runtime_exposed_libraries = runtime_public_libraries_;
 
     NativeLoaderNamespace native_loader_ns;
     if (!is_native_bridge) {
+      // The platform namespace is called "default" for binaries in /system and
+      // "platform" for those in the Runtime APEX. Try "platform" first since
+      // "default" always exists.
+      android_namespace_t* platform_ns = android_get_exported_namespace(kPlatformNamespaceName);
+      if (platform_ns == nullptr) {
+        platform_ns = android_get_exported_namespace(kDefaultNamespaceName);
+      }
+
       android_namespace_t* android_parent_ns;
       if (parent_ns != nullptr) {
         android_parent_ns = parent_ns->get_android_ns();
       } else {
-        // Fall back to the platform namespace if no parent is found. It is
-        // called "default" for binaries in /system and "platform" for those in
-        // the Runtime APEX. Try "platform" first since "default" always exists.
-        android_parent_ns = android_get_exported_namespace(kPlatformNamespaceName);
-        if (android_parent_ns == nullptr) {
-          android_parent_ns = android_get_exported_namespace(kDefaultNamespaceName);
-        }
+        // Fall back to the platform namespace if no parent is found.
+        android_parent_ns = platform_ns;
       }
 
       android_namespace_t* ns = android_create_namespace(namespace_name,
@@ -342,7 +347,7 @@
 
       android_namespace_t* runtime_ns = android_get_exported_namespace(kRuntimeNamespaceName);
 
-      if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
+      if (!android_link_namespaces(ns, platform_ns, system_exposed_libraries.c_str())) {
         *error_msg = dlerror();
         return nullptr;
       }
@@ -372,14 +377,19 @@
 
       native_loader_ns = NativeLoaderNamespace(ns);
     } else {
+      // Same functionality as in the branch above, but calling through native bridge.
+
+      native_bridge_namespace_t* platform_ns =
+          NativeBridgeGetExportedNamespace(kPlatformNamespaceName);
+      if (platform_ns == nullptr) {
+        platform_ns = NativeBridgeGetExportedNamespace(kDefaultNamespaceName);
+      }
+
       native_bridge_namespace_t* native_bridge_parent_namespace;
       if (parent_ns != nullptr) {
         native_bridge_parent_namespace = parent_ns->get_native_bridge_ns();
       } else {
-        native_bridge_parent_namespace = NativeBridgeGetExportedNamespace(kPlatformNamespaceName);
-        if (native_bridge_parent_namespace == nullptr) {
-          native_bridge_parent_namespace = NativeBridgeGetExportedNamespace(kDefaultNamespaceName);
-        }
+        native_bridge_parent_namespace = platform_ns;
       }
 
       native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
@@ -397,7 +407,7 @@
       native_bridge_namespace_t* runtime_ns =
           NativeBridgeGetExportedNamespace(kRuntimeNamespaceName);
 
-      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
+      if (!NativeBridgeLinkNamespaces(ns, platform_ns, system_exposed_libraries.c_str())) {
         *error_msg = NativeBridgeGetError();
         return nullptr;
       }
@@ -449,6 +459,7 @@
     std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
     std::string public_native_libraries_system_config =
             root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
+    std::string runtime_public_libraries = base::Join(kRuntimePublicLibraries, ":");
     std::string llndk_native_libraries_system_config =
             root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
     std::string vndksp_native_libraries_system_config =
@@ -470,6 +481,10 @@
         std::vector<std::string> additional_libs_vector = base::Split(additional_libs, ":");
         std::copy(additional_libs_vector.begin(), additional_libs_vector.end(),
                   std::back_inserter(sonames));
+        // Apply the same list to the runtime namespace, since some libraries
+        // might reside there.
+        CHECK(sizeof(kRuntimePublicLibraries) > 0);
+        runtime_public_libraries = runtime_public_libraries + ':' + additional_libs;
       }
     }
 
@@ -495,6 +510,7 @@
     }
 
     system_public_libraries_ = base::Join(sonames, ':');
+    runtime_public_libraries_ = runtime_public_libraries;
 
     // read /system/etc/public.libraries-<companyname>.txt which contain partner defined
     // system libs that are exposed to apps. The libs in the txt files must be
@@ -722,6 +738,7 @@
   bool initialized_;
   std::list<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
   std::string system_public_libraries_;
+  std::string runtime_public_libraries_;
   std::string vendor_public_libraries_;
   std::string oem_public_libraries_;
   std::string product_public_libraries_;
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index aa392ce..85b8cdc 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -20,6 +20,9 @@
 
 [legacy]
 namespace.default.isolated = false
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
 
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /product/${LIB}
@@ -41,7 +44,7 @@
 
 additional.namespaces = runtime,conscrypt,media,resolv
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
 # cannot be loaded into the default namespace, the dynamic linker tries
 # to load the shared library from the runtime namespace. And then, if the
@@ -50,9 +53,6 @@
 # Finally, if all attempts fail, the dynamic linker returns an error.
 namespace.default.links = runtime,resolv
 namespace.default.asan.links = runtime,resolv
-# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
-# libart.
-namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libnativebridge.so
 namespace.default.link.runtime.shared_libs += libnativehelper.so
@@ -71,11 +71,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -119,11 +121,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 3f9882a..b37a551 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -43,6 +43,9 @@
 # can't be loaded in this namespace.
 ###############################################################################
 namespace.default.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
 
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /%PRODUCT%/${LIB}
@@ -121,7 +124,7 @@
 namespace.default.asan.permitted.paths += /apex/com.android.runtime/${LIB}/bionic
 namespace.default.asan.permitted.paths += /system/${LIB}/bootstrap
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
 # cannot be loaded into the default namespace, the dynamic linker tries
 # to load the shared library from the runtime namespace. And then, if the
@@ -129,9 +132,6 @@
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
 namespace.default.links = runtime,resolv
-# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
-# libart.
-namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libnativebridge.so
 namespace.default.link.runtime.shared_libs += libnativehelper.so
@@ -150,11 +150,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -187,11 +189,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
@@ -234,6 +236,8 @@
 # Note that there is no link from the default namespace to this namespace.
 ###############################################################################
 namespace.sphal.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.sphal.visible = true
 
 namespace.sphal.search.paths  = /odm/${LIB}
@@ -323,6 +327,8 @@
 # This namespace is exclusively for vndk-sp libs.
 ###############################################################################
 namespace.vndk.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.vndk.visible = true
 
 namespace.vndk.search.paths  = /odm/${LIB}/vndk-sp
@@ -430,10 +436,10 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = system
@@ -564,6 +570,10 @@
 [unrestricted]
 additional.namespaces = runtime,media,conscrypt,resolv
 
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
+
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
 namespace.default.search.paths += /vendor/${LIB}
@@ -575,10 +585,8 @@
 namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 namespace.default.links = runtime,resolv
-namespace.default.visible = true
-
 namespace.default.link.runtime.shared_libs  = libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libnativebridge.so
 namespace.default.link.runtime.shared_libs += libnativehelper.so
@@ -594,11 +602,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -629,11 +639,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 6d89886..04fbd82 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -43,6 +43,9 @@
 # partitions are also allowed temporarily.
 ###############################################################################
 namespace.default.isolated = false
+# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
+# libart.
+namespace.default.visible = true
 
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
@@ -61,8 +64,7 @@
 namespace.default.asan.search.paths += /data/asan/%PRODUCT_SERVICES%/${LIB}
 namespace.default.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
-# Keep in sync with the platform namespace in the com.android.runtime APEX
-# ld.config.txt.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
 # cannot be loaded into the default namespace, the dynamic linker tries
 # to load the shared library from the runtime namespace. And then, if the
@@ -70,9 +72,6 @@
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
 namespace.default.links = runtime,resolv
-# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
-# libart.
-namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libnativebridge.so
 namespace.default.link.runtime.shared_libs += libnativehelper.so
@@ -91,12 +90,13 @@
 # "runtime" APEX namespace
 #
 # This namespace pulls in externally accessible libs from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with the default namespace in the com.android.runtime APEX
-# ld.config.txt.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -129,11 +129,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default
@@ -176,6 +176,8 @@
 # Note that there is no link from the default namespace to this namespace.
 ###############################################################################
 namespace.sphal.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.sphal.visible = true
 
 namespace.sphal.search.paths  = /odm/${LIB}
@@ -265,6 +267,8 @@
 # This namespace is exclusively for vndk-sp libs.
 ###############################################################################
 namespace.vndk.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.vndk.visible = true
 
 namespace.vndk.search.paths  = /odm/${LIB}/vndk-sp
@@ -367,10 +371,10 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -387,6 +391,10 @@
 [unrestricted]
 additional.namespaces = runtime,media,conscrypt,resolv
 
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
+namespace.default.visible = true
+
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
 namespace.default.search.paths += /vendor/${LIB}
@@ -398,10 +406,8 @@
 namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+# Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 namespace.default.links = runtime,resolv
-namespace.default.visible = true
-
 namespace.default.link.runtime.shared_libs  = libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libnativebridge.so
 namespace.default.link.runtime.shared_libs += libnativehelper.so
@@ -417,11 +423,13 @@
 # "runtime" APEX namespace
 #
 # This namespace exposes externally accessible libraries from the Runtime APEX.
+# Keep in sync with the "runtime" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.runtime.isolated = true
+# Visible to allow links to be created at runtime, e.g. through
+# android_link_namespaces in libnativeloader.
 namespace.runtime.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
 namespace.runtime.links = default
@@ -452,11 +460,11 @@
 # "conscrypt" APEX namespace
 #
 # This namespace is for libraries within the conscrypt APEX.
+# Keep in sync with the "conscrypt" namespace in art/build/apex/ld.config.txt.
 ###############################################################################
 namespace.conscrypt.isolated = true
 namespace.conscrypt.visible = true
 
-# Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.links = runtime,default