init: rename ServiceManager to ServiceList and clean it up

ServiceManager is essentially just a list now that the rest of its
functionality has been moved elsewhere, so the class is renamed
appropriately.

The ServiceList::Find* functions have been cleaned up into a single
smaller interface.
The ServiceList::ForEach functions have been removed in favor of
ServiceList itself being directly iterable.

Test: boot bullhead
Change-Id: Ibd57c103338f03b83d81e8b48ea0e46cd48fd8f0
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 15594e6..0351582 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -124,31 +124,32 @@
     return 0;
 }
 
+template <typename F>
+static void ForEachServiceInClass(const std::string& classname, F function) {
+    for (const auto& service : ServiceList::GetInstance()) {
+        if (service->classnames().count(classname)) std::invoke(function, service);
+    }
+}
+
 static int do_class_start(const std::vector<std::string>& args) {
-        /* Starting a class does not start services
-         * which are explicitly disabled.  They must
-         * be started individually.
-         */
-    ServiceManager::GetInstance().
-        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
+    // Starting a class does not start services which are explicitly disabled.
+    // They must  be started individually.
+    ForEachServiceInClass(args[1], &Service::StartIfNotDisabled);
     return 0;
 }
 
 static int do_class_stop(const std::vector<std::string>& args) {
-    ServiceManager::GetInstance().
-        ForEachServiceInClass(args[1], [] (Service* s) { s->Stop(); });
+    ForEachServiceInClass(args[1], &Service::Stop);
     return 0;
 }
 
 static int do_class_reset(const std::vector<std::string>& args) {
-    ServiceManager::GetInstance().
-        ForEachServiceInClass(args[1], [] (Service* s) { s->Reset(); });
+    ForEachServiceInClass(args[1], &Service::Reset);
     return 0;
 }
 
 static int do_class_restart(const std::vector<std::string>& args) {
-    ServiceManager::GetInstance().
-        ForEachServiceInClass(args[1], [] (Service* s) { s->Restart(); });
+    ForEachServiceInClass(args[1], &Service::Restart);
     return 0;
 }
 
@@ -162,7 +163,7 @@
 }
 
 static int do_enable(const std::vector<std::string>& args) {
-    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
+    Service* svc = ServiceList::GetInstance().FindService(args[1]);
     if (!svc) {
         return -1;
     }
@@ -179,12 +180,12 @@
         LOG(ERROR) << "Failed to Start exec service";
         return -1;
     }
