| // 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/commands/command_manager.h" | 
 |  | 
 | #include <base/values.h> | 
 | #include <weave/enum_to_string.h> | 
 | #include <weave/error.h> | 
 |  | 
 | #include "src/commands/schema_constants.h" | 
 | #include "src/utils.h" | 
 |  | 
 | namespace weave { | 
 |  | 
 | CommandManager::CommandManager() {} | 
 |  | 
 | CommandManager::~CommandManager() {} | 
 |  | 
 | void CommandManager::AddCommandDefChanged(const base::Closure& callback) { | 
 |   on_command_changed_.push_back(callback); | 
 |   callback.Run(); | 
 | } | 
 |  | 
 | const CommandDictionary& CommandManager::GetCommandDictionary() const { | 
 |   return dictionary_; | 
 | } | 
 |  | 
 | bool CommandManager::LoadCommands(const base::DictionaryValue& dict, | 
 |                                   ErrorPtr* error) { | 
 |   bool result = dictionary_.LoadCommands(dict, nullptr, error); | 
 |   for (const auto& cb : on_command_changed_) | 
 |     cb.Run(); | 
 |   return result; | 
 | } | 
 |  | 
 | bool CommandManager::LoadCommands(const std::string& json, | 
 |                                   ErrorPtr* error) { | 
 |   std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error); | 
 |   if (!dict) | 
 |     return false; | 
 |   return LoadCommands(*dict, error); | 
 | } | 
 |  | 
 | void CommandManager::AddCommand( | 
 |     std::unique_ptr<CommandInstance> command_instance) { | 
 |   command_queue_.Add(std::move(command_instance)); | 
 | } | 
 |  | 
 | bool CommandManager::AddCommand(const base::DictionaryValue& command, | 
 |                                 std::string* id, | 
 |                                 ErrorPtr* error) { | 
 |   return AddCommand(command, UserRole::kOwner, id, error); | 
 | } | 
 |  | 
 | bool CommandManager::AddCommand(const base::DictionaryValue& command, | 
 |                                 UserRole role, | 
 |                                 std::string* id, | 
 |                                 ErrorPtr* error) { | 
 |   auto command_instance = | 
 |       CommandInstance::FromJson(&command, Command::Origin::kLocal, | 
 |                                 GetCommandDictionary(), nullptr, error); | 
 |   if (!command_instance) | 
 |     return false; | 
 |  | 
 |   UserRole minimal_role = | 
 |       command_instance->GetCommandDefinition()->GetMinimalRole(); | 
 |   if (role < minimal_role) { | 
 |     Error::AddToPrintf( | 
 |         error, FROM_HERE, errors::commands::kDomain, "access_denied", | 
 |         "User role '%s' less than minimal: '%s'", EnumToString(role).c_str(), | 
 |         EnumToString(minimal_role).c_str()); | 
 |     return false; | 
 |   } | 
 |  | 
 |   *id = std::to_string(++next_command_id_); | 
 |   command_instance->SetID(*id); | 
 |   AddCommand(std::move(command_instance)); | 
 |   return true; | 
 | } | 
 |  | 
 | CommandInstance* CommandManager::FindCommand(const std::string& id) { | 
 |   return command_queue_.Find(id); | 
 | } | 
 |  | 
 | bool CommandManager::SetCommandVisibility( | 
 |     const std::vector<std::string>& command_names, | 
 |     CommandDefinition::Visibility visibility, | 
 |     ErrorPtr* error) { | 
 |   if (command_names.empty()) | 
 |     return true; | 
 |  | 
 |   std::vector<CommandDefinition*> definitions; | 
 |   definitions.reserve(command_names.size()); | 
 |  | 
 |   // Find/validate command definitions first. | 
 |   for (const std::string& name : command_names) { | 
 |     CommandDefinition* def = dictionary_.FindCommand(name); | 
 |     if (!def) { | 
 |       Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain, | 
 |                          errors::commands::kInvalidCommandName, | 
 |                          "Command '%s' is unknown", name.c_str()); | 
 |       return false; | 
 |     } | 
 |     definitions.push_back(def); | 
 |   } | 
 |  | 
 |   // Now that we know that all the command names were valid, | 
 |   // update the respective commands' visibility. | 
 |   for (CommandDefinition* def : definitions) | 
 |     def->SetVisibility(visibility); | 
 |   for (const auto& cb : on_command_changed_) | 
 |     cb.Run(); | 
 |   return true; | 
 | } | 
 |  | 
 | void CommandManager::AddCommandAddedCallback( | 
 |     const CommandQueue::CommandCallback& callback) { | 
 |   command_queue_.AddCommandAddedCallback(callback); | 
 | } | 
 |  | 
 | void CommandManager::AddCommandRemovedCallback( | 
 |     const CommandQueue::CommandCallback& callback) { | 
 |   command_queue_.AddCommandRemovedCallback(callback); | 
 | } | 
 |  | 
 | void CommandManager::AddCommandHandler( | 
 |     const std::string& command_name, | 
 |     const Device::CommandHandlerCallback& callback) { | 
 |   CHECK(command_name.empty() || dictionary_.FindCommand(command_name)) | 
 |       << "Command undefined: " << command_name; | 
 |   command_queue_.AddCommandHandler(command_name, callback); | 
 | } | 
 |  | 
 | }  // namespace weave |