OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 // |
| 5 // This tool is be used for manual testing. It's similar to dbus-send, but |
| 6 // has less features. This may be also useful as sample code. |
| 7 // |
| 8 // Example: |
| 9 // |
| 10 // % ninja/dbus_tool --system --async |
| 11 // --service_name=org.freedesktop.NetworkManager |
| 12 // --object_path=/org/freedesktop/NetworkManager |
| 13 // --interface_name=org.freedesktop.DBus.Properties |
| 14 // --method_name=GetAll |
| 15 // org.freedesktop.NetworkManager |
| 16 // |
| 17 // array [ |
| 18 // dict entry { |
| 19 // string "WirelessEnabled" |
| 20 // variant bool true |
| 21 // } |
| 22 // ... |
| 23 // |
| 24 |
| 25 #include <iostream> |
| 26 #include <string> |
| 27 #include <vector> |
| 28 |
| 29 #include "base/at_exit.h" |
| 30 #include "base/bind.h" |
| 31 #include "base/logging.h" |
| 32 #include "base/message_loop.h" |
| 33 #include "base/scoped_ptr.h" |
| 34 #include "base/command_line.h" |
| 35 #include "base/threading/thread.h" |
| 36 #include "dbus/bus.h" |
| 37 #include "dbus/message.h" |
| 38 #include "dbus/object_proxy.h" |
| 39 |
| 40 // This class is used to call methods. |
| 41 class TestClient { |
| 42 public: |
| 43 // Specifies the way to call a method. |
| 44 enum MethodCallType { |
| 45 SYNC, |
| 46 ASYNC, |
| 47 }; |
| 48 |
| 49 TestClient(dbus::Bus::BusType bus_type, |
| 50 bool use_io_thread, |
| 51 const std::string& service_name, |
| 52 const std::string& object_path) |
| 53 : bus_(NULL), |
| 54 object_proxy_(NULL) { |
| 55 dbus::Bus::Options bus_options; |
| 56 bus_options.bus_type = bus_type; |
| 57 if (use_io_thread) { |
| 58 base::Thread* io_thread = new base::Thread("Dispatch-thread"); |
| 59 base::Thread::Options thread_options; |
| 60 thread_options.message_loop_type = MessageLoop::TYPE_IO; |
| 61 io_thread->StartWithOptions(thread_options); |
| 62 |
| 63 bus_options.io_thread = io_thread; |
| 64 } |
| 65 bus_.reset(new dbus::Bus(bus_options)); |
| 66 object_proxy_.reset(bus_->GetObjectProxy(service_name, object_path)); |
| 67 } |
| 68 |
| 69 // Calls the method and returns the response as string. |
| 70 std::string CallMethod(MethodCallType method_call_type, |
| 71 const std::string& interface_name, |
| 72 const std::string& method_name, |
| 73 const std::vector<std::string>& parameters) { |
| 74 if (method_call_type == SYNC) { |
| 75 return CallMethodSync(interface_name, method_name, parameters); |
| 76 } else { |
| 77 return CallMethodAsync(interface_name, method_name, parameters); |
| 78 } |
| 79 } |
| 80 |
| 81 private: |
| 82 // Calls the method synchronously. Returns the response as string. |
| 83 std::string CallMethodSync(const std::string& interface_name, |
| 84 const std::string& method_name, |
| 85 const std::vector<std::string>& parameters) { |
| 86 dbus::MethodCall method_call(interface_name, method_name); |
| 87 AppendParameters(parameters, &method_call); |
| 88 |
| 89 dbus::Response response; |
| 90 if (!object_proxy_->CallMethodAndWait( |
| 91 &method_call, |
| 92 &response, |
| 93 dbus::ObjectProxy::TIMEOUT_INFINITE)) { |
| 94 LOG(ERROR) << "Failed to call the method"; |
| 95 } |
| 96 return response.ToString(); |
| 97 } |
| 98 |
| 99 // Calls the method asynchronously. Returns the response as string. |
| 100 std::string CallMethodAsync(const std::string& interface_name, |
| 101 const std::string& method_name, |
| 102 const std::vector<std::string>& parameters) { |
| 103 dbus::MethodCall method_call(interface_name, method_name); |
| 104 AppendParameters(parameters, &method_call); |
| 105 |
| 106 base::Callback<void(dbus::Response*)> response_callback = |
| 107 base::Bind(&TestClient::ResponseCallback, base::Unretained(this)); |
| 108 object_proxy_->CallMethod(&method_call, |
| 109 response_callback, |
| 110 dbus::ObjectProxy::TIMEOUT_INFINITE); |
| 111 // Runs the message loop so ResponseCallback() will be called. |
| 112 message_loop_.Run(); |
| 113 // ResponseCallback() will set the string. |
| 114 return async_response_string_; |
| 115 } |
| 116 |
| 117 // Called when the response is received. Stores the response in |
| 118 // async_response_string_ as string, and stops the message loop. |
| 119 void ResponseCallback(dbus::Response* response) { |
| 120 if (response) { |
| 121 async_response_string_ = response->ToString(); |
| 122 } else { |
| 123 LOG(ERROR) << "Failed to call the method"; |
| 124 } |
| 125 message_loop_.Quit(); |
| 126 }; |
| 127 |
| 128 // Appends parameters to the given method call. Currently, strings are |
| 129 // only supported. |
| 130 void AppendParameters(const std::vector<std::string>& parameters, |
| 131 dbus::MethodCall* method_call) { |
| 132 dbus::MessageWriter writer(method_call); |
| 133 for (size_t i = 0; i < parameters.size(); ++i) { |
| 134 writer.AppendString(parameters[i]); |
| 135 } |
| 136 } |
| 137 |
| 138 scoped_ptr<dbus::Bus> bus_; |
| 139 scoped_ptr<dbus::ObjectProxy> object_proxy_; |
| 140 MessageLoopForIO message_loop_; |
| 141 std::string async_response_string_; |
| 142 }; |
| 143 |
| 144 int main(int argc, char** argv) { |
| 145 CommandLine command_line(argc, argv); |
| 146 base::AtExitManager exit_manager; |
| 147 |
| 148 const TestClient::MethodCallType method_call_type = |
| 149 (command_line.HasSwitch("async") ? TestClient::ASYNC : TestClient::SYNC); |
| 150 |
| 151 const dbus::Bus::BusType bus_type = (command_line.HasSwitch("system") ? |
| 152 dbus::Bus::SYSTEM : |
| 153 dbus::Bus::SESSION); |
| 154 const bool use_io_thread = |
| 155 command_line.HasSwitch("use_io_thread"); |
| 156 const std::string service_name = |
| 157 command_line.GetSwitchValueASCII("service_name"); |
| 158 const std::string object_path = |
| 159 command_line.GetSwitchValueASCII("object_path"); |
| 160 const std::string interface_name = |
| 161 command_line.GetSwitchValueASCII("interface_name"); |
| 162 const std::string method_name = |
| 163 command_line.GetSwitchValueASCII("method_name"); |
| 164 CHECK(!service_name.empty()) << "--service_name should be set"; |
| 165 CHECK(!object_path.empty()) << "--object_path should be set"; |
| 166 CHECK(!interface_name.empty()) << "--interface_name should be set"; |
| 167 CHECK(!method_name.empty()) << "--method_name should be set"; |
| 168 |
| 169 std::vector<std::string> parameters = command_line.GetArgs(); |
| 170 TestClient test_client(bus_type, |
| 171 use_io_thread, |
| 172 service_name, |
| 173 object_path); |
| 174 |
| 175 std::cout << test_client.CallMethod(method_call_type, |
| 176 interface_name, |
| 177 method_name, |
| 178 parameters); |
| 179 return 0; |
| 180 } |
OLD | NEW |