Index: dbus/dbus_test_client.cc |
diff --git a/dbus/dbus_test_client.cc b/dbus/dbus_test_client.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..909cb1ba679b810afd1361fd2b3342712a6da98f |
--- /dev/null |
+++ b/dbus/dbus_test_client.cc |
@@ -0,0 +1,180 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+// |
+// This tool is be used for manual testing. It's similar to dbus-send, but |
+// has less features. This may be also useful as sample code. |
+// |
+// Example: |
+// |
+// % ninja/dbus_tool --system --async |
+// --service_name=org.freedesktop.NetworkManager |
+// --object_path=/org/freedesktop/NetworkManager |
+// --interface_name=org.freedesktop.DBus.Properties |
+// --method_name=GetAll |
+// org.freedesktop.NetworkManager |
+// |
+// array [ |
+// dict entry { |
+// string "WirelessEnabled" |
+// variant bool true |
+// } |
+// ... |
+// |
+ |
+#include <iostream> |
+#include <string> |
+#include <vector> |
+ |
+#include "base/at_exit.h" |
+#include "base/bind.h" |
+#include "base/logging.h" |
+#include "base/message_loop.h" |
+#include "base/scoped_ptr.h" |
+#include "base/command_line.h" |
+#include "base/threading/thread.h" |
+#include "dbus/bus.h" |
+#include "dbus/message.h" |
+#include "dbus/object_proxy.h" |
+ |
+// This class is used to call methods. |
+class TestClient { |
+ public: |
+ // Specifies the way to call a method. |
+ enum MethodCallType { |
+ SYNC, |
+ ASYNC, |
+ }; |
+ |
+ TestClient(dbus::Bus::BusType bus_type, |
+ bool use_io_thread, |
+ const std::string& service_name, |
+ const std::string& object_path) |
+ : bus_(NULL), |
+ object_proxy_(NULL) { |
+ dbus::Bus::Options bus_options; |
+ bus_options.bus_type = bus_type; |
+ if (use_io_thread) { |
+ base::Thread* io_thread = new base::Thread("Dispatch-thread"); |
+ base::Thread::Options thread_options; |
+ thread_options.message_loop_type = MessageLoop::TYPE_IO; |
+ io_thread->StartWithOptions(thread_options); |
+ |
+ bus_options.io_thread = io_thread; |
+ } |
+ bus_.reset(new dbus::Bus(bus_options)); |
+ object_proxy_.reset(bus_->GetObjectProxy(service_name, object_path)); |
+ } |
+ |
+ // Calls the method and returns the response as string. |
+ std::string CallMethod(MethodCallType method_call_type, |
+ const std::string& interface_name, |
+ const std::string& method_name, |
+ const std::vector<std::string>& parameters) { |
+ if (method_call_type == SYNC) { |
+ return CallMethodSync(interface_name, method_name, parameters); |
+ } else { |
+ return CallMethodAsync(interface_name, method_name, parameters); |
+ } |
+ } |
+ |
+ private: |
+ // Calls the method synchronously. Returns the response as string. |
+ std::string CallMethodSync(const std::string& interface_name, |
+ const std::string& method_name, |
+ const std::vector<std::string>& parameters) { |
+ dbus::MethodCall method_call(interface_name, method_name); |
+ AppendParameters(parameters, &method_call); |
+ |
+ dbus::Response response; |
+ if (!object_proxy_->CallMethodAndWait( |
+ &method_call, |
+ &response, |
+ dbus::ObjectProxy::TIMEOUT_INFINITE)) { |
+ LOG(ERROR) << "Failed to call the method"; |
+ } |
+ return response.ToString(); |
+ } |
+ |
+ // Calls the method asynchronously. Returns the response as string. |
+ std::string CallMethodAsync(const std::string& interface_name, |
+ const std::string& method_name, |
+ const std::vector<std::string>& parameters) { |
+ dbus::MethodCall method_call(interface_name, method_name); |
+ AppendParameters(parameters, &method_call); |
+ |
+ base::Callback<void(dbus::Response*)> response_callback = |
+ base::Bind(&TestClient::ResponseCallback, base::Unretained(this)); |
+ object_proxy_->CallMethod(&method_call, |
+ response_callback, |
+ dbus::ObjectProxy::TIMEOUT_INFINITE); |
+ // Runs the message loop so ResponseCallback() will be called. |
+ message_loop_.Run(); |
+ // ResponseCallback() will set the string. |
+ return async_response_string_; |
+ } |
+ |
+ // Called when the response is received. Stores the response in |
+ // async_response_string_ as string, and stops the message loop. |
+ void ResponseCallback(dbus::Response* response) { |
+ if (response) { |
+ async_response_string_ = response->ToString(); |
+ } else { |
+ LOG(ERROR) << "Failed to call the method"; |
+ } |
+ message_loop_.Quit(); |
+ }; |
+ |
+ // Appends parameters to the given method call. Currently, strings are |
+ // only supported. |
+ void AppendParameters(const std::vector<std::string>& parameters, |
+ dbus::MethodCall* method_call) { |
+ dbus::MessageWriter writer(method_call); |
+ for (size_t i = 0; i < parameters.size(); ++i) { |
+ writer.AppendString(parameters[i]); |
+ } |
+ } |
+ |
+ scoped_ptr<dbus::Bus> bus_; |
+ scoped_ptr<dbus::ObjectProxy> object_proxy_; |
+ MessageLoopForIO message_loop_; |
+ std::string async_response_string_; |
+}; |
+ |
+int main(int argc, char** argv) { |
+ CommandLine command_line(argc, argv); |
+ base::AtExitManager exit_manager; |
+ |
+ const TestClient::MethodCallType method_call_type = |
+ (command_line.HasSwitch("async") ? TestClient::ASYNC : TestClient::SYNC); |
+ |
+ const dbus::Bus::BusType bus_type = (command_line.HasSwitch("system") ? |
+ dbus::Bus::SYSTEM : |
+ dbus::Bus::SESSION); |
+ const bool use_io_thread = |
+ command_line.HasSwitch("use_io_thread"); |
+ const std::string service_name = |
+ command_line.GetSwitchValueASCII("service_name"); |
+ const std::string object_path = |
+ command_line.GetSwitchValueASCII("object_path"); |
+ const std::string interface_name = |
+ command_line.GetSwitchValueASCII("interface_name"); |
+ const std::string method_name = |
+ command_line.GetSwitchValueASCII("method_name"); |
+ CHECK(!service_name.empty()) << "--service_name should be set"; |
+ CHECK(!object_path.empty()) << "--object_path should be set"; |
+ CHECK(!interface_name.empty()) << "--interface_name should be set"; |
+ CHECK(!method_name.empty()) << "--method_name should be set"; |
+ |
+ std::vector<std::string> parameters = command_line.GetArgs(); |
+ TestClient test_client(bus_type, |
+ use_io_thread, |
+ service_name, |
+ object_path); |
+ |
+ std::cout << test_client.CallMethod(method_call_type, |
+ interface_name, |
+ method_name, |
+ parameters); |
+ return 0; |
+} |