Merge "Add a dummy entry for the 70220 event tag" into pi-dev
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 0ce3855..5017ebd 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -457,12 +457,6 @@
     }
     if (!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
         if (cmdline) bootimg_set_cmdline(reinterpret_cast<boot_img_hdr_v1*>(kdata), cmdline);
-        uint32_t header_version_existing =
-                reinterpret_cast<boot_img_hdr_v1*>(kdata)->header_version;
-        if (header_version != header_version_existing) {
-            die("header version mismatch, expected: %" PRIu32 " found %" PRIu32 "",
-                header_version, header_version_existing);
-        }
 
         if (!ramdisk.empty()) die("cannot boot a boot.img *and* ramdisk");
 
diff --git a/init/builtins.cpp b/init/builtins.cpp
index fc74dda..8bd92cc 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -82,6 +82,7 @@
 static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
 
 static Result<Success> reboot_into_recovery(const std::vector<std::string>& options) {
+    LOG(ERROR) << "Rebooting into recovery";
     std::string err;
     if (!write_bootloader_message(options, &err)) {
         return Error() << "Failed to set bootloader message: " << err;
@@ -285,11 +286,8 @@
 
     if (e4crypt_is_native()) {
         if (e4crypt_set_directory_policy(args[1].c_str())) {
-            const std::vector<std::string> options = {
-                "--prompt_and_wipe_data",
-                "--reason=set_policy_failed:"s + args[1]};
-            reboot_into_recovery(options);
-            return Success();
+            return reboot_into_recovery(
+                {"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + args[1]});
         }
     }
     return Success();
@@ -493,8 +491,7 @@
         /* Setup a wipe via recovery, and reboot into recovery */
         PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
         const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
-        reboot_into_recovery(options);
-        return Success();
+        return reboot_into_recovery(options);
         /* If reboot worked, there is no return. */
     } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
         if (e4crypt_install_keyring()) {
@@ -522,6 +519,7 @@
         if (e4crypt_install_keyring()) {
             return Error() << "e4crypt_install_keyring() failed";
         }
+        property_set("ro.crypto.state", "encrypted");
         property_set("ro.crypto.type", "file");
 
         // Although encrypted, vold has already set the device up, so we do not need to
@@ -987,6 +985,29 @@
     return android::base::GetProperty("ro.crypto.type", "") == "file";
 }
 
+static Result<Success> ExecWithRebootOnFailure(const std::string& reboot_reason,
+                                               const BuiltinArguments& args) {
+    auto service = Service::MakeTemporaryOneshotService(args.args);
+    if (!service) {
+        return Error() << "Could not create exec service";
+    }
+    service->AddReapCallback([reboot_reason](const siginfo_t& siginfo) {
+        if (siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) {
+            if (e4crypt_is_native()) {
+                LOG(ERROR) << "Rebooting into recovery, reason: " << reboot_reason;
+                reboot_into_recovery({"--prompt_and_wipe_data", "--reason="s + reboot_reason});
+            } else {
+                LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason;
+            }
+        }
+    });
+    if (auto result = service->ExecStart(); !result) {
+        return Error() << "Could not start exec service: " << result.error();
+    }
+    ServiceList::GetInstance().AddService(std::move(service));
+    return Success();
+}
+
 static Result<Success> do_installkey(const BuiltinArguments& args) {
     if (!is_file_crypto()) return Success();
 
@@ -994,15 +1015,15 @@
     if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) {
         return ErrnoError() << "Failed to create " << unencrypted_dir;
     }
-    std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",
-                                          "enablefilecrypto"};
-    return do_exec({std::move(exec_args), args.context});
+    return ExecWithRebootOnFailure(
+        "enablefilecrypto_failed",
+        {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}, args.context});
 }
 
 static Result<Success> do_init_user0(const BuiltinArguments& args) {
-    std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",
-                                          "init_user0"};
-    return do_exec({std::move(exec_args), args.context});
+    return ExecWithRebootOnFailure(
+        "init_user0_failed",
+        {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
 }
 
 // Builtin-function-map start
diff --git a/init/init.cpp b/init/init.cpp
index efb9c1d..4fe115e 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -595,6 +595,14 @@
         mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
         mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
 
+        // Mount staging areas for devices managed by vold
+        // See storage config details at http://source.android.com/devices/storage/
+        mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
+              "mode=0755,uid=0,gid=1000");
+        // /mnt/vendor is used to mount vendor-specific partitions that can not be
+        // part of the vendor partition, e.g. because they are mounted read-write.
+        mkdir("/mnt/vendor", 0755);
+
         // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
         // talk to the outside world...
         InitKernelLogging(argv);
diff --git a/init/service.cpp b/init/service.cpp
index 8130e73..09d8dae 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -303,7 +303,7 @@
     }
 }
 
