1 // Copyright 2015 The Weave 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 #ifndef LIBWEAVE_SRC_COMMANDS_CLOUD_COMMAND_PROXY_H_ 6 #define LIBWEAVE_SRC_COMMANDS_CLOUD_COMMAND_PROXY_H_ 7 8 #include <deque> 9 #include <memory> 10 #include <string> 11 #include <utility> 12 13 #include <base/macros.h> 14 #include <base/memory/weak_ptr.h> 15 #include <base/scoped_observer.h> 16 #include <weave/command.h> 17 18 #include "src/backoff_entry.h" 19 #include "src/commands/cloud_command_update_interface.h" 20 #include "src/commands/command_instance.h" 21 #include "src/component_manager.h" 22 23 namespace weave { 24 25 class CommandInstance; 26 27 namespace provider { 28 class TaskRunner; 29 } 30 31 // Command proxy which publishes command updates to the cloud. 32 class CloudCommandProxy : public CommandInstance::Observer { 33 public: 34 CloudCommandProxy(CommandInstance* command_instance, 35 CloudCommandUpdateInterface* cloud_command_updater, 36 ComponentManager* component_manager, 37 std::unique_ptr<BackoffEntry> backoff_entry, 38 provider::TaskRunner* task_runner); 39 ~CloudCommandProxy() override = default; 40 41 // CommandProxyInterface implementation/overloads. 42 void OnCommandDestroyed() override; 43 void OnErrorChanged() override; 44 void OnProgressChanged() override; 45 void OnResultsChanged() override; 46 void OnStateChanged() override; 47 48 private: 49 using UpdateQueueEntry = std::pair<ComponentManager::UpdateID, 50 std::unique_ptr<base::DictionaryValue>>; 51 // Puts a command update data into the update queue, and optionally sends an 52 // asynchronous request to GCD server to update the command resource, if there 53 // are no pending device status updates. 54 void QueueCommandUpdate(std::unique_ptr<base::DictionaryValue> patch); 55 56 // Sends an asynchronous request to GCD server to update the command resource, 57 // if there are no pending device status updates. 58 void SendCommandUpdate(); 59 60 // Retry the last failed command update request to the server. 61 void ResendCommandUpdate(); 62 63 // Callback invoked by the asynchronous PATCH request to the server. 64 void OnUpdateCommandDone(ErrorPtr error); 65 66 // Callback invoked by the device state change queue to notify of the 67 // successful device state update. |update_id| is the ID of the state that 68 // has been updated on the server. 69 void OnDeviceStateUpdated(ComponentManager::UpdateID update_id); 70 71 CommandInstance* command_instance_; 72 CloudCommandUpdateInterface* cloud_command_updater_; 73 ComponentManager* component_manager_; 74 provider::TaskRunner* task_runner_{nullptr}; 75 76 // Backoff for SendCommandUpdate() method. 77 std::unique_ptr<BackoffEntry> cloud_backoff_entry_; 78 79 // Set to true while a pending PATCH request is in flight to the server. 80 bool command_update_in_progress_{false}; 81 // Update queue with all the command update requests ready to be sent to 82 // the server. 83 std::deque<UpdateQueueEntry> update_queue_; 84 85 // Callback token from the state change queue for OnDeviceStateUpdated() 86 // callback for ask the device state change queue to call when the state 87 // is updated on the server. 88 ComponentManager::Token callback_token_; 89 90 // Last device state update ID that has been sent out to the server 91 // successfully. 92 ComponentManager::UpdateID last_state_update_id_{0}; 93 94 ScopedObserver<CommandInstance, CommandInstance::Observer> observer_{this}; 95 96 base::WeakPtrFactory<CloudCommandProxy> backoff_weak_ptr_factory_{this}; 97 base::WeakPtrFactory<CloudCommandProxy> weak_ptr_factory_{this}; 98 DISALLOW_COPY_AND_ASSIGN(CloudCommandProxy); 99 }; 100 101 } // namespace weave 102 103 #endif // LIBWEAVE_SRC_COMMANDS_CLOUD_COMMAND_PROXY_H_ 104