Merge "add shutdown animation" into oc-dev

This commit is contained in:
TreeHugger Robot 2017-04-03 23:51:34 +00:00 committed by Android (Google) Code Review
commit 49ab678930
2 changed files with 42 additions and 18 deletions

View File

@ -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.

View File

@ -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;
// 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();
}
s->Start(); // make sure that it is running.
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();