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.cc b/dhcp_config.cc
index 8e9e7ff..e9661e0 100644
--- a/dhcp_config.cc
+++ b/dhcp_config.cc
@@ -16,6 +16,7 @@
 #include "shill/glib.h"
 #include "shill/ip_address.h"
 #include "shill/proxy_factory.h"
+#include "shill/shill_event.h"
 
 using std::string;
 using std::vector;
@@ -44,6 +45,7 @@
 
 
 DHCPConfig::DHCPConfig(ControlInterface *control_interface,
+                       EventDispatcher *dispatcher,
                        DHCPProvider *provider,
                        const string &device_name,
                        GLib *glib)
@@ -52,6 +54,8 @@
       pid_(0),
       child_watch_tag_(0),
       root_("/"),
+      task_factory_(this),
+      dispatcher_(dispatcher),
       glib_(glib) {
   store_.RegisterConstString(flimflam::kAddressProperty,
                              &(properties().address));
@@ -85,10 +89,6 @@
   if (!pid_) {
     return false;
   }
-  if (!proxy_.get()) {
-    LOG(ERROR) << "Unable to renew IP before acquiring destination.";
-    return false;
-  }
   proxy_->Rebind(device_name());
   return true;
 }
@@ -98,17 +98,25 @@
   if (!pid_) {
     return true;
   }
-  if (!proxy_.get()) {
-    LOG(ERROR) << "Unable to release IP before acquiring destination.";
-    return false;
+  if (proxy_.get()) {
+    proxy_->Release(device_name());
   }
-  proxy_->Release(device_name());
   Stop();
   return true;
 }
 
-void DHCPConfig::InitProxy(const char *service) {
+void DHCPConfig::InitProxy(const string &service) {
+  // Defer proxy creation because dbus-c++ doesn't allow registration of new
+  // D-Bus objects in the context of a D-Bus signal handler.
   if (!proxy_.get()) {
+    dispatcher_->PostTask(
+        task_factory_.NewRunnableMethod(&DHCPConfig::InitProxyTask, service));
+  }
+}
+
+void DHCPConfig::InitProxyTask(const string &service) {
+  if (!proxy_.get()) {
+    VLOG(2) << "Init DHCP Proxy: " << device_name() << " at " << service;
     proxy_.reset(ProxyFactory::factory()->CreateDHCPProxy(service));
   }
 }
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);
diff --git a/dhcp_config_unittest.cc b/dhcp_config_unittest.cc
index 744e0ad..2ec6fb6 100644
--- a/dhcp_config_unittest.cc
+++ b/dhcp_config_unittest.cc
@@ -16,6 +16,8 @@
 #include "shill/mock_dhcp_proxy.h"
 #include "shill/mock_glib.h"
 #include "shill/property_store_unittest.h"
+#include "shill/proxy_factory.h"
+#include "shill/shill_event.h"
 
 using std::string;
 using std::vector;
@@ -27,23 +29,44 @@
 namespace shill {
 
 namespace {
-const char kDeviceName[] = "testdevicename";
+const char kDeviceName[] = "eth0";
 }  // namespace {}
 
 class DHCPConfigTest : public PropertyStoreTest {
  public:
   DHCPConfigTest()
       : proxy_(new MockDHCPProxy()),
+        proxy_factory_(this),
         config_(new DHCPConfig(&control_,
+                               &dispatcher_,
                                DHCPProvider::GetInstance(),
                                kDeviceName,
-                               &glib_)) {
-    config_->proxy_.reset(proxy_);  // pass ownership
+                               &glib_)) {}
+
+  virtual void SetUp() {
+    ProxyFactory::set_factory(&proxy_factory_);
+  }
+
+  virtual void TearDown() {
+    ProxyFactory::set_factory(NULL);
   }
 
  protected:
+  class TestProxyFactory : public ProxyFactory {
+   public:
+    TestProxyFactory(DHCPConfigTest *test) : test_(test) {}
+
+    virtual DHCPProxyInterface *CreateDHCPProxy(const string &service) {
+      return test_->proxy_.release();
+    }
+
+   private:
+    DHCPConfigTest *test_;
+  };
+
   MockGLib glib_;
-  MockDHCPProxy * const proxy_;
+  scoped_ptr<MockDHCPProxy> proxy_;
+  TestProxyFactory proxy_factory_;
   MockControl control_;
   DHCPConfigRefPtr config_;
 };
