shill: stop using ChromeosDBusDaemon
am: 646c7e8917

* commit '646c7e891789ea8abadd9e88bdd625d8bea2536d':
  shill: stop using ChromeosDBusDaemon
diff --git a/Android.mk b/Android.mk
index 2b53070..6c4a6de 100644
--- a/Android.mk
+++ b/Android.mk
@@ -208,7 +208,6 @@
     crypto_util_proxy.cc \
     dbus/chromeos_dbus_adaptor.cc \
     dbus/chromeos_dbus_control.cc \
-    dbus/chromeos_dbus_daemon.cc \
     dbus/chromeos_dbus_service_watcher.cc \
     dbus/chromeos_device_dbus_adaptor.cc \
     dbus/chromeos_dhcpcd_listener.cc \
diff --git a/chromeos_daemon.cc b/chromeos_daemon.cc
index 90a38c2..6acf8b8 100644
--- a/chromeos_daemon.cc
+++ b/chromeos_daemon.cc
@@ -17,6 +17,7 @@
 #include "shill/chromeos_daemon.h"
 
 #include <string>
+#include <sysexits.h>
 
 #include <base/bind.h>
 
@@ -26,9 +27,11 @@
 #endif
 
 #include "shill/control_interface.h"
+#if defined(ENABLE_CHROMEOS_DBUS)
+#include "shill/dbus/chromeos_dbus_control.h"
+#endif  // ENABLE_CHROMEOS_DBUS
 #include "shill/dhcp/dhcp_provider.h"
 #include "shill/error.h"
-#include "shill/event_dispatcher.h"
 #include "shill/logging.h"
 #include "shill/manager.h"
 #include "shill/net/ndisc.h"
@@ -55,34 +58,15 @@
 }
 
 
