libchromeos: Add support for async D-Bus method handlers
Changed DBusObject implementation infrastructure in libchromeos
to add support for registering asynchronous D-Bus method handlers.
Also changed the simple synchronous method handler signature to
eliminate the confusion when a handler returning a value throws
an error.
Currently, there are four kinds of D-Bus method handlers:
- SimpleMethodHandler - has one of the following signatures:
RetVal Handler(Args... args)
void Handler(Args... args)
The first one takes only input parameters (by value or const
reference) and returns a single value as a function return.
The second handler can mix both input (value/const reference)
and output (pointer) values.
This handler is synchronous (response is sent as soon as the
handler returns) and does not provide any error returns
(it always succeeds).
- SimpleMethodHanderWithError
This is similar to SimpleMethodHandler but provides a way
to return an error. The handler signature is as follows:
bool Handler(ErrorPtr* error, Args... args)
The parameters can include both IN and OUT arguments.
If the handler succeeds, it must return true. On failures,
it returns false and provides error details in |error|.
- MethodHandler - a generic (possibly asynchronous) handler
that has the following signature:
void Handler(scoped_ptr<DBusMethodResponse> response,
Args... args)
The parameters include only IN arguments and the method
sends back any return values using the |response| object.
The handler owns the |response| so it can start an
asynchronous operation (that holds on to the response) and
exit immediately. The D-Bus method response is sent only
when the handler provides the reply using the response
object.
- RawMethodHandler
This is the low-level method handler that does not go through
any of the parameter/return value parsing. It is provided
with the raw method call D-Bus message and is expected to
provide the response manually. The handler signtaure is:
void Handler(dbus::MethodCall* method_call,
ResponseSender sender)
This type of handler is useful to implement D-Bus methods
with variable number of parameters or those which
can accept a number of different types of arguments.
BUG=chromium:428390
TEST=FEATURES=test emerge-link libchromeos peerd buffet attestation
CQ-DEPEND=CL:227281
Change-Id: I1dde6b279ada9d350a4d0e6743c56d3b12cc38cf
Reviewed-on: https://chromium-review.googlesource.com/226666
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/commands/dbus_command_dispatcher_unittest.cc b/buffet/commands/dbus_command_dispatcher_unittest.cc
index 170d900..9de6889 100644
--- a/buffet/commands/dbus_command_dispatcher_unittest.cc
+++ b/buffet/commands/dbus_command_dispatcher_unittest.cc
@@ -108,7 +108,7 @@
}
void FinishCommand(DBusCommandProxy* proxy) {
- proxy->HandleDone(nullptr);
+ proxy->HandleDone();
}
void SetProgress(DBusCommandProxy* proxy, int progress) {
diff --git a/buffet/commands/dbus_command_proxy.cc b/buffet/commands/dbus_command_proxy.cc
index 0b97c06..07ead32 100644
--- a/buffet/commands/dbus_command_proxy.cc
+++ b/buffet/commands/dbus_command_proxy.cc
@@ -32,18 +32,18 @@
dbus_object_.AddOrGetInterface(dbus_constants::kCommandInterface);
// DBus methods.
- itf->AddMethodHandler(dbus_constants::kCommandSetProgress,
- base::Unretained(this),
- &DBusCommandProxy::HandleSetProgress);
- itf->AddMethodHandler(dbus_constants::kCommandAbort,
- base::Unretained(this),
- &DBusCommandProxy::HandleAbort);
- itf->AddMethodHandler(dbus_constants::kCommandCancel,
- base::Unretained(this),
- &DBusCommandProxy::HandleCancel);
- itf->AddMethodHandler(dbus_constants::kCommandDone,
- base::Unretained(this),
- &DBusCommandProxy::HandleDone);
+ itf->AddSimpleMethodHandlerWithError(dbus_constants::kCommandSetProgress,
+ base::Unretained(this),
+ &DBusCommandProxy::HandleSetProgress);
+ itf->AddSimpleMethodHandler(dbus_constants::kCommandAbort,
+ base::Unretained(this),
+ &DBusCommandProxy::HandleAbort);
+ itf->AddSimpleMethodHandler(dbus_constants::kCommandCancel,
+ base::Unretained(this),
+ &DBusCommandProxy::HandleCancel);
+ itf->AddSimpleMethodHandler(dbus_constants::kCommandDone,
+ base::Unretained(this),
+ &DBusCommandProxy::HandleDone);
// DBus properties.
itf->AddProperty(dbus_constants::kCommandName, &name_);
@@ -80,7 +80,7 @@
progress_.SetValue(progress);
}
-void DBusCommandProxy::HandleSetProgress(chromeos::ErrorPtr* error,
+bool DBusCommandProxy::HandleSetProgress(chromeos::ErrorPtr* error,
int32_t progress) {
LOG(INFO) << "Received call to Command<"
<< command_instance_->GetName() << ">::SetProgress("
@@ -89,24 +89,26 @@
// Validate |progress| parameter. Its value must be between 0 and 100.
IntPropType progress_type;
progress_type.AddMinMaxConstraint(0, 100);
- if (progress_type.ValidateValue(progress, error)) {
- command_instance_->SetProgress(progress);
- }
+ if (!progress_type.ValidateValue(progress, error))
+ return false;
+
+ command_instance_->SetProgress(progress);
+ return true;
}
-void DBusCommandProxy::HandleAbort(chromeos::ErrorPtr* error) {
+void DBusCommandProxy::HandleAbort() {
LOG(INFO) << "Received call to Command<"
<< command_instance_->GetName() << ">::Abort()";
command_instance_->Abort();
}
-void DBusCommandProxy::HandleCancel(chromeos::ErrorPtr* error) {
+void DBusCommandProxy::HandleCancel() {
LOG(INFO) << "Received call to Command<"
<< command_instance_->GetName() << ">::Cancel()";
command_instance_->Cancel();
}
-void DBusCommandProxy::HandleDone(chromeos::ErrorPtr* error) {
+void DBusCommandProxy::HandleDone() {
LOG(INFO) << "Received call to Command<"
<< command_instance_->GetName() << ">::Done()";
command_instance_->Done();
diff --git a/buffet/commands/dbus_command_proxy.h b/buffet/commands/dbus_command_proxy.h
index 553470e..50878fb 100644
--- a/buffet/commands/dbus_command_proxy.h
+++ b/buffet/commands/dbus_command_proxy.h
@@ -50,13 +50,13 @@
parameters_;
// Handles calls to org.chromium.Buffet.Command.SetProgress(progress).
- void HandleSetProgress(chromeos::ErrorPtr* error, int32_t progress);
+ bool HandleSetProgress(chromeos::ErrorPtr* error, int32_t progress);
// Handles calls to org.chromium.Buffet.Command.Abort().
- void HandleAbort(chromeos::ErrorPtr* error);
+ void HandleAbort();
// Handles calls to org.chromium.Buffet.Command.Cancel().
- void HandleCancel(chromeos::ErrorPtr* error);
+ void HandleCancel();
// Handles calls to org.chromium.Buffet.Command.Done().
- void HandleDone(chromeos::ErrorPtr* error);
+ void HandleDone();
dbus::ObjectPath object_path_;
CommandInstance* command_instance_;
diff --git a/buffet/commands/dbus_command_proxy_unittest.cc b/buffet/commands/dbus_command_proxy_unittest.cc
index f8fba8d..ae91b13 100644
--- a/buffet/commands/dbus_command_proxy_unittest.cc
+++ b/buffet/commands/dbus_command_proxy_unittest.cc
@@ -9,6 +9,7 @@
#include <dbus/mock_exported_object.h>
#include <dbus/property.h>
#include <chromeos/dbus/dbus_object.h>
+#include <chromeos/dbus/dbus_object_test_helpers.h>
#include <gtest/gtest.h>
#include "buffet/commands/command_dictionary.h"
@@ -131,8 +132,8 @@
dbus::MessageWriter writer(&method_call);
if (param_callback)
param_callback(&writer);
- return chromeos::dbus_utils::CallMethod(*GetProxyDBusObject(),
- &method_call);
+ return chromeos::dbus_utils::testing::CallMethod(*GetProxyDBusObject(),
+ &method_call);
}
static bool IsResponseError(const std::unique_ptr<dbus::Response>& response) {
@@ -157,8 +158,8 @@
dbus::MessageWriter writer(&method_call);
writer.AppendString(dbus_constants::kCommandInterface);
writer.AppendString(property_name);
- auto response = chromeos::dbus_utils::CallMethod(*GetProxyDBusObject(),
- &method_call);
+ auto response = chromeos::dbus_utils::testing::CallMethod(
+ *GetProxyDBusObject(), &method_call);
T value{};
VerifyResponse(response, [&value](dbus::MessageReader* reader) {
EXPECT_TRUE(chromeos::dbus_utils::PopValueFromReader(reader, &value));