普通文本  |  291行  |  10.79 KB

// 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 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> 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