Merge "Remove debugging code for a fixed 3.6 kernel bug."
diff --git a/include/utils/Condition.h b/include/utils/Condition.h
index 5a72519..a420185 100644
--- a/include/utils/Condition.h
+++ b/include/utils/Condition.h
@@ -106,30 +106,40 @@
     return -pthread_cond_wait(&mCond, &mutex.mMutex);
 }
 inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
-#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
-    struct timespec ts;
-    ts.tv_sec  = reltime/1000000000;
-    ts.tv_nsec = reltime%1000000000;
-    return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
-#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
     struct timespec ts;
 #if defined(__linux__)
     clock_gettime(CLOCK_REALTIME, &ts);
 #else // __APPLE__
-    // we don't support the clocks here.
+    // Apple doesn't support POSIX clocks.
     struct timeval t;
     gettimeofday(&t, NULL);
     ts.tv_sec = t.tv_sec;
-    ts.tv_nsec= t.tv_usec*1000;
+    ts.tv_nsec = t.tv_usec*1000;
 #endif
-    ts.tv_sec += reltime/1000000000;
-    ts.tv_nsec+= reltime%1000000000;
-    if (ts.tv_nsec >= 1000000000) {
+
+    // On 32-bit devices, tv_sec is 32-bit, but `reltime` is 64-bit.
+    int64_t reltime_sec = reltime/1000000000;
+
+    ts.tv_nsec += reltime%1000000000;
+    if (reltime_sec < INT64_MAX && ts.tv_nsec >= 1000000000) {
         ts.tv_nsec -= 1000000000;
-        ts.tv_sec  += 1;
+        ++reltime_sec;
     }
+
+    int64_t time_sec = ts.tv_sec;
+    if (time_sec > INT64_MAX - reltime_sec) {
+        time_sec = INT64_MAX;
+    } else {
+        time_sec += reltime_sec;
+    }
+
+#if defined(__LP64__)
+    ts.tv_sec = time_sec;
+#else
+    ts.tv_sec = (time_sec > INT32_MAX) ? INT32_MAX : time_sec;
+#endif
+
     return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
-#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
 }
 inline void Condition::signal() {
     /*
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 6469ec4..89f6c68 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -16,11 +16,13 @@
 
 #include "builtins.h"
 
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <mntent.h>
 #include <net/if.h>
 #include <signal.h>
+#include <sched.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -40,12 +42,12 @@
 #include <selinux/label.h>
 
 #include <fs_mgr.h>
+#include <android-base/file.h>
 #include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
 #include <cutils/partition_utils.h>
 #include <cutils/android_reboot.h>
 #include <logwrap/logwrap.h>
-#include <private/android_filesystem_config.h>
 
 #include "action.h"
 #include "bootchart.h"
@@ -105,6 +107,32 @@
     return ret;
 }
 
+// Turn off backlight while we are performing power down cleanup activities.
+static void turnOffBacklight() {
+    static const char off[] = "0";
+
+    android::base::WriteStringToFile(off, "/sys/class/leds/lcd-backlight/brightness");
+
+    static const char backlightDir[] = "/sys/class/backlight";
+    std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(backlightDir), closedir);
+    if (!dir) {
+        return;
+    }
+
+    struct dirent *dp;
+    while ((dp = readdir(dir.get())) != NULL) {
+        if (((dp->d_type != DT_DIR) && (dp->d_type != DT_LNK)) ||
+                (dp->d_name[0] == '.')) {
+            continue;
+        }
+
+        std::string fileName = android::base::StringPrintf("%s/%s/brightness",
+                                                           backlightDir,
+                                                           dp->d_name);
+        android::base::WriteStringToFile(off, fileName);
+    }
+}
+
 static void unmount_and_fsck(const struct mntent *entry) {
     if (strcmp(entry->mnt_type, "f2fs") && strcmp(entry->mnt_type, "ext4"))
         return;
@@ -129,6 +157,18 @@
     ServiceManager::GetInstance().ForEachService([] (Service* s) { s->Stop(); });
     TEMP_FAILURE_RETRY(kill(-1, SIGKILL));
 
+    // Restart Watchdogd to allow us to complete umounting and fsck
+    Service *svc = ServiceManager::GetInstance().FindServiceByName("watchdogd");
+    if (svc) {
+        do {
+            sched_yield(); // do not be so eager, let cleanup have priority
+            ServiceManager::GetInstance().ReapAnyOutstandingChildren();
+        } while (svc->flags() & SVC_RUNNING); // Paranoid Cargo
+        svc->Start();
+    }
+
+    turnOffBacklight();
+
     int count = 0;
     while (count++ < UNMOUNT_CHECK_TIMES) {
         int fd = TEMP_FAILURE_RETRY(open(entry->mnt_fsname, O_RDONLY | O_EXCL));
@@ -149,6 +189,11 @@
         }
     }
 
+    // NB: With watchdog still running, there is no cap on the time it takes
+    // to complete the fsck, from the users perspective the device graphics
+    // and responses are locked-up and they may choose to hold the power
+    // button in frustration if it drags out.
+
     int st;
     if (!strcmp(entry->mnt_type, "f2fs")) {
         const char *f2fs_argv[] = {
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 8c95f15..c617dc6 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -41,7 +41,6 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <sys/mman.h>
-#include <private/android_filesystem_config.h>
 
 #include <selinux/selinux.h>
 #include <selinux/label.h>
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 249739b..73b2136 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -16,14 +16,17 @@
 
 #include <ctype.h>
 #include <fcntl.h>
+#include <grp.h>
 #include <poll.h>
+#include <pwd.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include <sys/types.h>
+
 #include <android-base/stringprintf.h>
-#include <private/android_filesystem_config.h>
 #include <selinux/selinux.h>
 
 #include "ueventd.h"
@@ -84,15 +87,6 @@
     return 0;
 }
 
-static int get_android_id(const char *id)
-{
-    unsigned int i;
-    for (i = 0; i < ARRAY_SIZE(android_ids); i++)
-        if (!strcmp(id, android_ids[i].name))
-            return android_ids[i].aid;
-    return -1;
-}
-
 void set_device_permission(int nargs, char **args)
 {
     char *name;
@@ -103,7 +97,6 @@
     int prefix = 0;
     int wildcard = 0;
     char *endptr;
-    int ret;
     char *tmp = 0;
 
     if (nargs == 0)
@@ -151,21 +144,21 @@
         return;
     }
 
-    ret = get_android_id(args[2]);
-    if (ret < 0) {
+    struct passwd* pwd = getpwnam(args[2]);
+    if (!pwd) {
         ERROR("invalid uid '%s'\n", args[2]);
         free(tmp);
         return;
     }
-    uid = ret;
+    uid = pwd->pw_uid;
 
-    ret = get_android_id(args[3]);
-    if (ret < 0) {
+    struct group* grp = getgrnam(args[3]);
+    if (!grp) {
         ERROR("invalid gid '%s'\n", args[3]);
         free(tmp);
         return;
     }
-    gid = ret;
+    gid = grp->gr_gid;
 
     add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard);
     free(tmp);
diff --git a/init/util.cpp b/init/util.cpp
index 4d36dfd..750e040 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <time.h>
 #include <ftw.h>
+#include <pwd.h>
 
 #include <selinux/label.h>
 #include <selinux/android.h>
@@ -39,38 +40,24 @@
 #include <cutils/sockets.h>
 #include <android-base/stringprintf.h>
 
-#include <private/android_filesystem_config.h>
-
 #include "init.h"
 #include "log.h"
 #include "property_service.h"
 #include "util.h"
 
-/*
- * android_name_to_id - returns the integer uid/gid associated with the given
- * name, or UINT_MAX on error.
- */
-static unsigned int android_name_to_id(const char *name)
-{
-    const struct android_id_info *info = android_ids;
-    unsigned int n;
-
-    for (n = 0; n < android_id_count; n++) {
-        if (!strcmp(info[n].name, name))
-            return info[n].aid;
-    }
-
-    return UINT_MAX;
-}
-
 static unsigned int do_decode_uid(const char *s)
 {
     unsigned int v;
 
     if (!s || *s == '\0')
         return UINT_MAX;
-    if (isalpha(s[0]))
-        return android_name_to_id(s);
+
+    if (isalpha(s[0])) {
+        struct passwd* pwd = getpwnam(s);
+        if (!pwd)
+            return UINT_MAX;
+        return pwd->pw_uid;
+    }
 
     errno = 0;
     v = (unsigned int) strtoul(s, 0, 0);
diff --git a/metricsd/timer_test.cc b/metricsd/timer_test.cc
index 7a67e11..cfbcd8a 100644
--- a/metricsd/timer_test.cc
+++ b/metricsd/timer_test.cc
@@ -69,7 +69,7 @@
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime))
       .WillOnce(Return(etime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -88,7 +88,7 @@
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime))
       .WillOnce(Return(etime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   timer_.Start();
   base::TimeTicks buffer = timer_.start_time_;
   timer_.Start();
@@ -98,7 +98,7 @@
 TEST_F(TimerTest, Reset) {
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   timer_.Start();
   ASSERT_TRUE(timer_.Reset());
   ASSERT_FALSE(timer_.HasStarted());
@@ -110,7 +110,7 @@
       .WillOnce(Return(etime))
       .WillOnce(Return(stime2))
       .WillOnce(Return(etime2));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.Stop());
   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
@@ -130,7 +130,7 @@
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime))
       .WillOnce(Return(etime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_FALSE(timer_.Stop());
   // Now we try it again, but after a valid start/stop.
   timer_.Start();
@@ -152,7 +152,7 @@
       .WillOnce(Return(etime2))
       .WillOnce(Return(stime3))
       .WillOnce(Return(etime3));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Pause());  // Starts timer paused.
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -181,7 +181,7 @@
       .WillOnce(Return(stime2))
       .WillOnce(Return(etime2))
       .WillOnce(Return(stime3));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Resume());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -208,7 +208,7 @@
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime))
       .WillOnce(Return(etime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -230,7 +230,7 @@
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime))
       .WillOnce(Return(etime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -257,7 +257,7 @@
       .WillOnce(Return(etime))
       .WillOnce(Return(stime2))
       .WillOnce(Return(etime2));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -284,7 +284,7 @@
 TEST_F(TimerTest, PauseStop) {
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Pause());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -304,7 +304,7 @@
       .WillOnce(Return(stime))
       .WillOnce(Return(stime2))
       .WillOnce(Return(etime2));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Pause());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -328,7 +328,7 @@
       .WillOnce(Return(stime2))
       .WillOnce(Return(stime3))
       .WillOnce(Return(etime3));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -373,7 +373,7 @@
       .WillOnce(Return(etime2))
       .WillOnce(Return(stime3))
       .WillOnce(Return(etime3));
-  timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   ASSERT_TRUE(timer_.Start());
   ASSERT_TRUE(timer_.start_time_ == stime);
   ASSERT_TRUE(timer_.HasStarted());
@@ -444,7 +444,7 @@
   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
       .WillOnce(Return(stime))
       .WillOnce(Return(etime));
-  timer_reporter_.clock_wrapper_.reset(clock_wrapper_mock_.release());
+  timer_reporter_.clock_wrapper_ = std::move(clock_wrapper_mock_);
   EXPECT_CALL(lib_, SendToUMA(kMetricName, kDelta1MSec, kMinSample, kMaxSample,
                               kNumBuckets)).WillOnce(Return(true));
   ASSERT_TRUE(timer_reporter_.Start());