buffet: Implement command polling.

Now we periodically fetch the queue of commands to run
and publish them via CommandManager.

BUG=chromium:420604
TEST=cros_workon_make buffet --test&&manual

Change-Id: Idfa22145fcfa8d38ab44c1a65cfc5a4469d7c4e1
Reviewed-on: https://chromium-review.googlesource.com/225910
Commit-Queue: Anton Muhin <antonm@chromium.org>
Tested-by: Anton Muhin <antonm@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index 330b515..d4cee76 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -711,11 +711,40 @@
 }
 
 void DeviceRegistrationInfo::PeriodicallyPollCommands() {
-  auto delay = base::TimeDelta::FromSeconds(7);
-  PostRepeatingTask(FROM_HERE, base::Bind([]{
-    VLOG(1) << "Poll commands";
-    // TODO(antonm): Implement real polling of commands.
-  }), delay);
+  VLOG(1) << "Poll commands";
+  PostRepeatingTask(
+      FROM_HERE,
+      base::Bind(
+          &DeviceRegistrationInfo::FetchCommands,
+          base::Unretained(this),
+          base::Bind(&DeviceRegistrationInfo::PublishCommands,
+                     base::Unretained(this))),
+      base::TimeDelta::FromSeconds(7));
+}
+
+void DeviceRegistrationInfo::PublishCommands(const base::ListValue& commands) {
+  const CommandDictionary& command_dictionary =
+      command_manager_->GetCommandDictionary();
+
+  const size_t size{commands.GetSize()};
+  for (size_t i = 0; i < size; ++i) {
+    const base::DictionaryValue* command{nullptr};
+    if (!commands.GetDictionary(i, &command)) {
+      LOG(WARNING) << "No command resource at " << i;
+      continue;
+    }
+
+    std::unique_ptr<CommandInstance> command_instance =
+        CommandInstance::FromJson(command, command_dictionary, nullptr);
+    if (!command_instance) {
+      LOG(WARNING) << "Failed to parse a command";
+      continue;
+    }
+
+    // TODO(antonm): Double check if there is a chance to publish
+    // the same command twice if it doesn't change its status.
+    command_manager_->AddCommand(std::move(command_instance));
+  }
 }
 
 }  // namespace buffet
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h
index c683e37..c9b6335 100644
--- a/buffet/device_registration_info.h
+++ b/buffet/device_registration_info.h
@@ -145,6 +145,8 @@
 
   void PeriodicallyPollCommands();
 
+  void PublishCommands(const base::ListValue& commands);
+
   // Builds Cloud API devices collection REST resouce which matches
   // current state of the device including command definitions
   // for all supported commands and current device state.