-    ServiceManager::GetInstance().AddService(std::move(service));
+    ServiceList::GetInstance().AddService(std::move(service));
     return 0;
 }
 
 static int do_exec_start(const std::vector<std::string>& args) {
-    Service* service = ServiceManager::GetInstance().FindServiceByName(args[1]);
+    Service* service = ServiceList::GetInstance().FindService(args[1]);
     if (!service) {
         LOG(ERROR) << "ExecStart(" << args[1] << "): Service not found";
         return -1;
@@ -408,8 +409,8 @@
  */
 static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
     auto& action_manager = ActionManager::GetInstance();
-    auto& service_manager = ServiceManager::GetInstance();
-    Parser parser = CreateParser(action_manager, service_manager);
+    auto& service_list = ServiceList::GetInstance();
+    Parser parser = CreateParser(action_manager, service_list);
     if (end_index <= start_index) {
         // Fallbacks for partitions on which early mount isn't enabled.
         for (const auto& path : late_import_paths) {
@@ -599,7 +600,7 @@
 }
 
 static int do_start(const std::vector<std::string>& args) {
-    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
+    Service* svc = ServiceList::GetInstance().FindService(args[1]);
     if (!svc) {
         LOG(ERROR) << "do_start: Service " << args[1] << " not found";
         return -1;
@@ -610,7 +611,7 @@
 }
 
 static int do_stop(const std::vector<std::string>& args) {
-    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
+    Service* svc = ServiceList::GetInstance().FindService(args[1]);
     if (!svc) {
         LOG(ERROR) << "do_stop: Service " << args[1] << " not found";
         return -1;
@@ -620,7 +621,7 @@
 }
 
 static int do_restart(const std::vector<std::string>& args) {
-    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
+    Service* svc = ServiceList::GetInstance().FindService(args[1]);
     if (!svc) {
         LOG(ERROR) << "do_restart: Service " << args[1] << " not found";
         return -1;
diff --git a/init/init.cpp b/init/init.cpp
index a12afae..8f946f7 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -98,22 +98,22 @@
 std::vector<std::string> late_import_paths;
 
 void DumpState() {
-    ServiceManager::GetInstance().DumpState();
+    ServiceList::GetInstance().DumpState();
     ActionManager::GetInstance().DumpState();
 }
 
-Parser CreateParser(ActionManager& action_manager, ServiceManager& service_manager) {
+Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
     Parser parser;
 
-    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_manager));
+    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list));
     parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager));
     parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
 
     return parser;
 }
 
-static void LoadBootScripts(ActionManager& action_manager, ServiceManager& service_manager) {
-    Parser parser = CreateParser(action_manager, service_manager);
+static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
+    Parser parser = CreateParser(action_manager, service_list);
 
     std::string bootscript = GetProperty("ro.boot.init_rc", "");
     if (bootscript.empty()) {
@@ -221,8 +221,8 @@
 
 static std::optional<boot_clock::time_point> RestartProcesses() {
     std::optional<boot_clock::time_point> next_process_restart_time;
-    ServiceManager::GetInstance().ForEachService([&next_process_restart_time](Service* s) {
-        if (!(s->flags() & SVC_RESTARTING)) return;
+    for (const auto& s : ServiceList::GetInstance()) {
+        if (!(s->flags() & SVC_RESTARTING)) continue;
 
         auto restart_time = s->time_started() + 5s;
         if (boot_clock::now() > restart_time) {
@@ -232,12 +232,12 @@
                 next_process_restart_time = restart_time;
             }
         }
-    });
+    }
     return next_process_restart_time;
 }
 
 void handle_control_message(const std::string& msg, const std::string& name) {
-    Service* svc = ServiceManager::GetInstance().FindServiceByName(name);
+    Service* svc = ServiceList::GetInstance().FindService(name);
     if (svc == nullptr) {
         LOG(ERROR) << "no such service '" << name << "'";
         return;
@@ -1139,7 +1139,7 @@
     Action::set_function_map(&function_map);
 
     ActionManager& am = ActionManager::GetInstance();
-    ServiceManager& sm = ServiceManager::GetInstance();
+    ServiceList& sm = ServiceList::GetInstance();
 
     LoadBootScripts(am, sm);
 
diff --git a/init/init.h b/init/init.h
index 0a77bd2..92b9b70 100644
--- a/init/init.h
+++ b/init/init.h
@@ -38,7 +38,7 @@
 
 extern std::vector<std::string> late_import_paths;
 
-Parser CreateParser(ActionManager& action_manager, ServiceManager& service_manager);
+Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
 
 void handle_control_message(const std::string& msg, const std::string& arg);
 
diff --git a/init/keychords.cpp b/init/keychords.cpp
index a0d7cc5..2ef0ce7 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -79,7 +79,7 @@
     // Only handle keychords if adb is enabled.
     std::string adb_enabled = android::base::GetProperty("init.svc.adbd", "");
     if (adb_enabled == "running") {
-        Service* svc = ServiceManager::GetInstance().FindServiceByKeychord(id);
+        Service* svc = ServiceList::GetInstance().FindService(id, &Service::keychord_id);
         if (svc) {
             LOG(INFO) << "Starting service " << svc->name() << " from keychord " << id;
             svc->Start();
@@ -92,7 +92,9 @@
 }
 
 void keychord_init() {
-    ServiceManager::GetInstance().ForEachService(add_service_keycodes);
+    for (const auto& service : ServiceList::GetInstance()) {
+        add_service_keycodes(service.get());
+    }
 
     // Nothing to do if no services require keychords.
     if (!keychords) {
diff --git a/init/reboot.cpp b/init/reboot.cpp
index b1cde93..cfd703e 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -374,7 +374,7 @@
     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"};
-    ServiceManager::GetInstance().ForEachService([&kill_after_apps, &to_starts](Service* s) {
+    for (const auto& s : ServiceList::GetInstance()) {
         if (kill_after_apps.count(s->name())) {
             s->SetShutdownCritical();
         } else if (to_starts.count(s->name())) {
@@ -383,14 +383,15 @@
         } else if (s->IsShutdownCritical()) {
             s->Start();  // start shutdown critical service if not started
         }
-    });
+    }
 
-    Service* bootAnim = ServiceManager::GetInstance().FindServiceByName("bootanim");
-    Service* surfaceFlinger = ServiceManager::GetInstance().FindServiceByName("surfaceflinger");
+    Service* bootAnim = ServiceList::GetInstance().FindService("bootanim");
+    Service* surfaceFlinger = ServiceList::GetInstance().FindService("surfaceflinger");
     if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {
-        ServiceManager::GetInstance().ForEachServiceInClass("animation", [](Service* s) {
-            s->SetShutdownCritical();  // will not check animation class separately
-        });
+        // will not check animation class separately
+        for (const auto& service : ServiceList::GetInstance()) {
+            if (service->classnames().count("animation")) service->SetShutdownCritical();
+        }
     }
 
     // optional shutdown step
@@ -399,9 +400,9 @@
         LOG(INFO) << "terminating init services";
 
         // Ask all services to terminate except shutdown critical ones.
-        ServiceManager::GetInstance().ForEachServiceShutdownOrder([](Service* s) {
+        for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
             if (!s->IsShutdownCritical()) s->Terminate();
-        });
+        }
 
         int service_count = 0;
         // Only wait up to half of timeout here
@@ -410,7 +411,7 @@
             ReapAnyOutstandingChildren();
 
             service_count = 0;
-            ServiceManager::GetInstance().ForEachService([&service_count](Service* s) {
+            for (const auto& s : ServiceList::GetInstance()) {
                 // Count the number of services running except shutdown critical.
                 // Exclude the console as it will ignore the SIGTERM signal
                 // and not exit.
@@ -419,7 +420,7 @@
                 if (!s->IsShutdownCritical() && s->pid() != 0 && (s->flags() & SVC_CONSOLE) == 0) {
                     service_count++;
                 }
-            });
+            }
 
             if (service_count == 0) {
                 // All terminable services terminated. We can exit early.
@@ -435,13 +436,13 @@
 
     // minimum safety steps before restarting
     // 2. kill all services except ones that are necessary for the shutdown sequence.
-    ServiceManager::GetInstance().ForEachServiceShutdownOrder([](Service* s) {
+    for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
         if (!s->IsShutdownCritical()) s->Stop();
-    });
+    }
     ReapAnyOutstandingChildren();
 
     // 3. send volume shutdown to vold
-    Service* voldService = ServiceManager::GetInstance().FindServiceByName("vold");
+    Service* voldService = ServiceList::GetInstance().FindService("vold");
     if (voldService != nullptr && voldService->IsRunning()) {
         ShutdownVold();
         voldService->Stop();
@@ -449,9 +450,9 @@
         LOG(INFO) << "vold not running, skipping vold shutdown";
     }
     // logcat stopped here
-    ServiceManager::GetInstance().ForEachServiceShutdownOrder([&kill_after_apps](Service* s) {
+    for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
         if (kill_after_apps.count(s->name())) s->Stop();
-    });
+    }
     // 4. sync, try umount, and optionally run fsck for user shutdown
     sync();
     UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
@@ -526,7 +527,9 @@
     ResetWaitForProp();
 
     // Clear EXEC flag if there is one pending
-    ServiceManager::GetInstance().ForEachService([](Service* s) { s->UnSetExec(); });
+    for (const auto& s : ServiceList::GetInstance()) {
+        s->UnSetExec();
+    }
 
     return true;
 }
diff --git a/init/service.cpp b/init/service.cpp
index b5e2067..6f756fa 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -935,15 +935,14 @@
     close(fd);
 }
 
-ServiceManager::ServiceManager() {
-}
+ServiceList::ServiceList() {}
 
-ServiceManager& ServiceManager::GetInstance() {
-    static ServiceManager instance;
+ServiceList& ServiceList::GetInstance() {
+    static ServiceList instance;
     return instance;
 }
 
-void ServiceManager::AddService(std::unique_ptr<Service> service) {
+void ServiceList::AddService(std::unique_ptr<Service> service) {
     services_.emplace_back(std::move(service));
 }
 
@@ -1011,69 +1010,18 @@
                                      namespace_flags, seclabel, str_args);
 }
 
-Service* ServiceManager::FindServiceByName(const std::string& name) const {
-    auto svc = std::find_if(services_.begin(), services_.end(),
-                            [&name] (const std::unique_ptr<Service>& s) {
-                                return name == s->name();
-                            });
-    if (svc != services_.end()) {
-        return svc->get();
-    }
-    return nullptr;
-}
-
-Service* ServiceManager::FindServiceByPid(pid_t pid) const {
-    auto svc = std::find_if(services_.begin(), services_.end(),
-                            [&pid] (const std::unique_ptr<Service>& s) {
-                                return s->pid() == pid;
-                            });
-    if (svc != services_.end()) {
-        return svc->get();
-    }
-    return nullptr;
-}
-
-Service* ServiceManager::FindServiceByKeychord(int keychord_id) const {
-    auto svc = std::find_if(services_.begin(), services_.end(),
-                            [&keychord_id] (const std::unique_ptr<Service>& s) {
-                                return s->keychord_id() == keychord_id;
-                            });
-
-    if (svc != services_.end()) {
-        return svc->get();
-    }
-    return nullptr;
-}
-
-void ServiceManager::ForEachService(const std::function<void(Service*)>& callback) const {
-    for (const auto& s : services_) {
-        callback(s.get());
-    }
-}
-
 // Shutdown services in the opposite order that they were started.
-void ServiceManager::ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const {
+const std::vector<Service*> ServiceList::services_in_shutdown_order() const {
     std::vector<Service*> shutdown_services;
     for (const auto& service : services_) {
         if (service->start_order() > 0) shutdown_services.emplace_back(service.get());
     }
     std::sort(shutdown_services.begin(), shutdown_services.end(),
               [](const auto& a, const auto& b) { return a->start_order() > b->start_order(); });
-    for (const auto& service : shutdown_services) {
-        callback(service);
-    }
+    return shutdown_services;
 }
 
-void ServiceManager::ForEachServiceInClass(const std::string& classname,
-                                           void (*func)(Service* svc)) const {
-    for (const auto& s : services_) {
-        if (s->classnames().find(classname) != s->classnames().end()) {
-            func(s.get());
-        }
-    }
-}
-
-void ServiceManager::RemoveService(const Service& svc) {
+void ServiceList::RemoveService(const Service& svc) {
     auto svc_it = std::find_if(services_.begin(), services_.end(),
                                [&svc] (const std::unique_ptr<Service>& s) {
                                    return svc.name() == s->name();
@@ -1085,7 +1033,7 @@
     services_.erase(svc_it);
 }
 
-void ServiceManager::DumpState() const {
+void ServiceList::DumpState() const {
     for (const auto& s : services_) {
         s->DumpState();
     }
@@ -1104,7 +1052,7 @@
         return false;
     }
 
-    Service* old_service = service_manager_->FindServiceByName(name);
+    Service* old_service = service_list_->FindService(name);
     if (old_service) {
         *err = "ignored duplicate definition of service '" + name + "'";
         return false;
@@ -1121,7 +1069,7 @@
 
 void ServiceParser::EndSection() {
     if (service_) {
-        service_manager_->AddService(std::move(service_));
+        service_list_->AddService(std::move(service_));
     }
 }
 
diff --git a/init/service.h b/init/service.h
index a7c91ae..6c143cb 100644
--- a/init/service.h
+++ b/init/service.h
@@ -206,32 +206,42 @@
     std::vector<std::string> args_;
 };
 
-class ServiceManager {
+class ServiceList {
   public:
-    static ServiceManager& GetInstance();
+    static ServiceList& GetInstance();
 
     // Exposed for testing
-    ServiceManager();
+    ServiceList();
 
     void AddService(std::unique_ptr<Service> service);
-    Service* FindServiceByName(const std::string& name) const;
-    Service* FindServiceByPid(pid_t pid) const;
-    Service* FindServiceByKeychord(int keychord_id) const;
-    void ForEachService(const std::function<void(Service*)>& callback) const;
-    void ForEachServiceShutdownOrder(const std::function<void(Service*)>& callback) const;
-    void ForEachServiceInClass(const std::string& classname,
-                               void (*func)(Service* svc)) const;
     void RemoveService(const Service& svc);
+
+    template <typename T, typename F = decltype(&Service::name)>
+    Service* FindService(T value, F function = &Service::name) const {
+        auto svc = std::find_if(services_.begin(), services_.end(),
+                                [&function, &value](const std::unique_ptr<Service>& s) {
+                                    return std::invoke(function, s) == value;
+                                });
+        if (svc != services_.end()) {
+            return svc->get();
+        }
+        return nullptr;
+    }
+
     void DumpState() const;
 
+    auto begin() const { return services_.begin(); }
+    auto end() const { return services_.end(); }
+    const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
+    const std::vector<Service*> services_in_shutdown_order() const;
+
   private:
     std::vector<std::unique_ptr<Service>> services_;
 };
 
 class ServiceParser : public SectionParser {
   public:
-    ServiceParser(ServiceManager* service_manager)
-        : service_manager_(service_manager), service_(nullptr) {}
+    ServiceParser(ServiceList* service_list) : service_list_(service_list), service_(nullptr) {}
     bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
                       std::string* err) override;
     bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) override;
@@ -240,7 +250,7 @@
   private:
     bool IsValidName(const std::string& name) const;
 
-    ServiceManager* service_manager_;
+    ServiceList* service_list_;
     std::unique_ptr<Service> service_;
 };
 
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index d77a212..9e49c48 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -62,7 +62,7 @@
 
     if (PropertyChildReap(pid)) return true;
 
-    Service* service = ServiceManager::GetInstance().FindServiceByPid(pid);
+    Service* service = ServiceList::GetInstance().FindService(pid, &Service::pid);
 
     std::string name;
     std::string wait_string;
@@ -90,7 +90,7 @@
     service->Reap();
 
     if (service->flags() & SVC_TEMPORARY) {
-        ServiceManager::GetInstance().RemoveService(*service);
+        ServiceList::GetInstance().RemoveService(*service);
     }
 
     return true;