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