Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8aebd47c authored by Keun-young Park's avatar Keun-young Park Committed by android-build-merger
Browse files

Merge "add shutdown animation" am: 8aae1b15

am: e15756a6

Change-Id: I8595e5b6865f5c0f7ef5b43166853370ada8a141
parents e96faa6e e15756a6
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -198,6 +198,13 @@ runs the service.
  is in the class "default" if one is not specified via the
  class option. Additional classnames beyond the (required) first
  one are used to group services.
`animation class`
> 'animation' class should include all services necessary for both
  boot animation and shutdown animation. As these services can be
  launched very early during bootup and can run until the last stage
  of shutdown, access to /data partition is not guaranteed. These
  services can check files under /data but it should not keep files opened
  and should work when /data is not available.

`onrestart`
> Execute a Command (see below) when service restarts.
+35 −18
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <sys/wait.h>

#include <memory>
#include <set>
#include <string>
#include <thread>
#include <vector>
@@ -41,6 +42,7 @@
#include <logwrap/logwrap.h>

#include "log.h"
#include "property_service.h"
#include "reboot.h"
#include "service.h"
#include "util.h"
@@ -248,8 +250,9 @@ static bool UmountPartitions(std::vector<MountEntry>* partitions, int maxRetry,
                                              flags);
                } else {
                    umountDone = false;
                    PLOG(WARNING) << StringPrintf("cannot umount %s, flags:0x%x",
                                                  entry.mnt_fsname().c_str(), flags);
                    PLOG(WARNING) << StringPrintf("cannot umount %s, mnt_dir %s, flags:0x%x",
                                                  entry.mnt_fsname().c_str(),
                                                  entry.mnt_dir().c_str(), flags);
                }
            }
        }
@@ -351,26 +354,40 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
    }
    LOG(INFO) << "Shutdown timeout: " << shutdownTimeout;

    static const constexpr char* shutdown_critical_services[] = {"vold", "watchdogd"};
    for (const char* name : shutdown_critical_services) {
        Service* s = ServiceManager::GetInstance().FindServiceByName(name);
        if (s == nullptr) {
            LOG(WARNING) << "Shutdown critical service not found:" << name;
            continue;
        }
        s->Start();  // make sure that it is running.
    // keep debugging tools until non critical ones are all gone.
    const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
    // watchdogd is a vendor specific component but should be alive to complete shutdown safely.
    const std::set<std::string> to_starts{"watchdogd", "vold"};
    ServiceManager::GetInstance().ForEachService([&kill_after_apps, &to_starts](Service* s) {
        if (kill_after_apps.count(s->name())) {
            s->SetShutdownCritical();
        } else if (to_starts.count(s->name())) {
            s->Start();
            s->SetShutdownCritical();
        }
    });

    Service* bootAnim = ServiceManager::GetInstance().FindServiceByName("bootanim");
    Service* surfaceFlinger = ServiceManager::GetInstance().FindServiceByName("surfaceflinger");
    if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {
        property_set("service.bootanim.exit", "0");
        // Could be in the middle of animation. Stop and start so that it can pick
        // up the right mode.
        bootAnim->Stop();
        // start all animation classes if stopped.
        ServiceManager::GetInstance().ForEachServiceInClass("animation", [](Service* s) {
            s->Start();
            s->SetShutdownCritical();  // will not check animation class separately
        });
        bootAnim->Start();
        surfaceFlinger->SetShutdownCritical();
        bootAnim->SetShutdownCritical();
    }

    // optional shutdown step
    // 1. terminate all services except shutdown critical ones. wait for delay to finish
    if (shutdownTimeout > 0) {
        LOG(INFO) << "terminating init services";
        // tombstoned can write to data when other services are killed. so finish it first.
        static const constexpr char* first_to_kill[] = {"tombstoned"};
        for (const char* name : first_to_kill) {
            Service* s = ServiceManager::GetInstance().FindServiceByName(name);
            if (s != nullptr) s->Stop();
        }

        // Ask all services to terminate except shutdown critical ones.
        ServiceManager::GetInstance().ForEachService([](Service* s) {
@@ -409,8 +426,8 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re

    // minimum safety steps before restarting
    // 2. kill all services except ones that are necessary for the shutdown sequence.
    ServiceManager::GetInstance().ForEachService([](Service* s) {
        if (!s->IsShutdownCritical()) s->Stop();
    ServiceManager::GetInstance().ForEachService([&kill_after_apps](Service* s) {
        if (!s->IsShutdownCritical() || kill_after_apps.count(s->name())) s->Stop();
    });
    ServiceManager::GetInstance().ReapAnyOutstandingChildren();