blob: 1158df782a913478f85389dace343fd1d610735f [file] [log] [blame]
Vitaly Buka4615e0d2015-10-14 15:35:12 -07001// Copyright 2015 The Weave Authors. All rights reserved.
Vitaly Buka0fa51e52015-07-10 00:12:25 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Stefan Sauer2d16dfa2015-09-25 17:08:35 +02005#include "src/device_manager.h"
Vitaly Buka0fa51e52015-07-10 00:12:25 -07006
7#include <string>
8
Vitaly Buka0d501072015-08-18 18:09:46 -07009#include <base/bind.h>
10
Stefan Sauer2d16dfa2015-09-25 17:08:35 +020011#include "src/base_api_handler.h"
Alex Vakulenkod91d6252015-12-05 17:14:39 -080012#include "src/commands/schema_constants.h"
Alex Vakulenkoba981152015-12-05 13:58:22 -080013#include "src/component_manager_impl.h"
Stefan Sauer2d16dfa2015-09-25 17:08:35 +020014#include "src/config.h"
15#include "src/device_registration_info.h"
Vitaly Buka3d851b42015-12-08 16:17:01 -080016#include "src/privet/auth_manager.h"
Stefan Sauer2d16dfa2015-09-25 17:08:35 +020017#include "src/privet/privet_manager.h"
Alex Vakulenkod91d6252015-12-05 17:14:39 -080018#include "src/string_utils.h"
19#include "src/utils.h"
Vitaly Buka0fa51e52015-07-10 00:12:25 -070020
21namespace weave {
22
Vitaly Bukac5bdd172015-10-01 19:48:51 -070023DeviceManager::DeviceManager(provider::ConfigStore* config_store,
24 provider::TaskRunner* task_runner,
25 provider::HttpClient* http_client,
26 provider::Network* network,
27 provider::DnsServiceDiscovery* dns_sd,
28 provider::HttpServer* http_server,
29 provider::Wifi* wifi,
Vitaly Buka666b43e2015-12-08 16:35:47 -080030 provider::Bluetooth* bluetooth)
31 : config_{new Config{config_store}},
32 component_manager_{new ComponentManagerImpl} {
Vitaly Buka3d851b42015-12-08 16:17:01 -080033 if (http_server) {
Vitaly Buka229113e2015-12-13 23:12:42 -080034 auth_manager_.reset(new privet::AuthManager(
35 config_.get(), http_server->GetHttpsCertificateFingerprint()));
Vitaly Buka3d851b42015-12-08 16:17:01 -080036 }
37
Vitaly Buka0fa51e52015-07-10 00:12:25 -070038 device_info_.reset(new DeviceRegistrationInfo(
Vitaly Buka666b43e2015-12-08 16:35:47 -080039 config_.get(), component_manager_.get(), task_runner, http_client,
Vitaly Buka3d851b42015-12-08 16:17:01 -080040 network, auth_manager_.get()));
Vitaly Buka266e88b2015-10-06 11:33:00 -070041 base_api_handler_.reset(new BaseApiHandler{device_info_.get(), this});
Vitaly Buka0fa51e52015-07-10 00:12:25 -070042
43 device_info_->Start();
44
Vitaly Buka41a90d62015-09-29 16:58:39 -070045 if (http_server) {
Vitaly Buka41a90d62015-09-29 16:58:39 -070046 StartPrivet(task_runner, network, dns_sd, http_server, wifi, bluetooth);
Vitaly Buka2ad97342015-08-02 20:57:43 -070047 } else {
Vitaly Bukabeddc602015-09-24 15:28:03 -070048 CHECK(!dns_sd);
Vitaly Buka2ad97342015-08-02 20:57:43 -070049 }
Vitaly Buka0fa51e52015-07-10 00:12:25 -070050}
51
Vitaly Bukac5bdd172015-10-01 19:48:51 -070052DeviceManager::~DeviceManager() {}
53
Vitaly Bukaa8ece8f2015-10-05 13:30:23 -070054const Settings& DeviceManager::GetSettings() const {
Vitaly Bukaae6b35d2015-09-29 23:16:54 -070055 return device_info_->GetSettings();
56}
57
58void DeviceManager::AddSettingsChangedCallback(
59 const SettingsChangedCallback& callback) {
60 device_info_->GetMutableConfig()->AddOnChangedCallback(callback);
61}
62
Vitaly Buka8b4ab962015-07-14 19:19:39 -070063Config* DeviceManager::GetConfig() {
Vitaly Buka0fa51e52015-07-10 00:12:25 -070064 return device_info_->GetMutableConfig();
65}
66
Vitaly Buka41a90d62015-09-29 16:58:39 -070067void DeviceManager::StartPrivet(provider::TaskRunner* task_runner,
Vitaly Buka1e363672015-09-25 14:01:16 -070068 provider::Network* network,
69 provider::DnsServiceDiscovery* dns_sd,
70 provider::HttpServer* http_server,
71 provider::Wifi* wifi,
72 provider::Bluetooth* bluetooth) {
Vitaly Buka5fe76092015-10-08 13:37:53 -070073 privet_.reset(new privet::Manager{task_runner});
Vitaly Buka3d851b42015-12-08 16:17:01 -080074 privet_->Start(network, dns_sd, http_server, wifi, auth_manager_.get(),
75 device_info_.get(), component_manager_.get());
Vitaly Buka0fa51e52015-07-10 00:12:25 -070076}
77
Vitaly Bukac3c6dab2015-10-01 19:41:02 -070078GcdState DeviceManager::GetGcdState() const {
79 return device_info_->GetGcdState();
80}
81
82void DeviceManager::AddGcdStateChangedCallback(
83 const GcdStateChangedCallback& callback) {
84 device_info_->AddGcdStateChangedCallback(callback);
85}
86
Alex Vakulenkoe79fa912015-12-04 17:24:15 -080087void DeviceManager::AddTraitDefinitionsFromJson(const std::string& json) {
88 CHECK(component_manager_->LoadTraits(json, nullptr));
89}
90
91void DeviceManager::AddTraitDefinitions(const base::DictionaryValue& dict) {
92 CHECK(component_manager_->LoadTraits(dict, nullptr));
93}
94
95const base::DictionaryValue& DeviceManager::GetTraits() const {
96 return component_manager_->GetTraits();
97}
98
Alex Vakulenkoec9d8482015-12-10 10:16:21 -080099void DeviceManager::AddTraitDefsChangedCallback(const base::Closure& callback) {
100 component_manager_->AddTraitDefChangedCallback(callback);
101}
102
Alex Vakulenkoe79fa912015-12-04 17:24:15 -0800103bool DeviceManager::AddComponent(const std::string& name,
104 const std::vector<std::string>& traits,
105 ErrorPtr* error) {
106 return component_manager_->AddComponent("", name, traits, error);
107}
108
Alex Vakulenkoce850b52016-01-04 09:27:50 -0800109bool DeviceManager::RemoveComponent(const std::string& name, ErrorPtr* error) {
110 return component_manager_->RemoveComponent("", name, error);
111}
112
Alex Vakulenkoe79fa912015-12-04 17:24:15 -0800113void DeviceManager::AddComponentTreeChangedCallback(
114 const base::Closure& callback) {
115 component_manager_->AddComponentTreeChangedCallback(callback);
116}
117
118const base::DictionaryValue& DeviceManager::GetComponents() const {
119 return component_manager_->GetComponents();
120}
121
122bool DeviceManager::SetStatePropertiesFromJson(const std::string& component,
123 const std::string& json,
124 ErrorPtr* error) {
125 return component_manager_->SetStatePropertiesFromJson(component, json, error);
126}
127
128bool DeviceManager::SetStateProperties(const std::string& component,
129 const base::DictionaryValue& dict,
130 ErrorPtr* error) {
131 return component_manager_->SetStateProperties(component, dict, error);
132}
133
Vitaly Buka34668e72015-12-15 14:46:47 -0800134const base::Value* DeviceManager::GetStateProperty(const std::string& component,
135 const std::string& name,
136 ErrorPtr* error) const {
Alex Vakulenkoe79fa912015-12-04 17:24:15 -0800137 return component_manager_->GetStateProperty(component, name, error);
138}
139
140bool DeviceManager::SetStateProperty(const std::string& component,
141 const std::string& name,
142 const base::Value& value,
143 ErrorPtr* error) {
144 return component_manager_->SetStateProperty(component, name, value, error);
145}
146
147void DeviceManager::AddCommandHandler(const std::string& component,
148 const std::string& command_name,
149 const CommandHandlerCallback& callback) {
150 component_manager_->AddCommandHandler(component, command_name, callback);
151}
152
Vitaly Buka3110deb2015-10-06 19:54:09 -0700153void DeviceManager::AddCommandDefinitionsFromJson(const std::string& json) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800154 auto dict = LoadJsonDict(json, nullptr);
155 CHECK(dict);
156 AddCommandDefinitions(*dict);
Vitaly Buka77c2bff2015-10-06 18:31:20 -0700157}
158
159void DeviceManager::AddCommandDefinitions(const base::DictionaryValue& dict) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800160 CHECK(component_manager_->AddLegacyCommandDefinitions(dict, nullptr));
Vitaly Buka4c981352015-10-01 23:04:24 -0700161}
162
Vitaly Bukaa8ece8f2015-10-05 13:30:23 -0700163bool DeviceManager::AddCommand(const base::DictionaryValue& command,
164 std::string* id,
165 ErrorPtr* error) {
Vitaly Buka34668e72015-12-15 14:46:47 -0800166 auto command_instance = component_manager_->ParseCommandInstance(
167 command, Command::Origin::kLocal, UserRole::kOwner, id, error);
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800168 if (!command_instance)
169 return false;
170 component_manager_->AddCommand(std::move(command_instance));
171 return true;
Vitaly Bukaa8ece8f2015-10-05 13:30:23 -0700172}
173
174Command* DeviceManager::FindCommand(const std::string& id) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800175 return component_manager_->FindCommand(id);
Vitaly Bukaa8ece8f2015-10-05 13:30:23 -0700176}
177
Vitaly Buka695a5fb2015-10-06 16:26:08 -0700178void DeviceManager::AddCommandHandler(const std::string& command_name,
179 const CommandHandlerCallback& callback) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800180 if (command_name.empty())
181 return component_manager_->AddCommandHandler("", "", callback);
182
183 auto trait = SplitAtFirst(command_name, ".", true).first;
184 std::string component = component_manager_->FindComponentWithTrait(trait);
185 CHECK(!component.empty());
186 component_manager_->AddCommandHandler(component, command_name, callback);
Vitaly Bukaa8ece8f2015-10-05 13:30:23 -0700187}
188
Vitaly Buka77c2bff2015-10-06 18:31:20 -0700189void DeviceManager::AddStateChangedCallback(const base::Closure& callback) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800190 component_manager_->AddStateChangedCallback(callback);
Vitaly Buka77c2bff2015-10-06 18:31:20 -0700191}
192
Vitaly Buka3110deb2015-10-06 19:54:09 -0700193void DeviceManager::AddStateDefinitionsFromJson(const std::string& json) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800194 auto dict = LoadJsonDict(json, nullptr);
195 CHECK(dict);
196 AddStateDefinitions(*dict);
Vitaly Buka77c2bff2015-10-06 18:31:20 -0700197}
198
199void DeviceManager::AddStateDefinitions(const base::DictionaryValue& dict) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800200 CHECK(component_manager_->AddLegacyStateDefinitions(dict, nullptr));
Vitaly Buka77c2bff2015-10-06 18:31:20 -0700201}
202
Vitaly Buka216e86d2015-10-06 20:23:02 -0700203bool DeviceManager::SetStatePropertiesFromJson(const std::string& json,
204 ErrorPtr* error) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800205 auto dict = LoadJsonDict(json, error);
206 return dict && SetStateProperties(*dict, error);
Vitaly Buka77c2bff2015-10-06 18:31:20 -0700207}
208
Vitaly Buka216e86d2015-10-06 20:23:02 -0700209bool DeviceManager::SetStateProperties(const base::DictionaryValue& dict,
210 ErrorPtr* error) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800211 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
212 std::string component =
213 component_manager_->FindComponentWithTrait(it.key());
214 if (component.empty()) {
Vitaly Buka34668e72015-12-15 14:46:47 -0800215 Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
216 "unrouted_state",
217 "Unable to set property value because there is no "
218 "component supporting "
219 "trait '%s'",
220 it.key().c_str());
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800221 return false;
222 }
223 base::DictionaryValue trait_state;
224 trait_state.Set(it.key(), it.value().DeepCopy());
225 if (!component_manager_->SetStateProperties(component, trait_state, error))
226 return false;
227 }
228 return true;
Vitaly Buka4c981352015-10-01 23:04:24 -0700229}
230
Vitaly Bukac4305602015-11-24 23:33:09 -0800231const base::Value* DeviceManager::GetStateProperty(
Vitaly Buka4c981352015-10-01 23:04:24 -0700232 const std::string& name) const {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800233 auto trait = SplitAtFirst(name, ".", true).first;
234 std::string component = component_manager_->FindComponentWithTrait(trait);
235 if (component.empty())
236 return nullptr;
237 return component_manager_->GetStateProperty(component, name, nullptr);
Vitaly Buka4c981352015-10-01 23:04:24 -0700238}
239
240bool DeviceManager::SetStateProperty(const std::string& name,
241 const base::Value& value,
242 ErrorPtr* error) {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800243 auto trait = SplitAtFirst(name, ".", true).first;
244 std::string component = component_manager_->FindComponentWithTrait(trait);
245 if (component.empty()) {
246 Error::AddToPrintf(
Vitaly Buka34668e72015-12-15 14:46:47 -0800247 error, FROM_HERE, errors::commands::kDomain, "unrouted_state",
248 "Unable set value of state property '%s' because there is no component "
249 "supporting trait '%s'",
250 name.c_str(), trait.c_str());
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800251 return false;
252 }
253 return component_manager_->SetStateProperty(component, name, value, error);
Vitaly Buka4c981352015-10-01 23:04:24 -0700254}
255
Vitaly Bukac4305602015-11-24 23:33:09 -0800256const base::DictionaryValue& DeviceManager::GetState() const {
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800257 return component_manager_->GetLegacyState();
Vitaly Buka4c981352015-10-01 23:04:24 -0700258}
259
Vitaly Buka12870bd2015-10-08 23:49:39 -0700260void DeviceManager::Register(const std::string& ticket_id,
Vitaly Buka74763422015-10-11 00:39:52 -0700261 const DoneCallback& callback) {
262 device_info_->RegisterDevice(ticket_id, callback);
Vitaly Bukac3c6dab2015-10-01 19:41:02 -0700263}
264
Vitaly Bukae6073612015-10-01 17:58:52 -0700265void DeviceManager::AddPairingChangedCallbacks(
Vitaly Buka9aa15c72015-10-01 19:14:44 -0700266 const PairingBeginCallback& begin_callback,
267 const PairingEndCallback& end_callback) {
268 if (privet_)
269 privet_->AddOnPairingChangedCallbacks(begin_callback, end_callback);
Vitaly Bukae6073612015-10-01 17:58:52 -0700270}
271
Vitaly Bukac5bdd172015-10-01 19:48:51 -0700272std::unique_ptr<Device> Device::Create(provider::ConfigStore* config_store,
273 provider::TaskRunner* task_runner,
274 provider::HttpClient* http_client,
275 provider::Network* network,
276 provider::DnsServiceDiscovery* dns_sd,
277 provider::HttpServer* http_server,
278 provider::Wifi* wifi,
279 provider::Bluetooth* bluetooth) {
280 return std::unique_ptr<Device>{
281 new DeviceManager{config_store, task_runner, http_client, network, dns_sd,
282 http_server, wifi, bluetooth}};
Vitaly Buka0fa51e52015-07-10 00:12:25 -0700283}
284
285} // namespace weave