1 /* 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 21 namespace android { 22 namespace init { 23 ServiceList()24ServiceList::ServiceList() {} 25 GetInstance()26ServiceList& ServiceList::GetInstance() { 27 static ServiceList instance; 28 return instance; 29 } 30 CheckAllCommands()31size_t ServiceList::CheckAllCommands() { 32 size_t failures = 0; 33 for (const auto& service : services_) { 34 failures += service->CheckAllCommands(); 35 } 36 return failures; 37 } 38 AddService(std::unique_ptr<Service> service)39void 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. services_in_shutdown_order() const44const 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 RemoveService(const Service & svc)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 DumpState() const65void ServiceList::DumpState() const { 66 for (const auto& s : services_) { 67 s->DumpState(); 68 } 69 } 70 MarkPostData()71void ServiceList::MarkPostData() { 72 post_data_ = true; 73 } 74 IsPostData()75bool ServiceList::IsPostData() { 76 return post_data_; 77 } 78 MarkServicesUpdate()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 } 89 if (auto result = service->Start(); !result.ok()) { 90 LOG(ERROR) << result.error().message(); 91 } 92 } 93 delayed_service_names_.clear(); 94 } 95 DelayService(const Service & service)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 107