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
DeviceManager(provider::ConfigStore * config_store,provider::TaskRunner * task_runner,provider::HttpClient * http_client,provider::Network * network,provider::DnsServiceDiscovery * dns_sd,provider::HttpServer * http_server,provider::Wifi * wifi,provider::Bluetooth * bluetooth)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
~DeviceManager()58 DeviceManager::~DeviceManager() {}
59
GetSettings() const60 const Settings& DeviceManager::GetSettings() const {
61 return device_info_->GetSettings();
62 }
63
AddSettingsChangedCallback(const SettingsChangedCallback & callback)64 void DeviceManager::AddSettingsChangedCallback(
65 const SettingsChangedCallback& callback) {
66 device_info_->GetMutableConfig()->AddOnChangedCallback(callback);
67 }
68
GetConfig()69 Config* DeviceManager::GetConfig() {
70 return device_info_->GetMutableConfig();
71 }
72
StartPrivet(provider::TaskRunner * task_runner,provider::Network * network,provider::DnsServiceDiscovery * dns_sd,provider::HttpServer * http_server,provider::Wifi * wifi,provider::Bluetooth * bluetooth)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
GetGcdState() const84 GcdState DeviceManager::GetGcdState() const {
85 return device_info_->GetGcdState();
86 }
87
AddGcdStateChangedCallback(const GcdStateChangedCallback & callback)88 void DeviceManager::AddGcdStateChangedCallback(
89 const GcdStateChangedCallback& callback) {
90 device_info_->AddGcdStateChangedCallback(callback);
91 }
92
AddTraitDefinitionsFromJson(const std::string & json)93 void DeviceManager::AddTraitDefinitionsFromJson(const std::string& json) {
94 CHECK(component_manager_->LoadTraits(json, nullptr));
95 }
96
AddTraitDefinitions(const base::DictionaryValue & dict)97 void DeviceManager::AddTraitDefinitions(const base::DictionaryValue& dict) {
98 CHECK(component_manager_->LoadTraits(dict, nullptr));
99 }
100
GetTraits() const101 const base::DictionaryValue& DeviceManager::GetTraits() const {
102 return component_manager_->GetTraits();
103 }
104
AddTraitDefsChangedCallback(const base::Closure & callback)105 void DeviceManager::AddTraitDefsChangedCallback(const base::Closure& callback) {
106 component_manager_->AddTraitDefChangedCallback(callback);
107 }
108
AddComponent(const std::string & name,const std::vector<std::string> & traits,ErrorPtr * error)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
RemoveComponent(const std::string & name,ErrorPtr * error)115 bool DeviceManager::RemoveComponent(const std::string& name, ErrorPtr* error) {
116 return component_manager_->RemoveComponent("", name, error);
117 }
118
AddComponentTreeChangedCallback(const base::Closure & callback)119 void DeviceManager::AddComponentTreeChangedCallback(
120 const base::Closure& callback) {
121 component_manager_->AddComponentTreeChangedCallback(callback);
122 }
123
GetComponents() const124 const base::DictionaryValue& DeviceManager::GetComponents() const {
125 return component_manager_->GetComponents();
126 }
127
SetStatePropertiesFromJson(const std::string & component,const std::string & json,ErrorPtr * error)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
SetStateProperties(const std::string & component,const base::DictionaryValue & dict,ErrorPtr * error)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
GetStateProperty(const std::string & component,const std::string & name,ErrorPtr * error) const140 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
SetStateProperty(const std::string & component,const std::string & name,const base::Value & value,ErrorPtr * error)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
AddCommandHandler(const std::string & component,const std::string & command_name,const CommandHandlerCallback & callback)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
AddCommandDefinitionsFromJson(const std::string & json)159 void DeviceManager::AddCommandDefinitionsFromJson(const std::string& json) {
160 auto dict = LoadJsonDict(json, nullptr);
161 CHECK(dict);
162 AddCommandDefinitions(*dict);
163 }
164
AddCommandDefinitions(const base::DictionaryValue & dict)165 void DeviceManager::AddCommandDefinitions(const base::DictionaryValue& dict) {
166 CHECK(component_manager_->AddLegacyCommandDefinitions(dict, nullptr));
167 }
168
AddCommand(const base::DictionaryValue & command,std::string * id,ErrorPtr * error)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
FindCommand(const std::string & id)180 Command* DeviceManager::FindCommand(const std::string& id) {
181 return component_manager_->FindCommand(id);
182 }
183
AddCommandHandler(const std::string & command_name,const CommandHandlerCallback & callback)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
AddStateChangedCallback(const base::Closure & callback)195 void DeviceManager::AddStateChangedCallback(const base::Closure& callback) {
196 component_manager_->AddStateChangedCallback(callback);
197 }
198
AddStateDefinitionsFromJson(const std::string & json)199 void DeviceManager::AddStateDefinitionsFromJson(const std::string& json) {
200 auto dict = LoadJsonDict(json, nullptr);
201 CHECK(dict);
202 AddStateDefinitions(*dict);
203 }
204
AddStateDefinitions(const base::DictionaryValue & dict)205 void DeviceManager::AddStateDefinitions(const base::DictionaryValue& dict) {
206 CHECK(component_manager_->AddLegacyStateDefinitions(dict, nullptr));
207 }
208
SetStatePropertiesFromJson(const std::string & json,ErrorPtr * error)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
SetStateProperties(const base::DictionaryValue & dict,ErrorPtr * error)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
GetStateProperty(const std::string & name) const236 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
SetStateProperty(const std::string & name,const base::Value & value,ErrorPtr * error)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
GetState() const261 const base::DictionaryValue& DeviceManager::GetState() const {
262 return component_manager_->GetLegacyState();
263 }
264
Register(const std::string & ticket_id,const DoneCallback & callback)265 void DeviceManager::Register(const std::string& ticket_id,
266 const DoneCallback& callback) {
267 device_info_->RegisterDevice(ticket_id, callback);
268 }
269
AddPairingChangedCallbacks(const PairingBeginCallback & begin_callback,const PairingEndCallback & end_callback)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
Create(provider::ConfigStore * config_store,provider::TaskRunner * task_runner,provider::HttpClient * http_client,provider::Network * network,provider::DnsServiceDiscovery * dns_sd,provider::HttpServer * http_server,provider::Wifi * wifi,provider::Bluetooth * bluetooth)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