buffet: Implement exponential backoff for cloud requests

Simplified logic of DoCloudRequest() method in buffet to de-couple
the multiple levels of callbacks and retries. Also added support for
exponential backoff on request failures.

In the process made RefreshAccessToken and GetDeviceInfo methods
fully asynchronous.

BUG=brillo:955
TEST=`FEATURES=test emerge-link buffet`
     `test_that -b link 100.96.49.59 e:buffet_.*`

Change-Id: Ieeb2fa42ea25f15841bad5c6c09c6c9990f96943
Reviewed-on: https://chromium-review.googlesource.com/280833
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 6921f47..bcb5cd6 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -126,7 +126,8 @@
     privet_->OnShutdown();
 }
 
-void Manager::CheckDeviceRegistered(DBusMethodResponse<std::string> response) {
+void Manager::CheckDeviceRegistered(
+    DBusMethodResponsePtr<std::string> response) {
   LOG(INFO) << "Received call to Manager.CheckDeviceRegistered()";
   chromeos::ErrorPtr error;
   bool registered = device_info_->HaveRegistrationCredentials(&error);
@@ -142,23 +143,34 @@
                               : std::string());
 }
 
-void Manager::GetDeviceInfo(DBusMethodResponse<std::string> response) {
+void Manager::GetDeviceInfo(DBusMethodResponsePtr<std::string> response) {
   LOG(INFO) << "Received call to Manager.GetDeviceInfo()";
+  std::shared_ptr<DBusMethodResponse<std::string>> shared_response =
+      std::move(response);
 
-  chromeos::ErrorPtr error;
-  auto device_info = device_info_->GetDeviceInfo(&error);
-  if (!device_info) {
-    response->ReplyWithError(error.get());
-    return;
-  }
+  device_info_->GetDeviceInfo(
+      base::Bind(&Manager::OnGetDeviceInfoSuccess,
+                 weak_ptr_factory_.GetWeakPtr(), shared_response),
+      base::Bind(&Manager::OnGetDeviceInfoError,
+                 weak_ptr_factory_.GetWeakPtr(), shared_response));
+}
 
+void Manager::OnGetDeviceInfoSuccess(
+    const std::shared_ptr<DBusMethodResponse<std::string>>& response,
+    const base::DictionaryValue& device_info) {
   std::string device_info_str;
   base::JSONWriter::WriteWithOptions(
-      *device_info, base::JSONWriter::OPTIONS_PRETTY_PRINT, &device_info_str);
+      device_info, base::JSONWriter::OPTIONS_PRETTY_PRINT, &device_info_str);
   response->Return(device_info_str);
 }
 
-void Manager::RegisterDevice(DBusMethodResponse<std::string> response,
+void Manager::OnGetDeviceInfoError(
+    const std::shared_ptr<DBusMethodResponse<std::string>>& response,
+    const chromeos::Error* error) {
+  response->ReplyWithError(error);
+}
+
+void Manager::RegisterDevice(DBusMethodResponsePtr<std::string> response,
                              const std::string& ticket_id) {
   LOG(INFO) << "Received call to Manager.RegisterDevice()";
 
@@ -177,7 +189,7 @@
   response->ReplyWithError(error.get());
 }
 
-void Manager::UpdateState(DBusMethodResponse<> response,
+void Manager::UpdateState(DBusMethodResponsePtr<> response,
                           const chromeos::VariantDictionary& property_set) {
   chromeos::ErrorPtr error;
   if (!state_manager_->SetProperties(property_set, &error))
@@ -195,7 +207,7 @@
   return true;
 }
 
-void Manager::AddCommand(DBusMethodResponse<std::string> response,
+void Manager::AddCommand(DBusMethodResponsePtr<std::string> response,
                          const std::string& json_command,
                          const std::string& in_user_role) {
   std::string error_message;
@@ -222,7 +234,7 @@
   response->Return(id);
 }
 
-void Manager::GetCommand(DBusMethodResponse<std::string> response,
+void Manager::GetCommand(DBusMethodResponsePtr<std::string> response,
                          const std::string& id) {
   const CommandInstance* command = command_manager_->FindCommand(id);
   if (!command) {
@@ -236,10 +248,9 @@
   response->Return(command_str);
 }
 
-void Manager::SetCommandVisibility(
-    std::unique_ptr<chromeos::dbus_utils::DBusMethodResponse<>> response,
-    const std::vector<std::string>& in_names,
-    const std::string& in_visibility) {
+void Manager::SetCommandVisibility(DBusMethodResponsePtr<> response,
+                                   const std::vector<std::string>& in_names,
+                                   const std::string& in_visibility) {
   CommandDefinition::Visibility visibility;
   chromeos::ErrorPtr error;
   if (!visibility.FromString(in_visibility, &error)) {