@@ -54,6 +77,22 @@
   EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
 }
 
+TEST_F(DHCPConfigTest, InitProxy) {
+  static const char kService[] = ":1.200";
+  EXPECT_TRUE(config_->task_factory_.empty());
+  config_->InitProxy(kService);
+  EXPECT_FALSE(config_->task_factory_.empty());
+
+  EXPECT_TRUE(proxy_.get());
+  EXPECT_FALSE(config_->proxy_.get());
+  dispatcher_.DispatchPendingEvents();
+  EXPECT_FALSE(proxy_.get());
+  EXPECT_TRUE(config_->proxy_.get());
+
+  config_->InitProxy(kService);
+  EXPECT_TRUE(config_->task_factory_.empty());
+}
+
 TEST_F(DHCPConfigTest, ParseConfiguration) {
   DHCPConfig::Configuration conf;
   conf[DHCPConfig::kConfigurationKeyIPAddress].writer().append_uint32(
@@ -193,6 +232,7 @@
 TEST_F(DHCPConfigTest, ReleaseIP) {
   config_->pid_ = 1 << 18;  // Ensure unknown positive PID.
   EXPECT_CALL(*proxy_, Release(kDeviceName)).Times(1);
+  config_->proxy_.reset(proxy_.release());
   EXPECT_TRUE(config_->ReleaseIP());
   config_->pid_ = 0;
 }
@@ -200,6 +240,7 @@
 TEST_F(DHCPConfigTest, RenewIP) {
   config_->pid_ = 456;
   EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
+  config_->proxy_.reset(proxy_.release());
   EXPECT_TRUE(config_->RenewIP());
   config_->pid_ = 0;
 }
@@ -207,6 +248,7 @@
 TEST_F(DHCPConfigTest, RequestIP) {
   config_->pid_ = 567;
   EXPECT_CALL(*proxy_, Rebind(kDeviceName)).Times(1);
+  config_->proxy_.reset(proxy_.release());
   EXPECT_TRUE(config_->RenewIP());
   config_->pid_ = 0;
 }
@@ -287,7 +329,7 @@
   config_->Stop();
   config_->pid_ = kPID;
   config_->Stop();
-  EXPECT_CALL(glib_, SpawnClosePID(kPID)).Times(1);  // Invoked by destuctor.
+  EXPECT_CALL(glib_, SpawnClosePID(kPID)).Times(1);  // Invoked by destructor.
 }
 
 TEST_F(DHCPConfigTest, Dispatch) {
diff --git a/dhcp_provider.cc b/dhcp_provider.cc
index e17dbb3..b79a2b2 100644
--- a/dhcp_provider.cc
+++ b/dhcp_provider.cc
@@ -15,7 +15,10 @@
 
 namespace shill {
 
-DHCPProvider::DHCPProvider() : glib_(NULL) {
+DHCPProvider::DHCPProvider()
+    : control_interface_(NULL),
+      dispatcher_(NULL),
+      glib_(NULL) {
   VLOG(2) << __func__;
 }
 
@@ -27,17 +30,21 @@
   return Singleton<DHCPProvider>::get();
 }
 
-void DHCPProvider::Init(ControlInterface *control_interface, GLib *glib) {
+void DHCPProvider::Init(ControlInterface *control_interface,
+                        EventDispatcher *dispatcher,
+                        GLib *glib) {
   VLOG(2) << __func__;
   listener_.reset(
       new DHCPCDListener(ProxyFactory::factory()->connection(), this));
   glib_ = glib;
   control_interface_ = control_interface;
+  dispatcher_ = dispatcher;
 }
 
 DHCPConfigRefPtr DHCPProvider::CreateConfig(const string &device_name) {
   VLOG(2) << __func__ << " device: " << device_name;
-  return new DHCPConfig(control_interface_, this, device_name, glib_);
+  return new DHCPConfig(
+      control_interface_, dispatcher_, this, device_name, glib_);
 }
 
 DHCPConfigRefPtr DHCPProvider::GetConfig(int pid) {
diff --git a/dhcp_provider.h b/dhcp_provider.h
index 224a613..fd83029 100644
--- a/dhcp_provider.h
+++ b/dhcp_provider.h
@@ -18,6 +18,7 @@
 
 class ControlInterface;
 class DHCPCDListener;
+class EventDispatcher;
 class GLib;
 
 // DHCPProvider is a singleton providing the main DHCP configuration
@@ -34,7 +35,9 @@
   // Initializes the provider singleton. This method hooks up a D-Bus signal
   // listener that catches signals from spawned DHCP clients and dispatches them
   // to the appropriate DHCP configuration instance.
-  void Init(ControlInterface *control_interface, GLib *glib);
+  void Init(ControlInterface *control_interface,
+            EventDispatcher *dispatcher,
+            GLib *glib);
 
   // Creates a new DHCPConfig for |device_name|. The DHCP configuration for the
   // device can then be initiated through DHCPConfig::Request and
@@ -74,8 +77,9 @@
   // A map that binds PIDs to DHCP configuration instances.
   PIDConfigMap configs_;
 
-  GLib *glib_;
   ControlInterface *control_interface_;
+  EventDispatcher *dispatcher_;
+  GLib *glib_;
 
   DISALLOW_COPY_AND_ASSIGN(DHCPProvider);
 };
diff --git a/dhcpcd_proxy.cc b/dhcpcd_proxy.cc
index d77efb1..f1483e8 100644
--- a/dhcpcd_proxy.cc
+++ b/dhcpcd_proxy.cc
@@ -69,7 +69,7 @@
   config->InitProxy(signal.sender());
 }
 
-DHCPCDProxy::DHCPCDProxy(DBus::Connection *connection, const char *service)
+DHCPCDProxy::DHCPCDProxy(DBus::Connection *connection, const string &service)
     : proxy_(connection, service) {
   VLOG(2) << "DHCPCDProxy(service=" << service << ").";
 }
@@ -83,14 +83,16 @@
 }
 
 DHCPCDProxy::Proxy::Proxy(DBus::Connection *connection,
-                          const char *service)
-    : DBus::ObjectProxy(*connection, kDBusPath, service) {
+                          const string &service)
+    : DBus::ObjectProxy(*connection, kDBusPath, service.c_str()) {
   // Don't catch signals directly in this proxy because they will be dispatched
   // to the client by the DHCPCD listener.
   _signals.erase("Event");
   _signals.erase("StatusChanged");
 }
 
+DHCPCDProxy::Proxy::~Proxy() {}
+
 void DHCPCDProxy::Proxy::Event(const uint32_t &pid,
                                const std::string &reason,
                                const DHCPConfig::Configuration &configuration) {
diff --git a/dhcpcd_proxy.h b/dhcpcd_proxy.h
index d478d13..d639645 100644
--- a/dhcpcd_proxy.h
+++ b/dhcpcd_proxy.h
@@ -49,7 +49,7 @@
   static const char kDBusInterfaceName[];
   static const char kDBusPath[];
 
-  DHCPCDProxy(DBus::Connection *connection, const char *service);
+  DHCPCDProxy(DBus::Connection *connection, const std::string &service);
 
   // Inherited from DHCPProxyInterface.
   virtual void Rebind(const std::string &interface);
@@ -59,7 +59,8 @@
   class Proxy : public org::chromium::dhcpcd_proxy,
                 public DBus::ObjectProxy {
    public:
-    Proxy(DBus::Connection *connection, const char *service);
+    Proxy(DBus::Connection *connection, const std::string &service);
+    virtual ~Proxy();
 
    private:
     // Signal callbacks inherited from dhcpcd_proxy. Note that these callbacks
diff --git a/modem.cc b/modem.cc
index c557a5b..2d5b271 100644
--- a/modem.cc
+++ b/modem.cc
@@ -42,18 +42,23 @@
 void Modem::Init() {
   VLOG(2) << __func__;
   CHECK(!device_.get());
+
+  // Defer device creation because dbus-c++ doesn't allow registration of new
+  // D-Bus objects in the context of a D-Bus signal handler.
+  dispatcher_->PostTask(task_factory_.NewRunnableMethod(&Modem::InitTask));
+}
+
+void Modem::InitTask() {
+  VLOG(2) << __func__;
+  CHECK(!device_.get());
+
   dbus_properties_proxy_.reset(
       ProxyFactory::factory()->CreateDBusPropertiesProxy(this, path_, owner_));
 
   // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
   DBusPropertiesMap properties =
       dbus_properties_proxy_->GetAll(MM_MODEM_INTERFACE);
-
-  // Defer device creation because it may require the registration of new D-Bus
-  // objects and that can't be done in the context of a D-Bus signal handler.
-  dispatcher_->PostTask(
-      task_factory_.NewRunnableMethod(&Modem::CreateCellularDevice,
-                                      properties));
+  CreateCellularDevice(properties);
 }
 
 void Modem::CreateCellularDevice(const DBusPropertiesMap &properties) {
diff --git a/modem.h b/modem.h
index a51d875..e3e5f67 100644
--- a/modem.h
+++ b/modem.h
@@ -41,6 +41,8 @@
  private:
   friend class ModemManagerTest;
   friend class ModemTest;
+  FRIEND_TEST(ModemManagerTest, Connect);
+  FRIEND_TEST(ModemManagerTest, AddRemoveModem);
   FRIEND_TEST(ModemTest, CreateCellularDevice);
   FRIEND_TEST(ModemTest, Init);
 
@@ -50,6 +52,8 @@
   static const char kPropertyUnlockRequired[];
   static const char kPropertyUnlockRetries[];
 
+  void InitTask();
+
   // Creates and registers a Cellular device in |device_| based on
   // ModemManager.Modem's |properties|. The device may not be created if the
   // properties are invalid.
diff --git a/modem_manager_unittest.cc b/modem_manager_unittest.cc
index aa4961a..f7937b8 100644
--- a/modem_manager_unittest.cc
+++ b/modem_manager_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "shill/manager.h"
 #include "shill/mock_control.h"
-#include "shill/mock_dbus_properties_proxy.h"
 #include "shill/mock_glib.h"
 #include "shill/mock_modem_manager_proxy.h"
 #include "shill/modem.h"
@@ -34,7 +33,7 @@
                        &dispatcher_,
                        &manager_,
                        &glib_),
-        proxy_factory_(&proxy_, &dbus_properties_proxy_) {
+        proxy_factory_(&proxy_) {
     ProxyFactory::set_factory(&proxy_factory_);
   }
 
@@ -43,17 +42,8 @@
  protected:
   class TestProxyFactory : public ProxyFactory {
    public:
-    TestProxyFactory(ModemManagerProxyInterface *proxy,
-                     DBusPropertiesProxyInterface *dbus_properties_proxy)
-        : proxy_(proxy),
-          dbus_properties_proxy_(dbus_properties_proxy) {}
-
-    virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
-        Modem *modem,
-        const string &path,
-        const string &service) {
-      return dbus_properties_proxy_;
-    }
+    TestProxyFactory(ModemManagerProxyInterface *proxy)
+        : proxy_(proxy) {}
 
     virtual ModemManagerProxyInterface *CreateModemManagerProxy(
         ModemManager *manager,
@@ -64,7 +54,6 @@
 
    private:
     ModemManagerProxyInterface *proxy_;
-    DBusPropertiesProxyInterface *dbus_properties_proxy_;
   };
 
   static const char kService[];
@@ -72,15 +61,12 @@
   static const char kOwner[];
   static const char kModemPath[];
 
-  void ReleaseDBusPropertiesProxy();
-
   MockGLib glib_;
   MockControl control_interface_;
   EventDispatcher dispatcher_;
   Manager manager_;
   ModemManager modem_manager_;
   MockModemManagerProxy proxy_;
-  MockDBusPropertiesProxy dbus_properties_proxy_;
   TestProxyFactory proxy_factory_;
 };
 
@@ -93,22 +79,9 @@
   modem_manager_.watcher_id_ = 0;
   ModemManagerProxyInterface *proxy = modem_manager_.proxy_.release();
   EXPECT_TRUE(proxy == NULL || proxy == &proxy_);
-  ReleaseDBusPropertiesProxy();
   ProxyFactory::set_factory(NULL);
 }
 
-void ModemManagerTest::ReleaseDBusPropertiesProxy() {
-  if (modem_manager_.modems_.empty()) {
-    return;
-  }
-  EXPECT_EQ(1, modem_manager_.modems_.size());
-  ModemManager::Modems::iterator iter = modem_manager_.modems_.begin();
-  DBusPropertiesProxyInterface *dbus_properties_proxy =
-      iter->second->dbus_properties_proxy_.release();
-  EXPECT_TRUE(dbus_properties_proxy == NULL ||
-              dbus_properties_proxy == &dbus_properties_proxy_);
-}
-
 TEST_F(ModemManagerTest, Start) {
   const int kWatcher = 123;
   EXPECT_CALL(glib_, BusWatchName(G_BUS_TYPE_SYSTEM,
@@ -138,12 +111,11 @@
   EXPECT_EQ("", modem_manager_.owner_);
   EXPECT_CALL(proxy_, EnumerateDevices())
       .WillOnce(Return(vector<DBus::Path>(1, kModemPath)));
-  EXPECT_CALL(dbus_properties_proxy_, GetAll(MM_MODEM_INTERFACE))
-      .WillOnce(Return(DBusPropertiesMap()));
   modem_manager_.Connect(kOwner);
   EXPECT_EQ(kOwner, modem_manager_.owner_);
   EXPECT_EQ(1, modem_manager_.modems_.size());
-  EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
+  ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
+  EXPECT_FALSE(modem_manager_.modems_[kModemPath]->task_factory_.empty());
 }
 
 TEST_F(ModemManagerTest, Disconnect) {
@@ -168,13 +140,11 @@
 
 TEST_F(ModemManagerTest, AddRemoveModem) {
   modem_manager_.owner_ = kOwner;
-  EXPECT_CALL(dbus_properties_proxy_, GetAll(MM_MODEM_INTERFACE))
-      .WillOnce(Return(DBusPropertiesMap()));
   modem_manager_.AddModem(kModemPath);
   EXPECT_EQ(1, modem_manager_.modems_.size());
-  EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
+  ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
+  EXPECT_FALSE(modem_manager_.modems_[kModemPath]->task_factory_.empty());
 
-  ReleaseDBusPropertiesProxy();
   modem_manager_.RemoveModem(kModemPath);
   EXPECT_EQ(0, modem_manager_.modems_.size());
 }
diff --git a/proxy_factory.cc b/proxy_factory.cc
index a5633f9..6b87865 100644
--- a/proxy_factory.cc
+++ b/proxy_factory.cc
@@ -58,7 +58,7 @@
                                       dbus_addr);
 }
 
-DHCPProxyInterface *ProxyFactory::CreateDHCPProxy(const char *service) {
+DHCPProxyInterface *ProxyFactory::CreateDHCPProxy(const string &service) {
   return new DHCPCDProxy(connection(), service);
 }
 
diff --git a/proxy_factory.h b/proxy_factory.h
index 7d628c9..f3441ab 100644
--- a/proxy_factory.h
+++ b/proxy_factory.h
@@ -50,7 +50,7 @@
       const DBus::Path &object_path,
       const char *dbus_addr);
 
-  virtual DHCPProxyInterface *CreateDHCPProxy(const char *service);
+  virtual DHCPProxyInterface *CreateDHCPProxy(const std::string &service);
 
   static ProxyFactory *factory() { return factory_; }
   static void set_factory(ProxyFactory *factory) { factory_ = factory; }
diff --git a/shill_daemon.cc b/shill_daemon.cc
index ae2577f..f789186 100644
--- a/shill_daemon.cc
+++ b/shill_daemon.cc
@@ -2,36 +2,28 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <stdio.h>
-#include <glib.h>
+#include "shill/shill_daemon.h"
 
-#include <algorithm>
+#include <stdio.h>
+
 #include <string>
-#include <vector>
 
 #include <base/logging.h>
 
-#include "shill/shill_daemon.h"
-#include "shill/control_interface.h"
-#include "shill/dbus_control.h"
+#include "shill/dhcp_provider.h"
 #include "shill/rtnl_handler.h"
 
-using std::max;
-using std::min;
 using std::string;
-using std::vector;
 
 namespace shill {
 
-static const char kTaggedFilePath[] = "/var/lib/shill";
-
 // Daemon: Main for connection manager.  Starts main process and holds event
 // loop.
 
-Daemon::Daemon(Config *config, ControlInterface *control, GLib *glib)
-  : config_(config),
-    control_(control),
-    manager_(control_, &dispatcher_, glib) { }
+Daemon::Daemon(Config *config, ControlInterface *control)
+    : config_(config),
+      control_(control),
+      manager_(control_, &dispatcher_, &glib_) { }
 Daemon::~Daemon() {}
 
 void Daemon::AddDeviceToBlackList(const string &device_name) {
@@ -39,7 +31,11 @@
 }
 
 void Daemon::Start() {
+  glib_.TypeInit();
+  proxy_factory_.Init();
+  ProxyFactory::set_factory(&proxy_factory_);
   RTNLHandler::GetInstance()->Start(&dispatcher_, &sockets_);
+  DHCPProvider::GetInstance()->Init(control_, &dispatcher_, &glib_);
   manager_.Start();
 }
 
diff --git a/shill_daemon.h b/shill_daemon.h
index 17e687b..37906dd 100644
--- a/shill_daemon.h
+++ b/shill_daemon.h
@@ -7,7 +7,9 @@
 
 #include <string>
 
+#include "shill/glib.h"
 #include "shill/manager.h"
+#include "shill/proxy_factory.h"
 #include "shill/shill_event.h"
 #include "shill/sockets.h"
 
@@ -19,23 +21,24 @@
 
 class Daemon {
  public:
-  Daemon(Config *config, ControlInterface *control, GLib *glib);
+  Daemon(Config *config, ControlInterface *control);
   ~Daemon();
 
   void AddDeviceToBlackList(const std::string &device_name);
-  void Start();
   void Run();
 
  private:
   friend class ShillDaemonTest;
 
-  ControlInterface *CreateControl();
+  void Start();
 
   Config *config_;
   ControlInterface *control_;
   Manager manager_;
   EventDispatcher dispatcher_;
   Sockets sockets_;
+  GLib glib_;
+  ProxyFactory proxy_factory_;
 };
 
 }  // namespace shill
diff --git a/shill_main.cc b/shill_main.cc
index 03728b0..769669d 100644
--- a/shill_main.cc
+++ b/shill_main.cc
@@ -15,9 +15,6 @@
 #include <chromeos/syslog_logging.h>
 
 #include "shill/dbus_control.h"
-#include "shill/dhcp_provider.h"
-#include "shill/glib.h"
-#include "shill/proxy_factory.h"
 #include "shill/shill_config.h"
 #include "shill/shill_daemon.h"
 
@@ -105,16 +102,7 @@
   scoped_ptr<shill::DBusControl> dbus_control(new shill::DBusControl());
   dbus_control->Init();
 
-  shill::ProxyFactory proxy_factory;
-  proxy_factory.Init();
-  shill::ProxyFactory::set_factory(&proxy_factory);
-
-  shill::GLib glib;
-  glib.TypeInit();
-
-  shill::DHCPProvider::GetInstance()->Init(dbus_control.get(), &glib);
-
-  shill::Daemon daemon(&config, dbus_control.get(), &glib);
+  shill::Daemon daemon(&config, dbus_control.get());
 
   if (cl->HasSwitch(switches::kDeviceBlackList)) {
     vector<string> device_list;
diff --git a/shill_unittest.cc b/shill_unittest.cc
index c703b85..5d67369 100644
--- a/shill_unittest.cc
+++ b/shill_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include <stdint.h>
-#include <glib.h>
 
 #include <base/callback_old.h>
 #include <base/logging.h>
@@ -15,7 +14,6 @@
 
 #include "shill/io_handler.h"
 #include "shill/mock_control.h"
-#include "shill/mock_glib.h"
 #include "shill/shill_config.h"
 #include "shill/shill_daemon.h"
 
@@ -111,7 +109,7 @@
 class ShillDaemonTest : public Test {
  public:
   ShillDaemonTest()
-      : daemon_(&config_, new MockControl(), &glib_),
+      : daemon_(&config_, new MockControl()),
         device_info_(daemon_.control_, dispatcher_, &daemon_.manager_),
         dispatcher_(&daemon_.dispatcher_),
         dispatcher_test_(dispatcher_),
@@ -125,7 +123,6 @@
   }
  protected:
   Config config_;
-  MockGLib glib_;
   Daemon daemon_;
   DeviceInfo device_info_;
   EventDispatcher *dispatcher_;