Merge "Revert "adb: remove win32 dependency on libwinpthread-1.dll.""
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index f9e028b..76b156d 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -108,11 +108,10 @@
         return;
     }
 
-    std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
-
-    fstab = fs_mgr_read_fstab(fstab_filename.c_str());
+    // read all fstab entries at once from all sources
+    fstab = fs_mgr_read_fstab_default();
     if (!fstab) {
-        WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename.c_str());
+        WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
         return;
     }
 
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h
index 50677a3..e78edbb 100644
--- a/base/include/android-base/logging.h
+++ b/base/include/android-base/logging.h
@@ -17,6 +17,37 @@
 #ifndef ANDROID_BASE_LOGGING_H
 #define ANDROID_BASE_LOGGING_H
 
+//
+// Google-style C++ logging.
+//
+
+// This header provides a C++ stream interface to logging.
+//
+// To log:
+//
+//   LOG(INFO) << "Some text; " << some_value;
+//
+// Replace `INFO` with any severity from `enum LogSeverity`.
+//
+// To log the result of a failed function and include the string
+// representation of `errno` at the end:
+//
+//   PLOG(ERROR) << "Write failed";
+//
+// The output will be something like `Write failed: I/O error`.
+// Remember this as 'P' as in perror(3).
+//
+// To output your own types, simply implement operator<< as normal.
+//
+// By default, output goes to logcat on Android and stderr on the host.
+// A process can use `SetLogger` to decide where all logging goes.
+// Implementations are provided for logcat, stderr, and dmesg.
+
+// This header also provides assertions:
+//
+//   CHECK(must_be_true);
+//   CHECK_EQ(a, b) << z_is_interesting_too;
+
 // NOTE: For Windows, you must include logging.h after windows.h to allow the
 // following code to suppress the evil ERROR macro:
 #ifdef _WIN32
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index ae442cf..9decb27 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -49,8 +49,7 @@
     }
 
     // lastly, check the device tree
