| // Copyright 2015 The Weave Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/device_manager.h" | |
| #include <string> | |
| #include <base/bind.h> | |
| #include "src/access_api_handler.h" | |
| #include "src/access_black_list_manager_impl.h" | |
| #include "src/base_api_handler.h" | |
| #include "src/commands/schema_constants.h" | |
| #include "src/component_manager_impl.h" | |
| #include "src/config.h" | |
| #include "src/device_registration_info.h" | |
| #include "src/privet/auth_manager.h" | |
| #include "src/privet/privet_manager.h" | |
| #include "src/string_utils.h" | |
| #include "src/utils.h" | |
| namespace weave { | |
| DeviceManager::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) | |
| : config_{new Config{config_store}}, | |
| component_manager_{new ComponentManagerImpl{task_runner}} { | |
| if (http_server) { | |
| auth_manager_.reset(new privet::AuthManager( | |
| config_.get(), http_server->GetHttpsCertificateFingerprint())); | |
| } | |
| device_info_.reset(new DeviceRegistrationInfo( | |
| config_.get(), component_manager_.get(), task_runner, http_client, | |
| network, auth_manager_.get())); | |
| base_api_handler_.reset(new BaseApiHandler{device_info_.get(), this}); | |
| black_list_manager_.reset(new AccessBlackListManagerImpl{config_store}); | |
| access_api_handler_.reset( | |
| new AccessApiHandler{this, black_list_manager_.get()}); | |
| device_info_->Start(); | |
| if (http_server) { | |
| StartPrivet(task_runner, network, dns_sd, http_server, wifi, bluetooth); | |
| } else { | |
| CHECK(!dns_sd); | |
| } | |
| } | |
| DeviceManager::~DeviceManager() {} | |
| const Settings& DeviceManager::GetSettings() const { | |
| return device_info_->GetSettings(); | |
| } | |
| void DeviceManager::AddSettingsChangedCallback( | |
| const SettingsChangedCallback& callback) { | |
| device_info_->GetMutableConfig()->AddOnChangedCallback(callback); | |
| } | |
| Config* DeviceManager::GetConfig() { | |
| return device_info_->GetMutableConfig(); | |
| } | |
| void DeviceManager::StartPrivet(provider::TaskRunner* task_runner, | |
| provider::Network* network, | |
| provider::DnsServiceDiscovery* dns_sd, | |
| provider::HttpServer* http_server, | |
| provider::Wifi* wifi, | |
| provider::Bluetooth* bluetooth) { | |
| privet_.reset(new privet::Manager{task_runner}); | |
| privet_->Start(network, dns_sd, http_server, wifi, auth_manager_.get(), | |
| device_info_.get(), component_manager_.get()); | |
| } | |
| GcdState DeviceManager::GetGcdState() const { | |
| return device_info_->GetGcdState(); | |
| } | |
| void DeviceManager::AddGcdStateChangedCallback( | |
| const GcdStateChangedCallback& callback) { | |
| device_info_->AddGcdStateChangedCallback(callback); | |
| } | |
| void DeviceManager::AddTraitDefinitionsFromJson(const std::string& json) { | |
| CHECK(component_manager_->LoadTraits(json, nullptr)); | |
| } | |
| void DeviceManager::AddTraitDefinitions(const base::DictionaryValue& dict) { | |
| CHECK(component_manager_->LoadTraits(dict, nullptr)); | |
| } | |
| const base::DictionaryValue& DeviceManager::GetTraits() const { | |
| return component_manager_->GetTraits(); | |
| } | |
| void DeviceManager::AddTraitDefsChangedCallback(const base::Closure& callback) { | |
| component_manager_->AddTraitDefChangedCallback(callback); | |
| } | |
| bool DeviceManager::AddComponent(const std::string& name, | |
| const std::vector<std::string>& traits, | |
| ErrorPtr* error) { | |
| return component_manager_->AddComponent("", name, traits, error); | |
| } | |
| bool DeviceManager::RemoveComponent(const std::string& name, ErrorPtr* error) { | |
| return component_manager_->RemoveComponent("", name, error); | |
| } | |
| void DeviceManager::AddComponentTreeChangedCallback( | |
| const base::Closure& callback) { | |
| component_manager_->AddComponentTreeChangedCallback(callback); | |
| } | |
| const base::DictionaryValue& DeviceManager::GetComponents() const { | |
| return component_manager_->GetComponents(); | |
| } | |
| bool DeviceManager::SetStatePropertiesFromJson(const std::string& component, | |
| const std::string& json, | |
| ErrorPtr* error) { | |
| return component_manager_->SetStatePropertiesFromJson(component, json, error); | |
| } | |
| bool DeviceManager::SetStateProperties(const std::string& component, | |
| const base::DictionaryValue& dict, | |
| ErrorPtr* error) { | |
| return component_manager_->SetStateProperties(component, dict, error); | |
| } | |
| const base::Value* DeviceManager::GetStateProperty(const std::string& component, | |
| const std::string& name, | |
| ErrorPtr* error) const { | |
| return component_manager_->GetStateProperty(component, name, error); | |
| } | |
| bool DeviceManager::SetStateProperty(const std::string& component, | |
| const std::string& name, | |
| const base::Value& value, | |
| ErrorPtr* error) { | |
| return component_manager_->SetStateProperty(component, name, value, error); | |
| } | |
| void DeviceManager::AddCommandHandler(const std::string& component, | |
| const std::string& command_name, | |
| const CommandHandlerCallback& callback) { | |
| component_manager_->AddCommandHandler(component, command_name, callback); | |
| } | |
| void DeviceManager::AddCommandDefinitionsFromJson(const std::string& json) { | |
| auto dict = LoadJsonDict(json, nullptr); | |
| CHECK(dict); | |
| AddCommandDefinitions(*dict); | |
| } | |
| void DeviceManager::AddCommandDefinitions(const base::DictionaryValue& dict) { | |
| CHECK(component_manager_->AddLegacyCommandDefinitions(dict, nullptr)); | |
| } | |
| bool DeviceManager::AddCommand(const base::DictionaryValue& command, | |
| std::string* id, | |
| ErrorPtr* error) { | |
| auto command_instance = component_manager_->ParseCommandInstance( | |
| command, Command::Origin::kLocal, UserRole::kOwner, id, error); | |
| if (!command_instance) | |
| return false; | |
| component_manager_->AddCommand(std::move(command_instance)); | |
| return true; | |
| } | |
| Command* DeviceManager::FindCommand(const std::string& id) { | |
| return component_manager_->FindCommand(id); | |
| } | |
| void DeviceManager::AddCommandHandler(const std::string& command_name, | |
| const CommandHandlerCallback& callback) { | |
| if (command_name.empty()) | |
| return component_manager_->AddCommandHandler("", "", callback); | |
| auto trait = SplitAtFirst(command_name, ".", true).first; | |
| std::string component = component_manager_->FindComponentWithTrait(trait); | |
| CHECK(!component.empty()); | |
| component_manager_->AddCommandHandler(component, command_name, callback); | |
| } | |
| void DeviceManager::AddStateChangedCallback(const base::Closure& callback) { | |
| component_manager_->AddStateChangedCallback(callback); | |
| } | |
| void DeviceManager::AddStateDefinitionsFromJson(const std::string& json) { | |
| auto dict = LoadJsonDict(json, nullptr); | |
| CHECK(dict); | |
| AddStateDefinitions(*dict); | |
| } | |
| void DeviceManager::AddStateDefinitions(const base::DictionaryValue& dict) { | |
| CHECK(component_manager_->AddLegacyStateDefinitions(dict, nullptr)); | |
| } | |
| bool DeviceManager::SetStatePropertiesFromJson(const std::string& json, | |
| ErrorPtr* error) { | |
| auto dict = LoadJsonDict(json, error); | |
| return dict && SetStateProperties(*dict, error); | |
| } | |
| bool DeviceManager::SetStateProperties(const base::DictionaryValue& dict, | |
| ErrorPtr* error) { | |
| for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | |
| std::string component = | |
| component_manager_->FindComponentWithTrait(it.key()); | |
| if (component.empty()) { | |
| Error::AddToPrintf(error, FROM_HERE, "unrouted_state", | |
| "Unable to set property value because there is no " | |
| "component supporting " | |
| "trait '%s'", | |
| it.key().c_str()); | |
| return false; | |
| } | |
| base::DictionaryValue trait_state; | |
| trait_state.Set(it.key(), it.value().DeepCopy()); | |
| if (!component_manager_->SetStateProperties(component, trait_state, error)) | |
| return false; | |
| } | |
| return true; | |
| } | |
| const base::Value* DeviceManager::GetStateProperty( | |
| const std::string& name) const { | |
| auto trait = SplitAtFirst(name, ".", true).first; | |
| std::string component = component_manager_->FindComponentWithTrait(trait); | |
| if (component.empty()) | |
| return nullptr; | |
| return component_manager_->GetStateProperty(component, name, nullptr); | |
| } | |
| bool DeviceManager::SetStateProperty(const std::string& name, | |
| const base::Value& value, | |
| ErrorPtr* error) { | |
| auto trait = SplitAtFirst(name, ".", true).first; | |
| std::string component = component_manager_->FindComponentWithTrait(trait); | |
| if (component.empty()) { | |
| Error::AddToPrintf( | |
| error, FROM_HERE, "unrouted_state", | |
| "Unable set value of state property '%s' because there is no component " | |
| "supporting trait '%s'", | |
| name.c_str(), trait.c_str()); | |
| return false; | |
| } | |
| return component_manager_->SetStateProperty(component, name, value, error); | |
| } | |
| const base::DictionaryValue& DeviceManager::GetState() const { | |
| return component_manager_->GetLegacyState(); | |
| } | |
| void DeviceManager::Register(const RegistrationData& registration_data, | |
| const DoneCallback& callback) { | |
| device_info_->RegisterDevice(registration_data, callback); | |
| } | |
| void DeviceManager::AddPairingChangedCallbacks( | |
| const PairingBeginCallback& begin_callback, | |
| const PairingEndCallback& end_callback) { | |
| if (privet_) | |
| privet_->AddOnPairingChangedCallbacks(begin_callback, end_callback); | |
| } | |
| std::unique_ptr<Device> Device::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) { | |
| return std::unique_ptr<Device>{ | |
| new DeviceManager{config_store, task_runner, http_client, network, dns_sd, | |
| http_server, wifi, bluetooth}}; | |
| } | |
| } // namespace weave |