Merge "ld.config.txt: Move vendor vndk to vndk namespace"
diff --git a/init/Android.bp b/init/Android.bp
index 0db7824..6c80ee6 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -58,6 +58,34 @@
             cppflags: ["-DUSER_MODE_LINUX"],
         }
     },
+    static_libs: [
+        "libbootloader_message",
+        "libfs_mgr",
+        "libfec",
+        "libfec_rs",
+        "libhidl-gen-utils",
+        "libsquashfs_utils",
+        "liblogwrap",
+        "libext4_utils",
+        "libcutils",
+        "libbase",
+        "libc",
+        "libseccomp_policy",
+        "libselinux",
+        "liblog",
+        "libcrypto_utils",
+        "libcrypto",
+        "libc++_static",
+        "libdl",
+        "libsparse",
+        "libz",
+        "libprocessgroup",
+        "libavb",
+        "libkeyutils",
+        "libprotobuf-cpp-lite",
+        "libpropertyinfoserializer",
+        "libpropertyinfoparser",
+    ],
 }
 
 cc_library_static {
@@ -65,40 +93,38 @@
     defaults: ["init_defaults"],
     srcs: [
         "action.cpp",
+        "bootchart.cpp",
+        "builtins.cpp",
         "capabilities.cpp",
         "descriptors.cpp",
         "devices.cpp",
         "firmware_handler.cpp",
         "import_parser.cpp",
+        "init.cpp",
+        "init_first_stage.cpp",
+        "keychords.cpp",
         "log.cpp",
         "parser.cpp",
         "persistent_properties.cpp",
         "persistent_properties.proto",
         "property_service.cpp",
         "property_type.cpp",
+        "reboot.cpp",
         "security.cpp",
         "selinux.cpp",
         "service.cpp",
+        "sigchld_handler.cpp",
         "subcontext.cpp",
         "subcontext.proto",
         "rlimit_parser.cpp",
         "tokenizer.cpp",
         "uevent_listener.cpp",
+        "ueventd.cpp",
         "ueventd_parser.cpp",
         "util.cpp",
+        "watchdogd.cpp",
     ],
     whole_static_libs: ["libcap"],
-    static_libs: [
-        "libbase",
-        "libhidl-gen-utils",
-        "libselinux",
-        "liblog",
-        "libprocessgroup",
-        "libfs_mgr",
-        "libprotobuf-cpp-lite",
-        "libpropertyinfoserializer",
-        "libpropertyinfoparser",
-    ],
     include_dirs: [
         "system/core/mkbootimg",
     ],
@@ -125,42 +151,7 @@
         "make_f2fs",
     ],
     static_executable: true,
-    srcs: [
-        "bootchart.cpp",
-        "builtins.cpp",
-        "init.cpp",
-        "init_first_stage.cpp",
-        "keychords.cpp",
-        "reboot.cpp",
-        "sigchld_handler.cpp",
-        "ueventd.cpp",
-        "watchdogd.cpp",
-    ],
-    static_libs: [
-        "libinit",
-        "libbootloader_message",
-        "libfs_mgr",
-        "libfec",
-        "libfec_rs",
-        "libhidl-gen-utils",
-        "libsquashfs_utils",
-        "liblogwrap",
-        "libext4_utils",
-        "libcutils",
-        "libbase",
-        "libc",
-        "libselinux",
-        "liblog",
-        "libcrypto_utils",
-        "libcrypto",
-        "libc++_static",
-        "libdl",
-        "libsparse",
-        "libz",
-        "libprocessgroup",
-        "libavb",
-        "libkeyutils",
-    ],
+    srcs: ["main.cpp"],
     symlinks: [
         "sbin/ueventd",
         "sbin/watchdogd",
@@ -174,6 +165,7 @@
 cc_test {
     name: "init_tests",
     defaults: ["init_defaults"],
+    static_executable: true,
     srcs: [
         "devices_test.cpp",
         "init_test.cpp",
@@ -187,36 +179,17 @@
         "ueventd_test.cpp",
         "util_test.cpp",
     ],
-    shared_libs: [
-        "libbase",
-        "libcutils",
-    ],
-    static_libs: [
-        "libinit",
-        "libhidl-gen-utils",
-        "libselinux",
-        "libcrypto",
-        "libprotobuf-cpp-lite",
-        "libpropertyinfoparser",
-    ],
+    static_libs: ["libinit"],
 }
 
 cc_benchmark {
     name: "init_benchmarks",
+    static_executable: true,
     defaults: ["init_defaults"],
     srcs: [
         "subcontext_benchmark.cpp",
     ],
-    shared_libs: [
-        "libbase",
-        "libcutils",
-    ],
-    static_libs: [
-        "libinit",
-        "libselinux",
-        "libcrypto",
-        "libprotobuf-cpp-lite",
-    ],
+    static_libs: ["libinit"],
 }
 
 subdirs = ["*"]
diff --git a/init/Android.mk b/init/Android.mk
index 5239366..c4a6a50 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -41,16 +41,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_CPPFLAGS := $(init_cflags)
-LOCAL_SRC_FILES:= \
-    bootchart.cpp \
-    builtins.cpp \
-    init.cpp \
-    init_first_stage.cpp \
-    keychords.cpp \
-    reboot.cpp \
-    sigchld_handler.cpp \
-    ueventd.cpp \
-    watchdogd.cpp \
+LOCAL_SRC_FILES := main.cpp
 
 LOCAL_MODULE:= init
 
diff --git a/init/init.cpp b/init/init.cpp
index 571da7c..95f272b 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -746,7 +746,3 @@
 
 }  // namespace init
 }  // namespace android
