buffet: StartDevice automatically after a short delay

BUG=brillo:15
TEST=buffet_Registration confirms that we StartDevice
automatically shortly after registering.

Change-Id: I6c903e67f0556c7db817e126c72711f7d781592d
Reviewed-on: https://chromium-review.googlesource.com/249441
Tested-by: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index 31fb7b6..abe130b 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include <base/bind.h>
 #include <base/json/json_writer.h>
 #include <base/message_loop/message_loop.h>
 #include <base/values.h>
@@ -238,6 +239,17 @@
   return storage_->Save(&dict);
 }
 
+void DeviceRegistrationInfo::ScheduleStartDevice(const base::TimeDelta& later) {
+  base::MessageLoop* current = base::MessageLoop::current();
+  if (!current)
+    return;  // Assume we're in unittests
+  current->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&DeviceRegistrationInfo::StartDevice,
+                 weak_factory_.GetWeakPtr(), nullptr),
+      later);
+}
+
 bool DeviceRegistrationInfo::CheckRegistration(chromeos::ErrorPtr* error) {
   LOG(INFO) << "Checking device registration record.";
   if (refresh_token_.empty() ||
@@ -447,6 +459,10 @@
                              base::TimeDelta::FromSeconds(expires_in);
 
   Save();
+
+  // We're going to respond with our success immediately and we'll StartDevice
+  // shortly after.
+  ScheduleStartDevice(base::TimeDelta::FromSeconds(0));
   return device_id_;
 }
 
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h
index 4c9cfaa..31cc508 100644
--- a/buffet/device_registration_info.h
+++ b/buffet/device_registration_info.h
@@ -12,6 +12,7 @@
 
 #include <base/callback.h>
 #include <base/macros.h>
+#include <base/memory/weak_ptr.h>
 #include <base/time/time.h>
 #include <chromeos/data_encoding.h>
 #include <chromeos/errors/error.h>
@@ -89,6 +90,9 @@
   // Loads the device registration information from cache.
   bool Load();
 
+  // Cause DeviceRegistrationInfo to attempt to StartDevice on its own later.
+  void ScheduleStartDevice(const base::TimeDelta& later);
+
   // Checks for the valid device registration as well as refreshes
   // the device access token, if available.
   bool CheckRegistration(chromeos::ErrorPtr* error);
@@ -207,6 +211,7 @@
   std::unique_ptr<chromeos::KeyValueStore> config_store_;
 
   friend class TestHelper;
+  base::WeakPtrFactory<DeviceRegistrationInfo> weak_factory_{this};
   DISALLOW_COPY_AND_ASSIGN(DeviceRegistrationInfo);
 };
 
diff --git a/buffet/manager.cc b/buffet/manager.cc
index cbb2fad..a1457c4 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -11,6 +11,7 @@
 #include <base/bind_helpers.h>
 #include <base/json/json_reader.h>
 #include <base/json/json_writer.h>
+#include <base/time/time.h>
 #include <chromeos/dbus/async_event_sequencer.h>
 #include <chromeos/dbus/exported_object_manager.h>
 #include <chromeos/errors/error.h>
@@ -68,6 +69,13 @@
                                  chromeos::http::Transport::CreateDefault(),
                                  std::move(state_store)));
   device_info_->Load();
+  // Wait a significant amount of time for local daemons to publish their
+  // state to Buffet before publishing it to the cloud.
+  // TODO(wiley) We could do a lot of things here to either expose this
+  //             timeout as a configurable knob or allow local
+  //             daemons to signal that their state is up to date so that
+  //             we need not wait for them.
+  device_info_->ScheduleStartDevice(base::TimeDelta::FromSeconds(5));
   dbus_adaptor_.RegisterWithDBusObject(&dbus_object_);
   dbus_object_.RegisterAsync(cb);
 }