Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 1 | // Copyright 2014 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "buffet/commands/cloud_command_proxy.h" |
| 6 | |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 7 | #include <base/message_loop/message_loop.h> |
| 8 | |
Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 9 | #include "buffet/commands/command_instance.h" |
| 10 | #include "buffet/commands/prop_constraints.h" |
| 11 | #include "buffet/commands/prop_types.h" |
Vitaly Buka | 906d39e | 2015-03-24 10:08:26 -0700 | [diff] [blame] | 12 | #include "buffet/commands/schema_constants.h" |
Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 13 | #include "buffet/device_registration_info.h" |
| 14 | |
| 15 | namespace buffet { |
| 16 | |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 17 | namespace { |
| 18 | // Bits used in CommandUpdateFlags for various command resource parts. |
| 19 | enum { |
| 20 | kFlagResults, |
| 21 | kFlagState, |
| 22 | kFlagProgress |
| 23 | }; |
| 24 | |
| 25 | // Retry timeout for re-sending failed command update request. |
| 26 | static const int64_t kCommandUpdateRetryTimeoutSeconds = 5; |
| 27 | |
| 28 | } // anonymous namespace |
| 29 | |
Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 30 | CloudCommandProxy::CloudCommandProxy( |
| 31 | CommandInstance* command_instance, |
| 32 | DeviceRegistrationInfo* device_registration_info) |
| 33 | : command_instance_(command_instance), |
| 34 | device_registration_info_(device_registration_info) { |
| 35 | } |
| 36 | |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 37 | void CloudCommandProxy::OnResultsChanged() { |
| 38 | new_pending_command_updates_.set(kFlagResults); |
| 39 | SendCommandUpdate(); |
Anton Muhin | cfde869 | 2014-11-25 03:36:59 +0400 | [diff] [blame] | 40 | } |
| 41 | |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 42 | void CloudCommandProxy::OnStatusChanged() { |
| 43 | new_pending_command_updates_.set(kFlagState); |
| 44 | SendCommandUpdate(); |
Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 45 | } |
| 46 | |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 47 | void CloudCommandProxy::OnProgressChanged() { |
| 48 | new_pending_command_updates_.set(kFlagProgress); |
| 49 | SendCommandUpdate(); |
| 50 | } |
| 51 | |
| 52 | void CloudCommandProxy::SendCommandUpdate() { |
| 53 | if (command_update_in_progress_ || new_pending_command_updates_.none()) |
| 54 | return; |
| 55 | |
Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 56 | base::DictionaryValue patch; |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 57 | if (new_pending_command_updates_.test(kFlagResults)) { |
| 58 | auto json = TypedValueToJson(command_instance_->GetResults(), nullptr); |
| 59 | patch.Set(commands::attributes::kCommand_Results, json.release()); |
| 60 | } |
| 61 | |
| 62 | if (new_pending_command_updates_.test(kFlagState)) { |
| 63 | patch.SetString(commands::attributes::kCommand_State, |
| 64 | command_instance_->GetStatus()); |
| 65 | } |
| 66 | |
| 67 | if (new_pending_command_updates_.test(kFlagProgress)) { |
Vitaly Buka | 4129dfa | 2015-04-29 12:16:58 -0700 | [diff] [blame^] | 68 | auto json = TypedValueToJson(command_instance_->GetProgress(), nullptr); |
| 69 | patch.Set(commands::attributes::kCommand_Progress, json.release()); |
Alex Vakulenko | b211c10 | 2015-04-21 11:43:23 -0700 | [diff] [blame] | 70 | } |
| 71 | command_update_in_progress_ = true; |
| 72 | in_progress_command_updates_ = new_pending_command_updates_; |
| 73 | new_pending_command_updates_.reset(); |
| 74 | device_registration_info_->UpdateCommand( |
| 75 | command_instance_->GetID(), patch, |
| 76 | base::Bind(&CloudCommandProxy::OnUpdateCommandFinished, |
| 77 | weak_ptr_factory_.GetWeakPtr(), true), |
| 78 | base::Bind(&CloudCommandProxy::OnUpdateCommandFinished, |
| 79 | weak_ptr_factory_.GetWeakPtr(), false)); |
| 80 | } |
| 81 | |
| 82 | void CloudCommandProxy::ResendCommandUpdate() { |
| 83 | command_update_in_progress_ = false; |
| 84 | SendCommandUpdate(); |
| 85 | } |
| 86 | |
| 87 | void CloudCommandProxy::OnUpdateCommandFinished(bool success) { |
| 88 | if (success) { |
| 89 | command_update_in_progress_ = false; |
| 90 | // If previous update was successful, and we have new pending updates, |
| 91 | // send a new request to the server immediately. |
| 92 | SendCommandUpdate(); |
| 93 | } else { |
| 94 | // If previous request failed, re-send the old data as well. |
| 95 | new_pending_command_updates_ |= in_progress_command_updates_; |
| 96 | auto message_loop = base::MessageLoop::current(); |
| 97 | if (message_loop == nullptr) { |
| 98 | // Assume we are in unit tests, resend the request immediately... |
| 99 | ResendCommandUpdate(); |
| 100 | } else { |
| 101 | // Resend the request to the server after a pre-set delay... |
| 102 | message_loop->PostDelayedTask( |
| 103 | FROM_HERE, |
| 104 | base::Bind(&CloudCommandProxy::ResendCommandUpdate, |
| 105 | weak_ptr_factory_.GetWeakPtr()), |
| 106 | base::TimeDelta::FromSeconds(kCommandUpdateRetryTimeoutSeconds)); |
| 107 | } |
| 108 | } |
Anton Muhin | 5975552 | 2014-11-05 21:30:12 +0400 | [diff] [blame] | 109 | } |
| 110 | |
| 111 | } // namespace buffet |