chromeos-dbus-bindings: Use per signal handlers

When we use a delegate, we're forced into a situation where:

1) Some object must manage the lifetime of both the delegate and the
   proxy
2) We can continue to receive callbacks on the signal handler until
   we detach the proxy from the Bus

However, there is not a great mechanism to coordinate the lifetime
of the managing object with the required lifetime of the delegate
object.  If we ever reach the destructor of the managing object,
it is too late to try and tear down the proxy and its signal delegate.

BUG=chromium:438728
TEST=unittests and generated code compiles.

Change-Id: Ia6f8080b069f4aa6d1b92b1ca612e3d69eee88a7
Reviewed-on: https://chromium-review.googlesource.com/233009
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Tested-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
diff --git a/chromeos-dbus-bindings/proxy_generator_unittest.cc b/chromeos-dbus-bindings/proxy_generator_unittest.cc
index d3ebaad..9afc9ab 100644
--- a/chromeos-dbus-bindings/proxy_generator_unittest.cc
+++ b/chromeos-dbus-bindings/proxy_generator_unittest.cc
@@ -72,14 +72,6 @@
 // Interface proxy for org::chromium::TestInterface.
 class TestInterfaceProxy final {
  public:
-  class SignalReceiver {
-   public:
-    virtual void OnCloserSignal() {}
-    virtual void OnTheCurseOfKaZarSignal(
-        const std::vector<std::string>&,
-        uint8_t) {}
-  };
-
   TestInterfaceProxy(
       const scoped_refptr<dbus::Bus>& bus,
       const std::string& service_name) :
@@ -89,34 +81,30 @@
               bus_->GetObjectProxy(service_name_, object_path_)} {
   }
 
