blob: 033e88608a095234d568eb559f09471ef0fa0b00 [file] [log] [blame]
adamk@chromium.org35c0eef2012-02-11 06:45:23 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
satorux@chromium.org163f1cb2011-08-18 05:58:12 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef DBUS_OBJECT_PROXY_H_
6#define DBUS_OBJECT_PROXY_H_
satorux@chromium.org163f1cb2011-08-18 05:58:12 +09007
thestig@chromium.org519c9ac2011-11-15 09:29:48 +09008#include <dbus/dbus.h>
9
satorux@chromium.orgf77861f2011-08-25 14:18:29 +090010#include <map>
dcheng30c5a172016-04-09 07:55:04 +090011#include <memory>
satorux@chromium.org5b3e4962011-11-24 07:08:38 +090012#include <set>
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090013#include <string>
keybuk@chromium.org2594a712013-04-24 09:12:35 +090014#include <vector>
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090015
16#include "base/callback.h"
avi0ad0ce02015-12-23 03:12:45 +090017#include "base/macros.h"
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090018#include "base/memory/ref_counted.h"
tfarina@chromium.org0eed10b2013-04-18 06:42:40 +090019#include "base/strings/string_piece.h"
avi@chromium.org78a7e7b2013-06-29 00:20:02 +090020#include "base/time/time.h"
tfarina@chromium.org7928ea22012-11-05 10:56:14 +090021#include "dbus/dbus_export.h"
keybuk@google.combf4649a2012-02-15 06:29:06 +090022#include "dbus/object_path.h"
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090023
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090024namespace dbus {
25
26class Bus;
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +090027class ErrorResponse;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090028class MethodCall;
29class Response;
avakulenko1d8962b2014-09-17 10:44:09 +090030class ScopedDBusError;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +090031class Signal;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090032
33// ObjectProxy is used to communicate with remote objects, mainly for
34// calling methods of these objects.
35//
36// ObjectProxy is a ref counted object, to ensure that |this| of the
avakulenko1d8962b2014-09-17 10:44:09 +090037// object is alive when callbacks referencing |this| are called; the
keybuk@chromium.orgde7b4a92012-03-22 08:39:17 +090038// bus always holds at least one of those references so object proxies
39// always last as long as the bus that created them.
tfarina@chromium.org7928ea22012-11-05 10:56:14 +090040class CHROME_DBUS_EXPORT ObjectProxy
41 : public base::RefCountedThreadSafe<ObjectProxy> {
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090042 public:
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090043 // Client code should use Bus::GetObjectProxy() or
44 // Bus::GetObjectProxyWithOptions() instead of this constructor.
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090045 ObjectProxy(Bus* bus,
46 const std::string& service_name,
keybuk@google.combf4649a2012-02-15 06:29:06 +090047 const ObjectPath& object_path,
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090048 int options);
49
50 // Options to be OR-ed together when calling Bus::GetObjectProxyWithOptions().
51 // Set the IGNORE_SERVICE_UNKNOWN_ERRORS option to silence logging of
stevenjb@chromium.orgc415c482014-08-09 06:57:19 +090052 // org.freedesktop.DBus.Error.ServiceUnknown errors and
53 // org.freedesktop.DBus.Error.ObjectUnknown errors.
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090054 enum Options {
55 DEFAULT_OPTIONS = 0,
56 IGNORE_SERVICE_UNKNOWN_ERRORS = 1 << 0
57 };
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090058
59 // Special timeout constants.
60 //
61 // The constants correspond to DBUS_TIMEOUT_USE_DEFAULT and
62 // DBUS_TIMEOUT_INFINITE. Here we use literal numbers instead of these
63 // macros as these aren't defined with D-Bus earlier than 1.4.12.
64 enum {
65 TIMEOUT_USE_DEFAULT = -1,
66 TIMEOUT_INFINITE = 0x7fffffff,
67 };
68
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +090069 // Called when an error response is returned or no response is returned.
70 // Used for CallMethodWithErrorCallback().
71 typedef base::Callback<void(ErrorResponse*)> ErrorCallback;
72
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090073 // Called when the response is returned. Used for CallMethod().
74 typedef base::Callback<void(Response*)> ResponseCallback;
75
satorux@chromium.org7f0c4512011-08-23 16:29:21 +090076 // Called when a signal is received. Signal* is the incoming signal.
77 typedef base::Callback<void (Signal*)> SignalCallback;
78
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +090079 // Called when NameOwnerChanged signal is received.
80 typedef base::Callback<void(
81 const std::string& old_owner,
82 const std::string& new_owner)> NameOwnerChangedCallback;
83
hashimoto@chromium.orged268092013-10-02 16:53:09 +090084 // Called when the service becomes available.
85 typedef base::Callback<void(
86 bool service_is_available)> WaitForServiceToBeAvailableCallback;
87
satorux@chromium.org7f0c4512011-08-23 16:29:21 +090088 // Called when the object proxy is connected to the signal.
89 // Parameters:
90 // - the interface name.
91 // - the signal name.
92 // - whether it was successful or not.
93 typedef base::Callback<void (const std::string&, const std::string&, bool)>
94 OnConnectedCallback;
95
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090096 // Calls the method of the remote object and blocks until the response
avakulenko1d8962b2014-09-17 10:44:09 +090097 // is returned. Returns NULL on error with the error details specified
98 // in the |error| object.
99 //
100 // BLOCKING CALL.
dcheng30c5a172016-04-09 07:55:04 +0900101 virtual std::unique_ptr<Response> CallMethodAndBlockWithErrorDetails(
avakulenko1d8962b2014-09-17 10:44:09 +0900102 MethodCall* method_call,
103 int timeout_ms,
104 ScopedDBusError* error);
105
106 // Calls the method of the remote object and blocks until the response
satorux@chromium.orgffa83a92011-08-24 12:32:06 +0900107 // is returned. Returns NULL on error.
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900108 //
109 // BLOCKING CALL.
dcheng30c5a172016-04-09 07:55:04 +0900110 virtual std::unique_ptr<Response> CallMethodAndBlock(MethodCall* method_call,
111 int timeout_ms);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900112
113 // Requests to call the method of the remote object.
114 //
115 // |callback| will be called in the origin thread, once the method call
116 // is complete. As it's called in the origin thread, |callback| can
117 // safely reference objects in the origin thread (i.e. UI thread in most
satorux@chromium.orgb1753152011-11-11 17:36:22 +0900118 // cases). If the caller is not interested in the response from the
119 // method (i.e. calling a method that does not return a value),
120 // EmptyResponseCallback() can be passed to the |callback| parameter.
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900121 //
122 // If the method call is successful, a pointer to Response object will
123 // be passed to the callback. If unsuccessful, NULL will be passed to
124 // the callback.
125 //
126 // Must be called in the origin thread.
127 virtual void CallMethod(MethodCall* method_call,
128 int timeout_ms,
129 ResponseCallback callback);
130
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900131 // Requests to call the method of the remote object.
132 //
133 // |callback| and |error_callback| will be called in the origin thread, once
134 // the method call is complete. As it's called in the origin thread,
135 // |callback| can safely reference objects in the origin thread (i.e.
136 // UI thread in most cases). If the caller is not interested in the response
137 // from the method (i.e. calling a method that does not return a value),
138 // EmptyResponseCallback() can be passed to the |callback| parameter.
139 //
140 // If the method call is successful, a pointer to Response object will
141 // be passed to the callback. If unsuccessful, the error callback will be
142 // called and a pointer to ErrorResponse object will be passed to the error
143 // callback if available, otherwise NULL will be passed.
144 //
145 // Must be called in the origin thread.
146 virtual void CallMethodWithErrorCallback(MethodCall* method_call,
147 int timeout_ms,
148 ResponseCallback callback,
149 ErrorCallback error_callback);
150
quichea91b3d32015-10-24 00:06:03 +0900151 // Requests to connect to the signal from the remote object.
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900152 //
153 // |signal_callback| will be called in the origin thread, when the
154 // signal is received from the remote object. As it's called in the
155 // origin thread, |signal_callback| can safely reference objects in the
156 // origin thread (i.e. UI thread in most cases).
157 //
158 // |on_connected_callback| is called when the object proxy is connected
159 // to the signal, or failed to be connected, in the origin thread.
160 //
quichea91b3d32015-10-24 00:06:03 +0900161 // If a SignalCallback has already been registered for the given
162 // |interface_name| and |signal_name|, |signal_callback| will be
163 // added to the list of callbacks for |interface_name| and
164 // |signal_name|.
165 //
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900166 // Must be called in the origin thread.
167 virtual void ConnectToSignal(const std::string& interface_name,
168 const std::string& signal_name,
169 SignalCallback signal_callback,
170 OnConnectedCallback on_connected_callback);
171
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900172 // Sets a callback for "NameOwnerChanged" signal. The callback is called on
173 // the origin thread when D-Bus system sends "NameOwnerChanged" for the name
174 // represented by |service_name_|.
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900175 virtual void SetNameOwnerChangedCallback(NameOwnerChangedCallback callback);
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900176
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900177 // Runs the callback as soon as the service becomes available.
178 virtual void WaitForServiceToBeAvailable(
179 WaitForServiceToBeAvailableCallback callback);
180
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900181 // Detaches from the remote object. The Bus object will take care of
182 // detaching so you don't have to do this manually.
183 //
184 // BLOCKING CALL.
185 virtual void Detach();
186
stevenjb@chromium.orgb53cfb32013-10-08 07:56:57 +0900187 const ObjectPath& object_path() const { return object_path_; }
188
satorux@chromium.orgb1753152011-11-11 17:36:22 +0900189 // Returns an empty callback that does nothing. Can be used for
190 // CallMethod().
191 static ResponseCallback EmptyResponseCallback();
192
satorux@chromium.orgf77861f2011-08-25 14:18:29 +0900193 protected:
194 // This is protected, so we can define sub classes.
195 virtual ~ObjectProxy();
196
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900197 private:
198 friend class base::RefCountedThreadSafe<ObjectProxy>;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900199
200 // Struct of data we'll be passing from StartAsyncMethodCall() to
201 // OnPendingCallIsCompleteThunk().
202 struct OnPendingCallIsCompleteData {
203 OnPendingCallIsCompleteData(ObjectProxy* in_object_proxy,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900204 ResponseCallback in_response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900205 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900206 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900207 ~OnPendingCallIsCompleteData();
208
209 ObjectProxy* object_proxy;
210 ResponseCallback response_callback;
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900211 ErrorCallback error_callback;
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900212 base::TimeTicks start_time;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900213 };
214
215 // Starts the async method call. This is a helper function to implement
216 // CallMethod().
217 void StartAsyncMethodCall(int timeout_ms,
satorux@chromium.org47d706b2011-10-04 22:47:21 +0900218 DBusMessage* request_message,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900219 ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900220 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900221 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900222
223 // Called when the pending call is complete.
224 void OnPendingCallIsComplete(DBusPendingCall* pending_call,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900225 ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900226 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900227 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900228
229 // Runs the response callback with the given response object.
230 void RunResponseCallback(ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900231 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900232 base::TimeTicks start_time,
satorux@chromium.org47d706b2011-10-04 22:47:21 +0900233 DBusMessage* response_message);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900234
235 // Redirects the function call to OnPendingCallIsComplete().
236 static void OnPendingCallIsCompleteThunk(DBusPendingCall* pending_call,
237 void* user_data);
238
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900239 // Connects to NameOwnerChanged signal.
240 bool ConnectToNameOwnerChangedSignal();
241
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900242 // Helper function for ConnectToSignal().
hashimoto@chromium.orgce5c6152013-09-26 15:40:04 +0900243 bool ConnectToSignalInternal(const std::string& interface_name,
244 const std::string& signal_name,
245 SignalCallback signal_callback);
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900246
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900247 // Helper function for WaitForServiceToBeAvailable().
248 void WaitForServiceToBeAvailableInternal();
249
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900250 // Handles the incoming request messages and dispatches to the signal
251 // callbacks.
252 DBusHandlerResult HandleMessage(DBusConnection* connection,
253 DBusMessage* raw_message);
254
255 // Runs the method. Helper function for HandleMessage().
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900256 void RunMethod(base::TimeTicks start_time,
keybuk@chromium.org2594a712013-04-24 09:12:35 +0900257 std::vector<SignalCallback> signal_callbacks,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900258 Signal* signal);
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900259
260 // Redirects the function call to HandleMessage().
261 static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
262 DBusMessage* raw_message,
263 void* user_data);
264
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900265 // Helper method for logging response errors appropriately.
satorux@chromium.org31bb21e2012-05-31 15:12:11 +0900266 void LogMethodCallFailure(const base::StringPiece& interface_name,
267 const base::StringPiece& method_name,
268 const base::StringPiece& error_name,
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900269 const base::StringPiece& error_message) const;
270
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900271 // Used as ErrorCallback by CallMethod().
satorux@chromium.org31bb21e2012-05-31 15:12:11 +0900272 void OnCallMethodError(const std::string& interface_name,
273 const std::string& method_name,
274 ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900275 ErrorResponse* error_response);
276
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900277 // Adds the match rule to the bus and associate the callback with the signal.
278 bool AddMatchRuleWithCallback(const std::string& match_rule,
279 const std::string& absolute_signal_name,
280 SignalCallback signal_callback);
281
282 // Adds the match rule to the bus so that HandleMessage can see the signal.
283 bool AddMatchRuleWithoutCallback(const std::string& match_rule,
284 const std::string& absolute_signal_name);
285
286 // Calls D-Bus's GetNameOwner method synchronously to update
287 // |service_name_owner_| with the current owner of |service_name_|.
288 //
289 // BLOCKING CALL.
290 void UpdateNameOwnerAndBlock();
291
292 // Handles NameOwnerChanged signal from D-Bus's special message bus.
dcheng30c5a172016-04-09 07:55:04 +0900293 DBusHandlerResult HandleNameOwnerChanged(
294 std::unique_ptr<dbus::Signal> signal);
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900295
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900296 // Runs |name_owner_changed_callback_|.
297 void RunNameOwnerChangedCallback(const std::string& old_owner,
298 const std::string& new_owner);
299
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900300 // Runs |wait_for_service_to_be_available_callbacks_|.
301 void RunWaitForServiceToBeAvailableCallbacks(bool service_is_available);
302
satorux@chromium.orgf06eb892011-10-13 09:45:26 +0900303 scoped_refptr<Bus> bus_;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900304 std::string service_name_;
keybuk@google.combf4649a2012-02-15 06:29:06 +0900305 ObjectPath object_path_;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900306
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900307 // The method table where keys are absolute signal names (i.e. interface
keybuk@chromium.org2594a712013-04-24 09:12:35 +0900308 // name + signal name), and values are lists of the corresponding callbacks.
309 typedef std::map<std::string, std::vector<SignalCallback> > MethodTable;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900310 MethodTable method_table_;
311
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900312 // The callback called when NameOwnerChanged signal is received.
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900313 NameOwnerChangedCallback name_owner_changed_callback_;
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900314
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900315 // Called when the service becomes available.
316 std::vector<WaitForServiceToBeAvailableCallback>
317 wait_for_service_to_be_available_callbacks_;
318
satorux@chromium.org5b3e4962011-11-24 07:08:38 +0900319 std::set<std::string> match_rules_;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900320
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900321 const bool ignore_service_unknown_errors_;
322
avakulenko1d8962b2014-09-17 10:44:09 +0900323 // Known name owner of the well-known bus name represented by |service_name_|.
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900324 std::string service_name_owner_;
325
hashimoto14eb1502015-03-30 16:01:39 +0900326 std::set<DBusPendingCall*> pending_calls_;
327
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900328 DISALLOW_COPY_AND_ASSIGN(ObjectProxy);
329};
330
331} // namespace dbus
332
333#endif // DBUS_OBJECT_PROXY_H_