update_engine: Migrate UE DBus service to chrome DBus bindings.

chromeos-dbus-bindings now generates the adaptor interface that
update_engine exposes over DBus. This interface is implemented in
dbus_service.{h,cc}, which now has a UpdateEngineService class
encapsulating all the service methods implementation.

This allows to write unit test for those methods, which are included
in this CL for all the non-trivial methods.

This CL now uses chrome's DBus bindings for the update_engine serive,
but the proxy interaction is still done using dbus-glib. The main loop
in the main.cc file is now replaced with the chromeos::Dameon, which
uses a chromeos::BaseMessageLoop instead of a GlibMessageLoop. This
causes the asynchronous interactions in the proxy side to not work,
which will be fixed in the next CL.

CQ-DEPEND=CL:290990,CL:291092,CL:293334
BUG=chromium:419827
TEST=Added unittest for all dbus_service methods. deployed and tested manually that update_engine dbus interface works.

Change-Id: I6a6d142b2ac1a61a4c3abcb927665b26114abe5c
Reviewed-on: https://chromium-review.googlesource.com/225324
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
diff --git a/daemon.cc b/daemon.cc
new file mode 100644
index 0000000..bc221b5
--- /dev/null
+++ b/daemon.cc
@@ -0,0 +1,137 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/daemon.h"
+
+#include <sysexits.h>
+
+#include <base/bind.h>
+#include <base/location.h>
+#include <base/time/time.h>
+#include <chromeos/message_loops/message_loop.h>
+
+#include "update_engine/clock.h"
+#include "update_engine/update_attempter.h"
+
+using chromeos::MessageLoop;
+
+namespace {
+const int kDBusSystemMaxWaitSeconds = 2 * 60;
+}  // namespace
+
+namespace chromeos_update_engine {
+
+namespace {
+// Wait for passed |bus| DBus to be connected by attempting to connect it up to
+// |timeout| time. Returns whether the Connect() eventually succeeded.
+bool WaitForDBusSystem(dbus::Bus* bus, base::TimeDelta timeout) {
+  Clock clock;
+  base::Time deadline = clock.GetMonotonicTime() + timeout;
+
+  while (clock.GetMonotonicTime() < deadline) {
+    if (bus->Connect())
+      return true;
+    LOG(WARNING) << "Failed to get system bus, waiting.";
+    // Wait 1 second.
+    sleep(1);
+  }
+  LOG(ERROR) << "Failed to get system bus after " << timeout.InSeconds()
+             << " seconds.";
+  return false;
+}
+}  // namespace
+
+int UpdateEngineDaemon::OnInit() {
+  // Register the |subprocess_| singleton with this Daemon as the signal
+  // handler.
+  subprocess_.Init(this);
+
+  // We use Daemon::OnInit() and not DBusDaemon::OnInit() to gracefully wait for
+  // the D-Bus connection for up two minutes to avoid re-spawning the daemon
+  // too fast causing thrashing if dbus-daemon is not running.
+  int exit_code = Daemon::OnInit();
+  if (exit_code != EX_OK)
+    return exit_code;
+
+  dbus::Bus::Options options;
+  options.bus_type = dbus::Bus::SYSTEM;
+  bus_ = new dbus::Bus(options);
+
+  // Wait for DBus to be ready and exit if it doesn't become available after
+  // the timeout.
+  if (!WaitForDBusSystem(
+          bus_.get(),
+          base::TimeDelta::FromSeconds(kDBusSystemMaxWaitSeconds))) {
+    // TODO(deymo): Make it possible to run update_engine even if dbus-daemon
+    // is not running or constantly crashing.
+    LOG(ERROR) << "Failed to initialize DBus, aborting.";
+    return 1;
+  }
+
+  CHECK(bus_->SetUpAsyncOperations());
+
+  // Initialize update engine global state but continue if something fails.
+  real_system_state_.reset(new RealSystemState(bus_));
+  LOG_IF(ERROR, !real_system_state_->Initialize())
+      << "Failed to initialize system state.";
+  UpdateAttempter* update_attempter = real_system_state_->update_attempter();
+  CHECK(update_attempter);
+
+  // Sets static members for the certificate checker.
+  CertificateChecker::set_system_state(real_system_state_.get());
+  CertificateChecker::set_openssl_wrapper(&openssl_wrapper_);
+
+  // Create the DBus service.
+  dbus_adaptor_.reset(new UpdateEngineAdaptor(real_system_state_.get(), bus_));
+  update_attempter->set_dbus_adaptor(dbus_adaptor_.get());
+
+  dbus_adaptor_->RegisterAsync(base::Bind(&UpdateEngineDaemon::OnDBusRegistered,
+                                          base::Unretained(this)));
+  LOG(INFO) << "Waiting for DBus object to be registered.";
+  return EX_OK;
+}
+
+void UpdateEngineDaemon::OnDBusRegistered(bool succeeded) {
+  if (!succeeded) {
+    LOG(ERROR) << "Registering the UpdateEngineAdaptor";
+    QuitWithExitCode(1);
+    return;
+  }
+
+  // Take ownership of the service now that everything is initialized. We need
+  // to this now and not before to avoid exposing a well known DBus service
+  // path that doesn't have the service it is supposed to implement.
+  if (!dbus_adaptor_->RequestOwnership()) {
+    LOG(ERROR) << "Unable to take ownership of the DBus service, is there "
+               << "other update_engine daemon running?";
+    QuitWithExitCode(1);
+    return;
+  }
+
+  // Initiate update checks.
+  UpdateAttempter* update_attempter = real_system_state_->update_attempter();
+  update_attempter->ScheduleUpdates();
+
+  // Update boot flags after 45 seconds.
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&UpdateAttempter::UpdateBootFlags,
+                 base::Unretained(update_attempter)),
+      base::TimeDelta::FromSeconds(45));
+
+  // Broadcast the update engine status on startup to ensure consistent system
+  // state on crashes.
+  MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+      &UpdateAttempter::BroadcastStatus,
+      base::Unretained(update_attempter)));
+
+  // Run the UpdateEngineStarted() method on |update_attempter|.
+  MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+      &UpdateAttempter::UpdateEngineStarted,
+      base::Unretained(update_attempter)));
+
+  LOG(INFO) << "Finished initialization. Now running the loop.";
+}
+
+}  // namespace chromeos_update_engine