chromeos-dbus-bindings: passing multiple input files on command line

When generating D-Bus proxies for objects under D-Bus Object Manager
control, it is important to group all the proxies and tie them to
a single instance of Object Manager proxy that knows about the
subordinate interfaces and their properties.

In order to do this, multiple source XML files will be grouped into
one proxy header file, complete with all the proxy interfaces, signal
handlers as well as a single Object Manager proxy class that manages
all those proxies (this part will be done in a separate CL).

In order to supply more than one source XML file to the generator
executable, remove --input switch and let the files be passed directly.

GYP files that import proxies from other projects will need to do so
for more than one source target, so they can use a single GYP rule
as was defined in generate-dbus-bindings.gypi. However, that rule
is totally acceptable for generating adaptors, so, renamed the
generate-dbus-bindings.gypi into generate-dbus-adaptors.gypi to
be more specific and simplified it a bit.

Also made generated object proxies to allow explicit releasing of the
underlying dbus::ObjectProxy from the dbus::Bus. This is cannot be done
in the constructor since dbus::Bus::RemoveObjectProxy is an asynchronous
call and requires a message loop to be executed. For clients such as
buffet_client that doesn't have a message loop, removing the proxy
in the destructor causes a crash. For clients like Shill who need to
keep the bus clean, they can call ReleaseObjectProxy() before destroying
the proxy object.

BUG=chromium:431737
TEST=FEATURES=test emerge-link chromeos-dbus-bindings lorgnette apmanager

Change-Id: I6737c155c528f46d480d51aaf8420a1dad00f83e
Reviewed-on: https://chromium-review.googlesource.com/231155
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/chromeos-dbus-bindings/proxy_generator_unittest.cc b/chromeos-dbus-bindings/proxy_generator_unittest.cc
index 6c5e1a6..0b35fc8 100644
--- a/chromeos-dbus-bindings/proxy_generator_unittest.cc
+++ b/chromeos-dbus-bindings/proxy_generator_unittest.cc
@@ -66,6 +66,7 @@
 namespace org {
 namespace chromium {
 
+// Interface proxy for org::chromium::TestInterface.
 class TestInterfaceProxy final {
  public:
   class SignalReceiver {
@@ -79,13 +80,20 @@
   TestInterfaceProxy(
       const scoped_refptr<dbus::Bus>& bus,
       const std::string& service_name,
-      const std::string& object_path,
-      SignalReceiver* signal_receiver)
+      const std::string& object_path)
       : bus_(bus),
         service_name_(service_name),
         object_path_(object_path),
         dbus_object_proxy_(
             bus_->GetObjectProxy(service_name_, object_path_)) {
+  }
+
+  TestInterfaceProxy(
+      const scoped_refptr<dbus::Bus>& bus,
+      const std::string& service_name,
+      const std::string& object_path,
+      SignalReceiver* signal_receiver)
+      : TestInterfaceProxy(bus, service_name, object_path) {
     chromeos::dbus_utils::ConnectToSignal(
         dbus_object_proxy_,
         "org.chromium.TestInterface",
@@ -109,8 +117,10 @@
   }
 
   ~TestInterfaceProxy() {
-    dbus_object_proxy_->Detach();
-    bus_->RemoveObjectProxy(service_name_, object_path_, base::Closure());
+  }
+
+  void ReleaseObjectProxy(const base::Closure& callback) {
+    bus_->RemoveObjectProxy(service_name_, object_path_, callback);
   }
 
   void OnDBusSignalConnected(
@@ -179,6 +189,42 @@
         response.get(), error);
   }
 
+ private:
+  scoped_refptr<dbus::Bus> bus_;
+  std::string service_name_;
+  dbus::ObjectPath object_path_;
+  dbus::ObjectProxy* dbus_object_proxy_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestInterfaceProxy);
+};
+
+}  // namespace chromium
+}  // namespace org
+
+namespace org {
+namespace chromium {
+
+// Interface proxy for org::chromium::TestInterface2.
+class TestInterface2Proxy final {
+ public:
+  TestInterface2Proxy(
+      const scoped_refptr<dbus::Bus>& bus,
+      const std::string& service_name,
+      const std::string& object_path)
+      : bus_(bus),
+        service_name_(service_name),
+        object_path_(object_path),
+        dbus_object_proxy_(
+            bus_->GetObjectProxy(service_name_, object_path_)) {
+  }
+
+  ~TestInterface2Proxy() {
+  }
+
+  void ReleaseObjectProxy(const base::Closure& callback) {
+    bus_->RemoveObjectProxy(service_name_, object_path_, callback);
+  }
+
   bool GetPersonInfo(
       std::string* out_name,
       int32_t* out_age,
@@ -198,11 +244,12 @@
   dbus::ObjectPath object_path_;
   dbus::ObjectProxy* dbus_object_proxy_;
 
-  DISALLOW_COPY_AND_ASSIGN(TestInterfaceProxy);
+  DISALLOW_COPY_AND_ASSIGN(TestInterface2Proxy);
 };
 
 }  // namespace chromium
 }  // namespace org
+
 )literal_string";
 
 }  // namespace
@@ -260,7 +307,7 @@
           {kMethod5ArgumentName2, kMethod5Argument2}});
   vector<Interface> interfaces{interface, interface2};
   base::FilePath output_path = temp_dir_.path().Append("output.h");
-  EXPECT_TRUE(ProxyGenerator::GenerateProxy(interfaces, output_path));
+  EXPECT_TRUE(ProxyGenerator::GenerateProxies(interfaces, output_path));
   string contents;
   EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
   // The header guards contain the (temporary) filename, so we search for