-void Service::Reap() {
+void Service::Reap(const siginfo_t& siginfo) {
     if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
         KillProcessGroup(SIGKILL);
     }
@@ -312,6 +312,10 @@
     std::for_each(descriptors_.begin(), descriptors_.end(),
                   std::bind(&DescriptorInfo::Clean, std::placeholders::_1));
 
+    for (const auto& f : reap_callbacks_) {
+        f(siginfo);
+    }
+
     if (flags_ & SVC_EXEC) UnSetExec();
 
     if (flags_ & SVC_TEMPORARY) return;
diff --git a/init/service.h b/init/service.h
index d46a413..bcf1943 100644
--- a/init/service.h
+++ b/init/service.h
@@ -17,6 +17,7 @@
 #ifndef _INIT_SERVICE_H
 #define _INIT_SERVICE_H
 
+#include <signal.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 
@@ -81,7 +82,7 @@
     void Stop();
     void Terminate();
     void Restart();
-    void Reap();
+    void Reap(const siginfo_t& siginfo);
     void DumpState() const;
     void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
     bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
@@ -89,6 +90,9 @@
         is_exec_service_running_ = false;
         flags_ &= ~SVC_EXEC;
     }
+    void AddReapCallback(std::function<void(const siginfo_t& siginfo)> callback) {
+        reap_callbacks_.emplace_back(std::move(callback));
+    }
 
     static bool is_exec_service_running() { return is_exec_service_running_; }
 
@@ -210,6 +214,8 @@
     std::vector<std::pair<int, rlimit>> rlimits_;
 
     std::vector<std::string> args_;
+
+    std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
 };
 
 class ServiceList {
diff --git a/init/sigchld_handler.cpp b/init/sigchld_handler.cpp
index 072a0fb..badacaf 100644
--- a/init/sigchld_handler.cpp
+++ b/init/sigchld_handler.cpp
@@ -84,16 +84,15 @@
         }
     }
 