-
-int main(int argc, char** argv) {
-    android::init::main(argc, argv);
-}
diff --git a/init/init.h b/init/init.h
index b757c1d..ff7bdeb 100644
--- a/init/init.h
+++ b/init/init.h
@@ -47,6 +47,8 @@
 
 void ResetWaitForProp();
 
+int main(int argc, char** argv);
+
 }  // namespace init
 }  // namespace android
 
diff --git a/init/main.cpp b/init/main.cpp
new file mode 100644
index 0000000..9ed451b
--- /dev/null
+++ b/init/main.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "init.h"
+
+int main(int argc, char** argv) {
+    android::init::main(argc, argv);
+}
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 21086dc..a88a42d 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -137,25 +137,12 @@
 
 // Turn off backlight while we are performing power down cleanup activities.
 static void TurnOffBacklight() {
-    static constexpr 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) {
+    Service* service = ServiceList::GetInstance().FindService("blank_screen");
+    if (service == nullptr) {
+        LOG(WARNING) << "cannot find blank_screen in TurnOffBacklight";
         return;
     }
-
-    struct dirent* dp;
-    while ((dp = readdir(dir.get())) != nullptr) {
-        if (((dp->d_type != DT_DIR) && (dp->d_type != DT_LNK)) || (dp->d_name[0] == '.')) {
-            continue;
-        }
-
-        std::string fileName = StringPrintf("%s/%s/brightness", backlightDir, dp->d_name);
-        android::base::WriteStringToFile(OFF, fileName);
-    }
+    service->Start();
 }
 
 static void ShutdownVold() {
@@ -316,8 +303,6 @@
     std::vector<MountEntry> block_devices;
     std::vector<MountEntry> emulated_devices;
 
-    TurnOffBacklight();  // this part can take time. save power.
-
     if (runFsck && !FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
         return UMOUNT_STAT_ERROR;
     }
@@ -397,6 +382,11 @@
         }
     }
 
