Unregister Waiter in waitForService

IServiceManager's waitForService relies on notifications from servicemanager. Previously it registered with servicemanager but was missing an unregister call after use.

Bug: 144534962
Test: Manual (boot and dynamically start services)
Change-Id: Ic25349d42168a311e9fbce576f15de4067b0cc66
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 4f47db1..bac8b66 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -280,19 +280,31 @@
         std::condition_variable mCv;
     };
 
+    // Simple RAII object to ensure a function call immediately before going out of scope
+    class Defer {
+    public:
+        Defer(std::function<void()>&& f) : mF(std::move(f)) {}
+        ~Defer() { mF(); }
+    private:
+        std::function<void()> mF;
+    };
+
     const std::string name = String8(name16).c_str();
 
     sp<IBinder> out;
     if (!mTheRealServiceManager->getService(name, &out).isOk()) {
         return nullptr;
     }
-    if(out != nullptr) return out;
+    if (out != nullptr) return out;
 
     sp<Waiter> waiter = new Waiter;
     if (!mTheRealServiceManager->registerForNotifications(
             name, waiter).isOk()) {
         return nullptr;
     }
+    Defer unregister ([&] {
+        mTheRealServiceManager->unregisterForNotifications(name, waiter);
+    });
 
     while(true) {
         {
@@ -316,7 +328,7 @@
         if (!mTheRealServiceManager->getService(name, &out).isOk()) {
             return nullptr;
         }
-        if(out != nullptr) return out;
+        if (out != nullptr) return out;
 
         ALOGW("Waited one second for %s", name.c_str());
     }