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 #pragma once 18 19 #include <iterator> 20 #include <memory> 21 #include <vector> 22 23 #include <android-base/logging.h> 24 25 #include "service.h" 26 #include "util.h" 27 28 namespace android { 29 namespace init { 30 31 class ServiceList { 32 public: 33 static ServiceList& GetInstance(); 34 35 // Exposed for testing 36 ServiceList(); 37 size_t CheckAllCommands(); 38 39 void AddService(std::unique_ptr<Service> service); 40 void RemoveService(const Service& svc); 41 template <class UnaryPredicate> RemoveServiceIf(UnaryPredicate predicate)42 void RemoveServiceIf(UnaryPredicate predicate) { 43 services_.erase(std::remove_if(services_.begin(), services_.end(), predicate), 44 services_.end()); 45 } 46 47 template <typename T, typename F = decltype(&Service::name)> 48 Service* FindService(T value, F function = &Service::name) const { 49 auto svc = std::find_if(services_.begin(), services_.end(), 50 [&function, &value](const std::unique_ptr<Service>& s) { 51 return std::invoke(function, s) == value; 52 }); 53 if (svc != services_.end()) { 54 return svc->get(); 55 } 56 return nullptr; 57 } 58 FindServicesByApexName(const std::string & apex_name)59 std::vector<Service*> FindServicesByApexName(const std::string& apex_name) const { 60 CHECK(!apex_name.empty()) << "APEX name cannot be empty"; 61 std::vector<Service*> matches; 62 for (const auto& svc : services_) { 63 if (GetApexNameFromFileName(svc->filename()) == apex_name) { 64 matches.emplace_back(svc.get()); 65 } 66 } 67 return matches; 68 } 69 FindInterface(const std::string & interface_name)70 Service* FindInterface(const std::string& interface_name) { 71 for (const auto& svc : services_) { 72 if (svc->interfaces().count(interface_name) > 0) { 73 return svc.get(); 74 } 75 } 76 77 return nullptr; 78 } 79 80 void DumpState() const; 81 begin()82 auto begin() const { return services_.begin(); } end()83 auto end() const { return services_.end(); } 84 const std::vector<Service*> services_in_shutdown_order() const; 85 86 void MarkPostData(); 87 bool IsPostData(); 88 void DelayService(const Service& service); 89 void StartDelayedServices(); 90 ResetState()91 void ResetState() { post_data_ = false; } 92 size()93 auto size() const { return services_.size(); } 94 95 private: 96 std::vector<std::unique_ptr<Service>> services_; 97 98 bool post_data_ = false; 99 std::vector<std::string> delayed_service_names_; 100 }; 101 102 } // namespace init 103 } // namespace android 104