blob: 3047821fc124f34d4ca5bb7f1eae04cd52ae688e [file] [log] [blame]
Tom Cherry2aeb1ad2019-06-26 10:46:20 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "service_list.h"
18
19#include <android-base/logging.h>
20
21namespace android {
22namespace init {
23
24ServiceList::ServiceList() {}
25
26ServiceList& ServiceList::GetInstance() {
27 static ServiceList instance;
28 return instance;
29}
30
Tom Cherry6737a6b2019-08-05 15:03:58 -070031size_t ServiceList::CheckAllCommands() {
32 size_t failures = 0;
33 for (const auto& service : services_) {
34 failures += service->CheckAllCommands();
35 }
36 return failures;
37}
38
Tom Cherry2aeb1ad2019-06-26 10:46:20 -070039void ServiceList::AddService(std::unique_ptr<Service> service) {
40 services_.emplace_back(std::move(service));
41}
42
43// Shutdown services in the opposite order that they were started.
44const std::vector<Service*> ServiceList::services_in_shutdown_order() const {
45 std::vector<Service*> shutdown_services;
46 for (const auto& service : services_) {
47 if (service->start_order() > 0) shutdown_services.emplace_back(service.get());
48 }
49 std::sort(shutdown_services.begin(), shutdown_services.end(),
50 [](const auto& a, const auto& b) { return a->start_order() > b->start_order(); });
51 return shutdown_services;
52}
53
54void ServiceList::RemoveService(const Service& svc) {
55 auto svc_it = std::find_if(
56 services_.begin(), services_.end(),
57 [&svc](const std::unique_ptr<Service>& s) { return svc.name() == s->name(); });
58 if (svc_it == services_.end()) {
59 return;
60 }
61
62 services_.erase(svc_it);
63}
64
65void ServiceList::DumpState() const {
66 for (const auto& s : services_) {
67 s->DumpState();
68 }
69}
70
71void ServiceList::MarkPostData() {
72 post_data_ = true;
73}
74
75bool ServiceList::IsPostData() {
76 return post_data_;
77}
78
79void ServiceList::MarkServicesUpdate() {
80 services_update_finished_ = true;
81
82 // start the delayed services
83 for (const auto& name : delayed_service_names_) {
84 Service* service = FindService(name);
85 if (service == nullptr) {
86 LOG(ERROR) << "delayed service '" << name << "' could not be found.";
87 continue;
88 }
Bernie Innocenticecebbb2020-02-06 03:49:33 +090089 if (auto result = service->Start(); !result.ok()) {
Tom Cherry2aeb1ad2019-06-26 10:46:20 -070090 LOG(ERROR) << result.error().message();
91 }
92 }
93 delayed_service_names_.clear();
94}
95
96void ServiceList::DelayService(const Service& service) {
97 if (services_update_finished_) {
98 LOG(ERROR) << "Cannot delay the start of service '" << service.name()
99 << "' because all services are already updated. Ignoring.";
100 return;
101 }
102 delayed_service_names_.emplace_back(service.name());
103}
104
105} // namespace init
106} // namespace android