summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@chromium.org>2015-01-21 10:37:00 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-01-22 22:45:42 +0000
commit008e19dd69bfc8439454a14df159b5a829881956 (patch)
treeaf8bfbd9719e268aa93afe24d5423cd23a562a85
parente11e81c98987c5bd4b3d50f5cd0188c2b25df864 (diff)
downloaddbus-binding-generator-008e19dd69bfc8439454a14df159b5a829881956.tar.gz
chromeos-dbus-bindings: Added proxy mock generation
Now it is possible to generate Mocks for D-Bus proxy objects to mock out the D-Bus interfaces in tests. A new option --mock=<file> is added to the generator to specify the output file for the mock objects. If used with --proxy, the mock header file will include the proxy header file to share the definition of the common interface proxy abstract interface. Otherwise, the mock header file will provide its own definition of that abstract interface. As a result, the proxy generation has been changed to include the base abstract interface for the D-Bus interface proxy class which the proxy and/or mock objects derive from. The code using the proxy objects can be updated to pass around the abstract interface instead of concrete proxy classes which will make it possible to substruture proxies with mocks and facilitate testing of the code using D-Bus proxies. GYP action now has another variable 'mock_output_file' which can be used along with 'proxy_output_file' to control the location of the generated mock header file: 'actions': [ { 'action_name': 'generate-buffet-proxies', 'variables': { 'dbus_service_config': 'dbus_bindings/dbus-service-config.json', 'proxy_output_file': 'include/buffet/dbus-proxies.h' 'mock_output_file': 'include/buffet/dbus-mocks.h' }, 'sources': [ 'dbus_bindings/org.chromium.Buffet.Command.xml', 'dbus_bindings/org.chromium.Buffet.Manager.xml', ], 'includes': ['../common-mk/generate-dbus-proxies.gypi'], }, ], BUG=chromium:449176 TEST=FEATURES=test emerge-link chromeos-dbus-bindings Manually tested the generated proxy and mock classes with buffet. Change-Id: I1fb84cfbfd751793df72ad5b050ee1cf00a64d62 Reviewed-on: https://chromium-review.googlesource.com/242276 Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Alex Vakulenko <avakulenko@chromium.org> Tested-by: Alex Vakulenko <avakulenko@chromium.org>
-rw-r--r--chromeos-dbus-bindings/chromeos-dbus-bindings.gyp1
-rw-r--r--chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc22
-rw-r--r--chromeos-dbus-bindings/proxy_generator.cc378
-rw-r--r--chromeos-dbus-bindings/proxy_generator.h28
-rw-r--r--chromeos-dbus-bindings/proxy_generator_mock_unittest.cc205
-rw-r--r--chromeos-dbus-bindings/proxy_generator_unittest.cc203
6 files changed, 761 insertions, 76 deletions
diff --git a/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp b/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp
index 79468c1..9c78992 100644
--- a/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp
+++ b/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp
@@ -81,6 +81,7 @@
'indented_text_unittest.cc',
'method_name_generator_unittest.cc',
'name_parser_unittest.cc',
+ 'proxy_generator_mock_unittest.cc',
'proxy_generator_unittest.cc',
'xml_interface_parser_unittest.cc',
],
diff --git a/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc b/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc
index 62ba036..b8f1454 100644
--- a/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc
+++ b/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc
@@ -30,6 +30,7 @@ static const char kHelp[] = "help";
static const char kMethodNames[] = "method-names";
static const char kAdaptor[] = "adaptor";
static const char kProxy[] = "proxy";
+static const char kMock[] = "mock";
static const char kServiceConfig[] = "service-config";
static const char kHelpMessage[] = "\n"
"generate-chromeos-dbus-bindings itf1.xml [itf2.xml...] [switches]\n"
@@ -41,6 +42,8 @@ static const char kHelpMessage[] = "\n"
" The output header file name containing the DBus adaptor class.\n"
" --proxy=<proxy header filename>\n"
" The output header file name containing the DBus proxy class.\n"
+ " --mock=<mock header filename>\n"
+ " The output header file name containing the DBus proxy mock class.\n"
" --service-config=<config.json>\n"
" The DBus service configuration file for the generator.\n";
@@ -183,15 +186,30 @@ int main(int argc, char** argv) {
}
}
+ base::FilePath proxy_path; // Used by both Proxy and Mock generation.
if (cl->HasSwitch(switches::kProxy)) {
std::string proxy_file = cl->GetSwitchValueASCII(switches::kProxy);
- VLOG(1) << "Outputting proxy to " << proxy_file;
+ proxy_path = RemoveQuotes(proxy_file);
+ base::NormalizeFilePath(proxy_path, &proxy_path);
+ VLOG(1) << "Outputting proxy to " << proxy_path.value();
if (!ProxyGenerator::GenerateProxies(config, parser.interfaces(),
- RemoveQuotes(proxy_file))) {
+ proxy_path)) {
LOG(ERROR) << "Failed to output proxy.";
return 1;
}
}
+ if (cl->HasSwitch(switches::kMock)) {
+ std::string mock_file = cl->GetSwitchValueASCII(switches::kMock);
+ base::FilePath mock_path = RemoveQuotes(mock_file);
+ base::NormalizeFilePath(mock_path, &mock_path);
+ VLOG(1) << "Outputting mock to " << mock_path.value();
+ if (!ProxyGenerator::GenerateMocks(config, parser.interfaces(), mock_path,
+ proxy_path)) {
+ LOG(ERROR) << "Failed to output mock.";
+ return 1;
+ }
+ }
+
return 0;
}
diff --git a/chromeos-dbus-bindings/proxy_generator.cc b/chromeos-dbus-bindings/proxy_generator.cc
index 797a7d5..adc7004 100644
--- a/chromeos-dbus-bindings/proxy_generator.cc
+++ b/chromeos-dbus-bindings/proxy_generator.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <chromeos/strings/string_utils.h>
@@ -86,6 +87,7 @@ bool ProxyGenerator::GenerateProxies(
}
for (const auto& interface : interfaces) {
+ GenerateInterfaceProxyInterface(config, interface, &text);
GenerateInterfaceProxy(config, interface, &text);
}
@@ -96,11 +98,125 @@ bool ProxyGenerator::GenerateProxies(
}
// static
+bool ProxyGenerator::GenerateMocks(const ServiceConfig& config,
+ const std::vector<Interface>& interfaces,
+ const base::FilePath& mock_file,
+ const base::FilePath& proxy_file) {
+ IndentedText text;
+
+ text.AddLine("// Automatic generation of D-Bus interface mock proxies for:");
+ for (const auto& interface : interfaces) {
+ text.AddLine(StringPrintf("// - %s", interface.name.c_str()));
+ }
+ string header_guard = GenerateHeaderGuard(mock_file);
+ text.AddLine(StringPrintf("#ifndef %s", header_guard.c_str()));
+ text.AddLine(StringPrintf("#define %s", header_guard.c_str()));
+ text.AddLine("#include <string>");
+ text.AddLine("#include <vector>");
+ text.AddBlankLine();
+ text.AddLine("#include <base/callback_forward.h>");
+ text.AddLine("#include <base/macros.h>");
+ text.AddLine("#include <chromeos/any.h>");
+ text.AddLine("#include <chromeos/errors/error.h>");
+ text.AddLine("#include <chromeos/variant_dictionary.h>");
+ text.AddLine("#include <gmock/gmock.h>");
+ text.AddBlankLine();
+
+ if (!proxy_file.empty()) {
+ // If we have a proxy header file, it would have the proxy interfaces we
+ // need to base our mocks on, so we need to include that header file.
+ // Generate a relative path from |mock_file| to |proxy_file|.
+
+ // First, get the path components for both source and destination paths.
+ std::vector<base::FilePath::StringType> src_components;
+ mock_file.DirName().GetComponents(&src_components);
+ std::vector<base::FilePath::StringType> dest_components;
+ proxy_file.DirName().GetComponents(&dest_components);
+
+ // Find the common root.
+
+ // I wish we had C++14 and its 4-parameter version of std::mismatch()...
+ auto src_end = src_components.end();
+ if (src_components.size() > dest_components.size())
+ src_end = src_components.begin() + dest_components.size();
+
+ auto mismatch_pair =
+ std::mismatch(src_components.begin(), src_end, dest_components.begin());
+
+ // For each remaining components in the |src_components|, generate the
+ // parent directory references ("..").
+ size_t src_count = std::distance(mismatch_pair.first, src_components.end());
+ std::vector<base::FilePath::StringType> components{
+ src_count, base::FilePath::kParentDirectory};
+ // Append the remaining components from |dest_components|.
+ components.insert(components.end(),
+ mismatch_pair.second, dest_components.end());
+ // Finally, add the base name of the target file name.
+ components.push_back(proxy_file.BaseName().value());
+ // Now reconstruct the relative path.
+ base::FilePath relative_path{base::FilePath::kCurrentDirectory};
+ for (const auto& component : components)
+ relative_path = relative_path.Append(component);
+ text.AddLine(StringPrintf("#include \"%s\"",
+ relative_path.value().c_str()));
+ text.AddBlankLine();
+ }
+
+ for (const auto& interface : interfaces) {
+ // If we have no proxy file, we need the abstract interfaces generated here.
+ if (proxy_file.empty())
+ GenerateInterfaceProxyInterface(config, interface, &text);
+ GenerateInterfaceMock(config, interface, &text);
+ }
+
+ text.AddLine(StringPrintf("#endif // %s", header_guard.c_str()));
+ return WriteTextToFile(mock_file, text);
+}
+
+// static
+void ProxyGenerator::GenerateInterfaceProxyInterface(
+ const ServiceConfig& config,
+ const Interface& interface,
+ IndentedText* text) {
+ NameParser parser{interface.name};
+ string proxy_name = parser.MakeProxyName(false);
+ string base_interface_name = proxy_name + "Interface";
+
+ parser.AddOpenNamespaces(text, false);
+ text->AddBlankLine();
+
+ text->AddLine(StringPrintf("// Abstract interface proxy for %s.",
+ parser.MakeFullCppName().c_str()));
+ text->AddComments(interface.doc_string);
+ text->AddLine(StringPrintf("class %s {", base_interface_name.c_str()));
+ text->AddLineWithOffset("public:", kScopeOffset);
+ text->PushOffset(kBlockOffset);
+
+ for (const auto& method : interface.methods) {
+ AddMethodProxy(method, interface.name, true, text);
+ AddAsyncMethodProxy(method, interface.name, true, text);
+ }
+ AddProperties(config, interface, true, text);
+
+ text->PopOffset();
+ text->AddLineWithOffset("protected:", kScopeOffset);
+ text->AddLineWithOffset(
+ StringPrintf("~%s() = default;", base_interface_name.c_str()),
+ kBlockOffset);
+ text->AddLine("};");
+ text->AddBlankLine();
+
+ parser.AddCloseNamespaces(text, false);
+ text->AddBlankLine();
+}
+
+// static
void ProxyGenerator::GenerateInterfaceProxy(const ServiceConfig& config,
const Interface& interface,
IndentedText* text) {
NameParser parser{interface.name};
string proxy_name = parser.MakeProxyName(false);
+ string base_interface_name = proxy_name + "Interface";
parser.AddOpenNamespaces(text, false);
text->AddBlankLine();
@@ -108,7 +224,8 @@ void ProxyGenerator::GenerateInterfaceProxy(const ServiceConfig& config,
text->AddLine(StringPrintf("// Interface proxy for %s.",
parser.MakeFullCppName().c_str()));
text->AddComments(interface.doc_string);
- text->AddLine(StringPrintf("class %s final {", proxy_name.c_str()));
+ text->AddLine(StringPrintf("class %s final : public %s {",
+ proxy_name.c_str(), base_interface_name.c_str()));
text->AddLineWithOffset("public:", kScopeOffset);
text->PushOffset(kBlockOffset);
AddPropertySet(config, interface, text);
@@ -121,10 +238,10 @@ void ProxyGenerator::GenerateInterfaceProxy(const ServiceConfig& config,
if (!config.object_manager.name.empty() && !interface.properties.empty())
AddPropertyPublicMethods(proxy_name, text);
for (const auto& method : interface.methods) {
- AddMethodProxy(method, interface.name, text);
- AddAsyncMethodProxy(method, interface.name, text);
+ AddMethodProxy(method, interface.name, false, text);
+ AddAsyncMethodProxy(method, interface.name, false, text);
}
- AddProperties(config, interface, text);
+ AddProperties(config, interface, false, text);
text->PopOffset();
text->AddLineWithOffset("private:", kScopeOffset);
@@ -172,6 +289,54 @@ void ProxyGenerator::GenerateInterfaceProxy(const ServiceConfig& config,
}
// static
+void ProxyGenerator::GenerateInterfaceMock(const ServiceConfig& config,
+ const Interface& interface,
+ IndentedText* text) {
+ NameParser parser{interface.name};
+ string proxy_name = parser.MakeProxyName(false);
+ string base_interface_name = proxy_name + "Interface";
+ string mock_name = proxy_name + "Mock";
+
+ parser.AddOpenNamespaces(text, false);
+ text->AddBlankLine();
+
+ text->AddLine(StringPrintf("// Mock object for %s.",
+ base_interface_name.c_str()));
+ text->AddLine(StringPrintf("class %s final : public %s {",
+ mock_name.c_str(), base_interface_name.c_str()));
+ text->AddLineWithOffset("public:", kScopeOffset);
+ text->PushOffset(kBlockOffset);
+ text->AddLine(StringPrintf("%s() = default;", mock_name.c_str()));
+ text->AddBlankLine();
+
+ for (const auto& method : interface.methods) {
+ AddMethodMock(method, interface.name, text);
+ AddAsyncMethodMock(method, interface.name, text);
+ }
+
+ DbusSignature signature;
+ for (const auto& prop : interface.properties) {
+ string type;
+ CHECK(signature.Parse(prop.type, &type));
+ MakeConstReferenceIfNeeded(&type);
+ string name = NameParser{prop.name}.MakeVariableName();
+ text->AddLine(StringPrintf("MOCK_CONST_METHOD0(%s, %s());",
+ name.c_str(), type.c_str()));
+ }
+
+ text->PopOffset();
+ text->AddBlankLine();
+ text->AddLineWithOffset("private:", kScopeOffset);
+ text->AddLineWithOffset(StringPrintf("DISALLOW_COPY_AND_ASSIGN(%s);",
+ mock_name.c_str()),
+ kBlockOffset);
+ text->AddLine("};");
+
+ parser.AddCloseNamespaces(text, false);
+ text->AddBlankLine();
+}
+
+// static
void ProxyGenerator::AddConstructor(const ServiceConfig& config,
const Interface& interface,
const string& class_name,
@@ -389,6 +554,7 @@ void ProxyGenerator::AddPropertySet(const ServiceConfig& config,
// static
void ProxyGenerator::AddProperties(const ServiceConfig& config,
const Interface& interface,
+ bool declaration_only,
IndentedText* text) {
// Must have ObjectManager in order for property system to work correctly.
if (config.object_manager.name.empty())
@@ -401,25 +567,35 @@ void ProxyGenerator::AddProperties(const ServiceConfig& config,
MakeConstReferenceIfNeeded(&type);
string name = NameParser{prop.name}.MakeVariableName();
text->AddLine(
- StringPrintf("%s %s() const {",
+ StringPrintf("%s%s %s() const%s",
+ declaration_only ? "virtual " : "",
type.c_str(),
- name.c_str()));
- text->AddLineWithOffset(
- StringPrintf("return property_set_->%s.value();", name.c_str()),
- kBlockOffset);
- text->AddLine("}");
- text->AddBlankLine();
+ name.c_str(),
+ declaration_only ? " = 0;" : " override {"));
+ if (!declaration_only) {
+ text->AddLineWithOffset(
+ StringPrintf("return property_set_->%s.value();", name.c_str()),
+ kBlockOffset);
+ text->AddLine("}");
+ text->AddBlankLine();
+ }
}
+
+ if (declaration_only && !interface.properties.empty())
+ text->AddBlankLine();
}
// static
void ProxyGenerator::AddMethodProxy(const Interface::Method& method,
const string& interface_name,
+ bool declaration_only,
IndentedText* text) {
IndentedText block;
DbusSignature signature;
block.AddComments(method.doc_string);
- block.AddLine(StringPrintf("bool %s(", method.name.c_str()));
+ block.AddLine(StringPrintf("%sbool %s(",
+ declaration_only ? "virtual " : "",
+ method.name.c_str()));
block.PushOffset(kLineContinuationOffset);
vector<string> argument_names;
int argument_number = 0;
@@ -442,45 +618,51 @@ void ProxyGenerator::AddMethodProxy(const Interface::Method& method,
"%s* %s,", argument_type.c_str(), argument_name.c_str()));
}
block.AddLine("chromeos::ErrorPtr* error,");
- block.AddLine("int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {");
- block.PopOffset();
- block.PushOffset(kBlockOffset);
-
block.AddLine(
- "auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(");
- block.PushOffset(kLineContinuationOffset);
- block.AddLine("timeout_ms,");
- block.AddLine("dbus_object_proxy_,");
- block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
- block.AddLine(StringPrintf("\"%s\",", method.name.c_str()));
- string last_argument = "error";
- for (const auto& argument_name : argument_names) {
- block.AddLine(StringPrintf("%s,", last_argument.c_str()));
- last_argument = argument_name;
- }
- block.AddLine(StringPrintf("%s);", last_argument.c_str()));
+ StringPrintf("int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)%s",
+ declaration_only ? " = 0;" : " override {"));
block.PopOffset();
+ if (!declaration_only) {
+ block.PushOffset(kBlockOffset);
- block.AddLine("return response && "
- "chromeos::dbus_utils::ExtractMethodCallResults(");
- block.PushOffset(kLineContinuationOffset);
- block.AddLine(chromeos::string_utils::Join(", ", out_param_names) + ");");
- block.PopOffset();
- block.PopOffset();
- block.AddLine("}");
- block.AddBlankLine();
+ block.AddLine(
+ "auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(");
+ block.PushOffset(kLineContinuationOffset);
+ block.AddLine("timeout_ms,");
+ block.AddLine("dbus_object_proxy_,");
+ block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
+ block.AddLine(StringPrintf("\"%s\",", method.name.c_str()));
+ string last_argument = "error";
+ for (const auto& argument_name : argument_names) {
+ block.AddLine(StringPrintf("%s,", last_argument.c_str()));
+ last_argument = argument_name;
+ }
+ block.AddLine(StringPrintf("%s);", last_argument.c_str()));
+ block.PopOffset();
+ block.AddLine("return response && "
+ "chromeos::dbus_utils::ExtractMethodCallResults(");
+ block.PushOffset(kLineContinuationOffset);
+ block.AddLine(chromeos::string_utils::Join(", ", out_param_names) + ");");
+ block.PopOffset();
+ block.PopOffset();
+ block.AddLine("}");
+ }
+ block.AddBlankLine();
text->AddBlock(block);
}
// static
void ProxyGenerator::AddAsyncMethodProxy(const Interface::Method& method,
const string& interface_name,
+ bool declaration_only,
IndentedText* text) {
IndentedText block;
DbusSignature signature;
block.AddComments(method.doc_string);
- block.AddLine(StringPrintf("void %sAsync(", method.name.c_str()));
+ block.AddLine(StringPrintf("%svoid %sAsync(",
+ declaration_only ? "virtual " : "",
+ method.name.c_str()));
block.PushOffset(kLineContinuationOffset);
vector<string> argument_names;
int argument_number = 0;
@@ -507,29 +689,115 @@ void ProxyGenerator::AddAsyncMethodProxy(const Interface::Method& method,
chromeos::string_utils::Join(", ", out_params).c_str()));
block.AddLine(
"const base::Callback<void(chromeos::Error*)>& error_callback,");
- block.AddLine("int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {");
+ block.AddLine(
+ StringPrintf("int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)%s",
+ declaration_only ? " = 0;" : " override {"));
block.PopOffset();
- block.PushOffset(kBlockOffset);
+ if (!declaration_only) {
+ block.PushOffset(kBlockOffset);
- block.AddLine("chromeos::dbus_utils::CallMethodWithTimeout(");
- block.PushOffset(kLineContinuationOffset);
- block.AddLine("timeout_ms,");
- block.AddLine("dbus_object_proxy_,");
- block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
- block.AddLine(StringPrintf("\"%s\",", method.name.c_str()));
- block.AddLine("success_callback,");
- string last_argument = "error_callback";
- for (const auto& argument_name : argument_names) {
- block.AddLine(StringPrintf("%s,", last_argument.c_str()));
- last_argument = argument_name;
- }
- block.AddLine(StringPrintf("%s);", last_argument.c_str()));
- block.PopOffset();
+ block.AddLine("chromeos::dbus_utils::CallMethodWithTimeout(");
+ block.PushOffset(kLineContinuationOffset);
+ block.AddLine("timeout_ms,");
+ block.AddLine("dbus_object_proxy_,");
+ block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
+ block.AddLine(StringPrintf("\"%s\",", method.name.c_str()));
+ block.AddLine("success_callback,");
+ string last_argument = "error_callback";
+ for (const auto& argument_name : argument_names) {
+ block.AddLine(StringPrintf("%s,", last_argument.c_str()));
+ last_argument = argument_name;
+ }
+ block.AddLine(StringPrintf("%s);", last_argument.c_str()));
+ block.PopOffset();
- block.PopOffset();
- block.AddLine("}");
+ block.PopOffset();
+ block.AddLine("}");
+ }
block.AddBlankLine();
+ text->AddBlock(block);
+}
+
+// static
+void ProxyGenerator::AddMethodMock(const Interface::Method& method,
+ const string& interface_name,
+ IndentedText* text) {
+ IndentedText block;
+ DbusSignature signature;
+ vector<string> arguments;
+ for (const auto& argument : method.input_arguments) {
+ string argument_type;
+ CHECK(signature.Parse(argument.type, &argument_type));
+ MakeConstReferenceIfNeeded(&argument_type);
+ if (!argument.name.empty())
+ base::StringAppendF(&argument_type, " /*in_%s*/", argument.name.c_str());
+ arguments.push_back(argument_type);
+ }
+ for (const auto& argument : method.output_arguments) {
+ string argument_type;
+ CHECK(signature.Parse(argument.type, &argument_type));
+ argument_type += '*';
+ if (!argument.name.empty())
+ base::StringAppendF(&argument_type, " /*out_%s*/", argument.name.c_str());
+ arguments.push_back(argument_type);
+ }
+ arguments.push_back("chromeos::ErrorPtr* /*error*/");
+ arguments.push_back("int /*timeout_ms*/");
+
+ block.AddLineAndPushOffsetTo(
+ StringPrintf("MOCK_METHOD%ju(%s,", arguments.size(), method.name.c_str()),
+ 1, '(');
+ block.AddLineAndPushOffsetTo(
+ StringPrintf("bool(%s,", arguments.front().c_str()), 1, '(');
+ for (size_t i = 1; i < arguments.size() - 1; i++)
+ block.AddLine(StringPrintf("%s,", arguments[i].c_str()));
+ block.AddLine(StringPrintf("%s));", arguments.back().c_str()));
+ block.PopOffset();
+ block.PopOffset();
+ text->AddBlock(block);
+}
+// static
+void ProxyGenerator::AddAsyncMethodMock(const Interface::Method& method,
+ const string& interface_name,
+ IndentedText* text) {
+ IndentedText block;
+ DbusSignature signature;
+ vector<string> arguments;
+ for (const auto& argument : method.input_arguments) {
+ string argument_type;
+ CHECK(signature.Parse(argument.type, &argument_type));
+ MakeConstReferenceIfNeeded(&argument_type);
+ if (!argument.name.empty())
+ base::StringAppendF(&argument_type, " /*in_%s*/", argument.name.c_str());
+ arguments.push_back(argument_type);
+ }
+ vector<string> out_params;
+ for (const auto& argument : method.output_arguments) {
+ string argument_type;
+ CHECK(signature.Parse(argument.type, &argument_type));
+ MakeConstReferenceIfNeeded(&argument_type);
+ if (!argument.name.empty())
+ base::StringAppendF(&argument_type, " /*%s*/", argument.name.c_str());
+ out_params.push_back(argument_type);
+ }
+ arguments.push_back(StringPrintf(
+ "const base::Callback<void(%s)>& /*success_callback*/",
+ chromeos::string_utils::Join(", ", out_params).c_str()));
+ arguments.push_back(
+ "const base::Callback<void(chromeos::Error*)>& /*error_callback*/");
+ arguments.push_back("int /*timeout_ms*/");
+
+ block.AddLineAndPushOffsetTo(
+ StringPrintf("MOCK_METHOD%ju(%sAsync,", arguments.size(),
+ method.name.c_str()), 1, '(');
+ block.AddLineAndPushOffsetTo(
+ StringPrintf("void(%s,", arguments.front().c_str()), 1, '(');
+ for (size_t i = 1; i < arguments.size() - 1; i++)
+ block.AddLine(StringPrintf("%s,", arguments[i].c_str()));
+ block.AddLine(StringPrintf("%s));", arguments.back().c_str()));
+ block.PopOffset();
+ block.PopOffset();
text->AddBlock(block);
}
diff --git a/chromeos-dbus-bindings/proxy_generator.h b/chromeos-dbus-bindings/proxy_generator.h
index 682e6dc..aa9e89e 100644
--- a/chromeos-dbus-bindings/proxy_generator.h
+++ b/chromeos-dbus-bindings/proxy_generator.h
@@ -31,14 +31,29 @@ class ProxyGenerator : public HeaderGenerator {
const std::vector<Interface>& interfaces,
const base::FilePath& output_file);
+ static bool GenerateMocks(const ServiceConfig& config,
+ const std::vector<Interface>& interfaces,
+ const base::FilePath& mock_file,
+ const base::FilePath& proxy_file);
+
private:
friend class ProxyGeneratorTest;
+ // Generates an abstract interface for one D-Bus interface proxy.
+ static void GenerateInterfaceProxyInterface(const ServiceConfig& config,
+ const Interface& interface,
+ IndentedText* text);
+
// Generates one interface proxy.
static void GenerateInterfaceProxy(const ServiceConfig& config,
const Interface& interface,
IndentedText* text);
+ // Generates one interface mock object.
+ static void GenerateInterfaceMock(const ServiceConfig& config,
+ const Interface& interface,
+ IndentedText* text);
+
// Generates the constructor and destructor for the proxy.
static void AddConstructor(const ServiceConfig& config,
const Interface& interface,
@@ -76,18 +91,31 @@ class ProxyGenerator : public HeaderGenerator {
// Generates the property accessors.
static void AddProperties(const ServiceConfig& config,
const Interface& interface,
+ bool declaration_only,
IndentedText* text);
// Generates a native C++ method which calls a D-Bus method on the proxy.
static void AddMethodProxy(const Interface::Method& interface,
const std::string& interface_name,
+ bool declaration_only,
IndentedText* text);
// Generates a native C++ method which calls a D-Bus method asynchronously.
static void AddAsyncMethodProxy(const Interface::Method& interface,
const std::string& interface_name,
+ bool declaration_only,
IndentedText* text);
+ // Generates a mock for blocking D-Bus method.
+ static void AddMethodMock(const Interface::Method& interface,
+ const std::string& interface_name,
+ IndentedText* text);
+
+ // Generates a mock for asynchronous D-Bus method.
+ static void AddAsyncMethodMock(const Interface::Method& interface,
+ const std::string& interface_name,
+ IndentedText* text);
+
// Generates the Object Manager proxy class.
struct ObjectManager {
// Generates the top-level class for Object Manager proxy.
diff --git a/chromeos-dbus-bindings/proxy_generator_mock_unittest.cc b/chromeos-dbus-bindings/proxy_generator_mock_unittest.cc
new file mode 100644
index 0000000..aef4b97
--- /dev/null
+++ b/chromeos-dbus-bindings/proxy_generator_mock_unittest.cc
@@ -0,0 +1,205 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos-dbus-bindings/proxy_generator.h"
+
+#include <string>
+#include <vector>
+
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
+#include <gtest/gtest.h>
+
+#include "chromeos-dbus-bindings/interface.h"
+
+using std::string;
+using std::vector;
+using testing::Test;
+
+namespace chromeos_dbus_bindings {
+
+namespace {
+
+const char kInterfaceName[] = "org.chromium.TestInterface";
+const char kInterfaceName2[] = "org.chromium.TestInterface2";
+const char kMethod1Name[] = "Elements";
+const char kMethod1Return[] = "s";
+const char kMethod1Argument1[] = "s";
+const char kMethod1ArgumentName1[] = "space_walk";
+const char kMethod1Argument2[] = "ao";
+const char kMethod1ArgumentName2[] = "ramblin_man";
+const char kMethod2Name[] = "ReturnToPatagonia";
+const char kMethod2Return[] = "x";
+const char kMethod3Name[] = "NiceWeatherForDucks";
+const char kMethod3Argument1[] = "b";
+const char kMethod4Name[] = "ExperimentNumberSix";
+const char kMethod5Name[] = "GetPersonInfo";
+const char kMethod5Argument1[] = "s";
+const char kMethod5ArgumentName1[] = "name";
+const char kMethod5Argument2[] = "i";
+const char kMethod5ArgumentName2[] = "age";
+const char kSignal1Name[] = "Closer";
+const char kSignal2Name[] = "TheCurseOfKaZar";
+const char kSignal2Argument1[] = "as";
+const char kSignal2Argument2[] = "y";
+const char kExpectedContent[] = R"literal_string(
+#include <string>
+#include <vector>
+
+#include <base/callback_forward.h>
+#include <base/macros.h>
+#include <chromeos/any.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
+#include <gmock/gmock.h>
+
+#include "proxies.h"
+
+namespace org {
+namespace chromium {
+
+// Mock object for TestInterfaceProxyInterface.
+class TestInterfaceProxyMock final : public TestInterfaceProxyInterface {
+ public:
+ TestInterfaceProxyMock() = default;
+
+ MOCK_METHOD5(Elements,
+ bool(const std::string& /*in_space_walk*/,
+ const std::vector<dbus::ObjectPath>& /*in_ramblin_man*/,
+ std::string*,
+ chromeos::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(ElementsAsync,
+ void(const std::string& /*in_space_walk*/,
+ const std::vector<dbus::ObjectPath>& /*in_ramblin_man*/,
+ const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(chromeos::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ReturnToPatagonia,
+ bool(int64_t*,
+ chromeos::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ReturnToPatagoniaAsync,
+ void(const base::Callback<void(int64_t)>& /*success_callback*/,
+ const base::Callback<void(chromeos::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(NiceWeatherForDucks,
+ bool(bool,
+ chromeos::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(NiceWeatherForDucksAsync,
+ void(bool,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(chromeos::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(ExperimentNumberSix,
+ bool(chromeos::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ExperimentNumberSixAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(chromeos::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestInterfaceProxyMock);
+};
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+// Mock object for TestInterface2ProxyInterface.
+class TestInterface2ProxyMock final : public TestInterface2ProxyInterface {
+ public:
+ TestInterface2ProxyMock() = default;
+
+ MOCK_METHOD4(GetPersonInfo,
+ bool(std::string* /*out_name*/,
+ int32_t* /*out_age*/,
+ chromeos::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetPersonInfoAsync,
+ void(const base::Callback<void(const std::string& /*name*/, int32_t /*age*/)>& /*success_callback*/,
+ const base::Callback<void(chromeos::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestInterface2ProxyMock);
+};
+} // namespace chromium
+} // namespace org
+)literal_string";
+
+} // namespace
+
+class ProxyGeneratorMockTest : public Test {
+ public:
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ protected:
+ base::FilePath CreateInputFile(const string& contents) {
+ base::FilePath path;
+ EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &path));
+ EXPECT_EQ(contents.size(),
+ base::WriteFile(path, contents.c_str(), contents.size()));
+ return path;
+ }
+
+ base::ScopedTempDir temp_dir_;
+};
+
+TEST_F(ProxyGeneratorMockTest, GenerateMocks) {
+ Interface interface;
+ interface.name = kInterfaceName;
+ interface.path = "/org/chromium/Test";
+ interface.methods.emplace_back(
+ kMethod1Name,
+ vector<Interface::Argument>{
+ {kMethod1ArgumentName1, kMethod1Argument1},
+ {kMethod1ArgumentName2, kMethod1Argument2}},
+ vector<Interface::Argument>{{"", kMethod1Return}});
+ interface.methods.emplace_back(
+ kMethod2Name,
+ vector<Interface::Argument>{},
+ vector<Interface::Argument>{{"", kMethod2Return}});
+ interface.methods.emplace_back(
+ kMethod3Name,
+ vector<Interface::Argument>{{"", kMethod3Argument1}},
+ vector<Interface::Argument>{});
+ interface.methods.emplace_back(kMethod4Name);
+ interface.signals.emplace_back(kSignal1Name);
+ interface.signals.emplace_back(
+ kSignal2Name,
+ vector<Interface::Argument>{
+ {"", kSignal2Argument1},
+ {"", kSignal2Argument2}});
+ interface.methods.back().doc_string = "Comment line1\nline2";
+ Interface interface2;
+ interface2.name = kInterfaceName2;
+ interface2.methods.emplace_back(
+ kMethod5Name,
+ vector<Interface::Argument>{},
+ vector<Interface::Argument>{
+ {kMethod5ArgumentName1, kMethod5Argument1},
+ {kMethod5ArgumentName2, kMethod5Argument2}});
+ vector<Interface> interfaces{interface, interface2};
+ base::FilePath output_path = temp_dir_.path().Append("output.h");
+ base::FilePath proxy_path = temp_dir_.path().Append("proxies.h");
+ ServiceConfig config;
+ EXPECT_TRUE(ProxyGenerator::GenerateMocks(config, interfaces, output_path,
+ proxy_path));
+ string contents;
+ EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
+ // The header guards contain the (temporary) filename, so we search for
+ // the content we need within the string.
+ EXPECT_NE(string::npos, contents.find(kExpectedContent))
+ << "Expected to find the following content...\n"
+ << kExpectedContent << "...within content...\n" << contents;
+}
+
+} // namespace chromeos_dbus_bindings
diff --git a/chromeos-dbus-bindings/proxy_generator_unittest.cc b/chromeos-dbus-bindings/proxy_generator_unittest.cc
index d374ee4..aed7703 100644
--- a/chromeos-dbus-bindings/proxy_generator_unittest.cc
+++ b/chromeos-dbus-bindings/proxy_generator_unittest.cc
@@ -69,8 +69,69 @@ const char kExpectedContent[] = R"literal_string(
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::TestInterface.
+class TestInterfaceProxyInterface {
+ public:
+ virtual bool Elements(
+ const std::string& in_space_walk,
+ const std::vector<dbus::ObjectPath>& in_ramblin_man,
+ std::string* out_3,
+ chromeos::ErrorPtr* error,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ virtual void ElementsAsync(
+ const std::string& in_space_walk,
+ const std::vector<dbus::ObjectPath>& in_ramblin_man,
+ const base::Callback<void(const std::string&)>& success_callback,
+ const base::Callback<void(chromeos::Error*)>& error_callback,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ virtual bool ReturnToPatagonia(
+ int64_t* out_1,
+ chromeos::ErrorPtr* error,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ virtual void ReturnToPatagoniaAsync(
+ const base::Callback<void(int64_t)>& success_callback,
+ const base::Callback<void(chromeos::Error*)>& error_callback,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ virtual bool NiceWeatherForDucks(
+ bool in_1,
+ chromeos::ErrorPtr* error,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ virtual void NiceWeatherForDucksAsync(
+ bool in_1,
+ const base::Callback<void()>& success_callback,
+ const base::Callback<void(chromeos::Error*)>& error_callback,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ // Comment line1
+ // line2
+ virtual bool ExperimentNumberSix(
+ chromeos::ErrorPtr* error,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ // Comment line1
+ // line2
+ virtual void ExperimentNumberSixAsync(
+ const base::Callback<void()>& success_callback,
+ const base::Callback<void(chromeos::Error*)>& error_callback,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ protected:
+ ~TestInterfaceProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::TestInterface.
-class TestInterfaceProxy final {
+class TestInterfaceProxy final : public TestInterfaceProxyInterface {
public:
TestInterfaceProxy(
const scoped_refptr<dbus::Bus>& bus,
@@ -122,7 +183,7 @@ class TestInterfaceProxy final {
const std::vector<dbus::ObjectPath>& in_ramblin_man,
std::string* out_3,
chromeos::ErrorPtr* error,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -140,7 +201,7 @@ class TestInterfaceProxy final {
const std::vector<dbus::ObjectPath>& in_ramblin_man,
const base::Callback<void(const std::string&)>& success_callback,
const base::Callback<void(chromeos::Error*)>& error_callback,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
chromeos::dbus_utils::CallMethodWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -155,7 +216,7 @@ class TestInterfaceProxy final {
bool ReturnToPatagonia(
int64_t* out_1,
chromeos::ErrorPtr* error,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -169,7 +230,7 @@ class TestInterfaceProxy final {
void ReturnToPatagoniaAsync(
const base::Callback<void(int64_t)>& success_callback,
const base::Callback<void(chromeos::Error*)>& error_callback,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
chromeos::dbus_utils::CallMethodWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -182,7 +243,7 @@ class TestInterfaceProxy final {
bool NiceWeatherForDucks(
bool in_1,
chromeos::ErrorPtr* error,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -198,7 +259,7 @@ class TestInterfaceProxy final {
bool in_1,
const base::Callback<void()>& success_callback,
const base::Callback<void(chromeos::Error*)>& error_callback,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
chromeos::dbus_utils::CallMethodWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -213,7 +274,7 @@ class TestInterfaceProxy final {
// line2
bool ExperimentNumberSix(
chromeos::ErrorPtr* error,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -229,7 +290,7 @@ class TestInterfaceProxy final {
void ExperimentNumberSixAsync(
const base::Callback<void()>& success_callback,
const base::Callback<void(chromeos::Error*)>& error_callback,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
chromeos::dbus_utils::CallMethodWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -254,8 +315,32 @@ class TestInterfaceProxy final {
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::TestInterface2.
+class TestInterface2ProxyInterface {
+ public:
+ virtual bool GetPersonInfo(
+ std::string* out_name,
+ int32_t* out_age,
+ chromeos::ErrorPtr* error,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ virtual void GetPersonInfoAsync(
+ const base::Callback<void(const std::string& /*name*/, int32_t /*age*/)>& success_callback,
+ const base::Callback<void(chromeos::Error*)>& error_callback,
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;
+
+ protected:
+ ~TestInterface2ProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::TestInterface2.
-class TestInterface2Proxy final {
+class TestInterface2Proxy final : public TestInterface2ProxyInterface {
public:
TestInterface2Proxy(
const scoped_refptr<dbus::Bus>& bus,
@@ -285,7 +370,7 @@ class TestInterface2Proxy final {
std::string* out_name,
int32_t* out_age,
chromeos::ErrorPtr* error,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
auto response = chromeos::dbus_utils::CallMethodAndBlockWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -299,7 +384,7 @@ class TestInterface2Proxy final {
void GetPersonInfoAsync(
const base::Callback<void(const std::string& /*name*/, int32_t /*age*/)>& success_callback,
const base::Callback<void(chromeos::Error*)>& error_callback,
- int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
+ int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
chromeos::dbus_utils::CallMethodWithTimeout(
timeout_ms,
dbus_object_proxy_,
@@ -347,8 +432,21 @@ const char kExpectedContentWithService[] = R"literal_string(
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::TestInterface.
+class TestInterfaceProxyInterface {
+ public:
+ protected:
+ ~TestInterfaceProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::TestInterface.
-class TestInterfaceProxy final {
+class TestInterfaceProxy final : public TestInterfaceProxyInterface {
public:
TestInterfaceProxy(const scoped_refptr<dbus::Bus>& bus) :
bus_{bus},
@@ -395,8 +493,21 @@ class TestInterfaceProxy final {
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::TestInterface2.
+class TestInterface2ProxyInterface {
+ public:
+ protected:
+ ~TestInterface2ProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::TestInterface2.
-class TestInterface2Proxy final {
+class TestInterface2Proxy final : public TestInterface2ProxyInterface {
public:
TestInterface2Proxy(
const scoped_refptr<dbus::Bus>& bus,
@@ -464,8 +575,23 @@ class ObjectManagerProxy;
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::Itf1.
+class Itf1ProxyInterface {
+ public:
+ virtual const std::string& data() const = 0;
+
+ protected:
+ ~Itf1ProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::Itf1.
-class Itf1Proxy final {
+class Itf1Proxy final : public Itf1ProxyInterface {
public:
class PropertySet : public dbus::PropertySet {
public:
@@ -526,7 +652,7 @@ class Itf1Proxy final {
const PropertySet* GetProperties() const { return property_set_; }
PropertySet* GetProperties() { return property_set_; }
- const std::string& data() const {
+ const std::string& data() const override {
return property_set_->data.value();
}
@@ -553,8 +679,21 @@ class Itf1Proxy final {
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::Itf2.
+class Itf2ProxyInterface {
+ public:
+ protected:
+ ~Itf2ProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::Itf2.
-class Itf2Proxy final {
+class Itf2Proxy final : public Itf2ProxyInterface {
public:
class PropertySet : public dbus::PropertySet {
public:
@@ -815,8 +954,21 @@ class ObjectManagerProxy;
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::Itf1.
+class Itf1ProxyInterface {
+ public:
+ protected:
+ ~Itf1ProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::Itf1.
-class Itf1Proxy final {
+class Itf1Proxy final : public Itf1ProxyInterface {
public:
class PropertySet : public dbus::PropertySet {
public:
@@ -877,8 +1029,21 @@ class Itf1Proxy final {
namespace org {
namespace chromium {
+// Abstract interface proxy for org::chromium::Itf2.
+class Itf2ProxyInterface {
+ public:
+ protected:
+ ~Itf2ProxyInterface() = default;
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
// Interface proxy for org::chromium::Itf2.
-class Itf2Proxy final {
+class Itf2Proxy final : public Itf2ProxyInterface {
public:
class PropertySet : public dbus::PropertySet {
public: