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

Commit 8aae1b15 authored by Keun-young Park's avatar Keun-young Park Committed by Gerrit Code Review
Browse files

Merge "add shutdown animation"

parents 2aeed10a 7830d595
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();