Vitaly Buka | 4615e0d | 2015-10-14 15:35:12 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Weave Authors. All rights reserved. |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 5 | #include "src/privet/cloud_delegate.h" |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 6 | |
| 7 | #include <map> |
| 8 | #include <vector> |
| 9 | |
| 10 | #include <base/bind.h> |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 11 | #include <base/logging.h> |
| 12 | #include <base/memory/weak_ptr.h> |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 13 | #include <base/values.h> |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 14 | #include <weave/error.h> |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 15 | #include <weave/provider/task_runner.h> |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 16 | |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 17 | #include "src/backoff_entry.h" |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 18 | #include "src/component_manager.h" |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 19 | #include "src/config.h" |
| 20 | #include "src/device_registration_info.h" |
| 21 | #include "src/privet/constants.h" |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 22 | |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 23 | namespace weave { |
| 24 | namespace privet { |
| 25 | |
| 26 | namespace { |
| 27 | |
Vitaly Buka | 4ebd329 | 2015-09-23 18:04:17 -0700 | [diff] [blame] | 28 | const BackoffEntry::Policy register_backoff_policy = {0, 1000, 2.0, 0.2, |
| 29 | 5000, -1, false}; |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 30 | |
| 31 | const int kMaxDeviceRegistrationTimeMinutes = 5; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 32 | |
Vitaly Buka | ef213d7 | 2015-10-07 15:54:58 -0700 | [diff] [blame] | 33 | CommandInstance* ReturnNotFound(const std::string& command_id, |
| 34 | ErrorPtr* error) { |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 35 | Error::AddToPrintf(error, FROM_HERE, errors::kDomain, errors::kNotFound, |
| 36 | "Command not found, ID='%s'", command_id.c_str()); |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 37 | return nullptr; |
| 38 | } |
| 39 | |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 40 | class CloudDelegateImpl : public CloudDelegate { |
| 41 | public: |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 42 | CloudDelegateImpl(provider::TaskRunner* task_runner, |
Vitaly Buka | f9630fb | 2015-08-12 21:15:40 -0700 | [diff] [blame] | 43 | DeviceRegistrationInfo* device, |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 44 | ComponentManager* component_manager) |
Vitaly Buka | f9630fb | 2015-08-12 21:15:40 -0700 | [diff] [blame] | 45 | : task_runner_{task_runner}, |
| 46 | device_{device}, |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 47 | component_manager_{component_manager} { |
Vitaly Buka | ae6b35d | 2015-09-29 23:16:54 -0700 | [diff] [blame] | 48 | device_->GetMutableConfig()->AddOnChangedCallback(base::Bind( |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 49 | &CloudDelegateImpl::OnConfigChanged, weak_factory_.GetWeakPtr())); |
Vitaly Buka | c3c6dab | 2015-10-01 19:41:02 -0700 | [diff] [blame] | 50 | device_->AddGcdStateChangedCallback(base::Bind( |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 51 | &CloudDelegateImpl::OnRegistrationChanged, weak_factory_.GetWeakPtr())); |
| 52 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 53 | component_manager_->AddTraitDefChangedCallback(base::Bind( |
| 54 | &CloudDelegateImpl::NotifyOnTraitDefsChanged, |
| 55 | weak_factory_.GetWeakPtr())); |
| 56 | component_manager_->AddCommandAddedCallback(base::Bind( |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 57 | &CloudDelegateImpl::OnCommandAdded, weak_factory_.GetWeakPtr())); |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 58 | component_manager_->AddCommandRemovedCallback(base::Bind( |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 59 | &CloudDelegateImpl::OnCommandRemoved, weak_factory_.GetWeakPtr())); |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 60 | component_manager_->AddStateChangedCallback(base::Bind( |
Alex Vakulenko | 551a82b | 2015-12-07 14:46:12 -0800 | [diff] [blame] | 61 | &CloudDelegateImpl::NotifyOnStateChanged, |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 62 | weak_factory_.GetWeakPtr())); |
| 63 | component_manager_->AddComponentTreeChangedCallback(base::Bind( |
| 64 | &CloudDelegateImpl::NotifyOnComponentTreeChanged, |
| 65 | weak_factory_.GetWeakPtr())); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | ~CloudDelegateImpl() override = default; |
| 69 | |
Johan Euphrosine | 0b7bb9f | 2015-09-29 01:11:21 -0700 | [diff] [blame] | 70 | std::string GetDeviceId() const override { |
| 71 | return device_->GetSettings().device_id; |
| 72 | } |
| 73 | |
Vitaly Buka | 658aa36 | 2015-09-15 20:59:12 -0700 | [diff] [blame] | 74 | std::string GetModelId() const override { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 75 | CHECK_EQ(5u, device_->GetSettings().model_id.size()); |
| 76 | return device_->GetSettings().model_id; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 77 | } |
| 78 | |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 79 | std::string GetName() const override { return device_->GetSettings().name; } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 80 | |
| 81 | std::string GetDescription() const override { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 82 | return device_->GetSettings().description; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | std::string GetLocation() const override { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 86 | return device_->GetSettings().location; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 87 | } |
| 88 | |
| 89 | void UpdateDeviceInfo(const std::string& name, |
| 90 | const std::string& description, |
Vitaly Buka | b624bc4 | 2015-09-29 19:13:55 -0700 | [diff] [blame] | 91 | const std::string& location) override { |
| 92 | device_->UpdateDeviceInfo(name, description, location); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | std::string GetOemName() const override { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 96 | return device_->GetSettings().oem_name; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 97 | } |
| 98 | |
| 99 | std::string GetModelName() const override { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 100 | return device_->GetSettings().model_name; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 101 | } |
| 102 | |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 103 | AuthScope GetAnonymousMaxScope() const override { |
Vitaly Buka | b624bc4 | 2015-09-29 19:13:55 -0700 | [diff] [blame] | 104 | return device_->GetSettings().local_anonymous_access_role; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | const ConnectionState& GetConnectionState() const override { |
| 108 | return connection_state_; |
| 109 | } |
| 110 | |
| 111 | const SetupState& GetSetupState() const override { return setup_state_; } |
| 112 | |
| 113 | bool Setup(const std::string& ticket_id, |
| 114 | const std::string& user, |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 115 | ErrorPtr* error) override { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 116 | if (setup_state_.IsStatusEqual(SetupState::kInProgress)) { |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 117 | Error::AddTo(error, FROM_HERE, errors::kDomain, errors::kDeviceBusy, |
| 118 | "Setup in progress"); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 119 | return false; |
| 120 | } |
| 121 | VLOG(1) << "GCD Setup started. ticket_id: " << ticket_id |
| 122 | << ", user:" << user; |
| 123 | setup_state_ = SetupState(SetupState::kInProgress); |
| 124 | setup_weak_factory_.InvalidateWeakPtrs(); |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 125 | backoff_entry_.Reset(); |
| 126 | base::Time deadline = base::Time::Now(); |
| 127 | deadline += base::TimeDelta::FromMinutes(kMaxDeviceRegistrationTimeMinutes); |
Vitaly Buka | f9630fb | 2015-08-12 21:15:40 -0700 | [diff] [blame] | 128 | task_runner_->PostDelayedTask( |
Vitaly Buka | 4ebd329 | 2015-09-23 18:04:17 -0700 | [diff] [blame] | 129 | FROM_HERE, |
| 130 | base::Bind(&CloudDelegateImpl::CallManagerRegisterDevice, |
| 131 | setup_weak_factory_.GetWeakPtr(), ticket_id, deadline), |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 132 | {}); |
| 133 | // Return true because we initiated setup. |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 134 | return true; |
| 135 | } |
| 136 | |
| 137 | std::string GetCloudId() const override { |
Vitaly Buka | 1c522d8 | 2015-11-23 13:01:06 -0800 | [diff] [blame] | 138 | return connection_state_.status() > ConnectionState::kUnconfigured |
| 139 | ? device_->GetSettings().cloud_id |
| 140 | : ""; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 141 | } |
| 142 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 143 | const base::DictionaryValue& GetLegacyCommandDef() const override { |
| 144 | return component_manager_->GetLegacyCommandDefinitions(); |
| 145 | } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 146 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 147 | const base::DictionaryValue& GetLegacyState() const override { |
| 148 | return component_manager_->GetLegacyState(); |
| 149 | } |
| 150 | |
| 151 | const base::DictionaryValue& GetComponents() const override { |
| 152 | return component_manager_->GetComponents(); |
| 153 | } |
| 154 | |
| 155 | const base::DictionaryValue& GetTraits() const override { |
| 156 | return component_manager_->GetTraits(); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | void AddCommand(const base::DictionaryValue& command, |
| 160 | const UserInfo& user_info, |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 161 | const CommandDoneCallback& callback) override { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 162 | CHECK(user_info.scope() != AuthScope::kNone); |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 163 | CHECK_NE(user_info.user_id(), 0u); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 164 | |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 165 | ErrorPtr error; |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 166 | UserRole role; |
Vitaly Buka | 7197c1a | 2015-07-17 14:48:30 -0700 | [diff] [blame] | 167 | std::string str_scope = EnumToString(user_info.scope()); |
| 168 | if (!StringToEnum(str_scope, &role)) { |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 169 | Error::AddToPrintf(&error, FROM_HERE, errors::kDomain, |
| 170 | errors::kInvalidParams, "Invalid role: '%s'", |
| 171 | str_scope.c_str()); |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 172 | return callback.Run({}, std::move(error)); |
Vitaly Buka | 7197c1a | 2015-07-17 14:48:30 -0700 | [diff] [blame] | 173 | } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 174 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 175 | std::string id; |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 176 | auto command_instance = component_manager_->ParseCommandInstance( |
| 177 | command, Command::Origin::kLocal, role, &id, &error); |
| 178 | if (!command_instance) |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 179 | return callback.Run({}, std::move(error)); |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 180 | component_manager_->AddCommand(std::move(command_instance)); |
Vitaly Buka | 8b32d59 | 2015-06-24 16:41:25 -0700 | [diff] [blame] | 181 | command_owners_[id] = user_info.user_id(); |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 182 | callback.Run(*component_manager_->FindCommand(id)->ToJson(), nullptr); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | void GetCommand(const std::string& id, |
| 186 | const UserInfo& user_info, |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 187 | const CommandDoneCallback& callback) override { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 188 | CHECK(user_info.scope() != AuthScope::kNone); |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 189 | ErrorPtr error; |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 190 | auto command = GetCommandInternal(id, user_info, &error); |
| 191 | if (!command) |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 192 | return callback.Run({}, std::move(error)); |
| 193 | callback.Run(*command->ToJson(), nullptr); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | void CancelCommand(const std::string& id, |
| 197 | const UserInfo& user_info, |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 198 | const CommandDoneCallback& callback) override { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 199 | CHECK(user_info.scope() != AuthScope::kNone); |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 200 | ErrorPtr error; |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 201 | auto command = GetCommandInternal(id, user_info, &error); |
Vitaly Buka | 47a1f6f | 2015-10-07 18:09:57 -0700 | [diff] [blame] | 202 | if (!command || !command->Cancel(&error)) |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 203 | return callback.Run({}, std::move(error)); |
| 204 | callback.Run(*command->ToJson(), nullptr); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | void ListCommands(const UserInfo& user_info, |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 208 | const CommandDoneCallback& callback) override { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 209 | CHECK(user_info.scope() != AuthScope::kNone); |
| 210 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 211 | base::ListValue list_value; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 212 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 213 | for (const auto& it : command_owners_) { |
| 214 | if (CanAccessCommand(it.second, user_info, nullptr)) { |
| 215 | list_value.Append( |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 216 | component_manager_->FindCommand(it.first)->ToJson().release()); |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 217 | } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 218 | } |
| 219 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 220 | base::DictionaryValue commands_json; |
| 221 | commands_json.Set("commands", list_value.DeepCopy()); |
| 222 | |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 223 | callback.Run(commands_json, nullptr); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | private: |
Vitaly Buka | 12affd8 | 2015-07-23 18:45:35 -0700 | [diff] [blame] | 227 | void OnCommandAdded(Command* command) { |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 228 | // Set to 0 for any new unknown command. |
Vitaly Buka | 52d006a | 2015-11-21 17:14:51 -0800 | [diff] [blame] | 229 | command_owners_.insert(std::make_pair(command->GetID(), 0)); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 230 | } |
| 231 | |
Vitaly Buka | 12affd8 | 2015-07-23 18:45:35 -0700 | [diff] [blame] | 232 | void OnCommandRemoved(Command* command) { |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 233 | CHECK(command_owners_.erase(command->GetID())); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 234 | } |
| 235 | |
Vitaly Buka | bc3e8bd | 2015-07-20 00:37:48 -0700 | [diff] [blame] | 236 | void OnConfigChanged(const Settings&) { NotifyOnDeviceInfoChanged(); } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 237 | |
Vitaly Buka | c3c6dab | 2015-10-01 19:41:02 -0700 | [diff] [blame] | 238 | void OnRegistrationChanged(GcdState status) { |
Vitaly Buka | 672634b | 2015-11-20 09:49:30 -0800 | [diff] [blame] | 239 | if (status == GcdState::kUnconfigured || |
| 240 | status == GcdState::kInvalidCredentials) { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 241 | connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; |
Vitaly Buka | c3c6dab | 2015-10-01 19:41:02 -0700 | [diff] [blame] | 242 | } else if (status == GcdState::kConnecting) { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 243 | // TODO(vitalybuka): Find conditions for kOffline. |
| 244 | connection_state_ = ConnectionState{ConnectionState::kConnecting}; |
Vitaly Buka | c3c6dab | 2015-10-01 19:41:02 -0700 | [diff] [blame] | 245 | } else if (status == GcdState::kConnected) { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 246 | connection_state_ = ConnectionState{ConnectionState::kOnline}; |
| 247 | } else { |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 248 | ErrorPtr error; |
| 249 | Error::AddToPrintf( |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 250 | &error, FROM_HERE, errors::kDomain, errors::kInvalidState, |
Vitaly Buka | 8e2f416 | 2015-08-02 21:14:50 -0700 | [diff] [blame] | 251 | "Unexpected registration status: %s", EnumToString(status).c_str()); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 252 | connection_state_ = ConnectionState{std::move(error)}; |
| 253 | } |
| 254 | NotifyOnDeviceInfoChanged(); |
| 255 | } |
| 256 | |
Johan Euphrosine | 312c2f5 | 2015-09-29 00:04:29 -0700 | [diff] [blame] | 257 | void OnRegisterSuccess(const std::string& cloud_id) { |
| 258 | VLOG(1) << "Device registered: " << cloud_id; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 259 | setup_state_ = SetupState(SetupState::kSuccess); |
| 260 | } |
| 261 | |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 262 | void CallManagerRegisterDevice(const std::string& ticket_id, |
| 263 | const base::Time& deadline) { |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 264 | ErrorPtr error; |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 265 | if (base::Time::Now() > deadline) { |
Vitaly Buka | 4ebd329 | 2015-09-23 18:04:17 -0700 | [diff] [blame] | 266 | Error::AddTo(&error, FROM_HERE, errors::kDomain, errors::kInvalidState, |
| 267 | "Failed to register device"); |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 268 | setup_state_ = SetupState{std::move(error)}; |
| 269 | return; |
| 270 | } |
| 271 | |
Vitaly Buka | 12870bd | 2015-10-08 23:49:39 -0700 | [diff] [blame] | 272 | device_->RegisterDevice( |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 273 | ticket_id, |
| 274 | base::Bind(&CloudDelegateImpl::RegisterDeviceDone, |
Vitaly Buka | 12870bd | 2015-10-08 23:49:39 -0700 | [diff] [blame] | 275 | setup_weak_factory_.GetWeakPtr(), ticket_id, deadline)); |
| 276 | } |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 277 | |
Vitaly Buka | 7476342 | 2015-10-11 00:39:52 -0700 | [diff] [blame] | 278 | void RegisterDeviceDone(const std::string& ticket_id, |
| 279 | const base::Time& deadline, |
| 280 | ErrorPtr error) { |
| 281 | if (error) { |
| 282 | // Registration failed. Retry with backoff. |
| 283 | backoff_entry_.InformOfRequest(false); |
| 284 | return task_runner_->PostDelayedTask( |
| 285 | FROM_HERE, |
| 286 | base::Bind(&CloudDelegateImpl::CallManagerRegisterDevice, |
| 287 | setup_weak_factory_.GetWeakPtr(), ticket_id, deadline), |
| 288 | backoff_entry_.GetTimeUntilRelease()); |
| 289 | } |
Vitaly Buka | 12870bd | 2015-10-08 23:49:39 -0700 | [diff] [blame] | 290 | backoff_entry_.InformOfRequest(true); |
| 291 | setup_state_ = SetupState(SetupState::kSuccess); |
| 292 | } |
| 293 | |
Vitaly Buka | ef213d7 | 2015-10-07 15:54:58 -0700 | [diff] [blame] | 294 | CommandInstance* GetCommandInternal(const std::string& command_id, |
| 295 | const UserInfo& user_info, |
| 296 | ErrorPtr* error) const { |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 297 | if (user_info.scope() != AuthScope::kOwner) { |
| 298 | auto it = command_owners_.find(command_id); |
| 299 | if (it == command_owners_.end()) |
| 300 | return ReturnNotFound(command_id, error); |
| 301 | if (CanAccessCommand(it->second, user_info, error)) |
| 302 | return nullptr; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 303 | } |
| 304 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 305 | auto command = component_manager_->FindCommand(command_id); |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 306 | if (!command) |
| 307 | return ReturnNotFound(command_id, error); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 308 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 309 | return command; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 310 | } |
| 311 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 312 | bool CanAccessCommand(uint64_t owner_id, |
| 313 | const UserInfo& user_info, |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 314 | ErrorPtr* error) const { |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 315 | CHECK(user_info.scope() != AuthScope::kNone); |
| 316 | CHECK_NE(user_info.user_id(), 0u); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 317 | |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 318 | if (user_info.scope() == AuthScope::kOwner || |
| 319 | owner_id == user_info.user_id()) { |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 320 | return true; |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 321 | } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 322 | |
Vitaly Buka | 0801a1f | 2015-08-14 10:03:46 -0700 | [diff] [blame] | 323 | Error::AddTo(error, FROM_HERE, errors::kDomain, errors::kAccessDenied, |
| 324 | "Need to be owner of the command."); |
Vitaly Buka | 7ab89ff | 2015-06-09 22:11:40 -0700 | [diff] [blame] | 325 | return false; |
| 326 | } |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 327 | |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 328 | provider::TaskRunner* task_runner_{nullptr}; |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 329 | DeviceRegistrationInfo* device_{nullptr}; |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 330 | ComponentManager* component_manager_{nullptr}; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 331 | |
| 332 | // Primary state of GCD. |
| 333 | ConnectionState connection_state_{ConnectionState::kDisabled}; |
| 334 | |
| 335 | // State of the current or last setup. |
| 336 | SetupState setup_state_{SetupState::kNone}; |
| 337 | |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 338 | // Map of command IDs to user IDs. |
| 339 | std::map<std::string, uint64_t> command_owners_; |
| 340 | |
Alex Vakulenko | 464f93e | 2015-09-11 15:32:39 -0700 | [diff] [blame] | 341 | // Backoff entry for retrying device registration. |
| 342 | BackoffEntry backoff_entry_{®ister_backoff_policy}; |
| 343 | |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 344 | // |setup_weak_factory_| tracks the lifetime of callbacks used in connection |
| 345 | // with a particular invocation of Setup(). |
| 346 | base::WeakPtrFactory<CloudDelegateImpl> setup_weak_factory_{this}; |
| 347 | // |weak_factory_| tracks the lifetime of |this|. |
| 348 | base::WeakPtrFactory<CloudDelegateImpl> weak_factory_{this}; |
| 349 | }; |
| 350 | |
| 351 | } // namespace |
| 352 | |
Vitaly Buka | 4ebd329 | 2015-09-23 18:04:17 -0700 | [diff] [blame] | 353 | CloudDelegate::CloudDelegate() {} |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 354 | |
Vitaly Buka | 4ebd329 | 2015-09-23 18:04:17 -0700 | [diff] [blame] | 355 | CloudDelegate::~CloudDelegate() {} |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 356 | |
| 357 | // static |
| 358 | std::unique_ptr<CloudDelegate> CloudDelegate::CreateDefault( |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 359 | provider::TaskRunner* task_runner, |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 360 | DeviceRegistrationInfo* device, |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 361 | ComponentManager* component_manager) { |
Vitaly Buka | f9630fb | 2015-08-12 21:15:40 -0700 | [diff] [blame] | 362 | return std::unique_ptr<CloudDelegateImpl>{new CloudDelegateImpl{ |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 363 | task_runner, device, component_manager}}; |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 364 | } |
| 365 | |
| 366 | void CloudDelegate::NotifyOnDeviceInfoChanged() { |
| 367 | FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceInfoChanged()); |
| 368 | } |
| 369 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 370 | void CloudDelegate::NotifyOnTraitDefsChanged() { |
| 371 | FOR_EACH_OBSERVER(Observer, observer_list_, OnTraitDefsChanged()); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 372 | } |
| 373 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 374 | void CloudDelegate::NotifyOnComponentTreeChanged() { |
| 375 | FOR_EACH_OBSERVER(Observer, observer_list_, OnComponentTreeChanged()); |
Vitaly Buka | 7ce499f | 2015-06-09 08:04:11 -0700 | [diff] [blame] | 376 | } |
| 377 | |
Alex Vakulenko | 551a82b | 2015-12-07 14:46:12 -0800 | [diff] [blame] | 378 | void CloudDelegate::NotifyOnStateChanged() { |
| 379 | FOR_EACH_OBSERVER(Observer, observer_list_, OnStateChanged()); |
| 380 | } |
| 381 | |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 382 | } // namespace privet |
| 383 | } // namespace weave |