-ChromeosDaemon::ChromeosDaemon(const Settings& settings,
+ChromeosDaemon::ChromeosDaemon(const base::Closure& startup_callback,
+                               const Settings& settings,
                                Config* config)
-    : settings_(settings), config_(config) {}
+    : settings_(settings),
+      config_(config),
+      startup_callback_(startup_callback) {}
 
 ChromeosDaemon::~ChromeosDaemon() {}
 
-void ChromeosDaemon::Init(ControlInterface* control,
-                          EventDispatcher* dispatcher) {
-  control_.reset(control);
-  dispatcher_ = dispatcher;
-  metrics_.reset(new Metrics(dispatcher_));
-  rtnl_handler_ = RTNLHandler::GetInstance();
-  routing_table_ = RoutingTable::GetInstance();
-  dhcp_provider_ = DHCPProvider::GetInstance();
-  process_manager_ = ProcessManager::GetInstance();
-#if !defined(DISABLE_WIFI)
-  netlink_manager_ = NetlinkManager::GetInstance();
-  callback80211_metrics_.reset(new Callback80211Metrics(metrics_.get()));
-#endif  // DISABLE_WIFI
-  manager_.reset(new Manager(control_.get(),
-                             dispatcher_,
-                             metrics_.get(),
-                             config_->GetRunDirectory(),
-                             config_->GetStorageDirectory(),
-                             config_->GetUserStorageDirectory()));
-  ApplySettings();
-}
-
 void ChromeosDaemon::ApplySettings() {
   manager_->SetBlacklistedDevices(settings_.device_blacklist);
   Error error;
@@ -163,8 +147,8 @@
       RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
       RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE | RTMGRP_ND_USEROPT);
   routing_table_->Start();
-  dhcp_provider_->Init(control_.get(), dispatcher_, metrics_.get());
-  process_manager_->Init(dispatcher_);
+  dhcp_provider_->Init(control_.get(), dispatcher_.get(), metrics_.get());
+  process_manager_->Init(dispatcher_.get());
 #if !defined(DISABLE_WIFI)
   if (netlink_manager_) {
     netlink_manager_->Init();
@@ -188,6 +172,62 @@
   manager_->Start();
 }
 
+int ChromeosDaemon::OnInit() {
+  // Manager DBus interface will get registered as part of this init call.
+  int return_code = brillo::Daemon::OnInit();
+  if (return_code != EX_OK) {
+    return return_code;
+  }
+
+  dispatcher_.reset(new EventDispatcher());
+#if defined(ENABLE_CHROMEOS_DBUS)
+  control_.reset(new ChromeosDBusControl(dispatcher_.get()));
+#else
+  // TODO(zqiu): use default stub control interface.
+#error Control interface type not specified.
+#endif  // ENABLE_CHROMEOS_DBUS
+  metrics_.reset(new Metrics(dispatcher_.get()));
+  rtnl_handler_ = RTNLHandler::GetInstance();
+  routing_table_ = RoutingTable::GetInstance();
+  dhcp_provider_ = DHCPProvider::GetInstance();
+  process_manager_ = ProcessManager::GetInstance();
+#if !defined(DISABLE_WIFI)
+  netlink_manager_ = NetlinkManager::GetInstance();
+  callback80211_metrics_.reset(new Callback80211Metrics(metrics_.get()));
+#endif  // DISABLE_WIFI
+  manager_.reset(new Manager(control_.get(),
+                             dispatcher_.get(),
+                             metrics_.get(),
+                             config_->GetRunDirectory(),
+                             config_->GetStorageDirectory(),
+                             config_->GetUserStorageDirectory()));
+  control_->RegisterManagerObject(
+      manager_.get(),
+      base::Bind(&ChromeosDaemon::Start, base::Unretained(this)));
+  ApplySettings();
+
+  // Signal that we've acquired all resources.
+  startup_callback_.Run();
+
+  return EX_OK;
+}
+
+void ChromeosDaemon::OnShutdown(int* return_code) {
+  if (!Quit(base::Bind(&ChromeosDaemon::BreakTerminationLoop,
+                       base::Unretained(this)))) {
+    // Run a message loop to allow shill to complete its termination
+    // procedures. This is different from the secondary loop in
+    // brillo::Daemon. This loop will run until we explicitly
+    // breakout of the loop, whereas the secondary loop in
+    // brillo::Daemon will run until no more tasks are posted on the
+    // loop.  This allows asynchronous D-Bus method calls to complete
+    // before exiting.
+    brillo::MessageLoop::current()->Run();
+  }
+
+  brillo::Daemon::OnShutdown(return_code);
+}
+
 void ChromeosDaemon::Stop() {
   manager_->Stop();
   manager_ = nullptr;  // Release manager resources, including DBus adaptor.
@@ -202,4 +242,10 @@
   // have some work left to do. See crbug.com/537771.
 }
 
+void ChromeosDaemon::BreakTerminationLoop() {
+  // Break out of the termination loop, to continue on with other shutdown
+  // tasks.
+  brillo::MessageLoop::current()->BreakLoop();
+}
+
 }  // namespace shill
diff --git a/chromeos_daemon.h b/chromeos_daemon.h
index 029a928..98775bd 100644
--- a/chromeos_daemon.h
+++ b/chromeos_daemon.h
@@ -22,7 +22,9 @@
 #include <vector>
 
 #include <base/callback.h>
+#include <brillo/daemons/daemon.h>
 
+#include "shill/event_dispatcher.h"
 #if !defined(DISABLE_WIFI)
 #include "shill/wifi/callback80211_metrics.h"
 #endif  // DISABLE_WIFI
@@ -33,7 +35,6 @@
 class ControlInterface;
 class DHCPProvider;
 class Error;
-class EventDispatcher;
 class Manager;
 class Metrics;
 class ProcessManager;
@@ -45,7 +46,7 @@
 #endif  // DISABLE_WIFI
 
 