+    // remaining operations (specifically fsck) may take a substantial duration
+    if (cmd == ANDROID_RB_POWEROFF || is_thermal_shutdown) {
+        TurnOffBacklight();
+    }
+
     Service* bootAnim = ServiceList::GetInstance().FindService("bootanim");
     Service* surfaceFlinger = ServiceList::GetInstance().FindService("surfaceflinger");
     if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {
diff --git a/init/subcontext.h b/init/subcontext.h
index 262440d..5601b80 100644
--- a/init/subcontext.h
+++ b/init/subcontext.h
@@ -25,6 +25,7 @@
 #include <android-base/unique_fd.h>
 
 #include "builtins.h"
+#include "result.h"
 #include "system/core/init/subcontext.pb.h"
 
 namespace android {
diff --git a/libsuspend/autosuspend.c b/libsuspend/autosuspend.c
index 09fc061..b87f59c 100644
--- a/libsuspend/autosuspend.c
+++ b/libsuspend/autosuspend.c
@@ -24,28 +24,20 @@
 
 #include "autosuspend_ops.h"
 
-static struct autosuspend_ops *autosuspend_ops;
+static struct autosuspend_ops* autosuspend_ops = NULL;
 static bool autosuspend_enabled;
-static bool autosuspend_inited;
 
 static int autosuspend_init(void) {
-    if (autosuspend_inited) {
+    if (autosuspend_ops != NULL) {
         return 0;
     }
 
     autosuspend_ops = autosuspend_wakeup_count_init();
-    if (autosuspend_ops) {
-        goto out;
-    }
-
-    if (!autosuspend_ops) {
+    if (autosuspend_ops == NULL) {
         ALOGE("failed to initialize autosuspend");
         return -1;
     }
 
-out:
-    autosuspend_inited = true;
-
     ALOGV("autosuspend initialized");
     return 0;
 }
@@ -96,6 +88,19 @@
     return 0;
 }
 
+int autosuspend_force_suspend(int timeout_ms) {
+    int ret;
+
+    ret = autosuspend_init();
+    if (ret) {
+        return ret;
+    }
+
+    ALOGV("autosuspend_force_suspend");
+
+    return autosuspend_ops->force_suspend(timeout_ms);
+}
+
 void autosuspend_set_wakeup_callback(void (*func)(bool success)) {
     int ret;
 
diff --git a/libsuspend/autosuspend_ops.h b/libsuspend/autosuspend_ops.h
index 357b828..b0024c8 100644
--- a/libsuspend/autosuspend_ops.h
+++ b/libsuspend/autosuspend_ops.h
@@ -20,6 +20,7 @@
 struct autosuspend_ops {
     int (*enable)(void);
     int (*disable)(void);
+    int (*force_suspend)(int timeout_ms);
     void (*set_wakeup_callback)(void (*func)(bool success));
 };
 
diff --git a/libsuspend/autosuspend_wakeup_count.cpp b/libsuspend/autosuspend_wakeup_count.cpp
index cfca765..27c8629 100644
--- a/libsuspend/autosuspend_wakeup_count.cpp
+++ b/libsuspend/autosuspend_wakeup_count.cpp
@@ -37,7 +37,7 @@
 #define BASE_SLEEP_TIME 100000
 #define MAX_SLEEP_TIME 60000000
 
-static int state_fd;
+static int state_fd = -1;
 static int wakeup_count_fd;
 
 using android::base::ReadFdToString;
@@ -46,11 +46,12 @@
 
 static pthread_t suspend_thread;
 static sem_t suspend_lockout;
-static const char* sleep_state = "mem";
+static constexpr char sleep_state[] = "mem";
 static void (*wakeup_func)(bool success) = NULL;
 static int sleep_time = BASE_SLEEP_TIME;
 static constexpr char sys_power_state[] = "/sys/power/state";
 static constexpr char sys_power_wakeup_count[] = "/sys/power/wakeup_count";
+static bool autosuspend_is_init = false;
 
 static void update_sleep_time(bool success) {
     if (success) {
@@ -62,10 +63,9 @@
 }
 
 static void* suspend_thread_func(void* arg __attribute__((unused))) {
-    int ret;
     bool success = true;
 
-    while (1) {
+    while (true) {
         update_sleep_time(success);
         usleep(sleep_time);
         success = false;
@@ -84,7 +84,7 @@
         }
 
         LOG(VERBOSE) << "wait";
-        ret = sem_wait(&suspend_lockout);
+        int ret = sem_wait(&suspend_lockout);
         if (ret < 0) {
             PLOG(ERROR) << "error waiting on semaphore";
             continue;
@@ -112,13 +112,72 @@
     return NULL;
 }
 
-static int autosuspend_wakeup_count_enable(void) {
-    int ret;
+static int init_state_fd(void) {
+    if (state_fd >= 0) {
+        return 0;
+    }
 
+    int fd = TEMP_FAILURE_RETRY(open(sys_power_state, O_CLOEXEC | O_RDWR));
+    if (fd < 0) {
+        PLOG(ERROR) << "error opening " << sys_power_state;
+        return -1;
+    }
+
+    state_fd = fd;
+    LOG(INFO) << "init_state_fd success";
+    return 0;
+}
+
+static int autosuspend_init(void) {
+    if (autosuspend_is_init) {
+        return 0;
+    }
+
+    int ret = init_state_fd();
+    if (ret < 0) {
+        return -1;
+    }
+
+    wakeup_count_fd = TEMP_FAILURE_RETRY(open(sys_power_wakeup_count, O_CLOEXEC | O_RDWR));
+    if (wakeup_count_fd < 0) {
+        PLOG(ERROR) << "error opening " << sys_power_wakeup_count;
+        goto err_open_wakeup_count;
+    }
+
+    ret = sem_init(&suspend_lockout, 0, 0);
+    if (ret < 0) {
+        PLOG(ERROR) << "error creating suspend_lockout semaphore";
+        goto err_sem_init;
+    }
+
+    ret = pthread_create(&suspend_thread, NULL, suspend_thread_func, NULL);
+    if (ret) {
+        LOG(ERROR) << "error creating thread: " << strerror(ret);
+        goto err_pthread_create;
+    }
+
+    LOG(VERBOSE) << "autosuspend_init success";
+    autosuspend_is_init = true;
+    return 0;
+
+err_pthread_create:
+    sem_destroy(&suspend_lockout);
+err_sem_init:
+    close(wakeup_count_fd);
+err_open_wakeup_count:
+    return -1;
+}
+
+static int autosuspend_wakeup_count_enable(void) {
     LOG(VERBOSE) << "autosuspend_wakeup_count_enable";
 
-    ret = sem_post(&suspend_lockout);
+    int ret = autosuspend_init();
+    if (ret < 0) {
+        LOG(ERROR) << "autosuspend_init failed";
+        return ret;
+    }
 
+    ret = sem_post(&suspend_lockout);
     if (ret < 0) {
         PLOG(ERROR) << "error changing semaphore";
     }
@@ -129,11 +188,13 @@
 }
 
 static int autosuspend_wakeup_count_disable(void) {
-    int ret;
-
     LOG(VERBOSE) << "autosuspend_wakeup_count_disable";
 
-    ret = sem_wait(&suspend_lockout);
+    if (!autosuspend_is_init) {
+        return 0;  // always successful if no thread is running yet
+    }
+
+    int ret = sem_wait(&suspend_lockout);
 
     if (ret < 0) {
         PLOG(ERROR) << "error changing semaphore";
@@ -144,6 +205,17 @@
     return ret;
 }
 
+static int force_suspend(int timeout_ms) {
+    LOG(VERBOSE) << "force_suspend called with timeout: " << timeout_ms;
+
+    int ret = init_state_fd();
+    if (ret < 0) {
+        return ret;
+    }
+
+    return WriteStringToFd(sleep_state, state_fd) ? 0 : -1;
+}
+
 static void autosuspend_set_wakeup_callback(void (*func)(bool success)) {
     if (wakeup_func != NULL) {
         LOG(ERROR) << "duplicate wakeup callback applied, keeping original";
@@ -155,44 +227,10 @@
 struct autosuspend_ops autosuspend_wakeup_count_ops = {
     .enable = autosuspend_wakeup_count_enable,
     .disable = autosuspend_wakeup_count_disable,
+    .force_suspend = force_suspend,
     .set_wakeup_callback = autosuspend_set_wakeup_callback,
 };
 
 struct autosuspend_ops* autosuspend_wakeup_count_init(void) {
-    int ret;
-
-    state_fd = TEMP_FAILURE_RETRY(open(sys_power_state, O_RDWR));
-    if (state_fd < 0) {
-        PLOG(ERROR) << "error opening " << sys_power_state;
-        goto err_open_state;
-    }
-
-    wakeup_count_fd = TEMP_FAILURE_RETRY(open(sys_power_wakeup_count, O_RDWR));
-    if (wakeup_count_fd < 0) {
-        PLOG(ERROR) << "error opening " << sys_power_wakeup_count;
-        goto err_open_wakeup_count;
-    }
-
-    ret = sem_init(&suspend_lockout, 0, 0);
-    if (ret < 0) {
-        PLOG(ERROR) << "error creating semaphore";
-        goto err_sem_init;
-    }
-    ret = pthread_create(&suspend_thread, NULL, suspend_thread_func, NULL);
-    if (ret) {
-        LOG(ERROR) << "error creating thread: " << strerror(ret);
-        goto err_pthread_create;
-    }
-
-    LOG(INFO) << "selected wakeup count";
     return &autosuspend_wakeup_count_ops;
-
-err_pthread_create:
-    sem_destroy(&suspend_lockout);
-err_sem_init:
-    close(wakeup_count_fd);
-err_open_wakeup_count:
-    close(state_fd);
-err_open_state:
-    return NULL;
 }
diff --git a/libsuspend/include/suspend/autosuspend.h b/libsuspend/include/suspend/autosuspend.h
index e130ca3..21f4d61 100644
--- a/libsuspend/include/suspend/autosuspend.h
+++ b/libsuspend/include/suspend/autosuspend.h
@@ -45,6 +45,17 @@
 int autosuspend_disable(void);
 
 /*
+ * force_suspend
+ *
+ * Forces suspend to happen.  timeout_ms is used to give system a chance to suspend gracefully.
+ * When timeout expires, suspend will be forced via mem --> /sys/power/state.  timeout_ms of 0
+ * will force suspend immediately.
+ *
+ * Returns 0 if system suspended, -1 if suspend did not occur.
+ */
+int autosuspend_force_suspend(int timeout_ms);
+
+/*
  * set_wakeup_callback
  *
  * Set a function to be called each time the device returns from suspend.