// 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 #include #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& 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 std::string& ticket_id, const DoneCallback& callback) { device_info_->RegisterDevice(ticket_id, callback); } void DeviceManager::AddPairingChangedCallbacks( const PairingBeginCallback& begin_callback, const PairingEndCallback& end_callback) { if (privet_) privet_->AddOnPairingChangedCallbacks(begin_callback, end_callback); } std::unique_ptr 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{ new DeviceManager{config_store, task_runner, http_client, network, dns_sd, http_server, wifi, bluetooth}}; } } // namespace weave