-class ChromeosDaemon {
+class ChromeosDaemon : public brillo::Daemon {
  public:
   // Run-time settings retrieved from command line.
   struct Settings {
@@ -66,13 +67,11 @@
     bool use_portal_list;
   };
 
-  ChromeosDaemon(const Settings& settings,
+  ChromeosDaemon(const base::Closure& startup_callback,
+                 const Settings& settings,
                  Config* config);
   virtual ~ChromeosDaemon();
 
-  // Runs the message loop.
-  virtual void RunMessageLoop() = 0;
-
   // Starts the termination actions in the manager. Returns true if
   // termination actions have completed synchronously, and false
   // otherwise. Arranges for |completion_callback| to be invoked after
@@ -81,13 +80,14 @@
   virtual bool Quit(const base::Closure& completion_callback);
 
  protected:
-  // Initialize daemon with specific control interface.
-  void Init(ControlInterface* control, EventDispatcher* dispatcher);
-
   Manager* manager() const { return manager_.get(); }
 
   void Start();
 
+  // Implementation of brillo::Daemon.
+  int OnInit() override;
+  void OnShutdown(int* return_code) override;
+
  private:
   friend class ChromeosDaemonTest;
   friend class ChromeosDaemonForTest;
@@ -104,10 +104,14 @@
 
   void Stop();
 
+  // Break the termination loop started in ChromeosDaemon::OnShutdown. Invoked
+  // after shill completes its termination tasks during shutdown.
+  void BreakTerminationLoop();
+
   Settings settings_;
   Config* config_;
+  std::unique_ptr<EventDispatcher> dispatcher_;
   std::unique_ptr<ControlInterface> control_;
-  EventDispatcher* dispatcher_;
   std::unique_ptr<Metrics> metrics_;
   RTNLHandler* rtnl_handler_;
   RoutingTable* routing_table_;
@@ -119,6 +123,7 @@
 #endif  // DISABLE_WIFI
   std::unique_ptr<Manager> manager_;
   base::Closure termination_completed_callback_;
+  base::Closure startup_callback_;
 };
 
 }  // namespace shill
diff --git a/chromeos_daemon_unittest.cc b/chromeos_daemon_unittest.cc
index ff1966a..985ac61 100644
--- a/chromeos_daemon_unittest.cc
+++ b/chromeos_daemon_unittest.cc
@@ -41,6 +41,7 @@
 #if !defined(DISABLE_WIFI)
 #include "shill/net/mock_netlink_manager.h"
 #include "shill/net/nl80211_message.h"
+#include "shill/wifi/callback80211_metrics.h"
 #endif  // DISABLE_WIFI
 
 using base::Bind;
@@ -60,16 +61,15 @@
 class ChromeosDaemonForTest : public ChromeosDaemon {
  public:
   ChromeosDaemonForTest(const Settings& setttings,
-                        Config* config,
-                        EventDispatcher* dispatcher)
-      : ChromeosDaemon(Settings(), config) {
-    Init(new MockControl(), dispatcher);
-  }
+                        Config* config)
+      : ChromeosDaemon(base::Closure(),
+                       Settings(),
+                       config) {}
   virtual ~ChromeosDaemonForTest() {}
 
   bool quit_result() { return quit_result_; }
 
-  void RunMessageLoop() override { dispatcher_->DispatchForever(); }
+  void RunMessageLoop() { dispatcher_->DispatchForever(); }
 
   bool Quit(const base::Closure& completion_callback) override {
     quit_result_ = ChromeosDaemon::Quit(completion_callback);
@@ -84,14 +84,19 @@
 class ChromeosDaemonTest : public Test {
  public:
   ChromeosDaemonTest()
-      : daemon_(ChromeosDaemon::Settings(), &config_, &dispatcher_),
-        metrics_(new MockMetrics(daemon_.dispatcher_)),
-        manager_(new MockManager(daemon_.control_.get(),
-                                 daemon_.dispatcher_,
+      : daemon_(ChromeosDaemon::Settings(),
+                &config_),
+        dispatcher_(new EventDispatcherForTest()),
+        control_(new MockControl()),
+        metrics_(new MockMetrics(dispatcher_)),
+        callback_metrics_(new Callback80211Metrics(metrics_)),
+        manager_(new MockManager(control_,
+                                 dispatcher_,
                                  metrics_)),
-        device_info_(daemon_.control_.get(), daemon_.dispatcher_,
-                     metrics_, manager_) {
-  }
+        device_info_(control_,
+                     dispatcher_,
+                     metrics_,
+                     manager_) {}
   virtual ~ChromeosDaemonTest() {}
   virtual void SetUp() {
     // Tests initialization done by the daemon's constructor
@@ -102,6 +107,10 @@
     daemon_.process_manager_ = &process_manager_;
     daemon_.metrics_.reset(metrics_);  // Passes ownership
     daemon_.manager_.reset(manager_);  // Passes ownership
+    daemon_.control_.reset(control_);  // Passes ownership
+    daemon_.dispatcher_.reset(dispatcher_);  // Passes ownership
+    // Passes ownership
+    daemon_.callback80211_metrics_.reset(callback_metrics_);
 
 #if !defined(DISABLE_WIFI)
     daemon_.netlink_manager_ = &netlink_manager_;
@@ -125,17 +134,19 @@
   }
 
   MOCK_METHOD0(TerminationAction, void());
-  MOCK_METHOD0(TerminationCompleted, void());
+  MOCK_METHOD0(BreakTerminationLoop, void());
 
  protected:
-  EventDispatcherForTest dispatcher_;
   TestConfig config_;
   ChromeosDaemonForTest daemon_;
   MockRTNLHandler rtnl_handler_;
   MockRoutingTable routing_table_;
   MockDHCPProvider dhcp_provider_;
   MockProcessManager process_manager_;
+  EventDispatcherForTest* dispatcher_;
+  MockControl* control_;
   MockMetrics* metrics_;
+  Callback80211Metrics* callback_metrics_;
   MockManager* manager_;
 #if !defined(DISABLE_WIFI)
   MockNetlinkManager netlink_manager_;
@@ -186,17 +197,17 @@
   // This expectation verifies that the termination actions are invoked.
   EXPECT_CALL(*this, TerminationAction())
       .WillOnce(CompleteAction(manager_, "daemon test"));
-  EXPECT_CALL(*this, TerminationCompleted()).Times(1);
+  EXPECT_CALL(*this, BreakTerminationLoop()).Times(1);
 
   manager_->AddTerminationAction("daemon test",
                                  Bind(&ChromeosDaemonTest::TerminationAction,
                                       Unretained(this)));
 
   // Run Daemon::Quit() after the daemon starts running.
-  dispatcher_.PostTask(
+  dispatcher_->PostTask(
       Bind(IgnoreResult(&ChromeosDaemon::Quit),
            Unretained(&daemon_),
-           Bind(&ChromeosDaemonTest::TerminationCompleted,
+           Bind(&ChromeosDaemonTest::BreakTerminationLoop,
                 Unretained(this))));
 
   RunDaemon();
@@ -204,9 +215,9 @@
 }
 
 TEST_F(ChromeosDaemonTest, QuitWithoutTerminationActions) {
-  EXPECT_CALL(*this, TerminationCompleted()).Times(0);
+  EXPECT_CALL(*this, BreakTerminationLoop()).Times(0);
   EXPECT_TRUE(daemon_.Quit(
-      Bind(&ChromeosDaemonTest::TerminationCompleted,
+      Bind(&ChromeosDaemonTest::BreakTerminationLoop,
            Unretained(this))));
 }
 
diff --git a/control_interface.h b/control_interface.h
index ec9705e..31c7286 100644
--- a/control_interface.h
+++ b/control_interface.h
@@ -91,6 +91,8 @@
 class ControlInterface {
  public:
   virtual ~ControlInterface() {}
+  virtual void RegisterManagerObject(
+      Manager* manager, const base::Closure& registration_done_callback) = 0;
   virtual DeviceAdaptorInterface* CreateDeviceAdaptor(Device* device) = 0;
   virtual IPConfigAdaptorInterface* CreateIPConfigAdaptor(
       IPConfig* ipconfig) = 0;
diff --git a/dbus/chromeos_dbus_control.cc b/dbus/chromeos_dbus_control.cc
index f4c3d34..e97e2be 100644
--- a/dbus/chromeos_dbus_control.cc
+++ b/dbus/chromeos_dbus_control.cc
@@ -16,6 +16,14 @@
 
 #include "shill/dbus/chromeos_dbus_control.h"
 
+#include <brillo/dbus/async_event_sequencer.h>
+
+#if defined(__ANDROID__)
+#include <dbus/service_constants.h>
+#else
+#include <chromeos/dbus/service_constants.h>
+#endif  // __ANDROID__
+
 #include "shill/dbus/chromeos_device_dbus_adaptor.h"
 #include "shill/dbus/chromeos_ipconfig_dbus_adaptor.h"
 #include "shill/dbus/chromeos_manager_dbus_adaptor.h"
@@ -70,7 +78,9 @@
 #include "shill/dbus/chromeos_wimax_network_proxy.h"
 #endif  // DISABLE_WIMAX
 
-using brillo::dbus_utils::ExportedObjectManager;
+#include "shill/manager.h"
+
+using brillo::dbus_utils::AsyncEventSequencer;
 using std::string;
 
 namespace shill {
@@ -78,20 +88,22 @@
 // static.
 const char ChromeosDBusControl::kNullPath[] = "/";
 
-ChromeosDBusControl::ChromeosDBusControl(
-    const scoped_refptr<dbus::Bus>& bus,
-    EventDispatcher* dispatcher)
-    : adaptor_bus_(bus),
-      dispatcher_(dispatcher),
+ChromeosDBusControl::ChromeosDBusControl(EventDispatcher* dispatcher)
+    : dispatcher_(dispatcher),
       null_identifier_(kNullPath) {
   dbus::Bus::Options options;
   options.bus_type = dbus::Bus::SYSTEM;
 
+  adaptor_bus_ = new dbus::Bus(options);
   proxy_bus_ = new dbus::Bus(options);
+  CHECK(adaptor_bus_->Connect());
   CHECK(proxy_bus_->Connect());
 }
 
 ChromeosDBusControl::~ChromeosDBusControl() {
+  if (adaptor_bus_) {
+    adaptor_bus_->ShutdownAndBlock();
+  }
   if (proxy_bus_) {
     proxy_bus_->ShutdownAndBlock();
   }
@@ -101,11 +113,46 @@
   return null_identifier_;
 }
 
+void ChromeosDBusControl::RegisterManagerObject(
+    Manager* manager, const base::Closure& registration_done_callback) {
+  registration_done_callback_ = registration_done_callback;
+  scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
+  manager->RegisterAsync(
+      base::Bind(
+          &ChromeosDBusControl::OnDBusServiceRegistered,
+          base::Unretained(this),
+          sequencer->GetHandler("Manager.RegisterAsync() failed.", true)));
+  sequencer->OnAllTasksCompletedCall({
+      base::Bind(&ChromeosDBusControl::TakeServiceOwnership,
+                 base::Unretained(this))
+  });
+}
+
 template <typename Object, typename AdaptorInterface, typename Adaptor>
 AdaptorInterface* ChromeosDBusControl::CreateAdaptor(Object* object) {
   return new Adaptor(adaptor_bus_, object);
 }
 
+void ChromeosDBusControl::OnDBusServiceRegistered(
+    const base::Callback<void(bool)>& completion_action, bool success) {
+  // The DBus control interface will take over the ownership of the DBus service
+  // in this callback.  The daemon will crash if registration failed.
+  completion_action.Run(success);
+
+  // We can start the manager now that we have ownership of the D-Bus service.
+  // Doing so earlier would allow the manager to emit signals before service
+  // ownership was acquired.
+  registration_done_callback_.Run();
+}
+
+void ChromeosDBusControl::TakeServiceOwnership(bool success) {
+  // Success should always be true since we've said that failures are fatal.
+  CHECK(success) << "Init of one or more objects has failed.";
+  CHECK(adaptor_bus_->RequestOwnershipAndBlock(kFlimflamServiceName,
+                                       dbus::Bus::REQUIRE_PRIMARY))
+      << "Unable to take ownership of " << kFlimflamServiceName;
+}
+
 DeviceAdaptorInterface* ChromeosDBusControl::CreateDeviceAdaptor(
     Device* device) {
   return
diff --git a/dbus/chromeos_dbus_control.h b/dbus/chromeos_dbus_control.h
index 3dc6075..d71eafd 100644
--- a/dbus/chromeos_dbus_control.h
+++ b/dbus/chromeos_dbus_control.h
@@ -27,14 +27,17 @@
 namespace shill {
 
 class EventDispatcher;
+class Manager;
 
 // This is the Interface for the  DBus control channel for Shill.
 class ChromeosDBusControl : public ControlInterface {
  public:
-  ChromeosDBusControl(const scoped_refptr<dbus::Bus>& bus,
-                      EventDispatcher* dispatcher);
+  ChromeosDBusControl(EventDispatcher* dispatcher);
   ~ChromeosDBusControl() override;
 
+  void RegisterManagerObject(
+      Manager* manager,
+      const base::Closure& registration_done_callback) override;
   DeviceAdaptorInterface* CreateDeviceAdaptor(Device* device) override;
   IPConfigAdaptorInterface* CreateIPConfigAdaptor(IPConfig* ipconfig) override;
   ManagerAdaptorInterface* CreateManagerAdaptor(Manager* manager) override;
@@ -165,6 +168,10 @@
   template <typename Object, typename AdaptorInterface, typename Adaptor>
   AdaptorInterface* CreateAdaptor(Object* object);
 
+  void OnDBusServiceRegistered(
+      const base::Callback<void(bool)>& completion_action, bool success);
+  void TakeServiceOwnership(bool success);
+
   static const char kNullPath[];
 
   // Use separate bus connection for adaptors and proxies.  This allows the
@@ -174,6 +181,7 @@
   scoped_refptr<dbus::Bus> proxy_bus_;
   EventDispatcher* dispatcher_;
   std::string null_identifier_;
+  base::Closure registration_done_callback_;
 };
 
 }  // namespace shill
diff --git a/dbus/chromeos_dbus_daemon.cc b/dbus/chromeos_dbus_daemon.cc
deleted file mode 100644
index 1e8a266..0000000
--- a/dbus/chromeos_dbus_daemon.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "shill/dbus/chromeos_dbus_daemon.h"
-
-#include <sysexits.h>
-
-#if defined(__ANDROID__)
-#include <dbus/service_constants.h>
-#else
-#include <chromeos/dbus/service_constants.h>
-#endif  // __ANDROID__
-
-#include "shill/dbus/chromeos_dbus_control.h"
-#include "shill/manager.h"
-
-namespace shill {
-
-// TODO(zqiu): ObjectManager is not being exported as of now. To export
-// ObjectManager, initialize DBusServiceDaemon with a valid path.
-ChromeosDBusDaemon::ChromeosDBusDaemon(const base::Closure& startup_callback,
-                                       const Settings& settings,
-                                       Config* config)
-    : DBusServiceDaemon(kFlimflamServiceName, ""),
-      ChromeosDaemon(settings, config),
-      startup_callback_(startup_callback) {}
-
-void ChromeosDBusDaemon::RunMessageLoop() {
-  DBusServiceDaemon::Run();
-}
-
-int ChromeosDBusDaemon::OnInit() {
-  // Manager DBus interface will get registered as part of this init call.
-  int return_code = brillo::DBusServiceDaemon::OnInit();
-  if (return_code != EX_OK) {
-    return return_code;
-  }
-
-  // Signal that we've acquired all resources.
-  startup_callback_.Run();
-
-  return EX_OK;
-}
-
-void ChromeosDBusDaemon::OnShutdown(int* return_code) {
-  if (!ChromeosDaemon::Quit(
-          base::Bind(&ChromeosDBusDaemon::OnTerminationCompleted,
-                     base::Unretained(this)))) {
-    // Run a message loop to allow shill to complete its termination
-    // procedures. This is different from the secondary loop in
-    // brillo::Daemon. This loop will run until we explicitly
-    // breakout of the loop, whereas the secondary loop in
-    // brillo::Daemon will run until no more tasks are posted on the
-    // loop.  This allows asynchronous D-Bus method calls to complete
-    // before exiting.
-    brillo::MessageLoop::current()->Run();
-  }
-
-  brillo::DBusServiceDaemon::OnShutdown(return_code);
-}
-
-void ChromeosDBusDaemon::RegisterDBusObjectsAsync(
-    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
-  // Put the Init call here instead of the constructor so that
-  // ChromeosDBusControl initialization is performed after the |bus_| is
-  // initialized.
-  // |bus_| is initialized in brillo::DBusServiceDaemon::OnInit()
-  Init(new ChromeosDBusControl(bus_, &dispatcher_), &dispatcher_);
-
-  // Register "org.chromium.flimflam.Manager" interface.
-  // The daemon will request the ownership of the DBus service
-  // "org.chromium.flimflam" after Manager interface registration is
-  // completed.
-  manager()->RegisterAsync(
-      base::Bind(
-          &ChromeosDBusDaemon::OnDBusServiceRegistered,
-          base::Unretained(this),
-          sequencer->GetHandler("Manager.RegisterAsync() failed.", true)));
-}
-
-void ChromeosDBusDaemon::OnDBusServiceRegistered(
-    const base::Callback<void(bool)>& completion_action, bool success) {
-  // The daemon will take over the ownership of the DBus service in this
-  // callback.  The daemon will crash if registration failed.
-  completion_action.Run(success);
-
-  // We can start the manager now that we have ownership of the D-Bus service.
-  // Doing so earlier would allow the manager to emit signals before service
-  // ownership was acquired.
-  ChromeosDaemon::Start();
-}
-
-void ChromeosDBusDaemon::OnTerminationCompleted() {
-  // Break out of the termination loop, to continue on with other shutdown
-  // tasks.
-  brillo::MessageLoop::current()->BreakLoop();
-}
-
-}  // namespace shill
diff --git a/dbus/chromeos_dbus_daemon.h b/dbus/chromeos_dbus_daemon.h
deleted file mode 100644
index b9b41e9..0000000
--- a/dbus/chromeos_dbus_daemon.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef SHILL_DBUS_CHROMEOS_DBUS_DAEMON_H_
-#define SHILL_DBUS_CHROMEOS_DBUS_DAEMON_H_
-
-#include <base/callback.h>
-#include <brillo/daemons/dbus_daemon.h>
-
-#include "shill/chromeos_daemon.h"
-#include "shill/event_dispatcher.h"
-
-namespace shill {
-
-class ChromeosDBusDaemon : public brillo::DBusServiceDaemon,
-                           public ChromeosDaemon {
- public:
-  ChromeosDBusDaemon(const base::Closure& startup_callback,
-                     const Settings& settings,
-                     Config* config);
-  ~ChromeosDBusDaemon() = default;
-
-  // Implementation of ChromeosDaemon.
-  void RunMessageLoop() override;
-
- protected:
-  // Implementation of brillo::DBusServiceDaemon.
-  int OnInit() override;
-  void OnShutdown(int* return_code) override;
-  void RegisterDBusObjectsAsync(
-      brillo::dbus_utils::AsyncEventSequencer* sequencer) override;
-
- private:
-  // Invoked when DBus service is registered with the bus.  This function will
-  // request the ownership for our DBus service.
-  void OnDBusServiceRegistered(
-      const base::Callback<void(bool)>& completion_action,
-      bool success);
-
-  // Invoke when shill completes its termination tasks during shutdown.
-  void OnTerminationCompleted();
-
-  EventDispatcher dispatcher_;
-  base::Closure startup_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(ChromeosDBusDaemon);
-};
-
-}  // namespace shill
-
-#endif  // SHILL_DBUS_CHROMEOS_DBUS_DAEMON_H_
diff --git a/mock_control.h b/mock_control.h
index 839bbb0..9d40185 100644
--- a/mock_control.h
+++ b/mock_control.h
@@ -32,6 +32,10 @@
   MockControl();
   ~MockControl() override;
 
+  void RegisterManagerObject(
+      Manager* manager,
+      const base::Closure& registration_done_callback) override {};
+
   // Each of these can be called once.  Ownership of the appropriate
   // interface pointer is given up upon call.
   DeviceAdaptorInterface* CreateDeviceAdaptor(Device* device) override;
diff --git a/nice_mock_control.h b/nice_mock_control.h
index 573616b..d8e365f 100644
--- a/nice_mock_control.h
+++ b/nice_mock_control.h
@@ -32,6 +32,10 @@
   NiceMockControl();
   ~NiceMockControl() override;
 
+  void RegisterManagerObject(
+      Manager* manager,
+      const base::Closure& registration_done_callback) override {};
+
   // Each of these can be called once.  Ownership of the appropriate
   // interface pointer is given up upon call.
   DeviceAdaptorInterface* CreateDeviceAdaptor(Device* device) override;
diff --git a/shill.gyp b/shill.gyp
index 59e3fb7..8e1364f 100644
--- a/shill.gyp
+++ b/shill.gyp
@@ -455,7 +455,6 @@
         'crypto_util_proxy.cc',
         'dbus/chromeos_dbus_adaptor.cc',
         'dbus/chromeos_dbus_control.cc',
-        'dbus/chromeos_dbus_daemon.cc',
         'dbus/chromeos_dbus_service_watcher.cc',
         'dbus/chromeos_device_dbus_adaptor.cc',
         'dbus/chromeos_dhcpcd_listener.cc',
diff --git a/shill_main.cc b/shill_main.cc
index 53cca85..f0a7e1d 100644
--- a/shill_main.cc
+++ b/shill_main.cc
@@ -35,10 +35,6 @@
 #include "shill/shill_config.h"
 #include "shill/technology.h"
 
-#if defined(ENABLE_CHROMEOS_DBUS)
-#include "shill/dbus/chromeos_dbus_daemon.h"
-#endif  // ENABLE_CHROMEOS_DBUS
-
 using base::FilePath;
 using std::string;
 using std::vector;
@@ -238,18 +234,9 @@
 
   shill::Config config;
 
-  std::unique_ptr<shill::ChromeosDaemon> daemon;
-
-#if defined(ENABLE_CHROMEOS_DBUS)
-  daemon.reset(
-      new shill::ChromeosDBusDaemon(
-          base::Bind(&OnStartup, argv[0], cl), settings, &config));
-#else
-  // TODO(zqiu): use default stub control interface.
-#error Control interface type not specified.
-#endif  // ENABLE_CHROMEOS_DBUS
-
-  daemon->RunMessageLoop();
+  shill::ChromeosDaemon daemon(base::Bind(&OnStartup, argv[0], cl), settings,
+                               &config);
+  daemon.Run();
 
   LOG(INFO) << "Process exiting.";