Home | History | Annotate | Download | only in src
      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