blob: 22e44f1d64c020a140ee5c96266dd423540d0474 [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
Hidehiko Abefb4bdf42017-11-21 15:01:39 +090024namespace base {
25class TaskRunner;
26} // namespace base
27
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090028namespace dbus {
29
30class Bus;
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +090031class ErrorResponse;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090032class MethodCall;
33class Response;
avakulenko1d8962b2014-09-17 10:44:09 +090034class ScopedDBusError;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +090035class Signal;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090036
37// ObjectProxy is used to communicate with remote objects, mainly for
38// calling methods of these objects.
39//
40// ObjectProxy is a ref counted object, to ensure that |this| of the
avakulenko1d8962b2014-09-17 10:44:09 +090041// object is alive when callbacks referencing |this| are called; the
keybuk@chromium.orgde7b4a92012-03-22 08:39:17 +090042// bus always holds at least one of those references so object proxies
43// always last as long as the bus that created them.
tfarina@chromium.org7928ea22012-11-05 10:56:14 +090044class CHROME_DBUS_EXPORT ObjectProxy
45 : public base::RefCountedThreadSafe<ObjectProxy> {
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090046 public:
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090047 // Client code should use Bus::GetObjectProxy() or
48 // Bus::GetObjectProxyWithOptions() instead of this constructor.
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090049 ObjectProxy(Bus* bus,
50 const std::string& service_name,
keybuk@google.combf4649a2012-02-15 06:29:06 +090051 const ObjectPath& object_path,
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090052 int options);
53
54 // Options to be OR-ed together when calling Bus::GetObjectProxyWithOptions().
55 // Set the IGNORE_SERVICE_UNKNOWN_ERRORS option to silence logging of
stevenjb@chromium.orgc415c482014-08-09 06:57:19 +090056 // org.freedesktop.DBus.Error.ServiceUnknown errors and
57 // org.freedesktop.DBus.Error.ObjectUnknown errors.
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090058 enum Options {
59 DEFAULT_OPTIONS = 0,
60 IGNORE_SERVICE_UNKNOWN_ERRORS = 1 << 0
61 };
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090062
63 // Special timeout constants.
64 //
65 // The constants correspond to DBUS_TIMEOUT_USE_DEFAULT and
66 // DBUS_TIMEOUT_INFINITE. Here we use literal numbers instead of these
67 // macros as these aren't defined with D-Bus earlier than 1.4.12.
68 enum {
69 TIMEOUT_USE_DEFAULT = -1,
70 TIMEOUT_INFINITE = 0x7fffffff,
71 };
72
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +090073 // Called when an error response is returned or no response is returned.
74 // Used for CallMethodWithErrorCallback().
Ryo Hashimoto0102c162017-07-21 17:11:14 +090075 using ErrorCallback = base::OnceCallback<void(ErrorResponse*)>;
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +090076
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090077 // Called when the response is returned. Used for CallMethod().
Ryo Hashimoto0102c162017-07-21 17:11:14 +090078 using ResponseCallback = base::OnceCallback<void(Response*)>;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +090079
Hidehiko Abefb4fdb42017-10-20 04:54:56 +090080 // Called when the response is returned or an error occurs. Used for
81 // CallMethodWithErrorResponse().
82 // Note that even in error case, ErrorResponse* may be nullptr.
83 // E.g. out-of-memory error is found in libdbus, or the connection of
84 // |bus_| is not yet established.
85 using ResponseOrErrorCallback =
86 base::OnceCallback<void(Response*, ErrorResponse*)>;
87
satorux@chromium.org7f0c4512011-08-23 16:29:21 +090088 // Called when a signal is received. Signal* is the incoming signal.
Ryo Hashimoto0102c162017-07-21 17:11:14 +090089 using SignalCallback = base::Callback<void(Signal*)>;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +090090
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +090091 // Called when NameOwnerChanged signal is received.
Ryo Hashimoto0102c162017-07-21 17:11:14 +090092 using NameOwnerChangedCallback =
93 base::Callback<void(const std::string& old_owner,
94 const std::string& new_owner)>;
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +090095
hashimoto@chromium.orged268092013-10-02 16:53:09 +090096 // Called when the service becomes available.
Ryo Hashimoto0102c162017-07-21 17:11:14 +090097 using WaitForServiceToBeAvailableCallback =
Ryo Hashimotobaabdc72017-09-12 13:53:50 +090098 base::OnceCallback<void(bool service_is_available)>;
hashimoto@chromium.orged268092013-10-02 16:53:09 +090099
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900100 // Called when the object proxy is connected to the signal.
101 // Parameters:
102 // - the interface name.
103 // - the signal name.
104 // - whether it was successful or not.
Ryo Hashimoto0102c162017-07-21 17:11:14 +0900105 using OnConnectedCallback =
Ryo Hashimotobaabdc72017-09-12 13:53:50 +0900106 base::OnceCallback<void(const std::string&, const std::string&, bool)>;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900107
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900108 // Calls the method of the remote object and blocks until the response
avakulenko1d8962b2014-09-17 10:44:09 +0900109 // is returned. Returns NULL on error with the error details specified
110 // in the |error| object.
111 //
112 // BLOCKING CALL.
dcheng30c5a172016-04-09 07:55:04 +0900113 virtual std::unique_ptr<Response> CallMethodAndBlockWithErrorDetails(
avakulenko1d8962b2014-09-17 10:44:09 +0900114 MethodCall* method_call,
115 int timeout_ms,
116 ScopedDBusError* error);
117
118 // Calls the method of the remote object and blocks until the response
satorux@chromium.orgffa83a92011-08-24 12:32:06 +0900119 // is returned. Returns NULL on error.
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900120 //
121 // BLOCKING CALL.
dcheng30c5a172016-04-09 07:55:04 +0900122 virtual std::unique_ptr<Response> CallMethodAndBlock(MethodCall* method_call,
123 int timeout_ms);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900124
125 // Requests to call the method of the remote object.
126 //
127 // |callback| will be called in the origin thread, once the method call
128 // is complete. As it's called in the origin thread, |callback| can
129 // safely reference objects in the origin thread (i.e. UI thread in most
Peter Kasting24efe5e2018-02-24 09:03:01 +0900130 // cases).
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900131 //
132 // If the method call is successful, a pointer to Response object will
Ben Chan333256c2017-11-10 05:20:16 +0900133 // be passed to the callback. If unsuccessful, nullptr will be passed to
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900134 // the callback.
135 //
136 // Must be called in the origin thread.
137 virtual void CallMethod(MethodCall* method_call,
138 int timeout_ms,
139 ResponseCallback callback);
140
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900141 // Requests to call the method of the remote object.
142 //
Hidehiko Abefb4fdb42017-10-20 04:54:56 +0900143 // This is almost as same as CallMethod() defined above.
144 // The difference is that, the |callback| can take ErrorResponse.
145 // In case of error, ErrorResponse object is passed to the |callback|
146 // if the remote object returned an error, or nullptr if a response was not
147 // received at all (e.g., D-Bus connection is not established). In either
148 // error case, Response* should be nullptr.
149 virtual void CallMethodWithErrorResponse(MethodCall* method_call,
150 int timeout_ms,
151 ResponseOrErrorCallback callback);
152
153 // DEPRECATED. Please use CallMethodWithErrorResponse() instead.
154 // TODO(hidehiko): Remove this when migration is done.
155 // Requests to call the method of the remote object.
156 //
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900157 // |callback| and |error_callback| will be called in the origin thread, once
158 // the method call is complete. As it's called in the origin thread,
159 // |callback| can safely reference objects in the origin thread (i.e.
Peter Kasting24efe5e2018-02-24 09:03:01 +0900160 // UI thread in most cases).
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900161 //
hashimoto1a4a2e52016-09-01 14:18:38 +0900162 // If the method call is successful, |callback| will be invoked with a
163 // Response object. If unsuccessful, |error_callback| will be invoked with an
164 // ErrorResponse object (if the remote object returned an error) or nullptr
165 // (if a response was not received at all).
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900166 //
167 // Must be called in the origin thread.
168 virtual void CallMethodWithErrorCallback(MethodCall* method_call,
169 int timeout_ms,
170 ResponseCallback callback,
171 ErrorCallback error_callback);
172
quichea91b3d32015-10-24 00:06:03 +0900173 // Requests to connect to the signal from the remote object.
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900174 //
175 // |signal_callback| will be called in the origin thread, when the
176 // signal is received from the remote object. As it's called in the
177 // origin thread, |signal_callback| can safely reference objects in the
178 // origin thread (i.e. UI thread in most cases).
179 //
180 // |on_connected_callback| is called when the object proxy is connected
181 // to the signal, or failed to be connected, in the origin thread.
182 //
quichea91b3d32015-10-24 00:06:03 +0900183 // If a SignalCallback has already been registered for the given
184 // |interface_name| and |signal_name|, |signal_callback| will be
185 // added to the list of callbacks for |interface_name| and
186 // |signal_name|.
187 //
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900188 // Must be called in the origin thread.
189 virtual void ConnectToSignal(const std::string& interface_name,
190 const std::string& signal_name,
191 SignalCallback signal_callback,
192 OnConnectedCallback on_connected_callback);
193
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900194 // Sets a callback for "NameOwnerChanged" signal. The callback is called on
195 // the origin thread when D-Bus system sends "NameOwnerChanged" for the name
196 // represented by |service_name_|.
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900197 virtual void SetNameOwnerChangedCallback(NameOwnerChangedCallback callback);
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900198
derat05e85b32016-08-12 10:41:06 +0900199 // Registers |callback| to run when the service becomes available. If the
200 // service is already available, or if connecting to the name-owner-changed
201 // signal fails, |callback| will be run once asynchronously. Otherwise,
202 // |callback| will be run once in the future after the service becomes
203 // available.
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900204 virtual void WaitForServiceToBeAvailable(
205 WaitForServiceToBeAvailableCallback callback);
206
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900207 // Detaches from the remote object. The Bus object will take care of
208 // detaching so you don't have to do this manually.
209 //
210 // BLOCKING CALL.
211 virtual void Detach();
212
stevenjb@chromium.orgb53cfb32013-10-08 07:56:57 +0900213 const ObjectPath& object_path() const { return object_path_; }
214
satorux@chromium.orgf77861f2011-08-25 14:18:29 +0900215 protected:
216 // This is protected, so we can define sub classes.
217 virtual ~ObjectProxy();
218
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900219 private:
220 friend class base::RefCountedThreadSafe<ObjectProxy>;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900221
Hidehiko Abefb4bdf42017-11-21 15:01:39 +0900222 // Callback passed to CallMethod and its family should be deleted on the
223 // origin thread in any cases. This class manages the work.
224 class ReplyCallbackHolder {
225 public:
226 // Designed to be created on the origin thread.
227 // Both |origin_task_runner| and |callback| must not be null.
228 ReplyCallbackHolder(scoped_refptr<base::TaskRunner> origin_task_runner,
229 ResponseOrErrorCallback callback);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900230
Hidehiko Abefb4bdf42017-11-21 15:01:39 +0900231 // This is movable to be bound to an OnceCallback.
232 ReplyCallbackHolder(ReplyCallbackHolder&& other);
233
234 // |callback_| needs to be destroyed on the origin thread.
235 // If this is not destroyed on non-origin thread, it PostTask()s the
236 // callback to the origin thread for destroying.
237 ~ReplyCallbackHolder();
238
239 // Returns |callback_| with releasing its ownership.
240 // This must be called on the origin thread.
241 ResponseOrErrorCallback ReleaseCallback();
242
243 private:
244 scoped_refptr<base::TaskRunner> origin_task_runner_;
245 ResponseOrErrorCallback callback_;
246 DISALLOW_COPY_AND_ASSIGN(ReplyCallbackHolder);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900247 };
248
249 // Starts the async method call. This is a helper function to implement
250 // CallMethod().
251 void StartAsyncMethodCall(int timeout_ms,
satorux@chromium.org47d706b2011-10-04 22:47:21 +0900252 DBusMessage* request_message,
Hidehiko Abefb4bdf42017-11-21 15:01:39 +0900253 ReplyCallbackHolder callback_holder,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900254 base::TimeTicks start_time);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900255
256 // Called when the pending call is complete.
Hidehiko Abefb4bdf42017-11-21 15:01:39 +0900257 void OnPendingCallIsComplete(ReplyCallbackHolder callback_holder,
258 base::TimeTicks start_time,
259 DBusPendingCall* pending_call);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900260
Hidehiko Abefb4fdb42017-10-20 04:54:56 +0900261 // Runs the ResponseOrErrorCallback with the given response object.
Hidehiko Abefb4bdf42017-11-21 15:01:39 +0900262 void RunResponseOrErrorCallback(ReplyCallbackHolder callback_holderk,
Hidehiko Abefb4fdb42017-10-20 04:54:56 +0900263 base::TimeTicks start_time,
264 Response* response,
265 ErrorResponse* error_response);
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900266
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900267 // Connects to NameOwnerChanged signal.
268 bool ConnectToNameOwnerChangedSignal();
269
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900270 // Helper function for ConnectToSignal().
hashimoto@chromium.orgce5c6152013-09-26 15:40:04 +0900271 bool ConnectToSignalInternal(const std::string& interface_name,
272 const std::string& signal_name,
273 SignalCallback signal_callback);
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900274
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900275 // Helper function for WaitForServiceToBeAvailable().
276 void WaitForServiceToBeAvailableInternal();
277
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900278 // Handles the incoming request messages and dispatches to the signal
279 // callbacks.
280 DBusHandlerResult HandleMessage(DBusConnection* connection,
281 DBusMessage* raw_message);
282
283 // Runs the method. Helper function for HandleMessage().
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900284 void RunMethod(base::TimeTicks start_time,
keybuk@chromium.org2594a712013-04-24 09:12:35 +0900285 std::vector<SignalCallback> signal_callbacks,
satorux@chromium.org5a92cf32011-09-07 05:53:30 +0900286 Signal* signal);
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900287
288 // Redirects the function call to HandleMessage().
289 static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
290 DBusMessage* raw_message,
291 void* user_data);
292
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900293 // Helper method for logging response errors appropriately.
satorux@chromium.org31bb21e2012-05-31 15:12:11 +0900294 void LogMethodCallFailure(const base::StringPiece& interface_name,
295 const base::StringPiece& method_name,
296 const base::StringPiece& error_name,
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900297 const base::StringPiece& error_message) const;
298
Hidehiko Abefb4fdb42017-10-20 04:54:56 +0900299 // Used as ResponseOrErrorCallback by CallMethod().
300 // Logs error message, and drops |error_response| from the arguments to pass
301 // |response_callback|.
Ryo Hashimoto0102c162017-07-21 17:11:14 +0900302 void OnCallMethod(const std::string& interface_name,
303 const std::string& method_name,
304 ResponseCallback response_callback,
305 Response* response,
306 ErrorResponse* error_response);
hashimoto@chromium.org0d2477e2012-04-20 12:18:27 +0900307
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900308 // Adds the match rule to the bus and associate the callback with the signal.
309 bool AddMatchRuleWithCallback(const std::string& match_rule,
310 const std::string& absolute_signal_name,
311 SignalCallback signal_callback);
312
313 // Adds the match rule to the bus so that HandleMessage can see the signal.
314 bool AddMatchRuleWithoutCallback(const std::string& match_rule,
315 const std::string& absolute_signal_name);
316
317 // Calls D-Bus's GetNameOwner method synchronously to update
318 // |service_name_owner_| with the current owner of |service_name_|.
319 //
320 // BLOCKING CALL.
321 void UpdateNameOwnerAndBlock();
322
323 // Handles NameOwnerChanged signal from D-Bus's special message bus.
dcheng30c5a172016-04-09 07:55:04 +0900324 DBusHandlerResult HandleNameOwnerChanged(
325 std::unique_ptr<dbus::Signal> signal);
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900326
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900327 // Runs |name_owner_changed_callback_|.
328 void RunNameOwnerChangedCallback(const std::string& old_owner,
329 const std::string& new_owner);
330
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900331 // Runs |wait_for_service_to_be_available_callbacks_|.
332 void RunWaitForServiceToBeAvailableCallbacks(bool service_is_available);
333
satorux@chromium.orgf06eb892011-10-13 09:45:26 +0900334 scoped_refptr<Bus> bus_;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900335 std::string service_name_;
keybuk@google.combf4649a2012-02-15 06:29:06 +0900336 ObjectPath object_path_;
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900337
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900338 // The method table where keys are absolute signal names (i.e. interface
keybuk@chromium.org2594a712013-04-24 09:12:35 +0900339 // name + signal name), and values are lists of the corresponding callbacks.
Ryo Hashimoto0102c162017-07-21 17:11:14 +0900340 using MethodTable = std::map<std::string, std::vector<SignalCallback>>;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900341 MethodTable method_table_;
342
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900343 // The callback called when NameOwnerChanged signal is received.
hashimoto@chromium.org4f3851c2013-09-27 16:12:03 +0900344 NameOwnerChangedCallback name_owner_changed_callback_;
haruki@chromium.orgc8d231a2012-11-14 20:02:59 +0900345
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900346 // Called when the service becomes available.
347 std::vector<WaitForServiceToBeAvailableCallback>
348 wait_for_service_to_be_available_callbacks_;
349
satorux@chromium.org5b3e4962011-11-24 07:08:38 +0900350 std::set<std::string> match_rules_;
satorux@chromium.org7f0c4512011-08-23 16:29:21 +0900351
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900352 const bool ignore_service_unknown_errors_;
353
avakulenko1d8962b2014-09-17 10:44:09 +0900354 // Known name owner of the well-known bus name represented by |service_name_|.
haruki@chromium.orgc5623ec2012-10-29 15:27:33 +0900355 std::string service_name_owner_;
356
hashimoto14eb1502015-03-30 16:01:39 +0900357 std::set<DBusPendingCall*> pending_calls_;
358
satorux@chromium.org163f1cb2011-08-18 05:58:12 +0900359 DISALLOW_COPY_AND_ASSIGN(ObjectProxy);
360};
361
362} // namespace dbus
363
364#endif // DBUS_OBJECT_PROXY_H_