Merge "Move canned_fs_config into libcutils" into nyc-dev
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index e92cca5..bc072bc 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -101,6 +101,7 @@
     char tmpmnt_opts[64] = "errors=remount-ro";
     char *e2fsck_argv[] = {
         E2FSCK_BIN,
+        "-f",
         "-y",
         blk_device
     };
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index ae84d1e..a8646c5 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -73,6 +73,7 @@
     props->batteryCurrent = 0;
     props->batteryCycleCount = 0;
     props->batteryFullCharge = 0;
+    props->batteryChargeCounter = 0;
     props->batteryTechnology.clear();
 }
 
@@ -230,6 +231,9 @@
     if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
         props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
 
+    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
+        props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);
+
     props.batteryTemperature = mBatteryFixedTemperature ?
         mBatteryFixedTemperature :
         getIntField(mHealthdConfig->batteryTemperaturePath);
diff --git a/include/system/graphics.h b/include/system/graphics.h
index eabe18e..a9e451f 100644
--- a/include/system/graphics.h
+++ b/include/system/graphics.h
@@ -1066,6 +1066,20 @@
     HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA = 6
 } android_color_transform_t;
 
+/*
+ * Supported HDR formats. Must be kept in sync with equivalents in Display.java.
+ */
+typedef enum android_hdr {
+    /* Device supports Dolby Vision HDR */
+    HAL_HDR_DOLBY_VISION = 1,
+
+    /* Device supports HDR10 */
+    HAL_HDR_HDR10 = 2,
+
+    /* Device supports hybrid log-gamma HDR */
+    HAL_HDR_HLG = 3
+} android_hdr_t;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h
index f027c79..9b0b734 100644
--- a/include/utils/Mutex.h
+++ b/include/utils/Mutex.h
@@ -35,6 +35,10 @@
 class Condition;
 
 /*
+ * NOTE: This class is for code that builds on Win32.  Its usage is
+ * deprecated for code which doesn't build for Win32.  New code which
+ * doesn't build for Win32 should use std::mutex and std::lock_guard instead.
+ *
  * Simple mutex class.  The implementation is system-dependent.
  *
  * The mutex must be unlocked by the thread that locked it.  They are not
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 2e72832..1fddc63 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>
@@ -39,6 +41,7 @@
 #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>
@@ -103,6 +106,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;
@@ -127,6 +156,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));
@@ -147,6 +188,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/logcat/logcat.cpp b/logcat/logcat.cpp
index 15fc035..37f4f4f 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -451,10 +451,6 @@
         return retval;
     }
 
-    clockid_t clock_type = android_log_clockid();
-    log_time now(clock_type);
-    bool monotonic = clock_type == CLOCK_MONOTONIC;
-
     std::string directory;
     char *file = strrchr(outputFileName, '/');
     if (!file) {
@@ -466,10 +462,21 @@
         *file = '/';
         ++file;
     }
+
+    std::unique_ptr<DIR, int(*)(DIR*)>
+            dir(opendir(directory.c_str()), closedir);
+    if (!dir.get()) {
+        return retval;
+    }
+
+    clockid_t clock_type = android_log_clockid();
+    log_time now(clock_type);
+    bool monotonic = clock_type == CLOCK_MONOTONIC;
+
     size_t len = strlen(file);
     log_time modulo(0, NS_PER_SEC);
-    std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(directory.c_str()), closedir);
     struct dirent *dp;
+
     while ((dp = readdir(dir.get())) != NULL) {
         if ((dp->d_type != DT_REG)
                 // If we are using realtime, check all files that match the
@@ -578,11 +585,13 @@
           { "dividers",      no_argument,       NULL,   'D' },
           { "file",          required_argument, NULL,   'f' },
           { "format",        required_argument, NULL,   'v' },
+          // hidden and undocumented reserved alias for --regex
+          { "grep",          required_argument, NULL,   'e' },
           // hidden and undocumented reserved alias for --max-count
           { "head",          required_argument, NULL,   'm' },
           { "last",          no_argument,       NULL,   'L' },
-          { pid_str,         required_argument, NULL,   0 },
           { "max-count",     required_argument, NULL,   'm' },
+          { pid_str,         required_argument, NULL,   0 },
           { print_str,       no_argument,       NULL,   0 },
           { "prune",         optional_argument, NULL,   'p' },
           { "regex",         required_argument, NULL,   'e' },
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 2877209..921a461 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 
 #include <gtest/gtest.h>
 #include <log/log.h>
@@ -781,8 +782,15 @@
     EXPECT_FALSE(system(command));
 }
 
-static void caught_blocking_clear(int /*signum*/)
-{
+TEST(logcat, logrotate_nodir) {
+    // expect logcat to error out on writing content and exit(1) for nodir
+    EXPECT_EQ(W_EXITCODE(1, 0),
+              system("logcat -b all -d"
+                     " -f /das/nein/gerfingerpoken/logcat/log.txt"
+                     " -n 256 -r 1024"));
+}
+
+static void caught_blocking_clear(int /*signum*/) {
     unsigned long long v = 0xDEADBEEFA55C0000ULL;
 
     v += getpid() & 0xFFFF;
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index d8fda67..befe38c 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -43,6 +43,7 @@
 #include <cutils/hashmap.h>
 #include <cutils/log.h>
 #include <cutils/multiuser.h>
+#include <cutils/properties.h>
 #include <packagelistparser/packagelistparser.h>
 
 #include <private/android_filesystem_config.h>
@@ -89,6 +90,9 @@
 
 #define ERROR(x...) ALOGE(x)
 
+#define PROP_SDCARDFS_DEVICE "ro.sys.sdcardfs"
+#define PROP_SDCARDFS_USER "persist.sys.sdcardfs"
+
 #define FUSE_UNKNOWN_INO 0xffffffff
 
 /* Maximum number of bytes to write in one request. */
@@ -1993,6 +1997,29 @@
     return false;
 }
 
+static bool should_use_sdcardfs(void) {
+    char property[PROPERTY_VALUE_MAX];
+
+    // Allow user to have a strong opinion about state
+    property_get(PROP_SDCARDFS_USER, property, "");
+    if (!strcmp(property, "force_on")) {
+        ALOGW("User explicitly enabled sdcardfs");
+        return supports_sdcardfs();
+    } else if (!strcmp(property, "force_off")) {
+        ALOGW("User explicitly disabled sdcardfs");
+        return false;
+    }
+
+    // Fall back to device opinion about state
+    if (property_get_bool(PROP_SDCARDFS_DEVICE, false)) {
+        ALOGW("Device explicitly enabled sdcardfs");
+        return supports_sdcardfs();
+    } else {
+        ALOGW("Device explicitly disabled sdcardfs");
+        return false;
+    }
+}
+
 int main(int argc, char **argv) {
     const char *source_path = NULL;
     const char *label = NULL;
@@ -2065,7 +2092,7 @@
         sleep(1);
     }
 
-    if (supports_sdcardfs()) {
+    if (should_use_sdcardfs()) {
         run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write);
     } else {
         run(source_path, label, uid, gid, userid, multi_user, full_write);