-    auto status = siginfo.si_status;
-    if (WIFEXITED(status)) {
-        LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
-    } else if (WIFSIGNALED(status)) {
-        LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
+    if (siginfo.si_code == CLD_EXITED) {
+        LOG(INFO) << name << " exited with status " << siginfo.si_status << wait_string;
+    } else {
+        LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
     }
 
     if (!service) return true;
 
-    service->Reap();
+    service->Reap(siginfo);
 
     if (service->flags() & SVC_TEMPORARY) {
         ServiceList::GetInstance().RemoveService(*service);
diff --git a/libcutils/include/cutils/sched_policy.h b/libcutils/include/cutils/sched_policy.h
index 4c1113b..cf91b76 100644
--- a/libcutils/include/cutils/sched_policy.h
+++ b/libcutils/include/cutils/sched_policy.h
@@ -40,16 +40,17 @@
 
 /* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */
 typedef enum {
-    SP_DEFAULT    = -1,
+    SP_DEFAULT = -1,
     SP_BACKGROUND = 0,
     SP_FOREGROUND = 1,
-    SP_SYSTEM     = 2,  // can't be used with set_sched_policy()
-    SP_AUDIO_APP  = 3,
-    SP_AUDIO_SYS  = 4,
-    SP_TOP_APP    = 5,
-    SP_RT_APP     = 6,
+    SP_SYSTEM = 2,  // can't be used with set_sched_policy()
+    SP_AUDIO_APP = 3,
+    SP_AUDIO_SYS = 4,
+    SP_TOP_APP = 5,
+    SP_RT_APP = 6,
+    SP_RESTRICTED = 7,
     SP_CNT,
-    SP_MAX        = SP_CNT - 1,
+    SP_MAX = SP_CNT - 1,
     SP_SYSTEM_DEFAULT = SP_FOREGROUND,
 } SchedPolicy;
 
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index f5ce82f..f72ec52 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -57,6 +57,7 @@
 static int bg_cpuset_fd = -1;
 static int fg_cpuset_fd = -1;
 static int ta_cpuset_fd = -1; // special cpuset for top app
+static int rs_cpuset_fd = -1;  // special cpuset for screen off restrictions
 
 // File descriptors open to /dev/stune/../tasks, setup by initialize, or -1 on error
 static int bg_schedboost_fd = -1;
@@ -151,6 +152,8 @@
             system_bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
             filename = "/dev/cpuset/top-app/tasks";
             ta_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
+            filename = "/dev/cpuset/restricted/tasks";
+            rs_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
 
             if (schedboost_enabled()) {
                 filename = "/dev/stune/top-app/tasks";
@@ -308,6 +311,9 @@
     case SP_SYSTEM:
         fd = system_bg_cpuset_fd;
         break;
+    case SP_RESTRICTED:
+        fd = rs_cpuset_fd;
+        break;
     default:
         boost_fd = fd = -1;
         break;
@@ -457,14 +463,10 @@
 const char *get_sched_policy_name(SchedPolicy policy)
 {
     policy = _policy(policy);
-    static const char * const strings[SP_CNT] = {
-       [SP_BACKGROUND] = "bg",
-       [SP_FOREGROUND] = "fg",
-       [SP_SYSTEM]     = "  ",
-       [SP_AUDIO_APP]  = "aa",
-       [SP_AUDIO_SYS]  = "as",
-       [SP_TOP_APP]    = "ta",
-       [SP_RT_APP]    = "rt",
+    static const char* const strings[SP_CNT] = {
+            [SP_BACKGROUND] = "bg", [SP_FOREGROUND] = "fg", [SP_SYSTEM] = "  ",
+            [SP_AUDIO_APP] = "aa",  [SP_AUDIO_SYS] = "as",  [SP_TOP_APP] = "ta",
+            [SP_RT_APP] = "rt",     [SP_RESTRICTED] = "rs",
     };
     if ((policy < SP_CNT) && (strings[policy] != NULL))
         return strings[policy];
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index caca377..f872d0f 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -88,7 +88,6 @@
 cc_test {
     name: "memunreachable_binder_test",
     defaults: ["libmemunreachable_defaults"],
-    test_suites: ["vts"],
     srcs: [
         "tests/Binder_test.cpp",
     ],
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a6ed962..5b06fdb 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -21,9 +21,6 @@
     # Set the security context of /adb_keys if present.
     restorecon /adb_keys
 
-    # Shouldn't be necessary, but sdcard won't start without it. http://b/22568628.
-    mkdir /mnt 0775 root system
-
     # Set the security context of /postinstall if present.
     restorecon /postinstall
 
@@ -80,9 +77,6 @@
     chmod 0664 /dev/stune/top-app/tasks
     chmod 0664 /dev/stune/rt/tasks
 
-    # Mount staging areas for devices managed by vold
-    # See storage config details at http://source.android.com/tech/storage/
-    mount tmpfs tmpfs /mnt nodev noexec nosuid mode=0755,uid=0,gid=1000
     restorecon_recursive /mnt
 
     mount configfs none /config nodev noexec nosuid
@@ -182,6 +176,12 @@
     copy /dev/cpuset/cpus /dev/cpuset/system-background/cpus
     copy /dev/cpuset/mems /dev/cpuset/system-background/mems
 
+    # restricted is for system tasks that are being throttled
+    # due to screen off.
+    mkdir /dev/cpuset/restricted
+    copy /dev/cpuset/cpus /dev/cpuset/restricted/cpus
+    copy /dev/cpuset/mems /dev/cpuset/restricted/mems
+
     mkdir /dev/cpuset/top-app
     copy /dev/cpuset/cpus /dev/cpuset/top-app/cpus
     copy /dev/cpuset/mems /dev/cpuset/top-app/mems
@@ -192,11 +192,13 @@
     chown system system /dev/cpuset/background
     chown system system /dev/cpuset/system-background
     chown system system /dev/cpuset/top-app
+    chown system system /dev/cpuset/restricted
     chown system system /dev/cpuset/tasks
     chown system system /dev/cpuset/foreground/tasks
     chown system system /dev/cpuset/background/tasks
     chown system system /dev/cpuset/system-background/tasks
     chown system system /dev/cpuset/top-app/tasks
+    chown system system /dev/cpuset/restricted/tasks
 
     # set system-background to 0775 so SurfaceFlinger can touch it
     chmod 0775 /dev/cpuset/system-background
@@ -205,6 +207,7 @@
     chmod 0664 /dev/cpuset/background/tasks
     chmod 0664 /dev/cpuset/system-background/tasks
     chmod 0664 /dev/cpuset/top-app/tasks
+    chmod 0664 /dev/cpuset/restricted/tasks
     chmod 0664 /dev/cpuset/tasks