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#include "src/device_manager.h" 6 7#include <string> 8 9#include <base/bind.h> 10 11#include "src/access_api_handler.h" 12#include "src/access_black_list_manager_impl.h" 13#include "src/base_api_handler.h" 14#include "src/commands/schema_constants.h" 15#include "src/component_manager_impl.h" 16#include "src/config.h" 17#include "src/device_registration_info.h" 18#include "src/privet/auth_manager.h" 19#include "src/privet/privet_manager.h" 20#include "src/string_utils.h" 21#include "src/utils.h" 22 23namespace weave { 24 25DeviceManager::DeviceManager(provider::ConfigStore* config_store, 26 provider::TaskRunner* task_runner, 27 provider::HttpClient* http_client, 28 provider::Network* network, 29 provider::DnsServiceDiscovery* dns_sd, 30 provider::HttpServer* http_server, 31 provider::Wifi* wifi, 32 provider::Bluetooth* bluetooth) 33 : config_{new Config{config_store}}, 34 component_manager_{new ComponentManagerImpl{task_runner}} { 35 if (http_server) { 36 auth_manager_.reset(new privet::AuthManager( 37 config_.get(), http_server->GetHttpsCertificateFingerprint())); 38 } 39 40 device_info_.reset(new DeviceRegistrationInfo( 41 config_.get(), component_manager_.get(), task_runner, http_client, 42 network, auth_manager_.get())); 43 base_api_handler_.reset(new BaseApiHandler{device_info_.get(), this}); 44 45 black_list_manager_.reset(new AccessBlackListManagerImpl{config_store}); 46 access_api_handler_.reset( 47 new AccessApiHandler{this, black_list_manager_.get()}); 48 49 device_info_->Start(); 50 51 if (http_server) { 52 StartPrivet(task_runner, network, dns_sd, http_server, wifi, bluetooth); 53 } else { 54 CHECK(!dns_sd); 55 } 56} 57 58DeviceManager::~DeviceManager() {} 59 60const Settings& DeviceManager::GetSettings() const { 61 return device_info_->GetSettings(); 62} 63 64void DeviceManager::AddSettingsChangedCallback( 65 const SettingsChangedCallback& callback) { 66 device_info_->GetMutableConfig()->AddOnChangedCallback(callback); 67} 68 69Config* DeviceManager::GetConfig() { 70 return device_info_->GetMutableConfig(); 71} 72 73void DeviceManager::StartPrivet(provider::TaskRunner* task_runner, 74 provider::Network* network, 75 provider::DnsServiceDiscovery* dns_sd, 76 provider::HttpServer* http_server, 77 provider::Wifi* wifi, 78 provider::Bluetooth* bluetooth) { 79 privet_.reset(new privet::Manager{task_runner}); 80 privet_->Start(network, dns_sd, http_server, wifi, auth_manager_.get(), 81 device_info_.get(), component_manager_.get()); 82} 83 84GcdState DeviceManager::GetGcdState() const { 85 return device_info_->GetGcdState(); 86} 87 88void DeviceManager::AddGcdStateChangedCallback( 89 const GcdStateChangedCallback& callback) { 90 device_info_->AddGcdStateChangedCallback(callback); 91} 92 93void DeviceManager::AddTraitDefinitionsFromJson(const std::string& json) { 94 CHECK(component_manager_->LoadTraits(json, nullptr)); 95} 96 97void DeviceManager::AddTraitDefinitions(const base::DictionaryValue& dict) { 98 CHECK(component_manager_->LoadTraits(dict, nullptr)); 99} 100 101const base::DictionaryValue& DeviceManager::GetTraits() const { 102 return component_manager_->GetTraits(); 103} 104 105void DeviceManager::AddTraitDefsChangedCallback(const base::Closure& callback) { 106 component_manager_->AddTraitDefChangedCallback(callback); 107} 108 109bool DeviceManager::AddComponent(const std::string& name, 110 const std::vector<std::string>& traits, 111 ErrorPtr* error) { 112 return component_manager_->AddComponent("", name, traits, error); 113} 114 115bool DeviceManager::RemoveComponent(const std::string& name, ErrorPtr* error) { 116 return component_manager_->RemoveComponent("", name, error); 117} 118 119void DeviceManager::AddComponentTreeChangedCallback( 120 const base::Closure& callback) { 121 component_manager_->AddComponentTreeChangedCallback(callback); 122} 123 124const base::DictionaryValue& DeviceManager::GetComponents() const { 125 return component_manager_->GetComponents(); 126} 127 128bool DeviceManager::SetStatePropertiesFromJson(const std::string& component, 129 const std::string& json, 130 ErrorPtr* error) { 131 return component_manager_->SetStatePropertiesFromJson(component, json, error); 132} 133 134bool DeviceManager::SetStateProperties(const std::string& component, 135 const base::DictionaryValue& dict, 136 ErrorPtr* error) { 137 return component_manager_->SetStateProperties(component, dict, error); 138} 139 140const base::Value* DeviceManager::GetStateProperty(const std::string& component, 141 const std::string& name, 142 ErrorPtr* error) const { 143 return component_manager_->GetStateProperty(component, name, error); 144} 145 146bool DeviceManager::SetStateProperty(const std::string& component, 147 const std::string& name, 148 const base::Value& value, 149 ErrorPtr* error) { 150 return component_manager_->SetStateProperty(component, name, value, error); 151} 152 153void DeviceManager::AddCommandHandler(const std::string& component, 154 const std::string& command_name, 155 const CommandHandlerCallback& callback) { 156 component_manager_->AddCommandHandler(component, command_name, callback); 157} 158 159void DeviceManager::AddCommandDefinitionsFromJson(const std::string& json) { 160 auto dict = LoadJsonDict(json, nullptr); 161 CHECK(dict); 162 AddCommandDefinitions(*dict); 163} 164 165void DeviceManager::AddCommandDefinitions(const base::DictionaryValue& dict) { 166 CHECK(component_manager_->AddLegacyCommandDefinitions(dict, nullptr)); 167} 168 169bool DeviceManager::AddCommand(const base::DictionaryValue& command, 170 std::string* id, 171 ErrorPtr* error) { 172 auto command_instance = component_manager_->ParseCommandInstance( 173 command, Command::Origin::kLocal, UserRole::kOwner, id, error); 174 if (!command_instance) 175 return false; 176 component_manager_->AddCommand(std::move(command_instance)); 177 return true; 178} 179 180Command* DeviceManager::FindCommand(const std::string& id) { 181 return component_manager_->FindCommand(id); 182} 183 184void DeviceManager::AddCommandHandler(const std::string& command_name, 185 const CommandHandlerCallback& callback) { 186 if (command_name.empty()) 187 return component_manager_->AddCommandHandler("", "", callback); 188 189 auto trait = SplitAtFirst(command_name, ".", true).first; 190 std::string component = component_manager_->FindComponentWithTrait(trait); 191 CHECK(!component.empty()); 192 component_manager_->AddCommandHandler(component, command_name, callback); 193} 194 195void DeviceManager::AddStateChangedCallback(const base::Closure& callback) { 196 component_manager_->AddStateChangedCallback(callback); 197} 198 199void DeviceManager::AddStateDefinitionsFromJson(const std::string& json) { 200 auto dict = LoadJsonDict(json, nullptr); 201 CHECK(dict); 202 AddStateDefinitions(*dict); 203} 204 205void DeviceManager::AddStateDefinitions(const base::DictionaryValue& dict) { 206 CHECK(component_manager_->AddLegacyStateDefinitions(dict, nullptr)); 207} 208 209bool DeviceManager::SetStatePropertiesFromJson(const std::string& json, 210 ErrorPtr* error) { 211 auto dict = LoadJsonDict(json, error); 212 return dict && SetStateProperties(*dict, error); 213} 214 215bool DeviceManager::SetStateProperties(const base::DictionaryValue& dict, 216 ErrorPtr* error) { 217 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { 218 std::string component = 219 component_manager_->FindComponentWithTrait(it.key()); 220 if (component.empty()) { 221 Error::AddToPrintf(error, FROM_HERE, "unrouted_state", 222 "Unable to set property value because there is no " 223 "component supporting " 224 "trait '%s'", 225 it.key().c_str()); 226 return false; 227 } 228 base::DictionaryValue trait_state; 229 trait_state.Set(it.key(), it.value().DeepCopy()); 230 if (!component_manager_->SetStateProperties(component, trait_state, error)) 231 return false; 232 } 233 return true; 234} 235 236const base::Value* DeviceManager::GetStateProperty( 237 const std::string& name) const { 238 auto trait = SplitAtFirst(name, ".", true).first; 239 std::string component = component_manager_->FindComponentWithTrait(trait); 240 if (component.empty()) 241 return nullptr; 242 return component_manager_->GetStateProperty(component, name, nullptr); 243} 244 245bool DeviceManager::SetStateProperty(const std::string& name, 246 const base::Value& value, 247 ErrorPtr* error) { 248 auto trait = SplitAtFirst(name, ".", true).first; 249 std::string component = component_manager_->FindComponentWithTrait(trait); 250 if (component.empty()) { 251 Error::AddToPrintf( 252 error, FROM_HERE, "unrouted_state", 253 "Unable set value of state property '%s' because there is no component " 254 "supporting trait '%s'", 255 name.c_str(), trait.c_str()); 256 return false; 257 } 258 return component_manager_->SetStateProperty(component, name, value, error); 259} 260 261const base::DictionaryValue& DeviceManager::GetState() const { 262 return component_manager_->GetLegacyState(); 263} 264 265void DeviceManager::Register(const std::string& ticket_id, 266 const DoneCallback& callback) { 267 device_info_->RegisterDevice(ticket_id, callback); 268} 269 270void DeviceManager::AddPairingChangedCallbacks( 271 const PairingBeginCallback& begin_callback, 272 const PairingEndCallback& end_callback) { 273 if (privet_) 274 privet_->AddOnPairingChangedCallbacks(begin_callback, end_callback); 275} 276 277std::unique_ptr<Device> Device::Create(provider::ConfigStore* config_store, 278 provider::TaskRunner* task_runner, 279 provider::HttpClient* http_client, 280 provider::Network* network, 281 provider::DnsServiceDiscovery* dns_sd, 282 provider::HttpServer* http_server, 283 provider::Wifi* wifi, 284 provider::Bluetooth* bluetooth) { 285 return std::unique_ptr<Device>{ 286 new DeviceManager{config_store, task_runner, http_client, network, dns_sd, 287 http_server, wifi, bluetooth}}; 288} 289 290} // namespace weave 291