shill: Don't create DHCP and Modem D-Bus proxies in signal callbacks.

dbus-c++ doesn't allow proxy creation in signal callbacks so create them in
deferred tasks instead.

BUG=chromium-os:18228
TEST=unit tests, tested on device

Change-Id: I4f85ab937aef99ef4556c5a3c16af913d8fa08fd
Reviewed-on: http://gerrit.chromium.org/gerrit/4827
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
diff --git a/dhcp_config.h b/dhcp_config.h
index 0ad62c4..7b8e39d 100644
--- a/dhcp_config.h
+++ b/dhcp_config.h
@@ -7,6 +7,7 @@
 
 #include <base/file_path.h>
 #include <base/memory/scoped_ptr.h>
+#include <base/task.h>
 #include <dbus-c++/types.h>
 #include <glib.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
@@ -18,6 +19,7 @@
 class ControlInterface;
 class DHCPProvider;
 class DHCPProxyInterface;
+class EventDispatcher;
 class GLib;
 
 class DHCPConfig : public IPConfig {
@@ -25,6 +27,7 @@
   typedef std::map<std::string, DBus::Variant> Configuration;
 
   DHCPConfig(ControlInterface *control_interface,
+             EventDispatcher *dispatcher,
              DHCPProvider *provider,
              const std::string &device_name,
              GLib *glib);
@@ -37,7 +40,7 @@
 
   // If |proxy_| is not initialized already, sets it to a new D-Bus proxy to
   // |service|.
-  void InitProxy(const char *service);
+  void InitProxy(const std::string &service);
 
   // Processes an Event signal from dhcpcd.
   void ProcessEventSignal(const std::string &reason,
@@ -46,6 +49,7 @@
  private:
   friend class DHCPConfigTest;
   FRIEND_TEST(DHCPConfigTest, GetIPv4AddressString);
+  FRIEND_TEST(DHCPConfigTest, InitProxy);
   FRIEND_TEST(DHCPConfigTest, ParseConfiguration);
   FRIEND_TEST(DHCPConfigTest, ProcessEventSignalFail);
   FRIEND_TEST(DHCPConfigTest, ProcessEventSignalSuccess);
@@ -81,6 +85,10 @@
 
   static const char kType[];
 
+  // If |proxy_| is not initialized already, sets it to a new D-Bus proxy to
+  // |service|.
+  void InitProxyTask(const std::string &service);
+
   // Starts dhcpcd, returns true on success and false otherwise.
   bool Start();
 
@@ -122,6 +130,8 @@
   // Root file path, used for testing.
   FilePath root_;
 
+  ScopedRunnableMethodFactory<DHCPConfig> task_factory_;
+  EventDispatcher *dispatcher_;
   GLib *glib_;
 
   DISALLOW_COPY_AND_ASSIGN(DHCPConfig);