servicemanager: notifications

You can now register and receive notifications for new services.

Eye towards:
- avoiding while(true) getService loops
- need it to make AIDL dynamic HALs
- need it for feature parity w/ HIDL

Bug: 136027762
Test: servicemanager_test
Change-Id: Iffbf984e87214aa9c9b7af8a5ae682e127ba40a5
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 43723c5..fcc5124 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -17,11 +17,14 @@
 #pragma once
 
 #include <android/os/BnServiceManager.h>
+#include <android/os/IServiceCallback.h>
 
 #include "Access.h"
 
 namespace android {
 
+using os::IServiceCallback;
+
 class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {
 public:
     ServiceManager(std::unique_ptr<Access>&& access);
@@ -29,19 +32,35 @@
 
     binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override;
     binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override;
-    binder::Status addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) override;
+    binder::Status addService(const std::string& name, const sp<IBinder>& binder,
+                              bool allowIsolated, int32_t dumpPriority) override;
     binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override;
+    binder::Status registerForNotifications(const std::string& name,
+                                            const sp<IServiceCallback>& callback) override;
+    binder::Status unregisterForNotifications(const std::string& name,
+                                              const sp<IServiceCallback>& callback) override;
 
     void binderDied(const wp<IBinder>& who) override;
 
 private:
     struct Service {
-        sp<IBinder> binder;
+        sp<IBinder> binder; // not null
         bool allowIsolated;
         int32_t dumpPriority;
     };
 
-    std::map<std::string, Service> mNameToService;
+    using CallbackMap = std::map<std::string, std::vector<sp<IServiceCallback>>>;
+    using ServiceMap = std::map<std::string, Service>;
+
+    // removes a callback from mNameToCallback, removing it if the vector is empty
+    // this updates iterator to the next location
+    void removeCallback(const wp<IBinder>& who,
+                        CallbackMap::iterator* it,
+                        bool* found);
+
+    CallbackMap mNameToCallback;
+    ServiceMap mNameToService;
+
     std::unique_ptr<Access> mAccess;
 };