Merge "adb: enable -Wthread-safety on linux/darwin."
diff --git a/adb/Android.mk b/adb/Android.mk
index 7f5ea43..819bad1 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -367,6 +367,7 @@
 LOCAL_STRIP_MODULE := keep_symbols
 LOCAL_STATIC_LIBRARIES := \
     libadbd \
+    libavb_user \
     libbase \
     libbootloader_message \
     libfs_mgr \
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index c3f1fe0..365bf77 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -82,16 +82,17 @@
         return false;
     }
 
-    size_t base64_key_length;
-    if (!EVP_EncodedLength(&base64_key_length, sizeof(binary_key_data))) {
+    size_t expected_length;
+    if (!EVP_EncodedLength(&expected_length, sizeof(binary_key_data))) {
         LOG(ERROR) << "Public key too large to base64 encode";
         return false;
     }
 
     std::string content;
-    content.resize(base64_key_length);
-    base64_key_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
-                                        sizeof(binary_key_data));
+    content.resize(expected_length);
+    size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
+                                           sizeof(binary_key_data));
+    content.resize(actual_length);
 
     content += get_user_info();
 
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index da2cfa2..d0cc072 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -48,7 +48,7 @@
           show_progress_(show_progress),
           status_(0),
           line_(),
-          last_progress_(0) {
+          last_progress_percentage_(0) {
         SetLineMessage("generating");
     }
 
@@ -147,13 +147,14 @@
             size_t idx1 = line.rfind(BUGZ_PROGRESS_PREFIX) + strlen(BUGZ_PROGRESS_PREFIX);
             size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
             int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
-            if (progress <= last_progress_) {
+            int total = std::stoi(line.substr(idx2 + 1));
+            int progress_percentage = (progress * 100 / total);
+            if (progress_percentage <= last_progress_percentage_) {
                 // Ignore.
                 return;
             }
-            last_progress_ = progress;
-            int total = std::stoi(line.substr(idx2 + 1));
-            br_->UpdateProgress(line_message_, progress, total);
+            last_progress_percentage_ = progress_percentage;
+            br_->UpdateProgress(line_message_, progress_percentage);
         } else {
             invalid_lines_.push_back(line);
         }
@@ -189,7 +190,7 @@
 
     // Last displayed progress.
     // Since dumpstate progress can recede, only forward progress should be displayed
-    int last_progress_;
+    int last_progress_percentage_;
 
     DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
 };
@@ -267,8 +268,7 @@
     return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
 }
 
-void Bugreport::UpdateProgress(const std::string& message, int progress, int total) {
-    int progress_percentage = (progress * 100 / total);
+void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) {
     line_printer_.Print(
         android::base::StringPrintf("[%3d%%] %s", progress_percentage, message.c_str()),
         LinePrinter::INFO);
diff --git a/adb/bugreport.h b/adb/bugreport.h
index ee99cbc..d9a4468 100644
--- a/adb/bugreport.h
+++ b/adb/bugreport.h
@@ -43,7 +43,7 @@
                             const char* name);
 
   private:
-    virtual void UpdateProgress(const std::string& file_name, int progress, int total);
+    virtual void UpdateProgress(const std::string& file_name, int progress_percentage);
     LinePrinter line_printer_;
     DISALLOW_COPY_AND_ASSIGN(Bugreport);
 };
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
index b500c49..2b368d7 100644
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -123,7 +123,7 @@
                      bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
     MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
                                   bool copy_attrs, const char* name));
-    MOCK_METHOD3(UpdateProgress, void(const std::string&, int, int));
+    MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
 };
 
 class BugreportTest : public ::testing::Test {
@@ -142,8 +142,8 @@
                             WithArg<4>(ReturnCallbackDone(0))));
     }
 
-    void ExpectProgress(int progress, int total, const std::string& file = "file.zip") {
-        EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress, total));
+    void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
+        EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress_percentage));
     }
 
     BugreportMock br_;
@@ -200,7 +200,7 @@
     ExpectBugreportzVersion("1.1");
     std::string dest_file =
         android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
-    ExpectProgress(50, 100, "da_bugreport.zip");
+    ExpectProgress(50, "da_bugreport.zip");
     EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
         .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
                         WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
