buffet: Publish state updates. This is very simple implementation which periodically publishes all the state updates if any. It should be improved to reduce traffic/CPU consumption, see TODO. BUG=chromium:434767 TEST=manual&&cros_workon_make --test buffet CQ-DEPEND=CL:231035 Change-Id: I5f1e001c4407373381f0e0f864c1973369955422 Reviewed-on: https://chromium-review.googlesource.com/231024 Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Anton Muhin <antonm@chromium.org> Tested-by: Anton Muhin <antonm@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc index b36f114..25c6ee1 100644 --- a/buffet/device_registration_info.cc +++ b/buffet/device_registration_info.cc
@@ -153,7 +153,7 @@ DeviceRegistrationInfo::DeviceRegistrationInfo( const std::shared_ptr<CommandManager>& command_manager, - const std::shared_ptr<const StateManager>& state_manager) + const std::shared_ptr<StateManager>& state_manager) : DeviceRegistrationInfo( command_manager, state_manager, @@ -165,7 +165,7 @@ DeviceRegistrationInfo::DeviceRegistrationInfo( const std::shared_ptr<CommandManager>& command_manager, - const std::shared_ptr<const StateManager>& state_manager, + const std::shared_ptr<StateManager>& state_manager, const std::shared_ptr<chromeos::http::Transport>& transport, const std::shared_ptr<StorageInterface>& storage) : transport_{transport}, @@ -748,6 +748,14 @@ base::Bind(&DeviceRegistrationInfo::PublishCommands, base::Unretained(this))), base::TimeDelta::FromSeconds(7)); + // TODO(antonm): Use better trigger: when StateManager registers new updates, + // it should call closure which will post a task, probabluy with some + // throtlling, to publish state updates. + PostRepeatingTask( + FROM_HERE, + base::Bind(&DeviceRegistrationInfo::PublishStateUpdates, + base::Unretained(this)), + base::TimeDelta::FromSeconds(7)); } void DeviceRegistrationInfo::PublishCommands(const base::ListValue& commands) { @@ -779,4 +787,42 @@ } } +void DeviceRegistrationInfo::PublishStateUpdates() { + VLOG(1) << "PublishStateUpdates"; + const std::vector<StateChange> state_changes{ + state_manager_->GetAndClearRecordedStateChanges()}; + if (state_changes.empty()) + return; + + std::unique_ptr<base::ListValue> patches{new base::ListValue}; + for (const auto& state_change : state_changes) { + std::unique_ptr<base::DictionaryValue> patch{new base::DictionaryValue}; + // TODO(antonm): Weird part: API requires long here while there is no + // such thing like long in JSON. Also, ToJavaTime produces int64. + patch->SetInteger("timeMs", state_change.timestamp.ToJavaTime()); + + std::unique_ptr<base::DictionaryValue> changes{new base::DictionaryValue}; + for (const auto& pair : state_change.changed_properties) { + auto value = pair.second->ToJson(nullptr); + if (!value) { + return; + } + changes->SetWithoutPathExpansion(pair.first, value.release()); + } + patch->Set("patch", changes.release()); + + patches->Append(patch.release()); + } + + base::DictionaryValue body; + body.SetInteger("requestTimeMs", base::Time::Now().ToJavaTime()); + body.Set("patches", patches.release()); + + DoCloudRequest( + chromeos::http::request_type::kPost, + GetDeviceURL("patchState"), + &body, + base::Bind(&IgnoreCloudResult), base::Bind(&IgnoreCloudError)); +} + } // namespace buffet
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h index 7fb09f1..fad4dfd 100644 --- a/buffet/device_registration_info.h +++ b/buffet/device_registration_info.h
@@ -40,12 +40,12 @@ // This constructor uses CURL HTTP transport. DeviceRegistrationInfo( const std::shared_ptr<CommandManager>& command_manager, - const std::shared_ptr<const StateManager>& state_manager); + const std::shared_ptr<StateManager>& state_manager); // This constructor allows to pass in a custom HTTP transport // (mainly for testing). DeviceRegistrationInfo( const std::shared_ptr<CommandManager>& command_manager, - const std::shared_ptr<const StateManager>& state_manager, + const std::shared_ptr<StateManager>& state_manager, const std::shared_ptr<chromeos::http::Transport>& transport, const std::shared_ptr<StorageInterface>& storage); @@ -153,6 +153,8 @@ void PublishCommands(const base::ListValue& commands); + void PublishStateUpdates(); + // 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. @@ -186,7 +188,7 @@ // Global command manager. std::shared_ptr<CommandManager> command_manager_; // Device state manager. - std::shared_ptr<const StateManager> state_manager_; + std::shared_ptr<StateManager> state_manager_; friend class TestHelper; DISALLOW_COPY_AND_ASSIGN(DeviceRegistrationInfo);