blob: 5de390461e6e655a8a0d5353af0b887921a0757a [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 //
hashimoto1a4a2e52016-09-01 14:18:38 +0900140 // If the method call is successful, |callback| will be invoked with a
141 // Response object. If unsuccessful, |error_callback| will be invoked with an
142 // ErrorResponse object (if the remote object returned an error) or nullptr
143 // (if a response was not received at all).
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900144 //
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
derat05e85b32016-08-12 10:41:06 +0900177 // Registers |callback| to run when the service becomes available. If the
178 // service is already available, or if connecting to the name-owner-changed
179 // signal fails, |callback| will be run once asynchronously. Otherwise,
180 // |callback| will be run once in the future after the service becomes
181 // available.
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900182 virtual void WaitForServiceToBeAvailable(
183 WaitForServiceToBeAvailableCallback callback);
184
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900185 // Detaches from the remote object. The Bus object will take care of
186 // detaching so you don't have to do this manually.
187 //
188 // BLOCKING CALL.
189 virtual void Detach();
190
stevenjb@chromium.orgb53cfb32013-10-08 07:56:57 +0900191 const ObjectPath& object_path() const { return object_path_; }
192
satorux@chromium.orgb1753152011-11-11 17:36:22 +0900193 // Returns an empty callback that does nothing. Can be used for
194 // CallMethod().
195 static ResponseCallback EmptyResponseCallback();
196
satorux@chromium.orgf77861f2011-08-25 14:18:29 +0900197 protected:
198 // This is protected, so we can define sub classes.
199 virtual ~ObjectProxy();
200
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900201 private:
202 friend class base::RefCountedThreadSafe<ObjectProxy>;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900203
204 // Struct of data we'll be passing from StartAsyncMethodCall() to
205 // OnPendingCallIsCompleteThunk().
206 struct OnPendingCallIsCompleteData {
207 OnPendingCallIsCompleteData(ObjectProxy* in_object_proxy,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900208 ResponseCallback in_response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900209 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900210 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900211 ~OnPendingCallIsCompleteData();
212
213 ObjectProxy* object_proxy;
214 ResponseCallback response_callback;
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900215 ErrorCallback error_callback;
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900216 base::TimeTicks start_time;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900217 };
218
219 // Starts the async method call. This is a helper function to implement
220 // CallMethod().
221 void StartAsyncMethodCall(int timeout_ms,
satorux@chromium.org47d706b2011-10-04 22:47:21 +0900222 DBusMessage* request_message,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900223 ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900224 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900225 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900226
227 // Called when the pending call is complete.
228 void OnPendingCallIsComplete(DBusPendingCall* pending_call,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900229 ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900230 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900231 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900232
233 // Runs the response callback with the given response object.
234 void RunResponseCallback(ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900235 ErrorCallback error_callback,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900236 base::TimeTicks start_time,
satorux@chromium.org47d706b2011-10-04 22:47:21 +0900237 DBusMessage* response_message);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900238
239 // Redirects the function call to OnPendingCallIsComplete().
240 static void OnPendingCallIsCompleteThunk(DBusPendingCall* pending_call,
241 void* user_data);
242
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900243 // Connects to NameOwnerChanged signal.
244 bool ConnectToNameOwnerChangedSignal();
245
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900246 // Helper function for ConnectToSignal().
hashimoto@chromium.orgce5c6152013-09-26 15:40:04 +0900247 bool ConnectToSignalInternal(const std::string& interface_name,
248 const std::string& signal_name,
249 SignalCallback signal_callback);
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900250
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900251 // Helper function for WaitForServiceToBeAvailable().
252 void WaitForServiceToBeAvailableInternal();
253
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900254 // Handles the incoming request messages and dispatches to the signal
255 // callbacks.
256 DBusHandlerResult HandleMessage(DBusConnection* connection,
257 DBusMessage* raw_message);
258
259 // Runs the method. Helper function for HandleMessage().
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900260 void RunMethod(base::TimeTicks start_time,
keybuk@chromium.org2594a712013-04-24 09:12:35 +0900261 std::vector<SignalCallback> signal_callbacks,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900262 Signal* signal);
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900263
264 // Redirects the function call to HandleMessage().
265 static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
266 DBusMessage* raw_message,
267 void* user_data);
268
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900269 // Helper method for logging response errors appropriately.
satorux@chromium.org31bb21e2012-05-31 15:12:11 +0900270 void LogMethodCallFailure(const base::StringPiece& interface_name,
271 const base::StringPiece& method_name,
272 const base::StringPiece& error_name,
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900273 const base::StringPiece& error_message) const;
274
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900275 // Used as ErrorCallback by CallMethod().
satorux@chromium.org31bb21e2012-05-31 15:12:11 +0900276 void OnCallMethodError(const std::string& interface_name,
277 const std::string& method_name,
278 ResponseCallback response_callback,
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900279 ErrorResponse* error_response);
280
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900281 // Adds the match rule to the bus and associate the callback with the signal.
282 bool AddMatchRuleWithCallback(const std::string& match_rule,
283 const std::string& absolute_signal_name,
284 SignalCallback signal_callback);
285
286 // Adds the match rule to the bus so that HandleMessage can see the signal.
287 bool AddMatchRuleWithoutCallback(const std::string& match_rule,
288 const std::string& absolute_signal_name);
289
290 // Calls D-Bus's GetNameOwner method synchronously to update
291 // |service_name_owner_| with the current owner of |service_name_|.
292 //
293 // BLOCKING CALL.
294 void UpdateNameOwnerAndBlock();
295
296 // Handles NameOwnerChanged signal from D-Bus's special message bus.
dcheng30c5a172016-04-09 07:55:04 +0900297 DBusHandlerResult HandleNameOwnerChanged(
298 std::unique_ptr<dbus::Signal> signal);
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900299
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900300 // Runs |name_owner_changed_callback_|.
301 void RunNameOwnerChangedCallback(const std::string& old_owner,
302 const std::string& new_owner);
303
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900304 // Runs |wait_for_service_to_be_available_callbacks_|.
305 void RunWaitForServiceToBeAvailableCallbacks(bool service_is_available);
306
satorux@chromium.orgf06eb892011-10-13 09:45:26 +0900307 scoped_refptr<Bus> bus_;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900308 std::string service_name_;
keybuk@google.combf4649a2012-02-15 06:29:06 +0900309 ObjectPath object_path_;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900310
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900311 // The method table where keys are absolute signal names (i.e. interface
keybuk@chromium.org2594a712013-04-24 09:12:35 +0900312 // name + signal name), and values are lists of the corresponding callbacks.
313 typedef std::map<std::string, std::vector<SignalCallback> > MethodTable;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900314 MethodTable method_table_;
315
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900316 // The callback called when NameOwnerChanged signal is received.
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900317 NameOwnerChangedCallback name_owner_changed_callback_;
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900318
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900319 // Called when the service becomes available.
320 std::vector<WaitForServiceToBeAvailableCallback>
321 wait_for_service_to_be_available_callbacks_;
322
satorux@chromium.org5b3e4962011-11-24 07:08:38 +0900323 std::set<std::string> match_rules_;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900324
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900325 const bool ignore_service_unknown_errors_;
326
avakulenko1d8962b2014-09-17 10:44:09 +0900327 // Known name owner of the well-known bus name represented by |service_name_|.
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900328 std::string service_name_owner_;
329
hashimoto14eb1502015-03-30 16:01:39 +0900330 std::set<DBusPendingCall*> pending_calls_;
331
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900332 DISALLOW_COPY_AND_ASSIGN(ObjectProxy);
333};
334
335} // namespace dbus
336
337#endif // DBUS_OBJECT_PROXY_H_