object_proxy.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // Copyright (c) 2012 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. #ifndef DBUS_OBJECT_PROXY_H_
  5. #define DBUS_OBJECT_PROXY_H_
  6. #include <dbus/dbus.h>
  7. #include <map>
  8. #include <memory>
  9. #include <set>
  10. #include <string>
  11. #include <vector>
  12. #include "base/callback.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/strings/string_piece.h"
  15. #include "base/task/sequenced_task_runner.h"
  16. #include "base/time/time.h"
  17. #include "dbus/dbus_export.h"
  18. #include "dbus/object_path.h"
  19. namespace dbus {
  20. class Bus;
  21. class ErrorResponse;
  22. class MethodCall;
  23. class Response;
  24. class ScopedDBusError;
  25. class Signal;
  26. // ObjectProxy is used to communicate with remote objects, mainly for
  27. // calling methods of these objects.
  28. //
  29. // ObjectProxy is a ref counted object, to ensure that |this| of the
  30. // object is alive when callbacks referencing |this| are called; the
  31. // bus always holds at least one of those references so object proxies
  32. // always last as long as the bus that created them.
  33. class CHROME_DBUS_EXPORT ObjectProxy
  34. : public base::RefCountedThreadSafe<ObjectProxy> {
  35. public:
  36. // Client code should use Bus::GetObjectProxy() or
  37. // Bus::GetObjectProxyWithOptions() instead of this constructor.
  38. ObjectProxy(Bus* bus,
  39. const std::string& service_name,
  40. const ObjectPath& object_path,
  41. int options);
  42. ObjectProxy(const ObjectProxy&) = delete;
  43. ObjectProxy& operator=(const ObjectProxy&) = delete;
  44. // Options to be OR-ed together when calling Bus::GetObjectProxyWithOptions().
  45. // Set the IGNORE_SERVICE_UNKNOWN_ERRORS option to silence logging of
  46. // org.freedesktop.DBus.Error.ServiceUnknown errors and
  47. // org.freedesktop.DBus.Error.ObjectUnknown errors.
  48. enum Options {
  49. DEFAULT_OPTIONS = 0,
  50. IGNORE_SERVICE_UNKNOWN_ERRORS = 1 << 0
  51. };
  52. // Special timeout constants.
  53. //
  54. // The constants correspond to DBUS_TIMEOUT_USE_DEFAULT and
  55. // DBUS_TIMEOUT_INFINITE. Here we use literal numbers instead of these
  56. // macros as these aren't defined with D-Bus earlier than 1.4.12.
  57. enum {
  58. TIMEOUT_USE_DEFAULT = -1,
  59. TIMEOUT_INFINITE = 0x7fffffff,
  60. };
  61. // Called when an error response is returned or no response is returned.
  62. // Used for CallMethodWithErrorCallback().
  63. using ErrorCallback = base::OnceCallback<void(ErrorResponse*)>;
  64. // Called when the response is returned. Used for CallMethod().
  65. using ResponseCallback = base::OnceCallback<void(Response*)>;
  66. // Called when the response is returned or an error occurs. Used for
  67. // CallMethodWithErrorResponse().
  68. // Note that even in error case, ErrorResponse* may be nullptr.
  69. // E.g. out-of-memory error is found in libdbus, or the connection of
  70. // |bus_| is not yet established.
  71. using ResponseOrErrorCallback =
  72. base::OnceCallback<void(Response*, ErrorResponse*)>;
  73. // Called when a signal is received. Signal* is the incoming signal.
  74. using SignalCallback = base::RepeatingCallback<void(Signal*)>;
  75. // Called when NameOwnerChanged signal is received.
  76. using NameOwnerChangedCallback =
  77. base::RepeatingCallback<void(const std::string& old_owner,
  78. const std::string& new_owner)>;
  79. // Called when the service becomes available.
  80. using WaitForServiceToBeAvailableCallback =
  81. base::OnceCallback<void(bool service_is_available)>;
  82. // Called when the object proxy is connected to the signal.
  83. // Parameters:
  84. // - the interface name.
  85. // - the signal name.
  86. // - whether it was successful or not.
  87. using OnConnectedCallback =
  88. base::OnceCallback<void(const std::string&, const std::string&, bool)>;
  89. // Calls the method of the remote object and blocks until the response
  90. // is returned. Returns NULL on error with the error details specified
  91. // in the |error| object.
  92. //
  93. // BLOCKING CALL.
  94. virtual std::unique_ptr<Response> CallMethodAndBlockWithErrorDetails(
  95. MethodCall* method_call,
  96. int timeout_ms,
  97. ScopedDBusError* error);
  98. // Calls the method of the remote object and blocks until the response
  99. // is returned. Returns NULL on error.
  100. //
  101. // BLOCKING CALL.
  102. virtual std::unique_ptr<Response> CallMethodAndBlock(MethodCall* method_call,
  103. int timeout_ms);
  104. // Requests to call the method of the remote object.
  105. //
  106. // |callback| will be called in the origin thread, once the method call
  107. // is complete. As it's called in the origin thread, |callback| can
  108. // safely reference objects in the origin thread (i.e. UI thread in most
  109. // cases).
  110. //
  111. // If the method call is successful, a pointer to Response object will
  112. // be passed to the callback. If unsuccessful, nullptr will be passed to
  113. // the callback.
  114. //
  115. // Must be called in the origin thread.
  116. virtual void CallMethod(MethodCall* method_call,
  117. int timeout_ms,
  118. ResponseCallback callback);
  119. // Requests to call the method of the remote object.
  120. //
  121. // This is almost as same as CallMethod() defined above.
  122. // The difference is that, the |callback| can take ErrorResponse.
  123. // In case of error, ErrorResponse object is passed to the |callback|
  124. // if the remote object returned an error, or nullptr if a response was not
  125. // received at all (e.g., D-Bus connection is not established). In either
  126. // error case, Response* should be nullptr.
  127. virtual void CallMethodWithErrorResponse(MethodCall* method_call,
  128. int timeout_ms,
  129. ResponseOrErrorCallback callback);
  130. // DEPRECATED. Please use CallMethodWithErrorResponse() instead.
  131. // TODO(hidehiko): Remove this when migration is done.
  132. // Requests to call the method of the remote object.
  133. //
  134. // |callback| and |error_callback| will be called in the origin thread, once
  135. // the method call is complete. As it's called in the origin thread,
  136. // |callback| can safely reference objects in the origin thread (i.e.
  137. // UI thread in most cases).
  138. //
  139. // If the method call is successful, |callback| will be invoked with a
  140. // Response object. If unsuccessful, |error_callback| will be invoked with an
  141. // ErrorResponse object (if the remote object returned an error) or nullptr
  142. // (if a response was not received at all).
  143. //
  144. // Must be called in the origin thread.
  145. virtual void CallMethodWithErrorCallback(MethodCall* method_call,
  146. int timeout_ms,
  147. ResponseCallback callback,
  148. ErrorCallback error_callback);
  149. // Requests to connect to the signal from the remote object.
  150. //
  151. // |signal_callback| will be called in the origin thread, when the
  152. // signal is received from the remote object. As it's called in the
  153. // origin thread, |signal_callback| can safely reference objects in the
  154. // origin thread (i.e. UI thread in most cases).
  155. //
  156. // |on_connected_callback| is called when the object proxy is connected
  157. // to the signal, or failed to be connected, in the origin thread.
  158. //
  159. // If a SignalCallback has already been registered for the given
  160. // |interface_name| and |signal_name|, |signal_callback| will be
  161. // added to the list of callbacks for |interface_name| and
  162. // |signal_name|.
  163. //
  164. // Must be called in the origin thread.
  165. virtual void ConnectToSignal(const std::string& interface_name,
  166. const std::string& signal_name,
  167. SignalCallback signal_callback,
  168. OnConnectedCallback on_connected_callback);
  169. // Blocking version of ConnectToSignal. Returns true on success. Must be
  170. // called from the DBus thread.
  171. //
  172. // BLOCKING CALL.
  173. virtual bool ConnectToSignalAndBlock(const std::string& interface_name,
  174. const std::string& signal_name,
  175. SignalCallback signal_callback);
  176. // Sets a callback for "NameOwnerChanged" signal. The callback is called on
  177. // the origin thread when D-Bus system sends "NameOwnerChanged" for the name
  178. // represented by |service_name_|.
  179. virtual void SetNameOwnerChangedCallback(NameOwnerChangedCallback callback);
  180. // Registers |callback| to run when the service becomes available. If the
  181. // service is already available, or if connecting to the name-owner-changed
  182. // signal fails, |callback| will be run once asynchronously. Otherwise,
  183. // |callback| will be run once in the future after the service becomes
  184. // available.
  185. virtual void WaitForServiceToBeAvailable(
  186. WaitForServiceToBeAvailableCallback callback);
  187. // Detaches from the remote object. The Bus object will take care of
  188. // detaching so you don't have to do this manually.
  189. //
  190. // BLOCKING CALL.
  191. virtual void Detach();
  192. const ObjectPath& object_path() const { return object_path_; }
  193. protected:
  194. // This is protected, so we can define sub classes.
  195. virtual ~ObjectProxy();
  196. private:
  197. friend class base::RefCountedThreadSafe<ObjectProxy>;
  198. // Callback passed to CallMethod and its family should be deleted on the
  199. // origin thread in any cases. This class manages the work.
  200. class ReplyCallbackHolder {
  201. public:
  202. // Designed to be created on the origin thread.
  203. // Both |origin_task_runner| and |callback| must not be null.
  204. ReplyCallbackHolder(
  205. scoped_refptr<base::SequencedTaskRunner> origin_task_runner,
  206. ResponseOrErrorCallback callback);
  207. // This is movable to be bound to an OnceCallback.
  208. ReplyCallbackHolder(ReplyCallbackHolder&& other);
  209. ReplyCallbackHolder(const ReplyCallbackHolder&) = delete;
  210. ReplyCallbackHolder& operator=(const ReplyCallbackHolder&) = delete;
  211. // |callback_| needs to be destroyed on the origin thread.
  212. // If this is not destroyed on non-origin thread, it PostTask()s the
  213. // callback to the origin thread for destroying.
  214. ~ReplyCallbackHolder();
  215. // Returns |callback_| with releasing its ownership.
  216. // This must be called on the origin thread.
  217. ResponseOrErrorCallback ReleaseCallback();
  218. private:
  219. scoped_refptr<base::SequencedTaskRunner> origin_task_runner_;
  220. ResponseOrErrorCallback callback_;
  221. };
  222. // Starts the async method call. This is a helper function to implement
  223. // CallMethod().
  224. void StartAsyncMethodCall(int timeout_ms,
  225. DBusMessage* request_message,
  226. ReplyCallbackHolder callback_holder,
  227. base::TimeTicks start_time);
  228. // Called when the pending call is complete.
  229. void OnPendingCallIsComplete(ReplyCallbackHolder callback_holder,
  230. base::TimeTicks start_time,
  231. DBusPendingCall* pending_call);
  232. // Runs the ResponseOrErrorCallback with the given response object.
  233. void RunResponseOrErrorCallback(ReplyCallbackHolder callback_holderk,
  234. base::TimeTicks start_time,
  235. Response* response,
  236. ErrorResponse* error_response);
  237. // Connects to NameOwnerChanged signal.
  238. bool ConnectToNameOwnerChangedSignal();
  239. // Tries to connect to NameOwnerChanged signal, ignores any error.
  240. void TryConnectToNameOwnerChangedSignal();
  241. // Helper function for WaitForServiceToBeAvailable().
  242. void WaitForServiceToBeAvailableInternal();
  243. // Handles the incoming request messages and dispatches to the signal
  244. // callbacks.
  245. DBusHandlerResult HandleMessage(DBusConnection* connection,
  246. DBusMessage* raw_message);
  247. // Runs the method. Helper function for HandleMessage().
  248. void RunMethod(base::TimeTicks start_time,
  249. std::vector<SignalCallback> signal_callbacks,
  250. Signal* signal);
  251. // Redirects the function call to HandleMessage().
  252. static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
  253. DBusMessage* raw_message,
  254. void* user_data);
  255. // Helper method for logging response errors appropriately.
  256. void LogMethodCallFailure(const base::StringPiece& interface_name,
  257. const base::StringPiece& method_name,
  258. const base::StringPiece& error_name,
  259. const base::StringPiece& error_message) const;
  260. // Used as ResponseOrErrorCallback by CallMethod().
  261. // Logs error message, and drops |error_response| from the arguments to pass
  262. // |response_callback|.
  263. void OnCallMethod(const std::string& interface_name,
  264. const std::string& method_name,
  265. ResponseCallback response_callback,
  266. Response* response,
  267. ErrorResponse* error_response);
  268. // Adds the match rule to the bus and associate the callback with the signal.
  269. bool AddMatchRuleWithCallback(const std::string& match_rule,
  270. const std::string& absolute_signal_name,
  271. SignalCallback signal_callback);
  272. // Adds the match rule to the bus so that HandleMessage can see the signal.
  273. bool AddMatchRuleWithoutCallback(const std::string& match_rule,
  274. const std::string& absolute_signal_name);
  275. // Calls D-Bus's GetNameOwner method synchronously to update
  276. // |service_name_owner_| with the current owner of |service_name_|.
  277. //
  278. // BLOCKING CALL.
  279. void UpdateNameOwnerAndBlock();
  280. // Handles NameOwnerChanged signal from D-Bus's special message bus.
  281. DBusHandlerResult HandleNameOwnerChanged(
  282. std::unique_ptr<dbus::Signal> signal);
  283. // Runs |name_owner_changed_callback_|.
  284. void RunNameOwnerChangedCallback(const std::string& old_owner,
  285. const std::string& new_owner);
  286. // Runs |wait_for_service_to_be_available_callbacks_|.
  287. void RunWaitForServiceToBeAvailableCallbacks(bool service_is_available);
  288. scoped_refptr<Bus> bus_;
  289. std::string service_name_;
  290. ObjectPath object_path_;
  291. // The method table where keys are absolute signal names (i.e. interface
  292. // name + signal name), and values are lists of the corresponding callbacks.
  293. using MethodTable = std::map<std::string, std::vector<SignalCallback>>;
  294. MethodTable method_table_;
  295. // The callback called when NameOwnerChanged signal is received.
  296. NameOwnerChangedCallback name_owner_changed_callback_;
  297. // Called when the service becomes available.
  298. std::vector<WaitForServiceToBeAvailableCallback>
  299. wait_for_service_to_be_available_callbacks_;
  300. std::set<std::string> match_rules_;
  301. const bool ignore_service_unknown_errors_;
  302. // Known name owner of the well-known bus name represented by |service_name_|.
  303. std::string service_name_owner_;
  304. std::set<DBusPendingCall*> pending_calls_;
  305. };
  306. } // namespace dbus
  307. #endif // DBUS_OBJECT_PROXY_H_