@@ -247,10 +247,10 @@
 // Tests 'adb bugreport file.zip' when it succeeds and displays progress.
 TEST_F(BugreportTest, OkProgress) {
     ExpectBugreportzVersion("1.1");
-    ExpectProgress(1, 100);
-    ExpectProgress(10, 100);
-    ExpectProgress(50, 100);
-    ExpectProgress(99, 100);
+    ExpectProgress(1);
+    ExpectProgress(10);
+    ExpectProgress(50);
+    ExpectProgress(99);
     // clang-format off
     EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
@@ -283,21 +283,23 @@
 // Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
 TEST_F(BugreportTest, OkProgressAlwaysForward) {
     ExpectBugreportzVersion("1.1");
-    ExpectProgress(1, 100);
-    ExpectProgress(50, 100);
-    ExpectProgress(75, 100);
+    ExpectProgress(1);
+    ExpectProgress(50);
+    ExpectProgress(75);
     // clang-format off
     EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
         .WillOnce(DoAll(
             WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
-            WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
-            WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
-            // 25 should be ignored becaused it receded.
-            WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")),
-            WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")),
-            // 75 should be ignored becaused it didn't change.
-            WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")),
+            WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
+            WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
+            // 25% should be ignored becaused it receded.
+            WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
+            WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
+            // 75% should be ignored becaused it didn't change.
+            WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
+            // Try a receeding percentage with a different max progress
+            WithArg<4>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
             WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
             WithArg<4>(ReturnCallbackDone())));
     // clang-format on
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 5f55ab9..a9b1540 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -68,20 +68,17 @@
 static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
 static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
 
-static auto& gProductOutPath = *new std::string();
 extern int gListenAll;
 
 DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
 
-static std::string product_file(const char *extra) {
-    if (gProductOutPath.empty()) {
-        fprintf(stderr, "adb: Product directory not specified; "
-                "use -p or define ANDROID_PRODUCT_OUT\n");
+static std::string product_file(const char* file) {
+    const char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
+    if (ANDROID_PRODUCT_OUT == nullptr) {
+        fprintf(stderr, "adb: product directory not specified; set $ANDROID_PRODUCT_OUT\n");
         exit(1);
     }
-
-    return android::base::StringPrintf("%s%s%s",
-                                       gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
+    return android::base::StringPrintf("%s%s%s", ANDROID_PRODUCT_OUT, OS_PATH_SEPARATOR_STR, file);
 }
 
 static void help() {
@@ -92,11 +89,7 @@
         " -a         listen on all network interfaces, not just localhost\n"
         " -d         use USB device (error if multiple devices connected)\n"
         " -e         use TCP/IP device (error if multiple TCP/IP devices available)\n"
-        " -s SERIAL\n"
-        "     use device with given serial number (overrides $ANDROID_SERIAL)\n"
-        " -p PRODUCT\n"
-        "     name or path ('angler'/'out/target/product/angler');\n"
-        "     default $ANDROID_PRODUCT_OUT\n"
+        " -s SERIAL  use device with given serial (overrides $ANDROID_SERIAL)\n"
         " -H         name of adb server host [default=localhost]\n"
         " -P         port of adb server [default=5037]\n"
         " -L SOCKET  listen on given socket for adb server [default=tcp:localhost:5037]\n"
@@ -138,9 +131,8 @@
         " pull [-a] REMOTE... LOCAL\n"
         "     copy files/dirs from device\n"
         "     -a: preserve file timestamp and mode\n"
-        " sync [DIR]\n"
-        "     copy all changed files to device; if DIR is \"system\", \"vendor\", \"oem\",\n"
-        "     or \"data\", only sync that partition (default all)\n"
+        " sync [system|vendor|oem|data|all]\n"
+        "     sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)\n"
         "     -l: list but don't copy\n"
         "\n"
         "shell:\n"
@@ -769,55 +761,46 @@
     return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command);
 }
 
-static int adb_download_buffer(const char* service, const char* filename) {
-    std::string content;
-    if (!android::base::ReadFileToString(filename, &content)) {
-        fprintf(stderr, "error: couldn't read %s: %s\n", filename, strerror(errno));
-        return -1;
-    }
-
-    const uint8_t* data = reinterpret_cast<const uint8_t*>(content.data());
-    unsigned sz = content.size();
-
+static int adb_sideload_legacy(const char* filename, int in_fd, int size) {
     std::string error;
-    int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
-    if (fd < 0) {
-        fprintf(stderr,"error: %s\n", error.c_str());
+    int out_fd = adb_connect(android::base::StringPrintf("sideload:%d", size), &error);
+    if (out_fd < 0) {
+        fprintf(stderr, "adb: pre-KitKat sideload connection failed: %s\n", error.c_str());
         return -1;
     }
 
     int opt = CHUNK_SIZE;
-    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
+    opt = adb_setsockopt(out_fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
 
-    unsigned total = sz;
-    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
-
-    const char* x = strrchr(service, ':');
-    if (x) service = x + 1;
-
-    while (sz > 0) {
-        unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
-        if (!WriteFdExactly(fd, ptr, xfer)) {
-            std::string error;
-            adb_status(fd, &error);
-            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
-            adb_close(fd);
+    char buf[CHUNK_SIZE];
+    int total = size;
+    while (size > 0) {
+        unsigned xfer = (size > CHUNK_SIZE) ? CHUNK_SIZE : size;
+        if (!ReadFdExactly(in_fd, buf, xfer)) {
+            fprintf(stderr, "adb: failed to read data from %s: %s\n", filename, strerror(errno));
+            adb_close(out_fd);
             return -1;
         }
-        sz -= xfer;
-        ptr += xfer;
-        printf("sending: '%s' %4d%%    \r", filename, (int)(100LL - ((100LL * sz) / (total))));
+        if (!WriteFdExactly(out_fd, buf, xfer)) {
+            std::string error;
+            adb_status(out_fd, &error);
+            fprintf(stderr, "adb: failed to write data: %s\n", error.c_str());
+            adb_close(out_fd);
+            return -1;
+        }
+        size -= xfer;
+        printf("sending: '%s' %4d%%    \r", filename, (int)(100LL - ((100LL * size) / (total))));
         fflush(stdout);
     }
     printf("\n");
 
-    if (!adb_status(fd, &error)) {
-        fprintf(stderr,"* error response '%s' *\n", error.c_str());
-        adb_close(fd);
+    if (!adb_status(out_fd, &error)) {
+        fprintf(stderr, "adb: error response: %s\n", error.c_str());
+        adb_close(out_fd);
         return -1;
     }
 
-    adb_close(fd);
+    adb_close(out_fd);
     return 0;
 }
 
@@ -844,22 +827,17 @@
  */
 static int adb_sideload_host(const char* filename) {
     // TODO: use a LinePrinter instead...
-    fprintf(stdout, "opening '%s'...\n", filename);
-    fflush(stdout);
-
     struct stat sb;
     if (stat(filename, &sb) == -1) {
-        fprintf(stderr, "failed to stat file %s: %s\n", filename, strerror(errno));
+        fprintf(stderr, "adb: failed to stat file %s: %s\n", filename, strerror(errno));
         return -1;
     }
     unique_fd package_fd(adb_open(filename, O_RDONLY));
     if (package_fd == -1) {
-        fprintf(stderr, "failed to open file %s: %s\n", filename, strerror(errno));
+        fprintf(stderr, "adb: failed to open file %s: %s\n", filename, strerror(errno));
         return -1;
     }
 
-    fprintf(stdout, "connecting...\n");
-    fflush(stdout);
     std::string service = android::base::StringPrintf(
         "sideload-host:%d:%d", static_cast<int>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
     std::string error;
@@ -867,8 +845,9 @@
     if (device_fd < 0) {
         // Try falling back to the older (<= K) sideload method. Maybe this
         // is an older device that doesn't support sideload-host.
-        fprintf(stderr, "falling back to older sideload method...\n");
-        return adb_download_buffer("sideload", filename);
+        fprintf(stderr, "adb: sideload connection failed: %s\n", error.c_str());
+        fprintf(stderr, "adb: trying pre-KitKat sideload method...\n");
+        return adb_sideload_legacy(filename, package_fd, static_cast<int>(sb.st_size));
     }
 
     int opt = SIDELOAD_HOST_BLOCK_SIZE;
@@ -880,7 +859,7 @@
     int last_percent = -1;
     while (true) {
         if (!ReadFdExactly(device_fd, buf, 8)) {
-            fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
+            fprintf(stderr, "adb: failed to read command: %s\n", strerror(errno));
             return -1;
         }
         buf[8] = '\0';
@@ -896,7 +875,7 @@
 
         size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
         if (offset >= static_cast<size_t>(sb.st_size)) {
-            fprintf(stderr, "* attempt to read block %d past end\n", block);
+            fprintf(stderr, "adb: failed to read block %d past end\n", block);
             return -1;
         }
 
@@ -906,17 +885,17 @@
         }
 
         if (adb_lseek(package_fd, offset, SEEK_SET) != static_cast<int>(offset)) {
-            fprintf(stderr, "* failed to seek to package block: %s\n", strerror(errno));
+            fprintf(stderr, "adb: failed to seek to package block: %s\n", strerror(errno));
             return -1;
         }
         if (!ReadFdExactly(package_fd, buf, to_write)) {
-            fprintf(stderr, "* failed to read package block: %s\n", strerror(errno));
+            fprintf(stderr, "adb: failed to read package block: %s\n", strerror(errno));
             return -1;
         }
 
         if (!WriteFdExactly(device_fd, buf, to_write)) {
             adb_status(device_fd, &error);
-            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
+            fprintf(stderr, "adb: failed to write data '%s' *\n", error.c_str());
             return -1;
         }
         xfer += to_write;
@@ -1254,66 +1233,6 @@
     return 0;
 }
 
-/* <hint> may be:
- * - A simple product name
- *   e.g., "sooner"
- * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
- *   e.g., "out/target/product/sooner"
- * - An absolute path to the PRODUCT_OUT dir
- *   e.g., "/src/device/out/target/product/sooner"
- *
- * Given <hint>, try to construct an absolute path to the
- * ANDROID_PRODUCT_OUT dir.
- */
-static std::string find_product_out_path(const std::string& hint) {
-    if (hint.empty()) {
-        return "";
-    }
-
-    // If it's already absolute, don't bother doing any work.
-    if (adb_is_absolute_host_path(hint.c_str())) {
-        return hint;
-    }
-
-    // If any of the OS_PATH_SEPARATORS is found, assume it's a relative path;
-    // make it absolute.
-    // NOLINT: Do not complain if OS_PATH_SEPARATORS has only one character.
-    if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {  // NOLINT
-        std::string cwd;
-        if (!getcwd(&cwd)) {
-            perror("adb: getcwd failed");
-            return "";
-        }
-        return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
-    }
-
-    // It's a string without any slashes.  Try to do something with it.
-    //
-    // Try to find the root of the build tree, and build a PRODUCT_OUT
-    // path from there.
-    char* top = getenv("ANDROID_BUILD_TOP");
-    if (top == nullptr) {
-        fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
-        return "";
-    }
-
-    std::string path = top;
-    path += OS_PATH_SEPARATOR_STR;
-    path += "out";
-    path += OS_PATH_SEPARATOR_STR;
-    path += "target";
-    path += OS_PATH_SEPARATOR_STR;
-    path += "product";
-    path += OS_PATH_SEPARATOR_STR;
-    path += hint;
-    if (!directory_exists(path)) {
-        fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
-                        "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
-        return "";
-    }
-    return path;
-}
-
 static void parse_push_pull_args(const char** arg, int narg,
                                  std::vector<const char*>* srcs,
                                  const char** dst, bool* copy_attrs) {
@@ -1404,17 +1323,6 @@
     signal(SIGPIPE, SIG_IGN);
 #endif
 
-    // If defined, this should be an absolute path to
-    // the directory containing all of the various system images
-    // for a particular product.  If not defined, and the adb
-    // command requires this information, then the user must
-    // specify the path using "-p".
-    char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
-    if (ANDROID_PRODUCT_OUT != nullptr) {
-        gProductOutPath = ANDROID_PRODUCT_OUT;
-    }
-    // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
-
     const char* server_host_str = nullptr;
     const char* server_port_str = nullptr;
     const char* server_socket_str = nullptr;
@@ -1440,21 +1348,6 @@
                 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
                 return 1;
             }
-        } else if (!strncmp(argv[0], "-p", 2)) {
-            const char* product = nullptr;
-            if (argv[0][2] == '\0') {
-                if (argc < 2) return syntax_error("-p requires an argument");
-                product = argv[1];
-                argc--;
-                argv++;
-            } else {
-                product = argv[0] + 2;
-            }
-            gProductOutPath = find_product_out_path(product);
-            if (gProductOutPath.empty()) {
-                fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
-                return 1;
-            }
         } else if (argv[0][0]=='-' && argv[0][1]=='s') {
             if (isdigit(argv[0][2])) {
                 serial = argv[0] + 2;
@@ -1833,6 +1726,8 @@
             return syntax_error("adb sync [-l] [PARTITION]");
         }
 
+        if (src == "all") src = "";
+
         if (src != "" &&
             src != "system" && src != "data" && src != "vendor" && src != "oem") {
             return syntax_error("don't know how to sync %s partition", src.c_str());
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index d4dd256..b2b1c18 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -20,6 +20,7 @@
 
 #include <fcntl.h>
 #include <inttypes.h>
+#include <libavb_user/libavb_user.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -45,13 +46,12 @@
 #endif
 
 /* Turn verity on/off */
-static int set_verity_enabled_state(int fd, const char *block_device,
-                                    const char* mount_point, bool enable)
-{
+static bool set_verity_enabled_state(int fd, const char* block_device, const char* mount_point,
+                                     bool enable) {
     if (!make_block_device_writable(block_device)) {
         WriteFdFmt(fd, "Could not make block device %s writable (%s).\n",
                    block_device, strerror(errno));
-        return -1;
+        return false;
     }
 
     fec::io fh(block_device, O_RDWR);
@@ -59,39 +59,84 @@
     if (!fh) {
         WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno));
         WriteFdFmt(fd, "Maybe run adb root?\n");
-        return -1;
+        return false;
     }
 
     fec_verity_metadata metadata;
 
     if (!fh.get_verity_metadata(metadata)) {
         WriteFdFmt(fd, "Couldn't find verity metadata!\n");
-        return -1;
+        return false;
     }
 
     if (!enable && metadata.disabled) {
         WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point);
-        return -1;
+        return false;
     }
 
     if (enable && !metadata.disabled) {
         WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point);
-        return -1;
+        return false;
     }
 
     if (!fh.set_verity_status(enable)) {
         WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n",
                    enable ? "enabled" : "disabled",
                    block_device, strerror(errno));
-        return -1;
+        return false;
     }
 
     WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
-    return 0;
+    return true;
+}
+
+/* Helper function to get A/B suffix, if any. If the device isn't
+ * using A/B the empty string is returned. Otherwise either "_a",
+ * "_b", ... is returned.
+ *
+ * Note that since sometime in O androidboot.slot_suffix is deprecated
+ * and androidboot.slot should be used instead. Since bootloaders may
+ * be out of sync with the OS, we check both and for extra safety
+ * prepend a leading underscore if there isn't one already.
+ */
+static std::string get_ab_suffix() {
+    std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
+    if (ab_suffix == "") {
+        ab_suffix = android::base::GetProperty("ro.boot.slot", "");
+    }
+    if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
+        ab_suffix = std::string("_") + ab_suffix;
+    }
+    return ab_suffix;
+}
+
+/* Use AVB to turn verity on/off */
+static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity) {
+    std::string ab_suffix = get_ab_suffix();
+
+    bool verity_enabled;
+    if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
+        WriteFdFmt(fd, "Error getting verity state\n");
+        return false;
+    }
+
+    if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
+        WriteFdFmt(fd, "verity is already %s\n", verity_enabled ? "enabled" : "disabled");
+        return false;
+    }
+
+    if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
+        WriteFdFmt(fd, "Error setting verity\n");
+        return false;
+    }
+
+    WriteFdFmt(fd, "Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
+    return true;
 }
 
 void set_verity_enabled_state_service(int fd, void* cookie) {
     unique_fd closer(fd);
+    bool any_changed = false;
 
     bool enable = (cookie != NULL);
     if (!kAllowDisableVerity) {
@@ -108,21 +153,37 @@
         return;
     }
 
-    // read all fstab entries at once from all sources
-    fstab = fs_mgr_read_fstab_default();
-    if (!fstab) {
-        WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
-        return;
-    }
+    // Figure out if we're using VB1.0 or VB2.0 (aka AVB).
+    std::string vbmeta_hash = android::base::GetProperty("ro.boot.vbmeta.digest", "");
+    if (vbmeta_hash != "") {
+        // Yep, the system is using AVB (by contract, androidboot.vbmeta.hash is
+        // set by the bootloader when using AVB).
+        AvbOps* ops = avb_ops_user_new();
+        if (ops == nullptr) {
+            WriteFdFmt(fd, "Error getting AVB ops\n");
+            return;
+        }
+        if (set_avb_verity_enabled_state(fd, ops, enable)) {
+            any_changed = true;
+        }
+        avb_ops_user_free(ops);
+    } else {
+        // Not using AVB - assume VB1.0.
 
-    // Loop through entries looking for ones that vold manages.
-    bool any_changed = false;
-    for (int i = 0; i < fstab->num_entries; i++) {
-        if (fs_mgr_is_verified(&fstab->recs[i])) {
-            if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
-                                          fstab->recs[i].mount_point,
-                                          enable)) {
-                any_changed = true;
+        // read all fstab entries at once from all sources
+        fstab = fs_mgr_read_fstab_default();
+        if (!fstab) {
+            WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
+            return;
+        }
+
+        // Loop through entries looking for ones that vold manages.
+        for (int i = 0; i < fstab->num_entries; i++) {
+            if (fs_mgr_is_verified(&fstab->recs[i])) {
+                if (set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+                                             fstab->recs[i].mount_point, enable)) {
+                    any_changed = true;
+                }
             }
         }
     }
diff --git a/base/utf8.cpp b/base/utf8.cpp
old mode 100755
new mode 100644
diff --git a/base/utf8_test.cpp b/base/utf8_test.cpp
old mode 100755
new mode 100644
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 4783d6e..79d5c08 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -9,10 +9,6 @@
         "-Os",
     ],
 
-    // util.cpp gets async signal safe logging via libc_logging,
-    // which defines its interface in bionic private headers.
-    include_dirs: ["bionic/libc"],
-
     local_include_dirs: ["include"],
 }
 
@@ -26,7 +22,7 @@
     ],
 
     whole_static_libs: [
-        "libc_logging",
+        "libasync_safe",
         "libcutils",
         "libbase",
     ],
@@ -39,7 +35,7 @@
     srcs: ["handler/debuggerd_handler.cpp"],
 
     whole_static_libs: [
-        "libc_logging",
+        "libasync_safe",
         "libdebuggerd",
     ],
 
@@ -70,6 +66,7 @@
     whole_static_libs: [
         "libdebuggerd_handler_core",
         "libtombstoned_client",
+        "libasync_safe",
         "libbase",
         "libdebuggerd",
         "libbacktrace",
@@ -166,6 +163,7 @@
                 "tombstoned_client.cpp",
                 "util.cpp"
             ],
+            static_libs: ["libasync_safe"],
         },
     },
 
@@ -178,7 +176,6 @@
 
     static_libs: [
         "libdebuggerd",
-        "libc_logging",
     ],
 
     local_include_dirs: [
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index 5c6c59c..47c98d1 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -39,6 +39,7 @@
 
 #include <android-base/file.h>
 #include <android-base/unique_fd.h>
+#include <async_safe/log.h>
 
 #include "debuggerd/handler.h"
 #include "debuggerd/tombstoned.h"
@@ -47,8 +48,6 @@
 #include "backtrace.h"
 #include "tombstone.h"
 
-#include "private/libc_logging.h"
-
 using android::base::unique_fd;
 
 extern "C" void __linker_enable_fallback_allocator();
@@ -81,7 +80,7 @@
   DIR* dir = opendir(buf);
 
   if (!dir) {
-    __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to open %s: %s", buf, strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open %s: %s", buf, strerror(errno));
     return;
   }
 
@@ -145,7 +144,8 @@
   static pthread_mutex_t trace_mutex = PTHREAD_MUTEX_INITIALIZER;
   int ret = pthread_mutex_trylock(&trace_mutex);
   if (ret != 0) {
-    __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_try_lock failed: %s", strerror(ret));
+    async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_try_lock failed: %s",
+                          strerror(ret));
     return;
   }
 
@@ -167,7 +167,8 @@
       // receiving our signal.
       unique_fd pipe_read, pipe_write;
       if (!Pipe(&pipe_read, &pipe_write)) {
-        __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to create pipe: %s", strerror(errno));
+        async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create pipe: %s",
+                              strerror(errno));
         return false;
       }
 
@@ -180,8 +181,8 @@
       siginfo.si_uid = getuid();
 
       if (syscall(__NR_rt_tgsigqueueinfo, getpid(), tid, DEBUGGER_SIGNAL, &siginfo) != 0) {
-        __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to send trace signal to %d: %s", tid,
-                          strerror(errno));
+        async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to send trace signal to %d: %s",
+                              tid, strerror(errno));
         return false;
       }
 
@@ -209,7 +210,7 @@
   static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
   int ret = pthread_mutex_lock(&crash_mutex);
   if (ret != 0) {
-    __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
+    async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
     return;
   }
 
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index b70554f..6e3e6ac 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -48,8 +48,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include "private/bionic_futex.h"
-#include "private/libc_logging.h"
+#include <async_safe/log.h>
 
 // see man(2) prctl, specifically the section about PR_GET_NAME
 #define MAX_TASK_NAME_LEN (16)
@@ -62,6 +61,10 @@
 
 #define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME
 
+static inline void futex_wait(volatile void* ftx, int value) {
+  syscall(__NR_futex, ftx, FUTEX_WAIT, value, nullptr, nullptr, 0);
+}
+
 class ErrnoRestorer {
  public:
   ErrnoRestorer() : saved_errno_(errno) {
@@ -82,11 +85,12 @@
 // Mutex to ensure only one crashing thread dumps itself.
 static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-// Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler.
+// Don't use async_safe_fatal because it exits via abort, which might put us back into
+// a signal handler.
 static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) {
   va_list args;
   va_start(args, fmt);
-  __libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args);
+  async_safe_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args);
   _exit(1);
 }
 
@@ -96,7 +100,7 @@
   va_start(args, fmt);
 
   char buf[4096];
-  __libc_format_buffer_va_list(buf, sizeof(buf), fmt, args);
+  async_safe_format_buffer_va_list(buf, sizeof(buf), fmt, args);
   fatal("%s: %s", buf, strerror(err));
 }
 
@@ -120,8 +124,8 @@
   }
 
   if (signum == DEBUGGER_SIGNAL) {
-    __libc_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", gettid(),
-                      thread_name);
+    async_safe_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", gettid(),
+                          thread_name);
     return;
   }
 
@@ -166,14 +170,14 @@
   char addr_desc[32];  // ", fault addr 0x1234"
   addr_desc[0] = code_desc[0] = 0;
   if (info != nullptr) {
-    __libc_format_buffer(code_desc, sizeof(code_desc), ", code %d", info->si_code);
+    async_safe_format_buffer(code_desc, sizeof(code_desc), ", code %d", info->si_code);
     if (has_address) {
-      __libc_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
+      async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
     }
   }
 
-  __libc_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)", signum,
-                    signal_name, code_desc, addr_desc, gettid(), thread_name);
+  async_safe_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)",
+                        signum, signal_name, code_desc, addr_desc, gettid(), thread_name);
 }
 
 /*
@@ -182,8 +186,8 @@
 static bool have_siginfo(int signum) {
   struct sigaction old_action;
   if (sigaction(signum, nullptr, &old_action) < 0) {
-    __libc_format_log(ANDROID_LOG_WARN, "libc", "Failed testing for SA_SIGINFO: %s",
-                      strerror(errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc", "Failed testing for SA_SIGINFO: %s",
+                          strerror(errno));
     return false;
   }
   return (old_action.sa_flags & SA_SIGINFO) != 0;
@@ -207,7 +211,7 @@
     capdata[1].inheritable = capdata[1].permitted;
 
     if (capset(&capheader, &capdata[0]) == -1) {
-      __libc_format_log(ANDROID_LOG_ERROR, "libc", "capset failed: %s", strerror(errno));
+      async_safe_format_log(ANDROID_LOG_ERROR, "libc", "capset failed: %s", strerror(errno));
     }
   }
 
@@ -217,8 +221,8 @@
   for (unsigned long i = 0; i < 64; ++i) {
     if (capmask & (1ULL << i)) {
       if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) != 0) {
-        __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to raise ambient capability %lu: %s",
-                          i, strerror(errno));
+        async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                              "failed to raise ambient capability %lu: %s", i, strerror(errno));
       }
     }
   }
@@ -260,8 +264,8 @@
   // Don't use fork(2) to avoid calling pthread_atfork handlers.
   int forkpid = clone(nullptr, nullptr, 0, nullptr);
   if (forkpid == -1) {
-    __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to fork in debuggerd signal handler: %s",
-                      strerror(errno));
+    async_safe_format_log(ANDROID_LOG_FATAL, "libc",
+                          "failed to fork in debuggerd signal handler: %s", strerror(errno));
   } else if (forkpid == 0) {
     TEMP_FAILURE_RETRY(dup2(pipefds[1], STDOUT_FILENO));
     close(pipefds[0]);
@@ -271,8 +275,9 @@
 
     char main_tid[10];
     char pseudothread_tid[10];
-    __libc_format_buffer(main_tid, sizeof(main_tid), "%d", thread_info->crashing_tid);
-    __libc_format_buffer(pseudothread_tid, sizeof(pseudothread_tid), "%d", thread_info->pseudothread_tid);
+    async_safe_format_buffer(main_tid, sizeof(main_tid), "%d", thread_info->crashing_tid);
+    async_safe_format_buffer(pseudothread_tid, sizeof(pseudothread_tid), "%d",
+                             thread_info->pseudothread_tid);
 
     execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, main_tid, pseudothread_tid, nullptr);
 
@@ -282,15 +287,16 @@
     char buf[4];
     ssize_t rc = TEMP_FAILURE_RETRY(read(pipefds[0], &buf, sizeof(buf)));
     if (rc == -1) {
-      __libc_format_log(ANDROID_LOG_FATAL, "libc", "read of IPC pipe failed: %s", strerror(errno));
+      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "read of IPC pipe failed: %s",
+                            strerror(errno));
     } else if (rc == 0) {
-      __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper failed to exec");
+      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper failed to exec");
     } else if (rc != 1) {
-      __libc_format_log(ANDROID_LOG_FATAL, "libc",
-                        "read of IPC pipe returned unexpected value: %zd", rc);
+      async_safe_format_log(ANDROID_LOG_FATAL, "libc",
+                            "read of IPC pipe returned unexpected value: %zd", rc);
     } else {
       if (buf[0] != '\1') {
-        __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper reported failure");
+        async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper reported failure");
       } else {
         thread_info->crash_dump_started = true;
       }
@@ -300,10 +306,10 @@
     // Don't leave a zombie child.
     int status;
     if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, 0)) == -1) {
-      __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
-                        strerror(errno));
+      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
+                            strerror(errno));
     } else if (WIFSTOPPED(status) || WIFSIGNALED(status)) {
-      __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
+      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
       thread_info->crash_dump_started = false;
     }
   }
@@ -383,7 +389,7 @@
   // Only allow one thread to handle a signal at a time.
   int ret = pthread_mutex_lock(&crash_mutex);
   if (ret != 0) {
-    __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
+    async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
     return;
   }
 
@@ -419,10 +425,10 @@
   }
 
   // Wait for the child to start...
-  __futex_wait(&thread_info.pseudothread_tid, -1, nullptr);
+  futex_wait(&thread_info.pseudothread_tid, -1);
 
   // and then wait for it to finish.
-  __futex_wait(&thread_info.pseudothread_tid, child_pid, nullptr);
+  futex_wait(&thread_info.pseudothread_tid, child_pid);
 
   // Restore PR_SET_DUMPABLE to its original value.
   if (prctl(PR_SET_DUMPABLE, orig_dumpable) != 0) {
diff --git a/debuggerd/tombstoned_client.cpp b/debuggerd/tombstoned_client.cpp
index 03b4a20..4741fa6 100644
--- a/debuggerd/tombstoned_client.cpp
+++ b/debuggerd/tombstoned_client.cpp
@@ -22,11 +22,11 @@
 #include <utility>
 
 #include <android-base/unique_fd.h>
+#include <async_safe/log.h>
 #include <cutils/sockets.h>
 
 #include "debuggerd/protocol.h"
 #include "debuggerd/util.h"
-#include "private/libc_logging.h"
 
 using android::base::unique_fd;
 
@@ -34,8 +34,8 @@
   unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName,
                                        ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
   if (sockfd == -1) {
-    __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to tombstoned: %s",
-                      strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to tombstoned: %s",
+                          strerror(errno));
     return false;
   }
 
@@ -43,22 +43,22 @@
   packet.packet_type = CrashPacketType::kDumpRequest;
   packet.packet.dump_request.pid = pid;
   if (TEMP_FAILURE_RETRY(write(sockfd, &packet, sizeof(packet))) != sizeof(packet)) {
-    __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to write DumpRequest packet: %s",
-                      strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to write DumpRequest packet: %s",
+                          strerror(errno));
     return false;
   }
 
   unique_fd tmp_output_fd;
   ssize_t rc = recv_fd(sockfd, &packet, sizeof(packet), &tmp_output_fd);
   if (rc == -1) {
-    __libc_format_log(ANDROID_LOG_ERROR, "libc",
-                      "failed to read response to DumpRequest packet: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "failed to read response to DumpRequest packet: %s", strerror(errno));
     return false;
   } else if (rc != sizeof(packet)) {
-    __libc_format_log(
-      ANDROID_LOG_ERROR, "libc",
-      "received DumpRequest response packet of incorrect length (expected %zu, got %zd)",
-      sizeof(packet), rc);
+    async_safe_format_log(
+        ANDROID_LOG_ERROR, "libc",
+        "received DumpRequest response packet of incorrect length (expected %zu, got %zd)",
+        sizeof(packet), rc);
     return false;
   }
 
@@ -67,8 +67,8 @@
   // a regular fd, and writing to an fd with O_APPEND).
   int flags = fcntl(tmp_output_fd.get(), F_GETFL);
   if (fcntl(tmp_output_fd.get(), F_SETFL, flags | O_APPEND) != 0) {
-    __libc_format_log(ANDROID_LOG_WARN, "libc", "failed to set output fd flags: %s",
-                      strerror(errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc", "failed to set output fd flags: %s",
+                          strerror(errno));
   }
 
   *tombstoned_socket = std::move(sockfd);
diff --git a/debuggerd/util.cpp b/debuggerd/util.cpp
index 4c015d7..32d2f18 100644
--- a/debuggerd/util.cpp
+++ b/debuggerd/util.cpp
@@ -24,8 +24,6 @@
 #include <cutils/sockets.h>
 #include <debuggerd/protocol.h>
 
-#include "private/libc_logging.h"
-
 using android::base::unique_fd;
 
 ssize_t send_fd(int sockfd, const void* data, size_t len, unique_fd fd) {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 247768a..6e9069e 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -807,7 +807,7 @@
     FsManagerAvbUniquePtr avb_handle(nullptr);
 
     if (!fstab) {
-        return -1;
+        return FS_MGR_MNTALL_FAIL;
     }
 
     for (i = 0; i < fstab->num_entries; i++) {
@@ -853,7 +853,7 @@
                 avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab));
                 if (!avb_handle) {
                     LERROR << "Failed to open FsManagerAvbHandle";
-                    return -1;
+                    return FS_MGR_MNTALL_FAIL;
                 }
             }
             if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
@@ -983,7 +983,7 @@
     }
 
     if (error_count) {
-        return -1;
+        return FS_MGR_MNTALL_FAIL;
     } else {
         return encryptable;
     }
@@ -1016,14 +1016,13 @@
                     char *tmp_mount_point)
 {
     int i = 0;
-    int ret = FS_MGR_DOMNT_FAILED;
     int mount_errors = 0;
     int first_mount_errno = 0;
-    char *m;
+    char* mount_point;
     FsManagerAvbUniquePtr avb_handle(nullptr);
 
     if (!fstab) {
-        return ret;
+        return FS_MGR_DOMNT_FAILED;
     }
 
     for (i = 0; i < fstab->num_entries; i++) {
@@ -1038,7 +1037,7 @@
             !strcmp(fstab->recs[i].fs_type, "mtd")) {
             LERROR << "Cannot mount filesystem of type "
                    << fstab->recs[i].fs_type << " on " << n_blk_device;
-            goto out;
+            return FS_MGR_DOMNT_FAILED;
         }
 
         /* First check the filesystem if requested */
@@ -1065,7 +1064,7 @@
                 avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab));
                 if (!avb_handle) {
                     LERROR << "Failed to open FsManagerAvbHandle";
-                    return -1;
+                    return FS_MGR_DOMNT_FAILED;
                 }
             }
             if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
