chromeos-dbus-bindings: Add support for sending signals from the adaptor.
This patch creates helper methods in the Adaptor to send the defined
signals with the right signature.
BUG=chromium:426531
TEST=Unittests
Change-Id: Ib9b9c2bc125a3edbff368d3a2bccb80ba06ba089
Reviewed-on: https://chromium-review.googlesource.com/225306
Reviewed-by: Paul Stewart <pstew@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/chromeos-dbus-bindings/adaptor_generator.cc b/chromeos-dbus-bindings/adaptor_generator.cc
index 02c751e..53f7e79 100644
--- a/chromeos-dbus-bindings/adaptor_generator.cc
+++ b/chromeos-dbus-bindings/adaptor_generator.cc
@@ -55,6 +55,7 @@
text.PushOffset(kBlockOffset);
AddMethodInterface(interface, &text);
AddConstructor(interface, adaptor_name, &text);
+ AddSendSignalMethods(interface, &text);
text.AddLine(StringPrintf("virtual ~%s() = default;", adaptor_name.c_str()));
text.AddLine("virtual void OnRegisterComplete(bool success) {}");
text.PopOffset();
@@ -75,6 +76,7 @@
text.PushOffset(kBlockOffset);
text.AddLine("MethodInterface* interface_; // Owned by caller.");
text.AddLine("chromeos::dbus_utils::DBusObject dbus_object_;");
+ AddSignalDataMembers(interface, &text);
text.AddLine("// Owned by |dbus_object_|.");
text.AddLine("chromeos::dbus_utils::DBusInterface* dbus_interface_;");
text.AddLine(StringPrintf(
@@ -111,6 +113,17 @@
block.AddLine("bus,");
block.AddLine("dbus::ObjectPath(object_path)),");
block.PopOffset();
+
+ // Signal constructors.
+ for (const auto& signal : interface.signals) {
+ block.AddLine(StringPrintf("signal_%s_(", signal.name.c_str()));
+ block.PushOffset(kLineContinuationOffset);
+ block.AddLine("&dbus_object_,");
+ block.AddLine(StringPrintf("\"%s\",", interface.name.c_str()));
+ block.AddLine(StringPrintf("\"%s\"),", signal.name.c_str()));
+ block.PopOffset();
+ }
+
block.AddLine("dbus_interface_(");
block.PushOffset(kLineContinuationOffset);
block.AddLine(StringPrintf(
@@ -184,4 +197,67 @@
text->AddBlock(block);
}
+// static
+void AdaptorGenerator::AddSendSignalMethods(const Interface& interface,
+ IndentedText *text) {
+ IndentedText block;
+ DbusSignature signature;
+
+ for (const auto& signal : interface.signals) {
+ block.AddLine(StringPrintf("void Send%sSignal(", signal.name.c_str()));
+ block.PushOffset(kLineContinuationOffset);
+ string last_argument;
+ int unnamed_args = 0;
+ string call_arguments; // The arguments to pass to the Send() call.
+ for (const auto& argument : signal.arguments) {
+ if (!last_argument.empty())
+ block.AddLine(last_argument + ",");
+ CHECK(signature.Parse(argument.type, &last_argument));
+ if (!IsIntegralType(last_argument))
+ last_argument = StringPrintf("const %s&", last_argument.c_str());
+ string argument_name = argument.name;
+ if (argument.name.empty())
+ argument_name = StringPrintf("_arg_%d", ++unnamed_args);
+ last_argument.append(" " + argument_name);
+ if (!call_arguments.empty())
+ call_arguments.append(", ");
+ call_arguments.append(argument_name);
+ }
+ block.AddLine(last_argument + ") {");
+ block.PopOffset();
+ block.PushOffset(kBlockOffset);
+ block.AddLine(StringPrintf(
+ "signal_%s_.Send(%s);", signal.name.c_str(), call_arguments.c_str()));
+ block.PopOffset();
+ block.AddLine("}");
+ }
+ text->AddBlock(block);
+}
+
+// static
+void AdaptorGenerator::AddSignalDataMembers(const Interface& interface,
+ IndentedText *text) {
+ IndentedText block;
+ DbusSignature signature;
+
+ for (const auto& signal : interface.signals) {
+ block.AddLine("chromeos::dbus_utils::DBusSignal<");
+ block.PushOffset(kLineContinuationOffset);
+ string last_argument;
+ for (const auto& argument : signal.arguments) {
+ if (!last_argument.empty())
+ block.AddLine(last_argument + ",");
+ CHECK(signature.Parse(argument.type, &last_argument));
+ if (!argument.name.empty())
+ last_argument.append(StringPrintf(" /* %s */", argument.name.c_str()));
+ }
+ block.AddLine(StringPrintf(
+ "%s> signal_%s_;", last_argument.c_str(), signal.name.c_str()));
+ block.PopOffset();
+ }
+ text->AddBlock(block);
+}
+
+
+
} // namespace chromeos_dbus_bindings
diff --git a/chromeos-dbus-bindings/adaptor_generator.h b/chromeos-dbus-bindings/adaptor_generator.h
index fe32409..689d5bf 100644
--- a/chromeos-dbus-bindings/adaptor_generator.h
+++ b/chromeos-dbus-bindings/adaptor_generator.h
@@ -41,6 +41,14 @@
static void AddMethodInterface(const Interface& interface,
IndentedText *text);
+ // Generates adaptor methods to send the signals.
+ static void AddSendSignalMethods(const Interface& interface,
+ IndentedText *text);
+
+ // Generates DBusSignal data members for the signals.
+ static void AddSignalDataMembers(const Interface& interface,
+ IndentedText *text);
+
DISALLOW_COPY_AND_ASSIGN(AdaptorGenerator);
};
diff --git a/chromeos-dbus-bindings/adaptor_generator_unittest.cc b/chromeos-dbus-bindings/adaptor_generator_unittest.cc
index 993091a..62d25d8 100644
--- a/chromeos-dbus-bindings/adaptor_generator_unittest.cc
+++ b/chromeos-dbus-bindings/adaptor_generator_unittest.cc
@@ -35,6 +35,12 @@
const char kMethod3Name[] = "Kiyoko";
const char kMethod3Return0[] = "x";
const char kMethod3Return1[] = "s";
+const char kSignal0Name[] = "Update";
+const char kSignal1Name[] = "Mapping";
+const char kSignal1Argument0[] = "s";
+const char kSignal1ArgumentName0[] = "key";
+const char kSignal1Argument1[] = "ao";
+
const char kInterfaceName[] = "org.chromium.TestInterface";
const char kExpectedContent[] = R"literal_string(
#include <string>
@@ -74,6 +80,14 @@
object_manager,
bus,
dbus::ObjectPath(object_path)),
+ signal_Update_(
+ &dbus_object_,
+ "org.chromium.TestInterface",
+ "Update"),
+ signal_Mapping_(
+ &dbus_object_,
+ "org.chromium.TestInterface",
+ "Mapping"),
dbus_interface_(
dbus_object_.AddOrGetInterface("org.chromium.TestInterface")) {
dbus_interface_->AddMethodHandler(
@@ -91,6 +105,15 @@
dbus_object_.RegisterAsync(base::Bind(
&TestInterfaceAdaptor::OnRegisterComplete, base::Unretained(this)));
}
+ void SendUpdateSignal(
+ ) {
+ signal_Update_.Send();
+ }
+ void SendMappingSignal(
+ const std::string& key,
+ const std::vector<dbus::ObjectPath>& _arg_1) {
+ signal_Mapping_.Send(key, _arg_1);
+ }
virtual ~TestInterfaceAdaptor() = default;
virtual void OnRegisterComplete(bool success) {}
@@ -102,6 +125,11 @@
private:
MethodInterface* interface_; // Owned by caller.
chromeos::dbus_utils::DBusObject dbus_object_;
+ chromeos::dbus_utils::DBusSignal<
+ > signal_Update_;
+ chromeos::dbus_utils::DBusSignal<
+ std::string /* key */,
+ std::vector<dbus::ObjectPath>> signal_Mapping_;
// Owned by |dbus_object_|.
chromeos::dbus_utils::DBusInterface* dbus_interface_;
DISALLOW_COPY_AND_ASSIGN(TestInterfaceAdaptor);
@@ -151,6 +179,16 @@
vector<Interface::Argument>{
{"", kMethod3Return0},
{"", kMethod3Return1}});
+ // Signals generate helper methods to send them.
+ interface.signals.emplace_back(
+ kSignal0Name,
+ vector<Interface::Argument>{});
+ interface.signals.emplace_back(
+ kSignal1Name,
+ vector<Interface::Argument>{
+ {kSignal1ArgumentName0, kSignal1Argument0},
+ {"", kSignal1Argument1}});
+
base::FilePath output_path = temp_dir_.path().Append("output.h");
EXPECT_TRUE(AdaptorGenerator::GenerateAdaptor(interface, output_path));
string contents;