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 23 namespace weave { 24 25 DeviceManager::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 58 DeviceManager::~DeviceManager() {} 59 60 const Settings& DeviceManager::GetSettings() const { 61 return device_info_->GetSettings(); 62 } 63 64 void DeviceManager::AddSettingsChangedCallback( 65 const SettingsChangedCallback& callback) { 66 device_info_->GetMutableConfig()->AddOnChangedCallback(callback); 67 } 68 69 Config* DeviceManager::GetConfig() { 70 return device_info_->GetMutableConfig(); 71 } 72 73 void 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 84 GcdState DeviceManager::GetGcdState() const { 85 return device_info_->GetGcdState(); 86 } 87 88 void DeviceManager::AddGcdStateChangedCallback( 89 const GcdStateChangedCallback& callback) { 90 device_info_->AddGcdStateChangedCallback(callback); 91 } 92 93 void DeviceManager::AddTraitDefinitionsFromJson(const std::string& json) { 94 CHECK(component_manager_->LoadTraits(json, nullptr)); 95 } 96 97 void DeviceManager::AddTraitDefinitions(const base::DictionaryValue& dict) { 98 CHECK(component_manager_->LoadTraits(dict, nullptr)); 99 } 100 101 const base::DictionaryValue& DeviceManager::GetTraits() const { 102 return component_manager_->GetTraits(); 103 } 104 105 void DeviceManager::AddTraitDefsChangedCallback(const base::Closure& callback) { 106 component_manager_->AddTraitDefChangedCallback(callback); 107 } 108 109 bool 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 115 bool DeviceManager::RemoveComponent(const std::string& name, ErrorPtr* error) { 116 return component_manager_->RemoveComponent("", name, error); 117 } 118 119 void DeviceManager::AddComponentTreeChangedCallback( 120 const base::Closure& callback) { 121 component_manager_->AddComponentTreeChangedCallback(callback); 122 } 123 124 const base::DictionaryValue& DeviceManager::GetComponents() const { 125 return component_manager_->GetComponents(); 126 } 127 128 bool DeviceManager::SetStatePropertiesFromJson(const std::string& component, 129 const std::string& json, 130 ErrorPtr* error) { 131 return component_manager_->SetStatePropertiesFromJson(component, json, error); 132 } 133 134 bool DeviceManager::SetStateProperties(const std::string& component, 135 const base::DictionaryValue& dict, 136 ErrorPtr* error) { 137 return component_manager_->SetStateProperties(component, dict, error); 138 } 139 140 const 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 146 bool 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 153 void 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 159 void DeviceManager::AddCommandDefinitionsFromJson(const std::string& json) { 160 auto dict = LoadJsonDict(json, nullptr); 161 CHECK(dict); 162 AddCommandDefinitions(*dict); 163 } 164 165 void DeviceManager::AddCommandDefinitions(const base::DictionaryValue& dict) { 166 CHECK(component_manager_->AddLegacyCommandDefinitions(dict, nullptr)); 167 } 168 169 bool 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 180 Command* DeviceManager::FindCommand(const std::string& id) { 181 return component_manager_->FindCommand(id); 182 } 183 184 void 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 195 void DeviceManager::AddStateChangedCallback(const base::Closure& callback) { 196 component_manager_->AddStateChangedCallback(callback); 197 } 198 199 void DeviceManager::AddStateDefinitionsFromJson(const std::string& json) { 200 auto dict = LoadJsonDict(json, nullptr); 201 CHECK(dict); 202 AddStateDefinitions(*dict); 203 } 204 205 void DeviceManager::AddStateDefinitions(const base::DictionaryValue& dict) { 206 CHECK(component_manager_->AddLegacyStateDefinitions(dict, nullptr)); 207 } 208 209 bool DeviceManager::SetStatePropertiesFromJson(const std::string& json, 210 ErrorPtr* error) { 211 auto dict = LoadJsonDict(json, error); 212 return dict && SetStateProperties(*dict, error); 213 } 214 215 bool 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 236 const 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 245 bool 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 261 const base::DictionaryValue& DeviceManager::GetState() const { 262 return component_manager_->GetLegacyState(); 263 } 264 265 void DeviceManager::Register(const std::string& ticket_id, 266 const DoneCallback& callback) { 267 device_info_->RegisterDevice(ticket_id, callback); 268 } 269 270 void DeviceManager::AddPairingChangedCallbacks( 271 const PairingBeginCallback& begin_callback, 272 const PairingEndCallback& end_callback) { 273 if (privet_) 274 privet_->AddOnPairingChangedCallbacks(begin_callback, end_callback); 275 } 276 277 std::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