@@ -1086,16 +1085,15 @@
 
         /* Now mount it where requested */
         if (tmp_mount_point) {
-            m = tmp_mount_point;
+            mount_point = tmp_mount_point;
         } else {
-            m = fstab->recs[i].mount_point;
+            mount_point = fstab->recs[i].mount_point;
         }
         int retry_count = 2;
         while (retry_count-- > 0) {
-            if (!__mount(n_blk_device, m, &fstab->recs[i])) {
-                ret = 0;
+            if (!__mount(n_blk_device, mount_point, &fstab->recs[i])) {
                 fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED;
-                goto out;
+                return FS_MGR_DOMNT_SUCCESS;
             } else {
                 if (retry_count <= 0) break;  // run check_fs only once
                 if (!first_mount_errno) first_mount_errno = errno;
@@ -1107,22 +1105,16 @@
         }
         log_fs_stat(fstab->recs[i].blk_device, fs_stat);
     }
+
+    // Reach here means the mount attempt fails.
     if (mount_errors) {
-        PERROR << "Cannot mount filesystem on " << n_blk_device
-               << " at " << m;
-        if (first_mount_errno == EBUSY) {
-            ret = FS_MGR_DOMNT_BUSY;
-        } else {
-            ret = FS_MGR_DOMNT_FAILED;
-        }
+        PERROR << "Cannot mount filesystem on " << n_blk_device << " at " << mount_point;
+        if (first_mount_errno == EBUSY) return FS_MGR_DOMNT_BUSY;
     } else {
         /* We didn't find a match, say so and return an error */
-        LERROR << "Cannot find mount point " << fstab->recs[i].mount_point
-               << " in fstab";
+        LERROR << "Cannot find mount point " << n_name << " in fstab";
     }
-
-out:
-    return ret;
+    return FS_MGR_DOMNT_FAILED;
 }
 
 /*
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 83bf8a7..94cea57 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -190,7 +190,7 @@
 std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() {
     std::string cmdline;
     if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
-        LERROR << "Failed to read /proc/cmdline";
+        PERROR << "Failed to read /proc/cmdline";
         return nullptr;
     }
 
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index 981e9fc..caee4ec 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -96,7 +96,9 @@
     // We only need to provide the implementation of read_from_partition()
     // operation since that's all what is being used by the avb_slot_verify().
     // Other I/O operations are only required in bootloader but not in
-    // user-space so we set them as dummy operations.
+    // user-space so we set them as dummy operations. Also zero the entire
+    // struct so operations added in the future will be set to NULL.
+    memset(&avb_ops_, 0, sizeof(AvbOps));
     avb_ops_.read_from_partition = read_from_partition;
     avb_ops_.read_rollback_index = dummy_read_rollback_index;
     avb_ops_.validate_vbmeta_public_key = dummy_validate_vbmeta_public_key;
@@ -133,13 +135,13 @@
     if (offset < 0) {
         off64_t total_size = lseek64(fd, 0, SEEK_END);
         if (total_size == -1) {
-            LERROR << "Failed to lseek64 to end of the partition";
+            PERROR << "Failed to lseek64 to end of the partition";
             return AVB_IO_RESULT_ERROR_IO;
         }
         offset = total_size + offset;
         // Repositions the offset to the beginning.
         if (lseek64(fd, 0, SEEK_SET) == -1) {
-            LERROR << "Failed to lseek64 to the beginning of the partition";
+            PERROR << "Failed to lseek64 to the beginning of the partition";
             return AVB_IO_RESULT_ERROR_IO;
         }
     }
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 12db672..9079a43 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -105,6 +105,7 @@
 
 #define FS_MGR_DOMNT_FAILED (-1)
 #define FS_MGR_DOMNT_BUSY (-2)
+#define FS_MGR_DOMNT_SUCCESS 0
 
 int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
                     char *tmp_mount_point);
diff --git a/init/Android.mk b/init/Android.mk
index de3d076..537bbee 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -145,6 +145,7 @@
     init_parser_test.cpp \
     init_test.cpp \
     property_service_test.cpp \
+    service_test.cpp \
     util_test.cpp \
 
 LOCAL_SHARED_LIBRARIES += \
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 1d98ef1..3dadfd7 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -205,7 +205,7 @@
         mode = std::strtoul(args[2].c_str(), 0, 8);
     }
 
-    ret = make_dir(args[1].c_str(), mode);
+    ret = make_dir(args[1].c_str(), mode, sehandle);
     /* chmod in case the directory already exists */
     if (ret == -1 && errno == EEXIST) {
         ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW);
@@ -809,7 +809,7 @@
  * Callback to make a directory from the ext4 code
  */
 static int do_installkeys_ensure_dir_exists(const char* dir) {
-    if (make_dir(dir, 0700) && errno != EEXIST) {
+    if (make_dir(dir, 0700, sehandle) && errno != EEXIST) {
         return -1;
     }
 
@@ -835,7 +835,9 @@
 }
 
 static int do_init_user0(const std::vector<std::string>& args) {
-    return e4crypt_do_init_user0();
+    std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",
+                                          "init_user0"};
+    return do_exec(exec_args);
 }
 
 const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
diff --git a/init/descriptors.cpp b/init/descriptors.cpp
index bc6bc8d..b2142ca 100644
--- a/init/descriptors.cpp
+++ b/init/descriptors.cpp
@@ -80,7 +80,7 @@
   int flags = ((type() == "stream" ? SOCK_STREAM :
                 (type() == "dgram" ? SOCK_DGRAM :
                  SOCK_SEQPACKET)));
-  return create_socket(name().c_str(), flags, perm(), uid(), gid(), context.c_str());
+  return create_socket(name().c_str(), flags, perm(), uid(), gid(), context.c_str(), sehandle);
 }
 
 const std::string SocketInfo::key() const {
diff --git a/init/devices.cpp b/init/devices.cpp
index 07d28d0..74f099a 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -47,7 +47,6 @@
 #include <cutils/uevent.h>
 #include <private/android_filesystem_config.h>
 #include <selinux/android.h>
-#include <selinux/avc.h>
 #include <selinux/label.h>
 #include <selinux/selinux.h>
 
@@ -55,7 +54,11 @@
 #include "ueventd.h"
 #include "util.h"
 
-extern struct selabel_handle *sehandle;
+#ifdef _INIT_INIT_H
+#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#endif
+
+static selabel_handle* sehandle;
 
 static android::base::unique_fd device_fd;
 
@@ -555,7 +558,7 @@
 }
 
 static void make_link_init(const std::string& oldpath, const std::string& newpath) {
-    if (mkdir_recursive(dirname(newpath.c_str()), 0755)) {
+    if (mkdir_recursive(dirname(newpath.c_str()), 0755, sehandle)) {
         PLOG(ERROR) << "Failed to create directory " << dirname(newpath.c_str());
     }
 
@@ -600,7 +603,7 @@
     if (uevent->major < 0 || uevent->minor < 0) return;
 
     const char* base = "/dev/block/";
-    make_dir(base, 0755);
+    make_dir(base, 0755, sehandle);
 
     std::string name = android::base::Basename(uevent->path);
     std::string devpath = base + name;
@@ -642,7 +645,7 @@
         devpath = "/dev/" + android::base::Basename(uevent->path);
     }
 
-    mkdir_recursive(android::base::Dirname(devpath), 0755);
+    mkdir_recursive(android::base::Dirname(devpath), 0755, sehandle);
 
     auto links = get_character_device_symlinks(uevent);
 
@@ -783,15 +786,6 @@
 {
     coldboot_action_t ret = handle_device_fd_with(
         [&](uevent* uevent) -> coldboot_action_t {
-            if (selinux_status_updated() > 0) {
-                struct selabel_handle *sehandle2;
-                sehandle2 = selinux_android_file_context_handle();
-                if (sehandle2) {
-                    selabel_close(sehandle);
-                    sehandle = sehandle2;
-                }
-            }
-
             // default is to always create the devices
             coldboot_action_t act = COLDBOOT_CREATE;
             if (fn) {
@@ -881,7 +875,6 @@
             return;
         }
         fcntl(device_fd, F_SETFL, O_NONBLOCK);
-        selinux_status_open(true);
     }
 
     if (access(COLDBOOT_DONE, F_OK) == 0) {
@@ -915,7 +908,6 @@
 void device_close() {
     platform_devices.clear();
     device_fd.reset();
-    selinux_status_close();
 }
 
 int get_device_fd() {
diff --git a/init/init.cpp b/init/init.cpp
index 99ce5e6..8758653 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <keyutils.h>
 #include <libgen.h>
 #include <paths.h>
 #include <signal.h>
@@ -1015,6 +1016,11 @@
     InitKernelLogging(argv);
     LOG(INFO) << "init second stage started!";
 
+    // Set up a session keyring that all processes will have access to. It
+    // will hold things like FBE encryption keys. No process should override
+    // its session keyring.
+    keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 1);
+
     // Indicate that booting is in progress to background fw loaders, etc.
     close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
 
diff --git a/init/init.h b/init/init.h
index 6add75f..6725a70 100644
--- a/init/init.h
+++ b/init/init.h
@@ -19,6 +19,9 @@
 
 #include <string>
 
+// Note: These globals are *only* valid in init, so they should not be used in ueventd,
+// watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp.
+// TODO: Have an Init class and remove all globals.
 extern const char *ENV[32];
 extern std::string default_console;
 extern struct selabel_handle *sehandle;
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 43f1c15..2fa790d 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -143,8 +143,11 @@
     if (!GetRequiredDevices(&devices_partition_names, &need_dm_verity)) return false;
 
     if (need_dm_verity) {
-        device_init("/sys/devices/virtual/misc/device-mapper",
-                    [&](uevent* uevent) -> coldboot_action_t { return COLDBOOT_STOP; });
+        const std::string dm_path = "/devices/virtual/misc/device-mapper";
+        device_init(("/sys" + dm_path).c_str(), [&dm_path](uevent* uevent) -> coldboot_action_t {
+            if (uevent->path == dm_path) return COLDBOOT_STOP;
+            return COLDBOOT_CONTINUE;  // dm_path not found, continue to find it.
+        });
     }
 
     bool success = false;
diff --git a/init/keyutils.h b/init/keyutils.h
new file mode 100644
index 0000000..de01beb
--- /dev/null
+++ b/init/keyutils.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Miniature version of a header-only keyutils.h (no library required) */
+
+#ifndef _INIT_KEYUTILS_H_
+#define _INIT_KEYUTILS_H_
+
+#ifndef KEYUTILS_H /* walk away if the _real_ one exists */
+
+#include <linux/keyctl.h>
+#include <stdarg.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static inline long keyctl(int cmd, ...) {
+    va_list va;
+    unsigned long arg2, arg3, arg4, arg5;
+
+    va_start(va, cmd);
+    arg2 = va_arg(va, unsigned long);
+    arg3 = va_arg(va, unsigned long);
+    arg4 = va_arg(va, unsigned long);
+    arg5 = va_arg(va, unsigned long);
+    va_end(va);
+    return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+}
+
+#endif
+
+#endif
diff --git a/init/property_service.cpp b/init/property_service.cpp
index aa47976..6f40d1c 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -659,7 +659,7 @@
     property_set("ro.property_service.version", "2");
 
     property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
-                                    0666, 0, 0, NULL);
+                                    0666, 0, 0, nullptr, sehandle);
     if (property_set_fd == -1) {
         PLOG(ERROR) << "start_property_service socket creation failed";
         exit(1);
diff --git a/init/service.cpp b/init/service.cpp
index 39f6709..3a9f622 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -158,6 +158,7 @@
       namespace_flags_(0),
       seclabel_(""),
       onrestart_(false, "<Service '" + name + "' onrestart>", 0),
+      keychord_id_(0),
       ioprio_class_(IoSchedClass_NONE),
       ioprio_pri_(0),
       priority_(0),
@@ -182,6 +183,7 @@
       namespace_flags_(namespace_flags),
       seclabel_(seclabel),
       onrestart_(false, "<Service '" + name + "' onrestart>", 0),
+      keychord_id_(0),
       ioprio_class_(IoSchedClass_NONE),
       ioprio_pri_(0),
       priority_(0),
diff --git a/init/service.h b/init/service.h
index 634fe4e..426577f 100644
--- a/init/service.h
+++ b/init/service.h
@@ -94,14 +94,19 @@
     const std::set<std::string>& classnames() const { return classnames_; }
     unsigned flags() const { return flags_; }
     pid_t pid() const { return pid_; }
+    int crash_count() const { return crash_count_; }
     uid_t uid() const { return uid_; }
     gid_t gid() const { return gid_; }
-    int priority() const { return priority_; }
+    unsigned namespace_flags() const { return namespace_flags_; }
     const std::vector<gid_t>& supp_gids() const { return supp_gids_; }
     const std::string& seclabel() const { return seclabel_; }
     const std::vector<int>& keycodes() const { return keycodes_; }
     int keychord_id() const { return keychord_id_; }
     void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; }
+    IoSchedClass ioprio_class() const { return ioprio_class_; }
+    int ioprio_pri() const { return ioprio_pri_; }
+    int priority() const { return priority_; }
+    int oom_score_adjust() const { return oom_score_adjust_; }
     const std::vector<std::string>& args() const { return args_; }
 
   private:
@@ -181,6 +186,9 @@
 public:
     static ServiceManager& GetInstance();
 
+    // Exposed for testing
+    ServiceManager();
+
     void AddService(std::unique_ptr<Service> service);
     Service* MakeExecOneshotService(const std::vector<std::string>& args);
     bool Exec(const std::vector<std::string>& args);
@@ -199,8 +207,6 @@
     void DumpState() const;
 
 private:
-    ServiceManager();
-
     // Cleans up a child process that exited.
     // Returns true iff a children was cleaned up.
     bool ReapOneProcess();
diff --git a/init/service_test.cpp b/init/service_test.cpp
new file mode 100644
index 0000000..4493f25
--- /dev/null
+++ b/init/service_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "service.h"
+
+#include <algorithm>
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+TEST(service, pod_initialized) {
+    constexpr auto memory_size = sizeof(Service);
+    alignas(alignof(Service)) char old_memory[memory_size];
+
+    for (std::size_t i = 0; i < memory_size; ++i) {
+        old_memory[i] = 0xFF;
+    }
+
+    std::vector<std::string> dummy_args{"/bin/test"};
+    Service* service_in_old_memory = new (old_memory) Service("test_old_memory", dummy_args);
+
+    EXPECT_EQ(0U, service_in_old_memory->flags());
+    EXPECT_EQ(0, service_in_old_memory->pid());
+    EXPECT_EQ(0, service_in_old_memory->crash_count());
+    EXPECT_EQ(0U, service_in_old_memory->uid());
+    EXPECT_EQ(0U, service_in_old_memory->gid());
+    EXPECT_EQ(0U, service_in_old_memory->namespace_flags());
+    EXPECT_EQ(0, service_in_old_memory->keychord_id());
+    EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory->ioprio_class());
+    EXPECT_EQ(0, service_in_old_memory->ioprio_pri());
+    EXPECT_EQ(0, service_in_old_memory->priority());
+    EXPECT_EQ(-1000, service_in_old_memory->oom_score_adjust());
+
+    for (std::size_t i = 0; i < memory_size; ++i) {
+        old_memory[i] = 0xFF;
+    }
+
+    Service* service_in_old_memory2 = new (old_memory)
+        Service("test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), CapSet(), 0U, "", dummy_args);
+
+    EXPECT_EQ(0U, service_in_old_memory2->flags());
+    EXPECT_EQ(0, service_in_old_memory2->pid());
+    EXPECT_EQ(0, service_in_old_memory2->crash_count());
+    EXPECT_EQ(0U, service_in_old_memory2->uid());
+    EXPECT_EQ(0U, service_in_old_memory2->gid());
+    EXPECT_EQ(0U, service_in_old_memory2->namespace_flags());
+    EXPECT_EQ(0, service_in_old_memory2->keychord_id());
+    EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory2->ioprio_class());
+    EXPECT_EQ(0, service_in_old_memory2->ioprio_pri());
+    EXPECT_EQ(0, service_in_old_memory2->priority());
+    EXPECT_EQ(-1000, service_in_old_memory2->oom_score_adjust());
+}
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 963cc4d..8c0c574 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -33,9 +33,6 @@
 #include "log.h"
 #include "util.h"
 
