buffet: load standard GCD command definitions in CommandManager
Changed CommandManager to load the base command definitions
and use it as a base schema for loading device-specific commands
and make sure device vendors are not redefining standard commands
in breaking manner.
BUG=chromium:374861
TEST=USE=buffet P2_TEST_FILTER="buffet::*" FEATURES=test emerge-link platform2
Change-Id: I5f2d5500bc90ef918a8a6df1242bdd1fe3b78615
Reviewed-on: https://chromium-review.googlesource.com/209175
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/commands/command_manager.cc b/buffet/commands/command_manager.cc
index fc04b2d..d7cf34c 100644
--- a/buffet/commands/command_manager.cc
+++ b/buffet/commands/command_manager.cc
@@ -4,10 +4,78 @@
#include "buffet/commands/command_manager.h"
+#include <base/file_util.h>
+#include <base/values.h>
+#include <base/json/json_reader.h>
+
+#include "buffet/commands/schema_constants.h"
+#include "buffet/error_codes.h"
+
namespace buffet {
const CommandDictionary& CommandManager::GetCommandDictionary() const {
return dictionary_;
}
+bool CommandManager::LoadBaseCommands(const base::DictionaryValue& json,
+ ErrorPtr* error) {
+ return base_dictionary_.LoadCommands(json, "", nullptr, error);
+}
+
+bool CommandManager::LoadBaseCommands(const base::FilePath& json_file_path,
+ ErrorPtr* error) {
+ std::unique_ptr<const base::DictionaryValue> json = LoadJsonDict(
+ json_file_path, error);
+ if (!json)
+ return false;
+ return LoadBaseCommands(*json, error);
+}
+
+bool CommandManager::LoadCommands(const base::DictionaryValue& json,
+ const std::string& category,
+ ErrorPtr* error) {
+ return dictionary_.LoadCommands(json, category, &base_dictionary_, error);
+}
+
+bool CommandManager::LoadCommands(const base::FilePath& json_file_path,
+ ErrorPtr* error) {
+ std::unique_ptr<const base::DictionaryValue> json = LoadJsonDict(
+ json_file_path, error);
+ if (!json)
+ return false;
+ std::string category = json_file_path.BaseName().RemoveExtension().value();
+ return LoadCommands(*json, category, error);
+}
+
+std::unique_ptr<const base::DictionaryValue> CommandManager::LoadJsonDict(
+ const base::FilePath& json_file_path, ErrorPtr* error) {
+ std::string json_string;
+ if (!base::ReadFileToString(json_file_path, &json_string)) {
+ Error::AddToPrintf(error, errors::file_system::kDomain,
+ errors::file_system::kFileReadError,
+ "Failed to read file '%s'",
+ json_file_path.value().c_str());
+ return std::unique_ptr<const base::DictionaryValue>();
+ }
+ std::string error_message;
+ base::Value* value = base::JSONReader::ReadAndReturnError(
+ json_string, base::JSON_PARSE_RFC, nullptr, &error_message);
+ if (!value) {
+ Error::AddToPrintf(error, errors::json::kDomain, errors::json::kParseError,
+ "Error parsing content of JSON file '%s': %s",
+ json_file_path.value().c_str(), error_message.c_str());
+ return std::unique_ptr<const base::DictionaryValue>();
+ }
+ const base::DictionaryValue* dict_value = nullptr;
+ if (!value->GetAsDictionary(&dict_value)) {
+ delete value;
+ Error::AddToPrintf(error, errors::json::kDomain,
+ errors::json::kObjectExpected,
+ "Content of file '%s' is not a JSON object",
+ json_file_path.value().c_str());
+ return std::unique_ptr<const base::DictionaryValue>();
+ }
+ return std::unique_ptr<const base::DictionaryValue>(dict_value);
+}
+
} // namespace buffet