buffet: Allow setting command results.
Next step in command results support: now there is
CommandInstance::SetResults method which allows results
modifications.
BUG=chromium:435607
TEST=cros_workon_make --test buffet
Change-Id: I1f5da9c3613a2996cea3f65f07945cc64bfeda2e
Reviewed-on: https://chromium-review.googlesource.com/231337
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Anton Muhin <antonm@chromium.org>
Commit-Queue: Anton Muhin <antonm@chromium.org>
diff --git a/buffet/commands/cloud_command_proxy.cc b/buffet/commands/cloud_command_proxy.cc
index 5cbf6e6..8aa27ba 100644
--- a/buffet/commands/cloud_command_proxy.cc
+++ b/buffet/commands/cloud_command_proxy.cc
@@ -18,6 +18,12 @@
device_registration_info_(device_registration_info) {
}
+void CloudCommandProxy::OnResultsChanged(const native_types::Object& results) {
+ base::DictionaryValue patch;
+ patch.Set("results", TypedValueToJson(results, nullptr).get());
+ device_registration_info_->UpdateCommand(command_instance_->GetID(), patch);
+}
+
void CloudCommandProxy::OnStatusChanged(const std::string& status) {
base::DictionaryValue patch;
// TODO(antonm): Change status to state.
diff --git a/buffet/commands/cloud_command_proxy.h b/buffet/commands/cloud_command_proxy.h
index 0c35c0c..e78ff44 100644
--- a/buffet/commands/cloud_command_proxy.h
+++ b/buffet/commands/cloud_command_proxy.h
@@ -24,6 +24,7 @@
~CloudCommandProxy() override = default;
// CommandProxyInterface implementation/overloads.
+ void OnResultsChanged(const native_types::Object& results) override;
void OnStatusChanged(const std::string& status) override;
void OnProgressChanged(int progress) override;
diff --git a/buffet/commands/command_dictionary.cc b/buffet/commands/command_dictionary.cc
index 930e044..58ab823 100644
--- a/buffet/commands/command_dictionary.cc
+++ b/buffet/commands/command_dictionary.cc
@@ -70,8 +70,7 @@
const ObjectSchema* base_parameters_def = nullptr;
const ObjectSchema* base_results_def = nullptr;
if (base_commands) {
- const CommandDefinition* cmd =
- base_commands->FindCommand(full_command_name);
+ auto cmd = base_commands->FindCommand(full_command_name);
if (cmd) {
base_parameters_def = cmd->GetParameters().get();
base_results_def = cmd->GetResults().get();
@@ -210,10 +209,11 @@
return dict;
}
-const CommandDefinition* CommandDictionary::FindCommand(
+std::shared_ptr<const CommandDefinition> CommandDictionary::FindCommand(
const std::string& command_name) const {
auto pair = definitions_.find(command_name);
- return (pair != definitions_.end()) ? pair->second.get() : nullptr;
+ return (pair != definitions_.end()) ? pair->second :
+ std::shared_ptr<const CommandDefinition>();
}
void CommandDictionary::Clear() {
diff --git a/buffet/commands/command_dictionary.h b/buffet/commands/command_dictionary.h
index c316fd5..d051c62 100644
--- a/buffet/commands/command_dictionary.h
+++ b/buffet/commands/command_dictionary.h
@@ -69,7 +69,8 @@
// Remove all the command definitions from the dictionary.
void Clear();
// Finds a definition for the given command.
- const CommandDefinition* FindCommand(const std::string& command_name) const;
+ std::shared_ptr<const CommandDefinition> FindCommand(
+ const std::string& command_name) const;
private:
std::shared_ptr<ObjectSchema> BuildObjectSchema(
diff --git a/buffet/commands/command_instance.cc b/buffet/commands/command_instance.cc
index 6cde43e..7d54ed7 100644
--- a/buffet/commands/command_instance.cc
+++ b/buffet/commands/command_instance.cc
@@ -26,14 +26,22 @@
const char CommandInstance::kStatusAborted[] = "aborted";
const char CommandInstance::kStatusExpired[] = "expired";
-CommandInstance::CommandInstance(const std::string& name,
- const std::string& category,
- const native_types::Object& parameters)
- : name_(name), category_(category), parameters_(parameters) {
+CommandInstance::CommandInstance(
+ const std::string& name,
+ const std::shared_ptr<const CommandDefinition>& command_definition,
+ const native_types::Object& parameters)
+ : name_(name),
+ command_definition_(command_definition),
+ parameters_(parameters) {
+ CHECK(command_definition_.get());
}
CommandInstance::~CommandInstance() = default;
+const std::string& CommandInstance::GetCategory() const {
+ return command_definition_->GetCategory();
+}
+
std::shared_ptr<const PropValue> CommandInstance::FindParameter(
const std::string& name) const {
std::shared_ptr<const PropValue> value;
@@ -110,7 +118,7 @@
return instance;
}
// Make sure we know how to handle the command with this name.
- const CommandDefinition* command_def = dictionary.FindCommand(command_name);
+ auto command_def = dictionary.FindCommand(command_name);
if (!command_def) {
chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
errors::commands::kInvalidCommandName,
@@ -120,7 +128,7 @@
}
native_types::Object parameters;
- if (!GetCommandParameters(json, command_def, ¶meters, error)) {
+ if (!GetCommandParameters(json, command_def.get(), ¶meters, error)) {
chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
errors::commands::kCommandFailed,
"Failed to validate command '%s'",
@@ -128,9 +136,7 @@
return instance;
}
- instance.reset(new CommandInstance(command_name,
- command_def->GetCategory(),
- parameters));
+ instance.reset(new CommandInstance(command_name, command_def, parameters));
// TODO(antonm): Move command_id to ctor and remove setter.
std::string command_id;
if (json->GetStringWithoutPathExpansion(commands::attributes::kCommand_Id,
@@ -145,6 +151,17 @@
proxies_.push_back(std::move(proxy));
}
+bool CommandInstance::SetResults(const native_types::Object& results) {
+ // TODO(antonm): Add validation.
+ if (results != results_) {
+ results_ = results;
+ for (auto& proxy : proxies_) {
+ proxy->OnResultsChanged(results_);
+ }
+ }
+ return true;
+}
+
bool CommandInstance::SetProgress(int progress) {
if (progress < 0 || progress > 100)
return false;
diff --git a/buffet/commands/command_instance.h b/buffet/commands/command_instance.h
index b324850..b3bd2e0 100644
--- a/buffet/commands/command_instance.h
+++ b/buffet/commands/command_instance.h
@@ -22,6 +22,7 @@
namespace buffet {
+class CommandDefinition;
class CommandDictionary;
class CommandProxyInterface;
class CommandQueue;
@@ -31,9 +32,10 @@
// Construct a command instance given the full command |name| which must
// be in format "<package_name>.<command_name>", a command |category| and
// a list of parameters and their values specified in |parameters|.
- CommandInstance(const std::string& name,
- const std::string& category,
- const native_types::Object& parameters);
+ CommandInstance(
+ const std::string& name,
+ const std::shared_ptr<const CommandDefinition>& command_definition,
+ const native_types::Object& parameters);
~CommandInstance();
// Returns the full command ID.
@@ -41,13 +43,20 @@
// Returns the full name of the command.
const std::string& GetName() const { return name_; }
// Returns the command category.
- const std::string& GetCategory() const { return category_; }
+ const std::string& GetCategory() const;
// Returns the command parameters and their values.
const native_types::Object& GetParameters() const { return parameters_; }
+ // Returns the command results and their values.
+ const native_types::Object& GetResults() const { return results_; }
// Finds a command parameter value by parameter |name|. If the parameter
// with given name does not exist, returns null shared_ptr.
std::shared_ptr<const PropValue> FindParameter(const std::string& name) const;
+ // Returns command definition.
+ std::shared_ptr<const CommandDefinition> GetCommandDefinition() const {
+ return command_definition_;
+ }
+
// Parses a command instance JSON definition and constructs a CommandInstance
// object, checking the JSON |value| against the command definition schema
// found in command |dictionary|. On error, returns null unique_ptr and
@@ -66,8 +75,12 @@
// Sets the pointer to queue this command is part of.
void SetCommandQueue(CommandQueue* queue) { queue_ = queue; }
+ // Updates the command results. The |results| should match the schema.
+ // Returns false if |results| value is incorrect.
+ bool SetResults(const native_types::Object& results);
+
// Updates the command execution progress. The |progress| must be between
- // 0 and 100. Returns false if the progress value is incorrect.
+ // 0 and 100. Returns false if |progress| value is incorrect.
bool SetProgress(int progress);
// Aborts command execution.
void Abort();
@@ -103,12 +116,12 @@
std::string id_;
// Full command name as "<package_name>.<command_name>".
std::string name_;
- // Command category. See comments for CommandDefinitions::LoadCommands for the
- // detailed description of what command categories are and what they are used
- // for.
- std::string category_;
+ // Command definition.
+ std::shared_ptr<const CommandDefinition> command_definition_;
// Command parameters and their values.
native_types::Object parameters_;
+ // Command results.
+ native_types::Object results_;
// Current command status.
std::string status_ = kStatusQueued;
// Current command execution progress.
diff --git a/buffet/commands/command_instance_unittest.cc b/buffet/commands/command_instance_unittest.cc
index d5afc70..420361e 100644
--- a/buffet/commands/command_instance_unittest.cc
+++ b/buffet/commands/command_instance_unittest.cc
@@ -8,6 +8,7 @@
#include "buffet/commands/command_dictionary.h"
#include "buffet/commands/prop_types.h"
+#include "buffet/commands/schema_utils.h"
#include "buffet/commands/unittest_utils.h"
using buffet::unittests::CreateDictionaryValue;
@@ -65,26 +66,36 @@
} // anonymous namespace
-TEST(CommandInstance, Test) {
- buffet::native_types::Object params;
+TEST_F(CommandInstanceTest, Test) {
+ buffet::StringPropType str_prop;
buffet::IntPropType int_prop;
- buffet::DoublePropType dbl_prop;
- params.insert(std::make_pair("freq", dbl_prop.CreateValue(800.5, nullptr)));
- params.insert(std::make_pair("volume", int_prop.CreateValue(100, nullptr)));
- buffet::CommandInstance instance("robot._beep", "robotd", params);
+ buffet::native_types::Object params;
+ params["phrase"] = str_prop.CreateValue(std::string("iPityDaFool"),
+ nullptr);
+ params["volume"] = int_prop.CreateValue(5, nullptr);
+ buffet::CommandInstance instance("robot.speak",
+ dict_.FindCommand("robot.speak"),
+ params);
+
+ buffet::native_types::Object results;
+ results["foo"] = int_prop.CreateValue(239, nullptr);
+ instance.SetResults(results);
EXPECT_EQ("", instance.GetID());
- EXPECT_EQ("robot._beep", instance.GetName());
+ EXPECT_EQ("robot.speak", instance.GetName());
EXPECT_EQ("robotd", instance.GetCategory());
EXPECT_EQ(params, instance.GetParameters());
- EXPECT_DOUBLE_EQ(800.5,
- instance.FindParameter("freq")->GetDouble()->GetValue());
- EXPECT_EQ(100, instance.FindParameter("volume")->GetInt()->GetValue());
+ EXPECT_EQ("iPityDaFool",
+ instance.FindParameter("phrase")->GetString()->GetValue());
+ EXPECT_EQ(5, instance.FindParameter("volume")->GetInt()->GetValue());
EXPECT_EQ(nullptr, instance.FindParameter("blah").get());
+ EXPECT_EQ(results, instance.GetResults());
}
-TEST(CommandInstance, SetID) {
- buffet::CommandInstance instance("robot._beep", "robotd", {});
+TEST_F(CommandInstanceTest, SetID) {
+ buffet::CommandInstance instance("robot._beep",
+ dict_.FindCommand("robot.speak"),
+ {});
instance.SetID("command_id");
EXPECT_EQ("command_id", instance.GetID());
}
diff --git a/buffet/commands/command_proxy_interface.h b/buffet/commands/command_proxy_interface.h
index f9e78d6..f434c75 100644
--- a/buffet/commands/command_proxy_interface.h
+++ b/buffet/commands/command_proxy_interface.h
@@ -7,6 +7,8 @@
#include <string>
+#include "buffet/commands/schema_utils.h"
+
namespace buffet {
// This interface lets the command instance to update its proxy of command
@@ -16,6 +18,7 @@
public:
virtual ~CommandProxyInterface() = default;
+ virtual void OnResultsChanged(const native_types::Object& results) = 0;
virtual void OnStatusChanged(const std::string& status) = 0;
virtual void OnProgressChanged(int progress) = 0;
};
diff --git a/buffet/commands/command_queue_unittest.cc b/buffet/commands/command_queue_unittest.cc
index bea01c5..97431b8 100644
--- a/buffet/commands/command_queue_unittest.cc
+++ b/buffet/commands/command_queue_unittest.cc
@@ -11,14 +11,20 @@
#include <chromeos/strings/string_utils.h>
#include <gtest/gtest.h>
+#include "buffet/commands/command_definition.h"
#include "buffet/commands/command_dispatch_interface.h"
+#include "buffet/commands/object_schema.h"
namespace {
std::unique_ptr<buffet::CommandInstance> CreateDummyCommandInstance(
const std::string& name, const std::string& id) {
+ auto command_definition = std::make_shared<const buffet::CommandDefinition>(
+ "powerd",
+ std::make_shared<const buffet::ObjectSchema>(),
+ std::make_shared<const buffet::ObjectSchema>());
auto cmd = std::unique_ptr<buffet::CommandInstance>(
- new buffet::CommandInstance(name, "powerd", {}));
+ new buffet::CommandInstance(name, command_definition, {}));
cmd->SetID(id);
return cmd;
}
diff --git a/buffet/commands/dbus_command_proxy.cc b/buffet/commands/dbus_command_proxy.cc
index 2778a78..a067772 100644
--- a/buffet/commands/dbus_command_proxy.cc
+++ b/buffet/commands/dbus_command_proxy.cc
@@ -7,7 +7,9 @@
#include <chromeos/dbus/async_event_sequencer.h>
#include <chromeos/dbus/exported_object_manager.h>
+#include "buffet/commands/command_definition.h"
#include "buffet/commands/command_instance.h"
+#include "buffet/commands/object_schema.h"
#include "buffet/commands/prop_constraints.h"
#include "buffet/commands/prop_types.h"
@@ -34,19 +36,20 @@
dbus_adaptor_.SetId(command_instance_->GetID());
dbus_adaptor_.SetStatus(command_instance_->GetStatus());
dbus_adaptor_.SetProgress(command_instance_->GetProgress());
- // Convert a string-to-PropValue map into a string-to-Any map which can be
- // sent over D-Bus.
- chromeos::VariantDictionary params;
- for (const auto& param_pair : command_instance_->GetParameters()) {
- params.insert(std::make_pair(param_pair.first,
- param_pair.second->GetValueAsAny()));
- }
- dbus_adaptor_.SetParameters(params);
+
+ dbus_adaptor_.SetParameters(ObjectToDBusVariant(
+ command_instance_->GetParameters()));
+ dbus_adaptor_.SetResults(ObjectToDBusVariant(
+ command_instance_->GetResults()));
// Register the command DBus object and expose its methods and properties.
dbus_object_.RegisterAsync(completion_callback);
}
+void DBusCommandProxy::OnResultsChanged(const native_types::Object& results) {
+ dbus_adaptor_.SetResults(ObjectToDBusVariant(results));
+}
+
void DBusCommandProxy::OnStatusChanged(const std::string& status) {
dbus_adaptor_.SetStatus(status);
}
@@ -71,6 +74,20 @@
return true;
}
+bool DBusCommandProxy::SetResults(chromeos::ErrorPtr* error,
+ const chromeos::VariantDictionary& results) {
+ LOG(INFO) << "Received call to Command<"
+ << command_instance_->GetName() << ">::SetResults()";
+
+ auto results_schema = command_instance_->GetCommandDefinition()->GetResults();
+ native_types::Object obj;
+ if (!ObjectFromDBusVariant(results_schema.get(), results, &obj, error))
+ return false;
+
+ command_instance_->SetResults(obj);
+ return true;
+}
+
void DBusCommandProxy::Abort() {
LOG(INFO) << "Received call to Command<"
<< command_instance_->GetName() << ">::Abort()";
diff --git a/buffet/commands/dbus_command_proxy.h b/buffet/commands/dbus_command_proxy.h
index f3f3e4e..2d0f478 100644
--- a/buffet/commands/dbus_command_proxy.h
+++ b/buffet/commands/dbus_command_proxy.h
@@ -39,12 +39,16 @@
completion_callback);
// CommandProxyInterface implementation/overloads.
+ void OnResultsChanged(const native_types::Object& results) override;
void OnStatusChanged(const std::string& status) override;
void OnProgressChanged(int progress) override;
private:
// Handles calls to org.chromium.Buffet.Command.SetProgress(progress).
bool SetProgress(chromeos::ErrorPtr* error, int32_t progress) override;
+ // Handles calls to org.chromium.Buffet.Command.SetResults(results).
+ bool SetResults(chromeos::ErrorPtr* error,
+ const chromeos::VariantDictionary& results) override;
// Handles calls to org.chromium.Buffet.Command.Abort().
void Abort() override;
// Handles calls to org.chromium.Buffet.Command.Cancel().
diff --git a/buffet/commands/dbus_command_proxy_unittest.cc b/buffet/commands/dbus_command_proxy_unittest.cc
index a810464..eac207b 100644
--- a/buffet/commands/dbus_command_proxy_unittest.cc
+++ b/buffet/commands/dbus_command_proxy_unittest.cc
@@ -65,7 +65,14 @@
'enum': ['_withAirFlip', '_withSpin', '_withKick']
}
},
- 'results': {}
+ 'results': {
+ 'foo': {
+ 'type': 'integer'
+ },
+ 'bar': {
+ 'type': 'string'
+ }
+ }
}
}
})");
@@ -129,6 +136,10 @@
return GetCommandProxy()->dbus_adaptor_.GetParameters();
}
+ VariantDictionary GetResults() const {
+ return GetCommandProxy()->dbus_adaptor_.GetResults();
+ }
+
std::unique_ptr<dbus::Response> CallMethod(
const std::string& method_name,
const std::function<void(dbus::MessageWriter*)>& param_callback) {
@@ -185,9 +196,12 @@
{"height", int32_t{53}},
{"_jumpType", std::string{"_withKick"}},
};
+ VariantDictionary results;
+
EXPECT_EQ(CommandInstance::kStatusQueued, GetStatus());
EXPECT_EQ(0, GetProgress());
EXPECT_EQ(params, GetParameters());
+ EXPECT_EQ(results, GetResults());
EXPECT_EQ("robot.jump",
GetPropertyValue<std::string>(dbus_constants::kCommandName));
EXPECT_EQ(kTestCommandCategoty,
@@ -200,6 +214,9 @@
EXPECT_EQ(params,
GetPropertyValue<VariantDictionary>(
dbus_constants::kCommandParameters));
+ EXPECT_EQ(results,
+ GetPropertyValue<VariantDictionary>(
+ dbus_constants::kCommandResults));
}
TEST_F(DBusCommandProxyTest, SetProgress) {
@@ -226,6 +243,35 @@
EXPECT_EQ(0, GetProgress());
}
+TEST_F(DBusCommandProxyTest, SetResults) {
+ EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
+ const VariantDictionary results = {
+ {"foo", int32_t{42}},
+ {"bar", std::string{"foobar"}},
+ };
+ auto response = CallMethod(dbus_constants::kCommandSetResults,
+ [results](dbus::MessageWriter* writer) {
+ chromeos::dbus_utils::AppendValueToWriter(writer, results);
+ });
+ VerifyResponse(response, {});
+ EXPECT_EQ(results, GetResults());
+ EXPECT_EQ(results,
+ GetPropertyValue<VariantDictionary>(
+ dbus_constants::kCommandResults));
+}
+
+TEST_F(DBusCommandProxyTest, SetResults_UnknownProperty) {
+ EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(0);
+ const VariantDictionary results = {
+ {"quux", int32_t{42}},
+ };
+ auto response = CallMethod(dbus_constants::kCommandSetResults,
+ [results](dbus::MessageWriter* writer) {
+ chromeos::dbus_utils::AppendValueToWriter(writer, results);
+ });
+ EXPECT_TRUE(IsResponseError(response));
+}
+
TEST_F(DBusCommandProxyTest, Abort) {
EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
auto response = CallMethod(dbus_constants::kCommandAbort, {});
diff --git a/buffet/commands/schema_utils.cc b/buffet/commands/schema_utils.cc
index 8e83b1c..043f0ae 100644
--- a/buffet/commands/schema_utils.cc
+++ b/buffet/commands/schema_utils.cc
@@ -9,7 +9,6 @@
#include <string>
#include <base/json/json_writer.h>
-#include <chromeos/variant_dictionary.h>
#include "buffet/commands/object_schema.h"
#include "buffet/commands/prop_types.h"
@@ -202,10 +201,13 @@
chromeos::Any PropValueToDBusVariant(const PropValue* value) {
if (value->GetType() != ValueType::Object)
return value->GetValueAsAny();
- // Special case for object types.
- // Convert native_types::Object to chromeos::VariantDictionary
+ return ObjectToDBusVariant(value->GetObject()->GetValue());
+}
+
+chromeos::VariantDictionary
+ObjectToDBusVariant(const native_types::Object& object) {
chromeos::VariantDictionary dict;
- for (const auto& pair : value->GetObject()->GetValue()) {
+ for (const auto& pair : object) {
// Since we are inserting the elements from native_types::Object which is
// a map, the keys are already sorted. So use the "end()" position as a hint
// for dict.insert() so the destination map can optimize its insertion
@@ -213,7 +215,7 @@
chromeos::Any prop = PropValueToDBusVariant(pair.second.get());
dict.emplace_hint(dict.end(), pair.first, std::move(prop));
}
- return chromeos::Any(std::move(dict));
+ return dict;
}
std::shared_ptr<const PropValue> PropValueFromDBusVariant(
@@ -221,28 +223,41 @@
const chromeos::Any& value,
chromeos::ErrorPtr* error) {
std::shared_ptr<const PropValue> result;
- if (type->GetType() != ValueType::Object) {
+ if (type->GetType() == ValueType::Object) {
+ // Special case for object types.
+ // We expect the |value| to contain chromeos::VariantDictionary, while
+ // PropValue must use native_types::Object instead. Do the conversion.
+ if (!value.IsTypeCompatible<chromeos::VariantDictionary>()) {
+ type->GenerateErrorValueTypeMismatch(error);
+ return {};
+ }
+ CHECK(nullptr != type->GetObjectSchemaPtr())
+ << "An object type must have a schema defined for it";
+ native_types::Object obj;
+ if (!ObjectFromDBusVariant(type->GetObjectSchemaPtr(),
+ value.Get<chromeos::VariantDictionary>(),
+ &obj,
+ error))
+ return {};
+
+ result = type->CreateValue(std::move(obj), error);
+ } else {
result = type->CreateValue(value, error);
- if (result && !type->ValidateConstraints(*result, error))
- result.reset();
- return result;
}
- // Special case for object types.
- // We expect the |value| to contain chromeos::VariantDictionary, while
- // PropValue must use native_types::Object instead. Do the conversion.
- if (!value.IsTypeCompatible<chromeos::VariantDictionary>()) {
- type->GenerateErrorValueTypeMismatch(error);
- return result;
- }
- const auto& dict = value.Get<chromeos::VariantDictionary>();
- native_types::Object obj;
- CHECK(nullptr != type->GetObjectSchemaPtr())
- << "An object type must have a schema defined for it";
+ if (result && !type->ValidateConstraints(*result, error))
+ result.reset();
+ return result;
+}
+
+bool ObjectFromDBusVariant(const ObjectSchema* object_schema,
+ const chromeos::VariantDictionary& dict,
+ native_types::Object* obj,
+ chromeos::ErrorPtr* error) {
std::set<std::string> keys_processed;
// First go over all object parameters defined by type's object schema and
// extract the corresponding parameters from the source dictionary.
- for (const auto& pair : type->GetObjectSchemaPtr()->GetProps()) {
+ for (const auto& pair : object_schema->GetProps()) {
const PropValue* def_value = pair.second->GetDefaultValue();
auto it = dict.find(pair.first);
if (it != dict.end()) {
@@ -255,22 +270,22 @@
errors::commands::kInvalidPropValue,
"Invalid value for property '%s'",
pair.first.c_str());
- return result;
+ return false;
}
- obj.emplace_hint(obj.end(), pair.first, std::move(prop_value));
+ obj->emplace_hint(obj->end(), pair.first, std::move(prop_value));
} else if (def_value) {
std::shared_ptr<const PropValue> prop_value = def_value->Clone();
- obj.emplace_hint(obj.end(), pair.first, std::move(prop_value));
+ obj->emplace_hint(obj->end(), pair.first, std::move(prop_value));
} else {
ErrorMissingProperty(error, pair.first.c_str());
- return result;
+ return false;
}
keys_processed.insert(pair.first);
}
// Make sure that we processed all the necessary properties and there weren't
// any extra (unknown) ones specified, unless the schema allows them.
- if (!type->GetObjectSchemaPtr()->GetExtraPropertiesAllowed()) {
+ if (!object_schema->GetExtraPropertiesAllowed()) {
for (const auto& pair : dict) {
if (keys_processed.find(pair.first) == keys_processed.end()) {
chromeos::Error::AddToPrintf(error, FROM_HERE,
@@ -278,15 +293,12 @@
errors::commands::kUnknownProperty,
"Unrecognized property '%s'",
pair.first.c_str());
- return result;
+ return false;
}
}
}
- result = type->CreateValue(std::move(obj), error);
- if (result && !type->ValidateConstraints(*result, error))
- result.reset();
- return result;
+ return true;
}
} // namespace buffet
diff --git a/buffet/commands/schema_utils.h b/buffet/commands/schema_utils.h
index 33261f0..597a580 100644
--- a/buffet/commands/schema_utils.h
+++ b/buffet/commands/schema_utils.h
@@ -15,12 +15,14 @@
#include <base/values.h>
#include <chromeos/any.h>
#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
namespace buffet {
class PropType;
class PropValue;
class ObjectSchema;
+class ObjectValue;
namespace native_types {
// C++ representation of object values.
@@ -122,6 +124,10 @@
// Has special handling for Object types where native_types::Object are
// converted to chromeos::VariantDictionary.
chromeos::Any PropValueToDBusVariant(const PropValue* value);
+// Converts native_types::Object to chromeos::VariantDictionary
+// with proper conversion of all nested properties.
+chromeos::VariantDictionary
+ObjectToDBusVariant(const native_types::Object& object);
// Converts D-Bus variant to PropValue.
// Has special handling for Object types where chromeos::VariantDictionary
// is converted to native_types::Object.
@@ -129,6 +135,11 @@
const PropType* type,
const chromeos::Any& value,
chromeos::ErrorPtr* error);
+// Converts D-Bus variant to ObjectValue.
+bool ObjectFromDBusVariant(const ObjectSchema* object_schema,
+ const chromeos::VariantDictionary& dict,
+ native_types::Object* obj,
+ chromeos::ErrorPtr* error);
} // namespace buffet
diff --git a/buffet/dbus_bindings/org.chromium.Buffet.Command.xml b/buffet/dbus_bindings/org.chromium.Buffet.Command.xml
index 89d9efd..2f8ce2b 100644
--- a/buffet/dbus_bindings/org.chromium.Buffet.Command.xml
+++ b/buffet/dbus_bindings/org.chromium.Buffet.Command.xml
@@ -7,6 +7,10 @@
<arg name="progress" type="i" direction="in"/>
<annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
</method>
+ <method name="SetResults">
+ <arg name="results" type="a{sv}" direction="in"/>
+ <annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
+ </method>
<method name="Abort">
<annotation name="org.chromium.DBus.Method.Kind" value="simple"/>
</method>
@@ -22,5 +26,6 @@
<property name="Status" type="s" access="read"/>
<property name="Progress" type="i" access="read"/>
<property name="Parameters" type="a{sv}" access="read"/>
+ <property name="Results" type="a{sv}" access="read"/>
</interface>
</node>
diff --git a/buffet/libbuffet/dbus_constants.cc b/buffet/libbuffet/dbus_constants.cc
index 16cdb36..475ffba 100644
--- a/buffet/libbuffet/dbus_constants.cc
+++ b/buffet/libbuffet/dbus_constants.cc
@@ -26,6 +26,7 @@
const char kCommandInterface[] = "org.chromium.Buffet.Command";
const char kCommandServicePathPrefix[] = "/org/chromium/Buffet/commands/";
+const char kCommandSetResults[] = "SetResults";
const char kCommandSetProgress[] = "SetProgress";
const char kCommandAbort[] = "Abort";
const char kCommandCancel[] = "Cancel";
@@ -37,6 +38,7 @@
const char kCommandStatus[] = "Status";
const char kCommandProgress[] = "Progress";
const char kCommandParameters[] = "Parameters";
+const char kCommandResults[] = "Results";
} // namespace dbus_constants
diff --git a/buffet/libbuffet/dbus_constants.h b/buffet/libbuffet/dbus_constants.h
index e0dd22a..22a1447 100644
--- a/buffet/libbuffet/dbus_constants.h
+++ b/buffet/libbuffet/dbus_constants.h
@@ -35,6 +35,7 @@
LIBBUFFET_EXPORT extern const char kCommandServicePathPrefix[];
// Methods exposed as part of kCommandInterface.
+LIBBUFFET_EXPORT extern const char kCommandSetResults[];
LIBBUFFET_EXPORT extern const char kCommandSetProgress[];
LIBBUFFET_EXPORT extern const char kCommandAbort[];
LIBBUFFET_EXPORT extern const char kCommandCancel[];
@@ -47,6 +48,7 @@
LIBBUFFET_EXPORT extern const char kCommandStatus[];
LIBBUFFET_EXPORT extern const char kCommandProgress[];
LIBBUFFET_EXPORT extern const char kCommandParameters[];
+LIBBUFFET_EXPORT extern const char kCommandResults[];
} // namespace dbus_constants