-template <bool sysfs>
-static bool ParseSingleLine(std::vector<std::string>&& line, std::string* err);
-
 int ueventd_main(int argc, char **argv)
 {
     /*
diff --git a/init/util.cpp b/init/util.cpp
index a101ce5..87b8d9d 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -40,11 +40,13 @@
 #include <cutils/android_reboot.h>
 #include <cutils/sockets.h>
 #include <selinux/android.h>
-#include <selinux/label.h>
 
-#include "init.h"
 #include "reboot.h"
 
+#ifdef _INIT_INIT_H
+#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#endif
+
 using android::base::boot_clock;
 
 static unsigned int do_decode_uid(const char *s)
@@ -87,9 +89,8 @@
  * daemon. We communicate the file descriptor's value via the environment
  * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").
  */
-int create_socket(const char *name, int type, mode_t perm, uid_t uid,
-                  gid_t gid, const char *socketcon)
-{
+int create_socket(const char* name, int type, mode_t perm, uid_t uid, gid_t gid,
+                  const char* socketcon, selabel_handle* sehandle) {
     if (socketcon) {
         if (setsockcreatecon(socketcon) == -1) {
             PLOG(ERROR) << "setsockcreatecon(\"" << socketcon << "\") failed";
@@ -194,17 +195,17 @@
     return success;
 }
 
-int mkdir_recursive(const std::string& path, mode_t mode) {
+int mkdir_recursive(const std::string& path, mode_t mode, selabel_handle* sehandle) {
     std::string::size_type slash = 0;
     while ((slash = path.find('/', slash + 1)) != std::string::npos) {
         auto directory = path.substr(0, slash);
         struct stat info;
         if (stat(directory.c_str(), &info) != 0) {
-            auto ret = make_dir(directory.c_str(), mode);
+            auto ret = make_dir(directory.c_str(), mode, sehandle);
             if (ret && errno != EEXIST) return ret;
         }
     }
-    auto ret = make_dir(path.c_str(), mode);
+    auto ret = make_dir(path.c_str(), mode, sehandle);
     if (ret && errno != EEXIST) return ret;
     return 0;
 }
@@ -233,8 +234,7 @@
     }
 }
 
-int make_dir(const char *path, mode_t mode)
-{
+int make_dir(const char* path, mode_t mode, selabel_handle* sehandle) {
     int rc;
 
     char *secontext = NULL;
diff --git a/init/util.h b/init/util.h
index 92b3a1d..55ebded 100644
--- a/init/util.h
+++ b/init/util.h
@@ -26,6 +26,7 @@
 #include <string>
 
 #include <android-base/chrono_utils.h>
+#include <selinux/label.h>
 
 #define COLDBOOT_DONE "/dev/.coldboot_done"
 
@@ -34,8 +35,8 @@
 using android::base::boot_clock;
 using namespace std::chrono_literals;
 
-int create_socket(const char *name, int type, mode_t perm,
-                  uid_t uid, gid_t gid, const char *socketcon);
+int create_socket(const char* name, int type, mode_t perm, uid_t uid, gid_t gid,
+                  const char* socketcon, selabel_handle* sehandle);
 
 bool read_file(const std::string& path, std::string* content);
 bool write_file(const std::string& path, const std::string& content);
@@ -62,11 +63,11 @@
 
 unsigned int decode_uid(const char *s);
 
-int mkdir_recursive(const std::string& pathname, mode_t mode);
+int mkdir_recursive(const std::string& pathname, mode_t mode, selabel_handle* sehandle);
 int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
 void import_kernel_cmdline(bool in_qemu,
                            const std::function<void(const std::string&, const std::string&, bool)>&);
-int make_dir(const char *path, mode_t mode);
+int make_dir(const char* path, mode_t mode, selabel_handle* sehandle);
 int restorecon(const char *pathname, int flags = 0);
 std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
 bool is_dir(const char* pathname);
diff --git a/init/util_test.cpp b/init/util_test.cpp
index b8b409a..ac23a32 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -128,15 +128,10 @@
     EXPECT_FALSE(is_dir(tf.path));
 }
 
-// sehandle is needed for make_dir()
-// TODO: Remove once sehandle is encapsulated
-#include <selinux/label.h>
-selabel_handle* sehandle;
-
 TEST(util, mkdir_recursive) {
     TemporaryDir test_dir;
     std::string path = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
-    EXPECT_EQ(0, mkdir_recursive(path, 0755));
+    EXPECT_EQ(0, mkdir_recursive(path, 0755, nullptr));
     std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
     EXPECT_TRUE(is_dir(path1.c_str()));
     std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
@@ -148,7 +143,7 @@
 TEST(util, mkdir_recursive_extra_slashes) {
     TemporaryDir test_dir;
     std::string path = android::base::StringPrintf("%s/three////directories/deep//", test_dir.path);
-    EXPECT_EQ(0, mkdir_recursive(path, 0755));
+    EXPECT_EQ(0, mkdir_recursive(path, 0755, nullptr));
     std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
     EXPECT_TRUE(is_dir(path1.c_str()));
     std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
diff --git a/init/watchdogd.cpp b/init/watchdogd.cpp
index 21c1e5b..7baa487 100644
--- a/init/watchdogd.cpp
+++ b/init/watchdogd.cpp
@@ -24,7 +24,10 @@
 #include <android-base/logging.h>
 
 #include "log.h"
-#include "util.h"
+
+#ifdef _INIT_INIT_H
+#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#endif
 
 #define DEV_NAME "/dev/watchdog"
 
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 58170ec..245deb1 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -53,7 +53,7 @@
     host_supported: true,
     srcs: [
         "config_utils.c",
-        "fs_config.c",
+        "fs_config.cpp",
         "canned_fs_config.c",
         "hashmap.c",
         "iosched_policy.c",
@@ -94,6 +94,9 @@
             shared: {
                 enabled: false,
             },
+            cflags: [
+                "-D_GNU_SOURCE",
+            ],
         },
 
         android: {
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.cpp
similarity index 79%
rename from libcutils/fs_config.c
rename to libcutils/fs_config.cpp
index e1e8c8d..a2dd677 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.cpp
@@ -14,15 +14,12 @@
  * limitations under the License.
  */
 
-/* This file is used to define the properties of the filesystem
-** images generated by build tools (mkbootfs and mkyaffs2image) and
-** by the device side of adb.
-*/
+// This file is used to define the properties of the filesystem
+// images generated by build tools (mkbootfs and mkyaffs2image) and
+// by the device side of adb.
 
 #define LOG_TAG "fs_config"
 
-#define _GNU_SOURCE
-
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
@@ -42,8 +39,10 @@
 #define O_BINARY 0
 #endif
 
-/* My kingdom for <endian.h> */
-static inline uint16_t get2LE(const uint8_t* src) { return src[0] | (src[1] << 8); }
+// My kingdom for <endian.h>
+static inline uint16_t get2LE(const uint8_t* src) {
+    return src[0] | (src[1] << 8);
+}
 
 static inline uint64_t get8LE(const uint8_t* src) {
     uint32_t low, high;
@@ -55,14 +54,13 @@
 
 #define ALIGN(x, alignment) (((x) + ((alignment)-1)) & ~((alignment)-1))
 
-/* Rules for directories.
-** These rules are applied based on "first match", so they
-** should start with the most specific path and work their
-** way up to the root.
-*/
+// Rules for directories.
+// These rules are applied based on "first match", so they
+// should start with the most specific path and work their
+// way up to the root.
 
 static const struct fs_path_config android_dirs[] = {
-    /* clang-format off */
+    // clang-format off
     { 00770, AID_SYSTEM,       AID_CACHE,        0, "cache" },
     { 00500, AID_ROOT,         AID_ROOT,         0, "config" },
     { 00771, AID_SYSTEM,       AID_SYSTEM,       0, "data/app" },
@@ -92,25 +90,23 @@
     { 00755, AID_ROOT,         AID_SHELL,        0, "system/xbin" },
     { 00755, AID_ROOT,         AID_SHELL,        0, "vendor" },
     { 00755, AID_ROOT,         AID_ROOT,         0, 0 },
-    /* clang-format on */
+    // clang-format on
 };
 
-/* Rules for files.
-** These rules are applied based on "first match", so they
-** should start with the most specific path and work their
-** way up to the root. Prefixes ending in * denotes wildcard
-** and will allow partial matches.
-*/
+// Rules for files.
+// These rules are applied based on "first match", so they
+// should start with the most specific path and work their
+// way up to the root. Prefixes ending in * denotes wildcard
+// and will allow partial matches.
 static const char sys_conf_dir[] = "/system/etc/fs_config_dirs";
 static const char sys_conf_file[] = "/system/etc/fs_config_files";
-/* No restrictions are placed on the vendor and oem file-system config files,
- * although the developer is advised to restrict the scope to the /vendor or
- * oem/ file-system since the intent is to provide support for customized
- * portions of a separate vendor.img or oem.img.  Has to remain open so that
- * customization can also land on /system/vendor, /system/oem or /system/odm.
- * We expect build-time checking or filtering when constructing the associated
- * fs_config_* files (see build/tools/fs_config/fs_config_generate.c)
- */
+// No restrictions are placed on the vendor and oem file-system config files,
+// although the developer is advised to restrict the scope to the /vendor or
+// oem/ file-system since the intent is to provide support for customized
+// portions of a separate vendor.img or oem.img.  Has to remain open so that
+// customization can also land on /system/vendor, /system/oem or /system/odm.
+// We expect build-time checking or filtering when constructing the associated
+// fs_config_* files (see build/tools/fs_config/fs_config_generate.c)
 static const char ven_conf_dir[] = "/vendor/etc/fs_config_dirs";
 static const char ven_conf_file[] = "/vendor/etc/fs_config_files";
 static const char oem_conf_dir[] = "/oem/etc/fs_config_dirs";
@@ -125,7 +121,7 @@
 };
 
 static const struct fs_path_config android_files[] = {
-    /* clang-format off */
+    // clang-format off
     { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app/*" },
     { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app-ephemeral/*" },
     { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app-private/*" },
@@ -140,8 +136,14 @@
     { 00600, AID_ROOT,      AID_ROOT,      0, "odm/default.prop" },
     { 00444, AID_ROOT,      AID_ROOT,      0, odm_conf_dir + 1 },
     { 00444, AID_ROOT,      AID_ROOT,      0, odm_conf_file + 1 },
+    { 00600, AID_ROOT,      AID_ROOT,      0, "system/odm/build.prop" },
+    { 00600, AID_ROOT,      AID_ROOT,      0, "system/odm/default.prop" },
+    { 00444, AID_ROOT,      AID_ROOT,      0, "system/odm/etc/fs_config_dirs" },
+    { 00444, AID_ROOT,      AID_ROOT,      0, "system/odm/etc/fs_config_files" },
     { 00444, AID_ROOT,      AID_ROOT,      0, oem_conf_dir + 1 },
     { 00444, AID_ROOT,      AID_ROOT,      0, oem_conf_file + 1 },
+    { 00444, AID_ROOT,      AID_ROOT,      0, "system/oem/etc/fs_config_dirs" },
+    { 00444, AID_ROOT,      AID_ROOT,      0, "system/oem/etc/fs_config_files" },
     { 00750, AID_ROOT,      AID_SHELL,     0, "sbin/fs_mgr" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/crash_dump32" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/crash_dump64" },
@@ -158,18 +160,22 @@
     { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/ppp/*" },
     { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/rc.*" },
     { 00440, AID_ROOT,      AID_ROOT,      0, "system/etc/recovery.img" },
+    { 00600, AID_ROOT,      AID_ROOT,      0, "system/vendor/build.prop" },
+    { 00600, AID_ROOT,      AID_ROOT,      0, "system/vendor/default.prop" },
+    { 00444, AID_ROOT,      AID_ROOT,      0, "system/vendor/etc/fs_config_dirs" },
+    { 00444, AID_ROOT,      AID_ROOT,      0, "system/vendor/etc/fs_config_files" },
     { 00600, AID_ROOT,      AID_ROOT,      0, "vendor/build.prop" },
     { 00600, AID_ROOT,      AID_ROOT,      0, "vendor/default.prop" },
     { 00444, AID_ROOT,      AID_ROOT,      0, ven_conf_dir + 1 },
     { 00444, AID_ROOT,      AID_ROOT,      0, ven_conf_file + 1 },
 
-    /* the following two files are INTENTIONALLY set-uid, but they
-     * are NOT included on user builds. */
+    // the following two files are INTENTIONALLY set-uid, but they
+    // are NOT included on user builds.
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procmem" },
     { 04750, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
 
-    /* the following files have enhanced capabilities and ARE included
-     * in user builds. */
+    // the following files have enhanced capabilities and ARE included
+    // in user builds.
     { 00700, AID_SYSTEM,    AID_SHELL,     CAP_MASK_LONG(CAP_BLOCK_SUSPEND),
                                               "system/bin/inputflinger" },
     { 00550, AID_LOGD,      AID_LOGD,      CAP_MASK_LONG(CAP_SYSLOG) |
@@ -180,28 +186,33 @@
                                            CAP_MASK_LONG(CAP_SETGID),
                                               "system/bin/run-as" },
 
-    /* Support FIFO scheduling mode in SurfaceFlinger. */
+    // Support FIFO scheduling mode in SurfaceFlinger.
     { 00755, AID_SYSTEM,    AID_GRAPHICS,  CAP_MASK_LONG(CAP_SYS_NICE),
                                               "system/bin/surfaceflinger" },
 
-    /* Support hostapd administering a network interface. */
+    // Support hostapd administering a network interface.
     { 00755, AID_WIFI,      AID_WIFI,      CAP_MASK_LONG(CAP_NET_ADMIN) |
                                            CAP_MASK_LONG(CAP_NET_RAW),
                                               "system/bin/hostapd" },
 
-    /* Support Bluetooth legacy hal accessing /sys/class/rfkill
-     * Support RT scheduling in Bluetooth */
+    // Support Bluetooth legacy hal accessing /sys/class/rfkill
+    // Support RT scheduling in Bluetooth
+    { 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN) |
+                                           CAP_MASK_LONG(CAP_SYS_NICE),
+                                              "system/vendor/bin/hw/android.hardware.bluetooth@1.0-service" },
     { 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN) |
                                            CAP_MASK_LONG(CAP_SYS_NICE),
                                               "vendor/bin/hw/android.hardware.bluetooth@1.0-service" },
 
-    /* Support wifi_hal_legacy administering a network interface. */
+    // Support wifi_hal_legacy administering a network interface.
+    { 00755, AID_WIFI,      AID_WIFI,      CAP_MASK_LONG(CAP_NET_ADMIN) |
+                                           CAP_MASK_LONG(CAP_NET_RAW),
+                                              "system/vendor/bin/hw/android.hardware.wifi@1.0-service" },
     { 00755, AID_WIFI,      AID_WIFI,      CAP_MASK_LONG(CAP_NET_ADMIN) |
                                            CAP_MASK_LONG(CAP_NET_RAW),
                                               "vendor/bin/hw/android.hardware.wifi@1.0-service" },
 
-    /* A non-privileged zygote that spawns
-     * isolated processes for web rendering. */
+    // A non-privileged zygote that spawns isolated processes for web rendering.
     { 0750,  AID_ROOT,      AID_ROOT,      CAP_MASK_LONG(CAP_SETUID) |
                                            CAP_MASK_LONG(CAP_SETGID) |
                                            CAP_MASK_LONG(CAP_SETPCAP),
@@ -211,7 +222,7 @@
                                            CAP_MASK_LONG(CAP_SETPCAP),
                                               "system/bin/webview_zygote64" },
 
-    /* generic defaults */
+    // generic defaults
     { 00755, AID_ROOT,      AID_ROOT,      0, "bin/*" },
     { 00640, AID_ROOT,      AID_SHELL,     0, "fstab.*" },
     { 00750, AID_ROOT,      AID_SHELL,     0, "init*" },
@@ -225,7 +236,7 @@
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/xbin/*" },
     { 00644, AID_ROOT,      AID_ROOT,      0, 0 },
-    /* clang-format on */
+    // clang-format on
 };
 
 static size_t strip(const char* path, size_t len, const char suffix[]) {
@@ -238,9 +249,9 @@
     int fd = -1;
 
     if (target_out_path && *target_out_path) {
-        /* target_out_path is the path to the directory holding content of
-         * system partition but as we cannot guarantee it ends with '/system'
-         * or with or without a trailing slash, need to strip them carefully. */
+        // target_out_path is the path to the directory holding content of
+        // system partition but as we cannot guarantee it ends with '/system'
+        // or with or without a trailing slash, need to strip them carefully.
         char* name = NULL;
         size_t len = strlen(target_out_path);
         len = strip(target_out_path, len, "/");
@@ -262,7 +273,7 @@
             return false;
         }
     } else {
-        /* If name ends in * then allow partial matches. */
+        // If name ends in * then allow partial matches.
         if (prefix[len - 1] == '*') {
             return !strncmp(prefix, path, len - 1);
         }
@@ -298,7 +309,7 @@
                 ALOGE("%s len is corrupted", conf[which][dir]);
                 break;
             }
-            prefix = calloc(1, remainder);
+            prefix = static_cast<char*>(calloc(1, remainder));
             if (!prefix) {
                 ALOGE("%s out of memory", conf[which][dir]);
                 break;
@@ -309,7 +320,7 @@
                 break;
             }
             len = strnlen(prefix, remainder);
-            if (len >= remainder) { /* missing a terminating null */
+            if (len >= remainder) {  // missing a terminating null
                 free(prefix);
                 ALOGE("%s is corrupted", conf[which][dir]);
                 break;
diff --git a/libcutils/include/cutils/bitops.h b/libcutils/include/cutils/bitops.h
index 045830d..38d2840 100644
--- a/libcutils/include/cutils/bitops.h
+++ b/libcutils/include/cutils/bitops.h
@@ -24,94 +24,15 @@
 
 __BEGIN_DECLS
 
-/*
- * Bitmask Operations
- *
- * Note this doesn't provide any locking/exclusion, and isn't atomic.
- * Additionally no bounds checking is done on the bitmask array.
- *
- * Example:
- *
- * int num_resources;
- * unsigned int resource_bits[BITS_TO_WORDS(num_resources)];
- * bitmask_init(resource_bits, num_resources);
- * ...
- * int bit = bitmask_ffz(resource_bits, num_resources);
- * bitmask_set(resource_bits, bit);
- * ...
- * if (bitmask_test(resource_bits, bit)) { ... }
- * ...
- * bitmask_clear(resource_bits, bit);
- *
- */
-
-#define BITS_PER_WORD    (sizeof(unsigned int) * 8)
-#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)
-#define BIT_IN_WORD(x)   ((x) % BITS_PER_WORD)
-#define BIT_WORD(x)      ((x) / BITS_PER_WORD)
-#define BIT_MASK(x)      (1 << BIT_IN_WORD(x))
-
-static inline void bitmask_init(unsigned int *bitmask, int num_bits)
-{
-    memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));
-}
-
-static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
-{
-    int bit, result;
-    size_t i;
-
-    for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
-        bit = ffs(~bitmask[i]);
-        if (bit) {
-            // ffs is 1-indexed, return 0-indexed result
-            bit--;
-            result = BITS_PER_WORD * i + bit;
-            if (result >= num_bits)
-                return -1;
-            return result;
-        }
-    }
-    return -1;
-}
-
-static inline int bitmask_weight(unsigned int *bitmask, int num_bits)
-{
-    size_t i;
-    int weight = 0;
-
-    for (i = 0; i < BITS_TO_WORDS(num_bits); i++)
-        weight += __builtin_popcount(bitmask[i]);
-    return weight;
-}
-
-static inline void bitmask_set(unsigned int *bitmask, int bit)
-{
-    bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);
-}
-
-static inline void bitmask_clear(unsigned int *bitmask, int bit)
-{
-    bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);
-}
-
-static inline bool bitmask_test(unsigned int *bitmask, int bit)
-{
-    return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);
-}
-
-static inline int popcount(unsigned int x)
-{
+static inline int popcount(unsigned int x) {
     return __builtin_popcount(x);
 }
 
-static inline int popcountl(unsigned long x)
-{
+static inline int popcountl(unsigned long x) {
     return __builtin_popcountl(x);
 }
 
-static inline int popcountll(unsigned long long x)
-{
+static inline int popcountll(unsigned long long x) {
     return __builtin_popcountll(x);
 }
 
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 9f4840a..95bbc41 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "NativeHandle"
+#include <cutils/native_handle.h>
 
 #include <errno.h>
 #include <stdint.h>
@@ -22,15 +22,12 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <android/log.h>
-#include <cutils/native_handle.h>
-
 static const int kMaxNativeFds = 1024;
 static const int kMaxNativeInts = 1024;
 
-native_handle_t* native_handle_init(char* storage, int numFds, int numInts)
-{
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts) {
     if ((uintptr_t) storage % alignof(native_handle_t)) {
+        errno = EINVAL;
         return NULL;
     }
 
@@ -38,13 +35,12 @@
     handle->version = sizeof(native_handle_t);
     handle->numFds = numFds;
     handle->numInts = numInts;
-
     return handle;
 }
 
-native_handle_t* native_handle_create(int numFds, int numInts)
-{
+native_handle_t* native_handle_create(int numFds, int numInts) {
     if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {
+        errno = EINVAL;
         return NULL;
     }
 
@@ -58,14 +54,13 @@
     return h;
 }
 
-native_handle_t* native_handle_clone(const native_handle_t* handle)
-{
+native_handle_t* native_handle_clone(const native_handle_t* handle) {
     native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
-    int i;
+    if (clone == NULL) return NULL;
 
-    for (i = 0; i < handle->numFds; i++) {
+    for (int i = 0; i < handle->numFds; i++) {
         clone->data[i] = dup(handle->data[i]);
-        if (clone->data[i] < 0) {
+        if (clone->data[i] == -1) {
             clone->numFds = i;
             native_handle_close(clone);
             native_handle_delete(clone);
@@ -74,30 +69,27 @@
     }
 
     memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
-            sizeof(int) * handle->numInts);
+           sizeof(int) * handle->numInts);
 
     return clone;
 }
 
-int native_handle_delete(native_handle_t* h)
-{
+int native_handle_delete(native_handle_t* h) {
     if (h) {
-        if (h->version != sizeof(native_handle_t))
-            return -EINVAL;
+        if (h->version != sizeof(native_handle_t)) return -EINVAL;
         free(h);
     }
     return 0;
 }
 
-int native_handle_close(const native_handle_t* h)
-{
-    if (h->version != sizeof(native_handle_t))
-        return -EINVAL;
+int native_handle_close(const native_handle_t* h) {
+    if (h->version != sizeof(native_handle_t)) return -EINVAL;
 
+    int saved_errno = errno;
     const int numFds = h->numFds;
-    int i;
-    for (i=0 ; i<numFds ; i++) {
+    for (int i = 0; i < numFds; ++i) {
         close(h->data[i]);
     }
+    errno = saved_errno;
     return 0;
 }
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index 217733a..e29a844 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -343,16 +343,25 @@
 static void set_timerslack_ns(int tid, unsigned long long slack) {
     // v4.6+ kernels support the /proc/<tid>/timerslack_ns interface.
     // TODO: once we've backported this, log if the open(2) fails.
-    char buf[64];
-    snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", tid);
-    int fd = open(buf, O_WRONLY | O_CLOEXEC);
-    if (fd != -1) {
-        int len = snprintf(buf, sizeof(buf), "%llu", slack);
-        if (write(fd, buf, len) != len) {
-            SLOGE("set_timerslack_ns write failed: %s\n", strerror(errno));
+    if (__sys_supports_timerslack) {
+        char buf[64];
+        snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", tid);
+        int fd = open(buf, O_WRONLY | O_CLOEXEC);
+        if (fd != -1) {
+            int len = snprintf(buf, sizeof(buf), "%llu", slack);
+            if (write(fd, buf, len) != len) {
+                SLOGE("set_timerslack_ns write failed: %s\n", strerror(errno));
+            }
+            close(fd);
+            return;
         }
-        close(fd);
-        return;
+    }
+
+    // TODO: Remove when /proc/<tid>/timerslack_ns interface is backported.
+    if ((tid == 0) || (tid == gettid())) {
+        if (prctl(PR_SET_TIMERSLACK, slack) == -1) {
+            SLOGE("set_timerslack_ns prctl failed: %s\n", strerror(errno));
+        }
     }
 }
 
@@ -431,10 +440,7 @@
 
     }
 
-    if (__sys_supports_timerslack) {
-        set_timerslack_ns(tid, policy == SP_BACKGROUND ?
-                               TIMER_SLACK_BG : TIMER_SLACK_FG);
-    }
+    set_timerslack_ns(tid, policy == SP_BACKGROUND ? TIMER_SLACK_BG : TIMER_SLACK_FG);
 
     return 0;
 }
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index 6758c84..3a215e9 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -32,6 +32,7 @@
 #include <log/log_main.h>
 #include <log/log_radio.h>
 #include <log/log_read.h>
+#include <log/log_safetynet.h>
 #include <log/log_system.h>
 #include <log/log_time.h>
 #include <log/uio.h> /* helper to define iovec for portability */
@@ -167,31 +168,6 @@
 
 /* --------------------------------------------------------------------- */
 
-#ifndef _ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE
-#ifndef __ANDROID_API__
-#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 1
-#elif __ANDROID_API__ > 22 /* > Lollipop */
-#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 1
-#else
-#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 0
-#endif
-#endif
-
-#if __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE
-
-#define android_errorWriteLog(tag, subTag) \
-  __android_log_error_write(tag, subTag, -1, NULL, 0)
-
-#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \
-  __android_log_error_write(tag, subTag, uid, data, dataLen)
-
-int __android_log_error_write(int tag, const char* subTag, int32_t uid,
-                              const char* data, uint32_t dataLen);
-
-#endif /* __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE */
-
-/* --------------------------------------------------------------------- */
-
 #ifndef __ANDROID_USE_LIBLOG_CLOSE_INTERFACE
 #ifndef __ANDROID_API__
 #define __ANDROID_USE_LIBLOG_CLOSE_INTERFACE 1
diff --git a/liblog/include/log/log_safetynet.h b/liblog/include/log/log_safetynet.h
new file mode 100644
index 0000000..b8ca475
--- /dev/null
+++ b/liblog/include/log/log_safetynet.h
@@ -0,0 +1,44 @@
+/*
+**
+** Copyright 2017, The Android Open Source Project
+**
+** This file is dual licensed.  It may be redistributed and/or modified
+** under the terms of the Apache 2.0 License OR version 2 of the GNU
+** General Public License.
+*/
+
+#ifndef _LIBS_LOG_SAFETYNET_H
+#define _LIBS_LOG_SAFETYNET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE
+#ifndef __ANDROID_API__
+#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 1
+#elif __ANDROID_API__ > 22 /* > Lollipop */
+#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 1
+#else
+#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 0
+#endif
+#endif
+
+#if __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE
+
+#define android_errorWriteLog(tag, subTag) \
+  __android_log_error_write(tag, subTag, -1, NULL, 0)
+
+#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \
+  __android_log_error_write(tag, subTag, uid, data, dataLen)
+
+int __android_log_error_write(int tag, const char* subTag, int32_t uid,
+                              const char* data, uint32_t dataLen);
+
+#endif /* __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBS_LOG_SAFETYNET_H */
diff --git a/liblog/include_vndk/log/log.h b/liblog/include_vndk/log/log.h
index f93b377..01623df 100644
--- a/liblog/include_vndk/log/log.h
+++ b/liblog/include_vndk/log/log.h
@@ -8,6 +8,7 @@
 #include <log/log_main.h>
 #include <log/log_radio.h>
 #include <log/log_read.h>
+#include <log/log_safetynet.h>
 #include <log/log_time.h>
 
 /*
diff --git a/liblog/include_vndk/log/log_safetynet.h b/liblog/include_vndk/log/log_safetynet.h
new file mode 120000
index 0000000..a4614e7
--- /dev/null
+++ b/liblog/include_vndk/log/log_safetynet.h
@@ -0,0 +1 @@
+../../include/log/log_safetynet.h
\ No newline at end of file
diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt
index 58fb148..3c4c1f1 100644
--- a/liblog/liblog.map.txt
+++ b/liblog/liblog.map.txt
@@ -33,6 +33,7 @@
     android_logger_get_prune_list; # vndk
     android_logger_set_prune_list; # vndk
     android_logger_get_statistics; # vndk
+    __android_log_error_write; # vndk
     __android_log_is_loggable;
 };
 
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index 0e6432c..ab96429 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -55,6 +55,7 @@
     -fno-builtin \
 
 test_src_files := \
+    libc_test.cpp \
     liblog_test_default.cpp \
     liblog_test_local.cpp \
     liblog_test_stderr.cpp \
@@ -65,14 +66,6 @@
     log_system_test.cpp \
     log_time_test.cpp
 
-# to prevent breaking the build if bionic not relatively visible to us
-ifneq ($(wildcard $(LOCAL_PATH)/../../../../bionic/libc/bionic/libc_logging.cpp),)
-
-test_src_files += \
-    libc_test.cpp
-
-endif
-
 # Build tests for the device (with .so). Run with:
 #   adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
 include $(CLEAR_VARS)
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index 4662368..2867f64 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -30,7 +30,6 @@
 
     static_libs: [
         "libc_malloc_debug_backtrace",
-        "libc_logging",
     ],
     // Only need this for arm since libc++ uses its own unwind code that
     // doesn't mix with the other default unwind code.
diff --git a/lmkd/Android.bp b/lmkd/Android.bp
new file mode 100644
index 0000000..3f8a503
--- /dev/null
+++ b/lmkd/Android.bp
@@ -0,0 +1,13 @@
+cc_binary {
+    name: "lmkd",
+
+    srcs: ["lmkd.c"],
+    shared_libs: [
+        "liblog",
+        "libprocessgroup",
+        "libcutils",
+    ],
+    cflags: ["-Werror"],
+
+    init_rc: ["lmkd.rc"],
+}
diff --git a/lmkd/Android.mk b/lmkd/Android.mk
deleted file mode 100644
index 8980d1c..0000000
--- a/lmkd/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := lmkd.c
-LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup libcutils
-LOCAL_CFLAGS := -Werror
-
-LOCAL_MODULE := lmkd
-
-LOCAL_INIT_RC := lmkd.rc
-
-include $(BUILD_EXECUTABLE)
diff --git a/logd/Android.mk b/logd/Android.mk
index 9211037..fb51992 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -2,12 +2,9 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE:= logd
-
-LOCAL_INIT_RC := logd.rc
+LOCAL_MODULE:= liblogd
 
 LOCAL_SRC_FILES := \
-    main.cpp \
     LogCommand.cpp \
     CommandListener.cpp \
     LogListener.cpp \
@@ -15,6 +12,7 @@
     FlushCommand.cpp \
     LogBuffer.cpp \
     LogBufferElement.cpp \
+    LogBufferInterface.cpp \
     LogTimes.cpp \
     LogStatistics.cpp \
     LogWhiteBlackList.cpp \
@@ -25,12 +23,9 @@
     event.logtags
 
 LOCAL_SHARED_LIBRARIES := \
-    libsysutils \
-    liblog \
-    libcutils \
-    libbase \
-    libpackagelistparser \
-    libcap
+    libbase
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 
 # This is what we want to do:
 #  event_logtags = $(shell \
@@ -46,6 +41,30 @@
 
 LOCAL_CFLAGS := -Werror $(event_flag)
 
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= logd
+
+LOCAL_INIT_RC := logd.rc
+
+LOCAL_SRC_FILES := \
+    main.cpp
+
+LOCAL_STATIC_LIBRARIES := \
+    liblogd
+
+LOCAL_SHARED_LIBRARIES := \
+    libsysutils \
+    liblog \
+    libcutils \
+    libbase \
+    libpackagelistparser \
+    libcap
+
+LOCAL_CFLAGS := -Werror
+
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 51edd86..e597754 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -27,6 +27,7 @@
 #include <sysutils/SocketClient.h>
 
 #include "LogBufferElement.h"
+#include "LogBufferInterface.h"
 #include "LogStatistics.h"
 #include "LogTags.h"
 #include "LogTimes.h"
@@ -74,7 +75,7 @@
 
 typedef std::list<LogBufferElement*> LogBufferElementCollection;
 
-class LogBuffer {
+class LogBuffer : public LogBufferInterface {
     LogBufferElementCollection mLogElements;
     pthread_rwlock_t mLogElementsLock;
 
@@ -107,14 +108,14 @@
     LastLogTimes& mTimes;
 
     explicit LogBuffer(LastLogTimes* times);
-    ~LogBuffer();
+    ~LogBuffer() override;
     void init();
     bool isMonotonic() {
         return monotonic;
     }
 
     int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
-            const char* msg, unsigned short len);
+            const char* msg, unsigned short len) override;
     // lastTid is an optional context to help detect if the last previous
     // valid message was from the same source so we can differentiate chatty
     // filter types (identical or expired)
diff --git a/logd/LogBufferInterface.cpp b/logd/LogBufferInterface.cpp
new file mode 100644
index 0000000..3cb2b89
--- /dev/null
+++ b/logd/LogBufferInterface.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LogBufferInterface.h"
+
+LogBufferInterface::LogBufferInterface() {
+}
+LogBufferInterface::~LogBufferInterface() {
+}
\ No newline at end of file
diff --git a/logd/LogBufferInterface.h b/logd/LogBufferInterface.h
new file mode 100644
index 0000000..7d82b91
--- /dev/null
+++ b/logd/LogBufferInterface.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOGD_LOG_BUFFER_INTERFACE_H__
+#define _LOGD_LOG_BUFFER_INTERFACE_H__
+
+#include <sys/types.h>
+
+#include <android-base/macros.h>
+#include <log/log_id.h>
+#include <log/log_time.h>
+
+// Abstract interface that handles log when log available.
+class LogBufferInterface {
+   public:
+    LogBufferInterface();
+    virtual ~LogBufferInterface();
+    // Handles a log entry when available in LogListener.
+    // Returns the size of the handled log message.
+    virtual int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
+                    pid_t tid, const char* msg, unsigned short len) = 0;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(LogBufferInterface);
+};
+
+#endif  // _LOGD_LOG_BUFFER_INTERFACE_H__
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index dadc75f..709646e 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -30,7 +30,7 @@
 #include "LogListener.h"
 #include "LogUtils.h"
 
-LogListener::LogListener(LogBuffer* buf, LogReader* reader)
+LogListener::LogListener(LogBufferInterface* buf, LogReader* reader)
     : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {
 }
 
@@ -102,11 +102,14 @@
     // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
     // truncated message to the logs.
 
-    if (logbuf->log((log_id_t)header->id, header->realtime, cred->uid,
-                    cred->pid, header->tid, msg,
-                    ((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX) >=
-        0) {
-        reader->notifyNewLog();
+    if (logbuf != nullptr) {
+        int res = logbuf->log(
+            (log_id_t)header->id, header->realtime, cred->uid, cred->pid,
+            header->tid, msg,
+            ((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
+        if (res > 0 && reader != nullptr) {
+            reader->notifyNewLog();
+        }
     }
 
     return true;
diff --git a/logd/LogListener.h b/logd/LogListener.h
index 2973b8b..e16c5fb 100644
--- a/logd/LogListener.h
+++ b/logd/LogListener.h
@@ -21,11 +21,11 @@
 #include "LogReader.h"
 
 class LogListener : public SocketListener {
-    LogBuffer* logbuf;
+    LogBufferInterface* logbuf;
     LogReader* reader;
 
    public:
-    LogListener(LogBuffer* buf, LogReader* reader);
+    LogListener(LogBufferInterface* buf, LogReader* reader /* nullable */);
 
    protected:
     virtual bool onDataAvailable(SocketClient* cli);
diff --git a/logd/logd.rc b/logd/logd.rc
index ee89b83..7494d8f 100644
--- a/logd/logd.rc
+++ b/logd/logd.rc
@@ -5,7 +5,7 @@
     file /proc/kmsg r
     file /dev/kmsg w
     user logd
-    group logd system readproc
+    group logd system package_info readproc
     writepid /dev/cpuset/system-background/tasks
 
 service logd-reinit /system/bin/logd --reinit
diff --git a/logd/main.cpp b/logd/main.cpp
index 18029eb..c8183f0 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -240,23 +240,36 @@
     set_sched_policy(0, SP_BACKGROUND);
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND);
 
+    // We should drop to AID_LOGD, if we are anything else, we have
+    // even lesser privileges and accept our fate.
+    gid_t groups[] = {
+        AID_SYSTEM,        // search access to /data/system path
+        AID_PACKAGE_INFO,  // readonly access to /data/system/packages.list
+    };
+    if (setgroups(arraysize(groups), groups) == -1) {
+        android::prdebug(
+            "logd.daemon: failed to set AID_SYSTEM AID_PACKAGE_INFO groups");
+    }
+    if (setgid(AID_LOGD) != 0) {
+        android::prdebug("logd.daemon: failed to set AID_LOGD gid");
+    }
+    if (setuid(AID_LOGD) != 0) {
+        android::prdebug("logd.daemon: failed to set AID_LOGD uid");
+    }
+
     cap_t caps = cap_init();
     (void)cap_clear(caps);
     (void)cap_set_proc(caps);
     (void)cap_free(caps);
 
-    // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are
-    // anything else, we have even lesser privileges and accept our fate. Not
-    // worth checking for error returns setting this thread's privileges.
-    (void)setgid(AID_SYSTEM);  // readonly access to /data/system/packages.list
-    (void)setuid(AID_LOGD);    // access to everything logd, eg /data/misc/logd
-
     while (reinit_running && !sem_wait(&reinit) && reinit_running) {
         // uidToName Privileged Worker
         if (uid) {
             name = nullptr;
 
-            packagelist_parse(package_list_parser_cb, nullptr);
+            // if we got the perms wrong above, this would spam if we reported
+            // problems with acquisition of an uid name from the packages.
+            (void)packagelist_parse(package_list_parser_cb, nullptr);
 
             uid = 0;
             sem_post(&uidName);
diff --git a/logd/tests/Android.mk b/logd/tests/Android.mk
index c053993..1915677 100644
--- a/logd/tests/Android.mk
+++ b/logd/tests/Android.mk
@@ -49,3 +49,38 @@
 LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
 LOCAL_SRC_FILES := $(test_src_files)
 include $(BUILD_NATIVE_TEST)
+
+cts_executable := CtsLogdTestCases
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(cts_executable)
+LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS += $(test_c_flags)
+LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
+LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
+LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_CTS_TEST_PACKAGE := android.core.logd
+include $(BUILD_CTS_EXECUTABLE)
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(cts_executable)_list
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(test_c_flags) -DHOST
+LOCAL_C_INCLUDES := external/gtest/include
+LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_CXX_STL := libc++
+LOCAL_SHARED_LIBRARIES := libbase libcutils liblog
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_NATIVE_TEST)
+
+endif  # ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
diff --git a/logd/tests/AndroidTest.xml b/logd/tests/AndroidTest.xml
new file mode 100644
index 0000000..b16bdfd
--- /dev/null
+++ b/logd/tests/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Logging Daemon test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="CtsLogdTestCases->/data/local/tmp/CtsLogdTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="CtsLogdTestCases" />
+        <option name="runtime-hint" value="65s" />
+    </test>
+</configuration>
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index a1d154a..f90c9fb 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <ctype.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <poll.h>
@@ -26,6 +27,7 @@
 
 #include <string>
 
+#include <android-base/file.h>
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
 #include <cutils/sockets.h>
@@ -39,6 +41,7 @@
 #include "../LogReader.h"  // pickup LOGD_SNDTIMEO
 #include "../libaudit.h"   // pickup AUDIT_RATE_LIMIT_*
 
+#ifdef __ANDROID__
 static void send_to_control(char* buf, size_t len) {
     int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
                                    SOCK_STREAM);
@@ -84,7 +87,7 @@
         size_t ret = atol(buf) + 1;
         if (ret < 4) {
             delete[] buf;
-            buf = NULL;
+            buf = nullptr;
             break;
         }
         bool check = ret <= len;
@@ -106,7 +109,7 @@
     // UID   PACKAGE                                                BYTES LINES
     // 0     root                                                  54164 147569
     //
-    char* benchmark = NULL;
+    char* benchmark = nullptr;
     do {
         static const char signature[] = "\n0     root ";
 
@@ -121,7 +124,7 @@
         benchmark = cp;
 #ifdef DEBUG
         char* end = strstr(benchmark, "\n");
-        if (end == NULL) {
+        if (end == nullptr) {
             end = benchmark + strlen(benchmark);
         }
         fprintf(stderr, "parse for spam counter in \"%.*s\"\n",
@@ -153,18 +156,25 @@
         if (value > 10UL) {
             break;
         }
-        benchmark = NULL;
+        benchmark = nullptr;
     } while (*cp);
     return benchmark;
 }
+#endif
 
 TEST(logd, statistics) {
+#ifdef __ANDROID__
     size_t len;
     char* buf;
 
+    // Drop cache so that any access problems can be discovered.
+    if (!android::base::WriteStringToFile("3\n", "/proc/sys/vm/drop_caches")) {
+        GTEST_LOG_(INFO) << "Could not open trigger dropping inode cache";
+    }
+
     alloc_statistics(&buf, &len);
 
-    ASSERT_TRUE(NULL != buf);
+    ASSERT_TRUE(nullptr != buf);
 
     // remove trailing FF
     char* cp = buf + len - 1;
@@ -189,23 +199,46 @@
     EXPECT_EQ(0, truncated);
 
     char* main_logs = strstr(cp, "\nChattiest UIDs in main ");
-    EXPECT_TRUE(NULL != main_logs);
+    EXPECT_TRUE(nullptr != main_logs);
 
     char* radio_logs = strstr(cp, "\nChattiest UIDs in radio ");
     if (!radio_logs)
-        GTEST_LOG_(INFO) << "Value of: NULL != radio_logs\n"
+        GTEST_LOG_(INFO) << "Value of: nullptr != radio_logs\n"
                             "Actual: false\n"
                             "Expected: false\n";
 
     char* system_logs = strstr(cp, "\nChattiest UIDs in system ");
-    EXPECT_TRUE(NULL != system_logs);
+    EXPECT_TRUE(nullptr != system_logs);
 
     char* events_logs = strstr(cp, "\nChattiest UIDs in events ");
-    EXPECT_TRUE(NULL != events_logs);
+    EXPECT_TRUE(nullptr != events_logs);
+
+    // Check if there is any " u0_a#### " as this means packagelistparser broken
+    char* used_getpwuid = nullptr;
+    int used_getpwuid_len;
+    char* uid_name = cp;
+    static const char getpwuid_prefix[] = " u0_a";
+    while ((uid_name = strstr(uid_name, getpwuid_prefix)) != nullptr) {
+        used_getpwuid = uid_name + 1;
+        uid_name += strlen(getpwuid_prefix);
+        while (isdigit(*uid_name)) ++uid_name;
+        used_getpwuid_len = uid_name - used_getpwuid;
+        if (isspace(*uid_name)) break;
+        used_getpwuid = nullptr;
+    }
+    EXPECT_TRUE(nullptr == used_getpwuid);
+    if (used_getpwuid) {
+        fprintf(stderr, "libpackagelistparser failed to pick up %.*s\n",
+                used_getpwuid_len, used_getpwuid);
+    }
 
     delete[] buf;
+#else
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
+#ifdef __ANDROID__
 static void caught_signal(int /* signum */) {
 }
 
@@ -315,8 +348,10 @@
     fprintf(stderr, "}\n");
     fflush(stderr);
 }
+#endif
 
 TEST(logd, both) {
+#ifdef __ANDROID__
     log_msg msg;
 
     // check if we can read any logs from logd
@@ -343,7 +378,7 @@
         }
 
         alarm(old_alarm);
-        sigaction(SIGALRM, &old_sigaction, NULL);
+        sigaction(SIGALRM, &old_sigaction, nullptr);
 
         close(fd);
     }
@@ -390,8 +425,12 @@
     EXPECT_EQ(0, !user_logger_available && !kernel_logger_available);
     EXPECT_EQ(0, user_logger_content && kernel_logger_content);
     EXPECT_EQ(0, !user_logger_content && !kernel_logger_content);
+#else
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
+#ifdef __ANDROID__
 // BAD ROBOT
 //   Benchmark threshold are generally considered bad form unless there is
 //   is some human love applied to the continued maintenance and whether the
@@ -421,7 +460,7 @@
 
     // Introduce some extreme spam for the worst UID filter
     ASSERT_TRUE(
-        NULL !=
+        nullptr !=
         (fp = popen("/data/nativetest/liblog-benchmarks/liblog-benchmarks"
                     " BM_log_maximum_retry"
                     " BM_log_maximum"
@@ -492,10 +531,10 @@
     bool collected_statistics = !!buf;
     EXPECT_EQ(true, collected_statistics);
 
-    ASSERT_TRUE(NULL != buf);
+    ASSERT_TRUE(nullptr != buf);
 
     char* benchmark_statistics_found = find_benchmark_spam(buf);
-    ASSERT_TRUE(benchmark_statistics_found != NULL);
+    ASSERT_TRUE(benchmark_statistics_found != nullptr);
 
     // Check how effective the SPAM filter is, parse out Now size.
     // 0     root                      54164 147569
@@ -560,9 +599,11 @@
     // 50% threshold for SPAM filter (<20% typical, lots of engineering margin)
     ASSERT_GT(totalSize, nowSpamSize * 2);
 }
+#endif
 
 // b/26447386 confirm fixed
 void timeout_negative(const char* command) {
+#ifdef __ANDROID__
     log_msg msg_wrap, msg_timeout;
     bool content_wrap = false, content_timeout = false, written = false;
     unsigned int alarm_wrap = 0, alarm_timeout = 0;
@@ -588,7 +629,7 @@
         written = write(fd, ask.c_str(), len) == (ssize_t)len;
         if (!written) {
             alarm(old_alarm);
-            sigaction(SIGALRM, &old_sigaction, NULL);
+            sigaction(SIGALRM, &old_sigaction, nullptr);
             close(fd);
             continue;
         }
@@ -610,7 +651,7 @@
                                    : (old_alarm > (1 + 3 - alarm_wrap))
                                          ? old_alarm - 3 + alarm_wrap
                                          : 2);
-        sigaction(SIGALRM, &old_sigaction, NULL);
+        sigaction(SIGALRM, &old_sigaction, nullptr);
 
         close(fd);
 
@@ -632,6 +673,10 @@
     EXPECT_NE(0U, alarm_wrap);
     EXPECT_TRUE(content_timeout);
     EXPECT_NE(0U, alarm_timeout);
+#else
+    command = nullptr;
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 TEST(logd, timeout_no_start) {
@@ -645,6 +690,7 @@
 
 // b/26447386 refined behavior
 TEST(logd, timeout) {
+#ifdef __ANDROID__
     // b/33962045 This test interferes with other log reader tests that
     // follow because of file descriptor socket persistence in the same
     // process.  So let's fork it to isolate it from giving us pain.
@@ -693,7 +739,7 @@
         written = write(fd, ask.c_str(), len) == (ssize_t)len;
         if (!written) {
             alarm(old_alarm);
-            sigaction(SIGALRM, &old_sigaction, NULL);
+            sigaction(SIGALRM, &old_sigaction, nullptr);
             close(fd);
             continue;
         }
@@ -715,7 +761,7 @@
                                    : (old_alarm > (1 + 3 - alarm_wrap))
                                          ? old_alarm - 3 + alarm_wrap
                                          : 2);
-        sigaction(SIGALRM, &old_sigaction, NULL);
+        sigaction(SIGALRM, &old_sigaction, nullptr);
 
         close(fd);
 
@@ -768,10 +814,14 @@
 
     _exit(!written + content_wrap + alarm_wrap + !content_timeout +
           !alarm_timeout);
+#else
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 // b/27242723 confirmed fixed
 TEST(logd, SNDTIMEO) {
+#ifdef __ANDROID__
     static const unsigned sndtimeo =
         LOGD_SNDTIMEO;  // <sigh> it has to be done!
     static const unsigned sleep_time = sndtimeo + 3;
@@ -813,7 +863,7 @@
     int save_errno = (recv_ret < 0) ? errno : 0;
 
     EXPECT_NE(0U, alarm(old_alarm));
-    sigaction(SIGALRM, &old_sigaction, NULL);
+    sigaction(SIGALRM, &old_sigaction, nullptr);
 
     EXPECT_EQ(0, recv_ret);
     if (recv_ret > 0) {
@@ -822,6 +872,9 @@
     EXPECT_EQ(0, save_errno);
 
     close(fd);
+#else
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 TEST(logd, getEventTag_list) {
@@ -849,8 +902,8 @@
     char* cp;
     long ret = strtol(buffer, &cp, 10);
     EXPECT_GT(ret, 16);
-    EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != NULL);
-    EXPECT_TRUE(strstr(buffer, "answer") != NULL);
+    EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != nullptr);
+    EXPECT_TRUE(strstr(buffer, "answer") != nullptr);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -870,8 +923,8 @@
     char* cp;
     long ret = strtol(buffer, &cp, 10);
     EXPECT_GT(ret, 16);
-    EXPECT_TRUE(strstr(buffer, "\t(new|1)") != NULL);
-    EXPECT_TRUE(strstr(buffer, name) != NULL);
+    EXPECT_TRUE(strstr(buffer, "\t(new|1)") != nullptr);
+    EXPECT_TRUE(strstr(buffer, name) != nullptr);
 // ToDo: also look for this in /data/misc/logd/event-log-tags and
 // /dev/event-log-tags.
 #else
@@ -879,11 +932,14 @@
 #endif
 }
 
+#ifdef __ANDROID__
 static inline int32_t get4LE(const char* src) {
     return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
 }
+#endif
 
 void __android_log_btwrite_multiple__helper(int count) {
+#ifdef __ANDROID__
     log_time ts(CLOCK_MONOTONIC);
 
     log_time ts1(CLOCK_MONOTONIC);
@@ -912,7 +968,7 @@
     ASSERT_EQ(0, info.si_status);
 
     struct logger_list* logger_list;
-    ASSERT_TRUE(NULL !=
+    ASSERT_TRUE(nullptr !=
                 (logger_list = android_logger_list_open(
                      LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
                      0, pid)));
@@ -976,6 +1032,10 @@
     EXPECT_EQ(expected_chatty_count, chatty_count);
     EXPECT_EQ(expected_identical_count, identical_count);
     EXPECT_EQ(expected_expire_count, expire_count);
+#else
+    count = 0;
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 TEST(logd, multiple_test_1) {