-  TestInterfaceProxy(
-      const scoped_refptr<dbus::Bus>& bus,
-      const std::string& service_name,
-      SignalReceiver* signal_receiver) :
-          TestInterfaceProxy(bus, service_name) {
+  ~TestInterfaceProxy() {
+  }
+
+  void RegisterCloserSignalHandler(
+      const base::Closure& signal_callback,
+      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
     chromeos::dbus_utils::ConnectToSignal(
         dbus_object_proxy_,
         "org.chromium.TestInterface",
         "Closer",
-        base::Bind(
-            &SignalReceiver::OnCloserSignal,
-            base::Unretained(signal_receiver)),
-        base::Bind(
-            &TestInterfaceProxy::OnDBusSignalConnected,
-            base::Unretained(this)));
+        signal_callback,
+        on_connected_callback);
+  }
+
+  void RegisterTheCurseOfKaZarSignalHandler(
+      const base::Callback<void(const std::vector<std::string>&,
+                                uint8_t)>& signal_callback,
+      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
     chromeos::dbus_utils::ConnectToSignal(
         dbus_object_proxy_,
         "org.chromium.TestInterface",
         "TheCurseOfKaZar",
-        base::Bind(
-            &SignalReceiver::OnTheCurseOfKaZarSignal,
-            base::Unretained(signal_receiver)),
-        base::Bind(
-            &TestInterfaceProxy::OnDBusSignalConnected,
-            base::Unretained(this)));
-  }
-
-  ~TestInterfaceProxy() {
+        signal_callback,
+        on_connected_callback);
   }
 
   void ReleaseObjectProxy(const base::Closure& callback) {
@@ -129,18 +117,6 @@
 
   dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
 
-  void OnDBusSignalConnected(
-      const std::string& interface,
-      const std::string& signal,
-      bool success) {
-    if (!success) {
-      LOG(ERROR)
-          << "Failed to connect to " << interface << "." << signal
-          << " for " << service_name_ << " at "
-          << object_path_.value();
-    }
-  }
-
   bool Elements(
       const std::string& in_space_walk,
       const std::vector<dbus::ObjectPath>& in_ramblin_man,
@@ -291,34 +267,24 @@
 // Interface proxy for org::chromium::TestInterface.
 class TestInterfaceProxy final {
  public:
-  class SignalReceiver {
-   public:
-    virtual void OnCloserSignal() {}
-  };
-
   TestInterfaceProxy(const scoped_refptr<dbus::Bus>& bus) :
       bus_{bus},
       dbus_object_proxy_{
           bus_->GetObjectProxy(service_name_, object_path_)} {
   }
 
-  TestInterfaceProxy(
-      const scoped_refptr<dbus::Bus>& bus,
-      SignalReceiver* signal_receiver) :
-          TestInterfaceProxy(bus) {
+  ~TestInterfaceProxy() {
+  }
+
+  void RegisterCloserSignalHandler(
+      const base::Closure& signal_callback,
+      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
     chromeos::dbus_utils::ConnectToSignal(
         dbus_object_proxy_,
         "org.chromium.TestInterface",
         "Closer",
-        base::Bind(
-            &SignalReceiver::OnCloserSignal,
-            base::Unretained(signal_receiver)),
-        base::Bind(
-            &TestInterfaceProxy::OnDBusSignalConnected,
-            base::Unretained(this)));
-  }
-
-  ~TestInterfaceProxy() {
+        signal_callback,
+        on_connected_callback);
   }
 
   void ReleaseObjectProxy(const base::Closure& callback) {
@@ -331,18 +297,6 @@
 
   dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
 
-  void OnDBusSignalConnected(
-      const std::string& interface,
-      const std::string& signal,
-      bool success) {
-    if (!success) {
-      LOG(ERROR)
-          << "Failed to connect to " << interface << "." << signal
-          << " for " << service_name_ << " at "
-          << object_path_.value();
-    }
-  }
-
  private:
   scoped_refptr<dbus::Bus> bus_;
   const std::string service_name_{"org.chromium.Test"};
@@ -430,11 +384,6 @@
 // Interface proxy for org::chromium::Itf1.
 class Itf1Proxy final {
  public:
-  class SignalReceiver {
-   public:
-    virtual void OnCloserSignal() {}
-  };
-
   class PropertySet : public dbus::PropertySet {
    public:
     PropertySet(dbus::ObjectProxy* object_proxy,
@@ -462,25 +411,18 @@
               bus_->GetObjectProxy(service_name_, object_path_)} {
   }
 
-  Itf1Proxy(
-      const scoped_refptr<dbus::Bus>& bus,
-      const std::string& service_name,
-      PropertySet* property_set,
-      SignalReceiver* signal_receiver) :
-          Itf1Proxy(bus, service_name, property_set) {
+  ~Itf1Proxy() {
+  }
+
+  void RegisterCloserSignalHandler(
+      const base::Closure& signal_callback,
+      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
     chromeos::dbus_utils::ConnectToSignal(
         dbus_object_proxy_,
         "org.chromium.Itf1",
         "Closer",
-        base::Bind(
-            &SignalReceiver::OnCloserSignal,
-            base::Unretained(signal_receiver)),
-        base::Bind(
-            &Itf1Proxy::OnDBusSignalConnected,
-            base::Unretained(this)));
-  }
-
-  ~Itf1Proxy() {
+        signal_callback,
+        on_connected_callback);
   }
 
   void ReleaseObjectProxy(const base::Closure& callback) {
@@ -501,18 +443,6 @@
   const PropertySet* GetProperties() const { return property_set_; }
   PropertySet* GetProperties() { return property_set_; }
 
-  void OnDBusSignalConnected(
-      const std::string& interface,
-      const std::string& signal,
-      bool success) {
-    if (!success) {
-      LOG(ERROR)
-          << "Failed to connect to " << interface << "." << signal
-          << " for " << service_name_ << " at "
-          << object_path_.value();
-    }
-  }
-
   const std::string& data() const {
     return property_set_->data.value();
   }
@@ -800,11 +730,6 @@
 // Interface proxy for org::chromium::Itf1.
 class Itf1Proxy final {
  public:
-  class SignalReceiver {
-   public:
-    virtual void OnCloserSignal() {}
-  };
-
   class PropertySet : public dbus::PropertySet {
    public:
     PropertySet(dbus::ObjectProxy* object_proxy,
@@ -825,23 +750,18 @@
           bus_->GetObjectProxy(service_name_, object_path_)} {
   }
 
-  Itf1Proxy(
-      const scoped_refptr<dbus::Bus>& bus,
-      SignalReceiver* signal_receiver) :
-          Itf1Proxy(bus) {
+  ~Itf1Proxy() {
+  }
+
+  void RegisterCloserSignalHandler(
+      const base::Closure& signal_callback,
+      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
     chromeos::dbus_utils::ConnectToSignal(
         dbus_object_proxy_,
         "org.chromium.Itf1",
         "Closer",
-        base::Bind(
-            &SignalReceiver::OnCloserSignal,
-            base::Unretained(signal_receiver)),
-        base::Bind(
-            &Itf1Proxy::OnDBusSignalConnected,
-            base::Unretained(this)));
-  }
-
-  ~Itf1Proxy() {
+        signal_callback,
+        on_connected_callback);
   }
 
   void ReleaseObjectProxy(const base::Closure& callback) {
@@ -854,18 +774,6 @@
 
   dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
 
-  void OnDBusSignalConnected(
-      const std::string& interface,
-      const std::string& signal,
-      bool success) {
-    if (!success) {
-      LOG(ERROR)
-          << "Failed to connect to " << interface << "." << signal
-          << " for " << service_name_ << " at "
-          << object_path_.value();
-    }
-  }
-
  private:
   scoped_refptr<dbus::Bus> bus_;
   const std::string service_name_{"org.chromium.Test"};