-    static const std::string android_dt_dir("/proc/device-tree/firmware/android");
-    std::string file_name = android_dt_dir + "/compatible";
+    std::string file_name = kAndroidDtDir + "/compatible";
     std::string dt_value;
     if (android::base::ReadFileToString(file_name, &dt_value)) {
         if (dt_value != "android,firmware") {
@@ -58,7 +57,7 @@
             return false;
         }
 
-        file_name = android_dt_dir + "/" + key;
+        file_name = kAndroidDtDir + "/" + key;
         // DT entries terminate with '\0' but so do the properties
         if (android::base::ReadFileToString(file_name, out_val)) {
             return true;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 10e70d6..f989787 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <ctype.h>
+#include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -22,6 +23,10 @@
 #include <sys/mount.h>
 #include <unistd.h>
 
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
 #include "fs_mgr_priv.h"
 
 struct fs_mgr_flag_values {
@@ -290,6 +295,110 @@
     return f;
 }
 
+static bool is_dt_compatible() {
+    std::string file_name = kAndroidDtDir + "/compatible";
+    std::string dt_value;
+    if (android::base::ReadFileToString(file_name, &dt_value)) {
+        // trim the trailing '\0' out, otherwise the comparison
+        // will produce false-negatives.
+        dt_value.resize(dt_value.size() - 1);
+        if (dt_value == "android,firmware") {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static bool is_dt_fstab_compatible() {
+    std::string dt_value;
+    std::string file_name = kAndroidDtDir + "/fstab/compatible";
+
+    if (android::base::ReadFileToString(file_name, &dt_value)) {
+        // trim the trailing '\0' out, otherwise the comparison
+        // will produce false-negatives.
+        dt_value.resize(dt_value.size() - 1);
+        if (dt_value == "android,fstab") {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static std::string read_fstab_from_dt() {
+    std::string fstab;
+    if (!is_dt_compatible() || !is_dt_fstab_compatible()) {
+        return fstab;
+    }
+
+    std::string fstabdir_name = kAndroidDtDir + "/fstab";
+    std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
+    if (!fstabdir) return fstab;
+
+    dirent* dp;
+    while ((dp = readdir(fstabdir.get())) != NULL) {
+        // skip over name and compatible
+        if (dp->d_type != DT_DIR) {
+            continue;
+        }
+
+        // skip if its not 'vendor', 'odm' or 'system'
+        if (strcmp(dp->d_name, "odm") && strcmp(dp->d_name, "system") &&
+            strcmp(dp->d_name, "vendor")) {
+            continue;
+        }
+
+        // create <dev> <mnt_point>  <type>  <mnt_flags>  <fsmgr_flags>\n
+        std::vector<std::string> fstab_entry;
+        std::string file_name;
+        std::string value;
+        file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
+        if (!android::base::ReadFileToString(file_name, &value)) {
+            LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
+            fstab.clear();
+            break;
+        }
+        // trim the terminating '\0' out
+        value.resize(value.size() - 1);
+        fstab_entry.push_back(value);
+        fstab_entry.push_back(android::base::StringPrintf("/%s", dp->d_name));
+
+        file_name = android::base::StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);
+        if (!android::base::ReadFileToString(file_name, &value)) {
+            LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
+            fstab.clear();
+            break;
+        }
+        value.resize(value.size() - 1);
+        fstab_entry.push_back(value);
+
+        file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
+        if (!android::base::ReadFileToString(file_name, &value)) {
+            LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
+            fstab.clear();
+            break;
+        }
+        value.resize(value.size() - 1);
+        fstab_entry.push_back(value);
+
+        file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
+        if (!android::base::ReadFileToString(file_name, &value)) {
+            LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
+            fstab.clear();
+            break;
+        }
+        value.resize(value.size() - 1);
+        fstab_entry.push_back(value);
+
+        fstab += android::base::Join(fstab_entry, " ");
+        fstab += '\n';
+    }
+
+    return fstab;
+}
+
+
 struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
 {
     int cnt, entries;
@@ -444,6 +553,84 @@
     return fstab;
 }
 
+/* Returns fstab entries parsed from the device tree if they
+ * exist
+ */
+struct fstab *fs_mgr_read_fstab_dt()
+{
+    std::string fstab_buf = read_fstab_from_dt();
+    if (fstab_buf.empty()) {
+        return NULL;
+    }
+
+    std::unique_ptr<FILE, decltype(&fclose)> fstab_file(
+        fmemopen(static_cast<void*>(const_cast<char*>(fstab_buf.c_str())),
+                 fstab_buf.length(), "r"), fclose);
+    if (!fstab_file) {
+        return NULL;
+    }
+
+    struct fstab *fstab = fs_mgr_read_fstab_file(fstab_file.get());
+    if (!fstab) {
+        LERROR << "failed to load fstab from kernel:" << std::endl << fstab_buf;
+    }
+
+    return fstab;
+}
+
+/* combines fstab entries passed in from device tree with
+ * the ones found in /fstab.<hardware>
+ */
+struct fstab *fs_mgr_read_fstab_default()
+{
+    struct fstab *fstab = fs_mgr_read_fstab_dt();
+    std::string hw;
+    if (!fs_mgr_get_boot_config("hardware", &hw)) {
+        // if we fail to find this, return whatever was found in device tree
+        LWARNING << "failed to find device hardware name";
+        return fstab;
+    }
+
+    std::string default_fstab = FSTAB_PREFIX + hw;
+    struct fstab *f = fs_mgr_read_fstab(default_fstab.c_str());
+    if (!f) {
+        // return what we have
+        LWARNING << "failed to read fstab entries from '" << default_fstab << "'";
+        return fstab;
+    }
+
+    // return the fstab read from file if device tree doesn't
+    // have one, other wise merge the two
+    if (!fstab) {
+        fstab = f;
+    } else {
+        int total_entries = fstab->num_entries + f->num_entries;
+        fstab->recs = static_cast<struct fstab_rec *>(realloc(
+                        fstab->recs, total_entries * (sizeof(struct fstab_rec))));
+        if (!fstab->recs) {
+            LERROR << "failed to allocate fstab recs";
+            fstab->num_entries = 0;
+            fs_mgr_free_fstab(fstab);
+            return NULL;
+        }
+
+        for (int i = fstab->num_entries, j = 0; i < total_entries; i++, j++) {
+            // copy everything and *not* strdup
+            fstab->recs[i] = f->recs[j];
+        }
+
+        // free up fstab entries read from file, but don't cleanup
+        // the strings within f->recs[X] to make sure they are accessible
+        // through fstab->recs[X].
+        free(f->fstab_filename);
+        free(f);
+
+        fstab->num_entries = total_entries;
+    }
+
+    return fstab;
+}
+
 void fs_mgr_free_fstab(struct fstab *fstab)
 {
     int i;
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 478c145..95295d8 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -41,6 +41,8 @@
 #define PWARNING PLOG(WARNING) << FS_MGR_TAG
 #define PERROR   PLOG(ERROR) << FS_MGR_TAG
 
+const std::string FSTAB_PREFIX("/fstab.");
+
 __BEGIN_DECLS
 
 #define CRYPTO_TMPFS_OPTIONS "size=256m,mode=0771,uid=1000,gid=1000"
diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/fs_mgr_priv_boot_config.h
index 74bb5eb..8773d33 100644
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/fs_mgr_priv_boot_config.h
@@ -20,6 +20,8 @@
 #include <sys/cdefs.h>
 #include <string>
 
+const std::string kAndroidDtDir("/proc/device-tree/firmware/android");
+
 bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);
 
 #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 2c9b0a9..5b81a54 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -46,8 +46,6 @@
 #include "fs_mgr_priv.h"
 #include "fs_mgr_priv_dm_ioctl.h"
 
-#define FSTAB_PREFIX "/fstab."
-
 #define VERITY_TABLE_RSA_KEY "/verity_key"
 #define VERITY_TABLE_HASH_IDX 8
 #define VERITY_TABLE_SALT_IDX 9
@@ -694,8 +692,6 @@
 
 int fs_mgr_load_verity_state(int *mode)
 {
-    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-    char propbuf[PROPERTY_VALUE_MAX];
     int rc = -1;
     int i;
     int current;
@@ -705,13 +701,9 @@
      * logging mode, in which case return that */
     *mode = VERITY_MODE_DEFAULT;
 
-    property_get("ro.hardware", propbuf, "");
-    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
-    fstab = fs_mgr_read_fstab(fstab_filename);
-
+    fstab = fs_mgr_read_fstab_default();
     if (!fstab) {
-        LERROR << "Failed to read " << fstab_filename;
+        LERROR << "Failed to read default fstab";
         goto out;
     }
 
@@ -745,7 +737,6 @@
 {
     alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
     bool system_root = false;
-    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
     std::string mount_point;
     char propbuf[PROPERTY_VALUE_MAX];
     const char *status;
@@ -765,22 +756,16 @@
     }
 
     fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
-
     if (fd == -1) {
         PERROR << "Error opening device mapper";
         goto out;
     }
 
-    property_get("ro.hardware", propbuf, "");
-    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
     property_get("ro.build.system_root_image", propbuf, "");
     system_root = !strcmp(propbuf, "true");
-
-    fstab = fs_mgr_read_fstab(fstab_filename);
-
+    fstab = fs_mgr_read_fstab_default();
     if (!fstab) {
-        LERROR << "Failed to read " << fstab_filename;
+        LERROR << "Failed to read default fstab";
         goto out;
     }
 
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 0402b55..52f27ab 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -85,6 +85,8 @@
 typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab,
         const char *mount_point, int mode, int status);
 
+struct fstab *fs_mgr_read_fstab_default();
+struct fstab *fs_mgr_read_fstab_dt();
 struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file);
 struct fstab *fs_mgr_read_fstab(const char *fstab_path);
 void fs_mgr_free_fstab(struct fstab *fstab);
diff --git a/init/devices.cpp b/init/devices.cpp
index 5f54ff8..bd11f5f 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -251,7 +251,10 @@
      * some device nodes, so the uid has to be set with chown() and is still
      * racy. Fixing the gid race at least fixed the issue with system_server
      * opening dynamic input devices under the AID_INPUT gid. */
-    setegid(gid);
+    if (setegid(gid)) {
+        PLOG(ERROR) << "setegid(" << gid << ") for " << path << " device failed";
+        goto out;
+    }
     /* If the node already exists update its SELinux label to handle cases when
      * it was created with the wrong context during coldboot procedure. */
     if (mknod(path, mode, dev) && (errno == EEXIST) && secontext) {
@@ -273,7 +276,9 @@
 
 out:
     chown(path, uid, -1);
-    setegid(AID_ROOT);
+    if (setegid(AID_ROOT)) {
+        PLOG(FATAL) << "setegid(AID_ROOT) failed";
+    }
 
     if (secontext) {
         freecon(secontext);
diff --git a/init/init.cpp b/init/init.cpp
index 05f2cfd..3cb1276 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -502,26 +502,30 @@
     std::string dt_value;
     std::string file_name = StringPrintf("%s/compatible", android_dt_dir);
 
-    android::base::ReadFileToString(file_name, &dt_value);
-    if (!dt_value.compare("android,firmware")) {
-        LOG(ERROR) << "firmware/android is not compatible with 'android,firmware'";
-        return false;
+    if (android::base::ReadFileToString(file_name, &dt_value)) {
+        // trim the trailing '\0' out, otherwise the comparison
+        // will produce false-negatives.
+        dt_value.resize(dt_value.size() - 1);
+        if (dt_value == "android,firmware") {
+            return true;
+        }
     }
 
-    return true;
+    return false;
 }
 
 static bool is_dt_fstab_compatible() {
     std::string dt_value;
     std::string file_name = StringPrintf("%s/%s/compatible", android_dt_dir, "fstab");
 
-    android::base::ReadFileToString(file_name, &dt_value);
-    if (!dt_value.compare("android,fstab")) {
-        LOG(ERROR) << "firmware/android/fstab is not compatible with 'android,fstab'";
-        return false;
+    if (android::base::ReadFileToString(file_name, &dt_value)) {
+        dt_value.resize(dt_value.size() - 1);
+        if (dt_value == "android,fstab") {
+            return true;
+        }
     }
 
-    return true;
+    return false;
 }
 
 static void process_kernel_dt() {
@@ -664,78 +668,6 @@
     }
 }
 
-static std::string import_dt_fstab() {
-    std::string fstab;
-    if (!is_dt_compatible() || !is_dt_fstab_compatible()) {
-        return fstab;
-    }
-
-    std::string fstabdir_name = StringPrintf("%s/fstab", android_dt_dir);
-    std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
-    if (!fstabdir) return fstab;
-
-    dirent* dp;
-    while ((dp = readdir(fstabdir.get())) != NULL) {
-        // skip over name and compatible
-        if (dp->d_type != DT_DIR) {
-            continue;
-        }
-
-        // skip if its not 'vendor', 'odm' or 'system'
-        if (strcmp(dp->d_name, "odm") && strcmp(dp->d_name, "system") &&
-            strcmp(dp->d_name, "vendor")) {
-            continue;
-        }
-
-        // create <dev> <mnt_point>  <type>  <mnt_flags>  <fsmgr_flags>\n
-        std::vector<std::string> fstab_entry;
-        std::string file_name;
-        std::string value;
-        file_name = StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
-        if (!android::base::ReadFileToString(file_name, &value)) {
-            LOG(ERROR) << "dt_fstab: Failed to find device for partition " << dp->d_name;
-            fstab.clear();
-            break;
-        }
-        // trim the terminating '\0' out
-        value.resize(value.size() - 1);
-        fstab_entry.push_back(value);
-        fstab_entry.push_back(StringPrintf("/%s", dp->d_name));
-
-        file_name = StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);
-        if (!android::base::ReadFileToString(file_name, &value)) {
-            LOG(ERROR) << "dt_fstab: Failed to find type for partition " << dp->d_name;
-            fstab.clear();
-            break;
-        }
-        value.resize(value.size() - 1);
-        fstab_entry.push_back(value);
-
-        file_name = StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
-        if (!android::base::ReadFileToString(file_name, &value)) {
-            LOG(ERROR) << "dt_fstab: Failed to find type for partition " << dp->d_name;
-            fstab.clear();
-            break;
-        }
-        value.resize(value.size() - 1);
-        fstab_entry.push_back(value);
-
-        file_name = StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
-        if (!android::base::ReadFileToString(file_name, &value)) {
-            LOG(ERROR) << "dt_fstab: Failed to find type for partition " << dp->d_name;
-            fstab.clear();
-            break;
-        }
-        value.resize(value.size() - 1);
-        fstab_entry.push_back(value);
-
-        fstab += android::base::Join(fstab_entry, " ");
-        fstab += '\n';
-    }
-
-    return fstab;
-}
-
 static bool early_mount_one(struct fstab_rec* rec) {
     if (rec && fs_mgr_is_verified(rec)) {
         // setup verity and create the dm-XX block device
@@ -770,23 +702,16 @@
 
 /* Early mount vendor and ODM partitions. The fstab is read from device-tree. */
 static bool early_mount() {
-    std::string fstab = import_dt_fstab();
-    if (fstab.empty()) {
-        LOG(INFO) << "Early mount skipped (missing fstab in device tree)";
+    // first check if device tree fstab entries are compatible
+    if (!is_dt_fstab_compatible()) {
+        LOG(INFO) << "Early mount skipped (missing/incompatible fstab in device tree)";
         return true;
     }
 
-    std::unique_ptr<FILE, decltype(&fclose)> fstab_file(
-        fmemopen(static_cast<void*>(const_cast<char*>(fstab.c_str())), fstab.length(), "r"), fclose);
-    if (!fstab_file) {
-        PLOG(ERROR) << "Early mount failed to open fstab file in memory";
-        return false;
-    }
-
-    std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> tab(
-        fs_mgr_read_fstab_file(fstab_file.get()), fs_mgr_free_fstab);
+    std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> tab(
+        fs_mgr_read_fstab_dt(), fs_mgr_free_fstab);
     if (!tab) {
-        LOG(ERROR) << "Early mount fsmgr failed to load fstab from kernel:" << std::endl << fstab;
+        LOG(ERROR) << "Early mount failed to read fstab from device tree";
         return false;
     }
 
diff --git a/libutils/include/utils/Condition.h b/libutils/include/utils/Condition.h
index 25a53aa..2c80acd 100644
--- a/libutils/include/utils/Condition.h
+++ b/libutils/include/utils/Condition.h
@@ -86,19 +86,22 @@
 
 #if !defined(_WIN32)
 
-inline Condition::Condition() {
-    pthread_cond_init(&mCond, NULL);
+inline Condition::Condition() : Condition(PRIVATE) {
 }
 inline Condition::Condition(int type) {
+    pthread_condattr_t attr;
+    pthread_condattr_init(&attr);
+#if defined(__linux__)
+    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+#endif
+
     if (type == SHARED) {
-        pthread_condattr_t attr;
-        pthread_condattr_init(&attr);
         pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
-        pthread_cond_init(&mCond, &attr);
-        pthread_condattr_destroy(&attr);
-    } else {
-        pthread_cond_init(&mCond, NULL);
     }
+
+    pthread_cond_init(&mCond, &attr);
+    pthread_condattr_destroy(&attr);
+
 }
 inline Condition::~Condition() {
     pthread_cond_destroy(&mCond);
@@ -109,7 +112,7 @@
 inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
     struct timespec ts;
 #if defined(__linux__)
-    clock_gettime(CLOCK_REALTIME, &ts);
+    clock_gettime(CLOCK_MONOTONIC, &ts);
 #else // __APPLE__
     // Apple doesn't support POSIX clocks.
     struct timeval t;
diff --git a/libutils/include/utils/Singleton.h b/libutils/include/utils/Singleton.h
index 7cc4c18..a989a47 100644
--- a/libutils/include/utils/Singleton.h
+++ b/libutils/include/utils/Singleton.h
@@ -26,6 +26,16 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
+// Singleton<TYPE> may be used in multiple libraries, only one of which should
+// define the static member variables using ANDROID_SINGLETON_STATIC_INSTANCE.
+// Turn off -Wundefined-var-template so other users don't get:
+// instantiation of variable 'android::Singleton<TYPE>::sLock' required here,
+// but no definition is available
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundefined-var-template"
+#endif
+
 template <typename TYPE>
 class ANDROID_API Singleton
 {
@@ -56,11 +66,9 @@
     static TYPE* sInstance;
 };
 
-template <typename TYPE>
-Mutex Singleton<TYPE>::sLock;
-
-template <typename TYPE>
-TYPE* Singleton<TYPE>::sInstance;
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
 
 /*
  * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file
diff --git a/libutils/tests/StrongPointer_test.cpp b/libutils/tests/StrongPointer_test.cpp
index 323a6f2..153cf96 100644
--- a/libutils/tests/StrongPointer_test.cpp
+++ b/libutils/tests/StrongPointer_test.cpp
@@ -21,13 +21,13 @@
 
 using namespace android;
 
-class Foo : public LightRefBase<Foo> {
+class SPFoo : public LightRefBase<SPFoo> {
 public:
-    explicit Foo(bool* deleted_check) : mDeleted(deleted_check) {
+    explicit SPFoo(bool* deleted_check) : mDeleted(deleted_check) {
         *mDeleted = false;
     }
 
-    ~Foo() {
+    ~SPFoo() {
         *mDeleted = true;
     }
 private:
@@ -36,13 +36,13 @@
 
 TEST(StrongPointer, move) {
     bool isDeleted;
-    Foo* foo = new Foo(&isDeleted);
+    SPFoo* foo = new SPFoo(&isDeleted);
     ASSERT_EQ(0, foo->getStrongCount());
     ASSERT_FALSE(isDeleted) << "Already deleted...?";
-    sp<Foo> sp1(foo);
+    sp<SPFoo> sp1(foo);
     ASSERT_EQ(1, foo->getStrongCount());
     {
-        sp<Foo> sp2 = std::move(sp1);
+        sp<SPFoo> sp2 = std::move(sp1);
         ASSERT_EQ(1, foo->getStrongCount()) << "std::move failed, incremented refcnt";
         ASSERT_EQ(nullptr, sp1.get()) << "std::move failed, sp1 is still valid";
         // The strong count isn't increasing, let's double check the old object
@@ -52,7 +52,7 @@
     ASSERT_FALSE(isDeleted) << "deleted too early! still has a reference!";
     {
         // Now let's double check it deletes on time
-        sp<Foo> sp2 = std::move(sp1);
+        sp<SPFoo> sp2 = std::move(sp1);
     }
     ASSERT_TRUE(isDeleted) << "foo was leaked!";
 }