blob: dd90e7de34c54468d60a45dfade8aacd61e00874 [file] [log] [blame]
Alex Vakulenko7c36b672014-07-16 14:50:58 -07001// Copyright 2014 The Chromium OS 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 "buffet/commands/command_manager.h"
6
Alex Vakulenko5841c302014-07-23 10:49:49 -07007#include <base/files/file_enumerator.h>
Alex Vakulenko5841c302014-07-23 10:49:49 -07008#include <base/values.h>
Alex Vakulenko95110752014-09-03 16:27:21 -07009#include <chromeos/dbus/exported_object_manager.h>
Alex Vakulenkoa8b95bc2014-08-27 11:00:57 -070010#include <chromeos/errors/error.h>
Alex Vakulenkofd448692014-07-22 07:46:53 -070011
12#include "buffet/commands/schema_constants.h"
Alex Vakulenkob04936f2014-09-19 14:53:58 -070013#include "buffet/utils.h"
Alex Vakulenkofd448692014-07-22 07:46:53 -070014
Alex Vakulenko95110752014-09-03 16:27:21 -070015using chromeos::dbus_utils::ExportedObjectManager;
16
Alex Vakulenko7c36b672014-07-16 14:50:58 -070017namespace buffet {
18
Alex Vakulenko95110752014-09-03 16:27:21 -070019CommandManager::CommandManager() {
20 command_queue_.SetCommandDispachInterface(&command_dispatcher_);
21}
22
23CommandManager::CommandManager(
24 const base::WeakPtr<ExportedObjectManager>& object_manager)
25 : command_dispatcher_(object_manager->GetBus(), object_manager.get()) {
26 command_queue_.SetCommandDispachInterface(&command_dispatcher_);
27}
28
Alex Vakulenko9e2f8cd2015-04-07 16:28:09 -070029CommandManager::CommandManager(CommandDispachInterface* dispatch_interface) {
30 command_queue_.SetCommandDispachInterface(dispatch_interface);
31}
32
Alex Vakulenko7c36b672014-07-16 14:50:58 -070033const CommandDictionary& CommandManager::GetCommandDictionary() const {
34 return dictionary_;
35}
36
Alex Vakulenkofd448692014-07-22 07:46:53 -070037bool CommandManager::LoadBaseCommands(const base::DictionaryValue& json,
Alex Vakulenko5f472062014-08-14 17:54:04 -070038 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070039 return base_dictionary_.LoadCommands(json, "", nullptr, error);
40}
41
42bool CommandManager::LoadBaseCommands(const base::FilePath& json_file_path,
Alex Vakulenko5f472062014-08-14 17:54:04 -070043 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070044 std::unique_ptr<const base::DictionaryValue> json = LoadJsonDict(
45 json_file_path, error);
46 if (!json)
47 return false;
48 return LoadBaseCommands(*json, error);
49}
50
51bool CommandManager::LoadCommands(const base::DictionaryValue& json,
52 const std::string& category,
Alex Vakulenko5f472062014-08-14 17:54:04 -070053 chromeos::ErrorPtr* error) {
Vitaly Bukaaabadee2015-03-18 23:33:44 -070054 bool result =
55 dictionary_.LoadCommands(json, category, &base_dictionary_, error);
Alex Vakulenko9ea5a322015-04-17 15:35:34 -070056 on_command_changed_.Notify();
Vitaly Bukaaabadee2015-03-18 23:33:44 -070057 return result;
Alex Vakulenkofd448692014-07-22 07:46:53 -070058}
59
60bool CommandManager::LoadCommands(const base::FilePath& json_file_path,
Alex Vakulenko5f472062014-08-14 17:54:04 -070061 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070062 std::unique_ptr<const base::DictionaryValue> json = LoadJsonDict(
63 json_file_path, error);
64 if (!json)
65 return false;
66 std::string category = json_file_path.BaseName().RemoveExtension().value();
67 return LoadCommands(*json, category, error);
68}
69
Christopher Wileybb5b8482015-02-12 13:42:16 -080070void CommandManager::Startup(const base::FilePath& definitions_path,
71 const base::FilePath& test_definitions_path) {
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070072 LOG(INFO) << "Initializing CommandManager.";
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070073 // Load global standard GCD command dictionary.
Christopher Wileybb5b8482015-02-12 13:42:16 -080074 base::FilePath base_command_file{definitions_path.Append("gcd.json")};
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070075 LOG(INFO) << "Loading standard commands from " << base_command_file.value();
Alex Vakulenkoc2bc9a42014-07-23 10:57:58 -070076 CHECK(LoadBaseCommands(base_command_file, nullptr))
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070077 << "Failed to load the standard command definitions.";
78
Christopher Wileybb5b8482015-02-12 13:42:16 -080079 auto LoadPackages = [this](const base::FilePath& root,
80 const base::FilePath::StringType& pattern) {
81 base::FilePath device_command_dir{root.Append("commands")};
82 VLOG(2) << "Looking for commands in " << root.value();
83 base::FileEnumerator enumerator(device_command_dir, false,
84 base::FileEnumerator::FILES,
85 pattern);
86 base::FilePath json_file_path = enumerator.Next();
87 while (!json_file_path.empty()) {
88 LOG(INFO) << "Loading command schema from " << json_file_path.value();
89 CHECK(this->LoadCommands(json_file_path, nullptr))
90 << "Failed to load the command definition file.";
91 json_file_path = enumerator.Next();
92 }
93 };
94 LoadPackages(definitions_path, FILE_PATH_LITERAL("*.json"));
95 LoadPackages(test_definitions_path, FILE_PATH_LITERAL("*test.json"));
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070096}
97
Anton Muhin5191e812014-10-30 17:49:48 +040098void CommandManager::AddCommand(
Alex Vakulenko95110752014-09-03 16:27:21 -070099 std::unique_ptr<CommandInstance> command_instance) {
Anton Muhin5191e812014-10-30 17:49:48 +0400100 command_queue_.Add(std::move(command_instance));
101}
102
103CommandInstance* CommandManager::FindCommand(const std::string& id) const {
104 return command_queue_.Find(id);
Alex Vakulenko95110752014-09-03 16:27:21 -0700105}
106
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700107bool CommandManager::SetCommandVisibility(
108 const std::vector<std::string>& command_names,
109 CommandDefinition::Visibility visibility,
110 chromeos::ErrorPtr* error) {
111 if (command_names.empty())
112 return true;
113
114 std::vector<CommandDefinition*> definitions;
115 definitions.reserve(command_names.size());
116
117 // Find/validate command definitions first.
118 for (const std::string& name : command_names) {
119 CommandDefinition* def = dictionary_.FindCommand(name);
120 if (!def) {
121 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
122 errors::commands::kInvalidCommandName,
123 "Command '%s' is unknown", name.c_str());
124 return false;
125 }
126 definitions.push_back(def);
127 }
128
129 // Now that we know that all the command names were valid,
130 // update the respective commands' visibility.
131 for (CommandDefinition* def : definitions) {
132 def->SetVisibility(visibility);
133 }
134 on_command_changed_.Notify();
135 return true;
136}
137
Alex Vakulenko7c36b672014-07-16 14:50:58 -0700138} // namespace buffet