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