Merge "libcutils: fs_config.c mark vendor, odm and oem partitions in duplicate"
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 5f55ab9..b8f790d 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"
@@ -1254,66 +1246,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 +1336,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 +1361,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 +1739,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/base/Android.bp b/base/Android.bp
index 81b96db..14bfe36 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -42,6 +42,7 @@
     clang: true,
     host_supported: true,
     srcs: [
+        "chrono_utils.cpp",
         "file.cpp",
         "logging.cpp",
         "parsenetaddress.cpp",
@@ -64,7 +65,6 @@
             srcs: [
                 "errors_unix.cpp",
                 "properties.cpp",
-                "chrono_utils.cpp",
             ],
             cppflags: ["-Wexit-time-destructors"],
             sanitize: {
@@ -74,14 +74,12 @@
         },
         darwin: {
             srcs: [
-                "chrono_utils.cpp",
                 "errors_unix.cpp",
             ],
             cppflags: ["-Wexit-time-destructors"],
         },
         linux_bionic: {
             srcs: [
-                "chrono_utils.cpp",
                 "errors_unix.cpp",
             ],
             cppflags: ["-Wexit-time-destructors"],
@@ -89,7 +87,6 @@
         },
         linux: {
             srcs: [
-                "chrono_utils.cpp",
                 "errors_unix.cpp",
             ],
             cppflags: ["-Wexit-time-destructors"],
diff --git a/base/chrono_utils.cpp b/base/chrono_utils.cpp
index 5eedf3b..d73b551 100644
--- a/base/chrono_utils.cpp
+++ b/base/chrono_utils.cpp
@@ -21,17 +21,14 @@
 namespace android {
 namespace base {
 
+#if defined(__linux__)
 boot_clock::time_point boot_clock::now() {
-#ifdef __ANDROID__
   timespec ts;
   clock_gettime(CLOCK_BOOTTIME, &ts);
   return boot_clock::time_point(std::chrono::seconds(ts.tv_sec) +
                                 std::chrono::nanoseconds(ts.tv_nsec));
-#else
-  // Darwin does not support clock_gettime.
-  return boot_clock::time_point();
-#endif  // __ANDROID__
 }
+#endif
 
 }  // namespace base
 }  // namespace android
diff --git a/base/chrono_utils_test.cpp b/base/chrono_utils_test.cpp
index 057132d..1f1ce15 100644
--- a/base/chrono_utils_test.cpp
+++ b/base/chrono_utils_test.cpp
@@ -16,6 +16,7 @@
 
 #include "android-base/chrono_utils.h"
 
+#include <err.h>
 #include <time.h>
 
 #include <chrono>
@@ -25,9 +26,12 @@
 namespace android {
 namespace base {
 
+#if defined(__linux__)
 std::chrono::seconds GetBootTimeSeconds() {
   struct timespec now;
-  clock_gettime(CLOCK_BOOTTIME, &now);
+  if (clock_gettime(CLOCK_BOOTTIME, &now) != 0) {
+    err(1, "clock_gettime failed");
+  }
 
   auto now_tp = boot_clock::time_point(std::chrono::seconds(now.tv_sec) +
                                        std::chrono::nanoseconds(now.tv_nsec));
@@ -41,6 +45,7 @@
       std::chrono::duration_cast<std::chrono::seconds>(boot_clock::now().time_since_epoch());
   EXPECT_EQ(now, boot_seconds);
 }
+#endif  // defined(__linux__)
 
 }  // namespace base
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/base/include/android-base/chrono_utils.h b/base/include/android-base/chrono_utils.h
index 0086425..795225b 100644
--- a/base/include/android-base/chrono_utils.h
+++ b/base/include/android-base/chrono_utils.h
@@ -22,6 +22,7 @@
 namespace android {
 namespace base {
 
+#if defined(__linux__)
 // A std::chrono clock based on CLOCK_BOOTTIME.
 class boot_clock {
  public:
@@ -30,6 +31,7 @@
 
   static time_point now();
 };
+#endif  // defined(__linux__)
 
 }  // namespace base
 }  // namespace android
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..edcfd54 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -133,13 +133,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/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/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/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/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..bd9fa93 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -39,6 +39,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);
@@ -157,8 +158,10 @@
     } while (*cp);
     return benchmark;
 }
+#endif
 
 TEST(logd, statistics) {
+#ifdef __ANDROID__
     size_t len;
     char* buf;
 
@@ -204,8 +207,12 @@
     EXPECT_TRUE(NULL != events_logs);
 
     delete[] buf;
+#else
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
+#ifdef __ANDROID__
 static void caught_signal(int /* signum */) {
 }
 
@@ -315,8 +322,10 @@
     fprintf(stderr, "}\n");
     fflush(stderr);
 }
+#endif
 
 TEST(logd, both) {
+#ifdef __ANDROID__
     log_msg msg;
 
     // check if we can read any logs from logd
@@ -390,8 +399,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
@@ -560,9 +573,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;
@@ -632,6 +647,10 @@
     EXPECT_NE(0U, alarm_wrap);
     EXPECT_TRUE(content_timeout);
     EXPECT_NE(0U, alarm_timeout);
+#else
+    command = NULL;
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 TEST(logd, timeout_no_start) {
@@ -645,6 +664,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.
@@ -768,10 +788,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;
@@ -822,6 +846,9 @@
     EXPECT_EQ(0, save_errno);
 
     close(fd);
+#else
+    GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 TEST(logd, getEventTag_list) {
@@ -879,11 +906,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);
@@ -976,6 +1006,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) {