exported_object.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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_EXPORTED_OBJECT_H_
  5. #define DBUS_EXPORTED_OBJECT_H_
  6. #include <dbus/dbus.h>
  7. #include <map>
  8. #include <memory>
  9. #include <string>
  10. #include <utility>
  11. #include "base/callback.h"
  12. #include "base/memory/ref_counted.h"
  13. #include "base/synchronization/waitable_event.h"
  14. #include "base/threading/platform_thread.h"
  15. #include "base/time/time.h"
  16. #include "dbus/dbus_export.h"
  17. #include "dbus/object_path.h"
  18. namespace dbus {
  19. class Bus;
  20. class MethodCall;
  21. class Response;
  22. class Signal;
  23. // ExportedObject is used to export objects and methods to other D-Bus
  24. // clients.
  25. //
  26. // ExportedObject is a ref counted object, to ensure that |this| of the
  27. // object is alive when callbacks referencing |this| are called.
  28. class CHROME_DBUS_EXPORT ExportedObject
  29. : public base::RefCountedThreadSafe<ExportedObject> {
  30. public:
  31. // Client code should use Bus::GetExportedObject() instead of this
  32. // constructor.
  33. ExportedObject(Bus* bus, const ObjectPath& object_path);
  34. // Called to send a response from an exported method. |response| is the
  35. // response message. Callers should pass nullptr in the event of an error that
  36. // prevents the sending of a response.
  37. using ResponseSender =
  38. base::OnceCallback<void(std::unique_ptr<Response> response)>;
  39. // Called when an exported method is called. |method_call| is the request
  40. // message. |sender| is the callback that's used to send a response.
  41. //
  42. // |method_call| is owned by ExportedObject, hence client code should not
  43. // delete |method_call|.
  44. using MethodCallCallback =
  45. base::RepeatingCallback<void(MethodCall* method_call,
  46. ResponseSender sender)>;
  47. // Called when method exporting is done.
  48. // |success| indicates whether exporting was successful or not.
  49. using OnExportedCallback =
  50. base::OnceCallback<void(const std::string& interface_name,
  51. const std::string& method_name,
  52. bool success)>;
  53. // Called when method unexporting is done.
  54. // |success| indicates whether unexporting was successful or not.
  55. using OnUnexportedCallback =
  56. base::OnceCallback<void(const std::string& interface_name,
  57. const std::string& method_name,
  58. bool success)>;
  59. // Exports the method specified by |interface_name| and |method_name|,
  60. // and blocks until exporting is done. Returns true on success.
  61. //
  62. // |method_call_callback| will be called in the origin thread, when the
  63. // exported method is called. As it's called in the origin thread,
  64. // |method_callback| can safely reference objects in the origin thread
  65. // (i.e. UI thread in most cases).
  66. //
  67. // IMPORTANT NOTE: You should export all methods before requesting a
  68. // service name by Bus::RequestOwnership/AndBlock(). If you do it in the
  69. // wrong order (i.e. request a service name then export methods), there
  70. // will be a short time period where your service is unable to respond to
  71. // method calls because these methods aren't yet exposed. This race is a
  72. // real problem as clients may start calling methods of your service as
  73. // soon as you acquire a service name, by watching the name owner change.
  74. //
  75. // BLOCKING CALL.
  76. virtual bool ExportMethodAndBlock(
  77. const std::string& interface_name,
  78. const std::string& method_name,
  79. const MethodCallCallback& method_call_callback);
  80. // Unexports the method specified by |interface_name| and |method_name|,
  81. // and blocks until unexporting is done. Returns true on success.
  82. virtual bool UnexportMethodAndBlock(const std::string& interface_name,
  83. const std::string& method_name);
  84. // Requests to export the method specified by |interface_name| and
  85. // |method_name|. See Also ExportMethodAndBlock().
  86. //
  87. // |on_exported_callback| is called when the method is exported or
  88. // failed to be exported, in the origin thread.
  89. //
  90. // Must be called in the origin thread.
  91. virtual void ExportMethod(const std::string& interface_name,
  92. const std::string& method_name,
  93. const MethodCallCallback& method_call_callback,
  94. OnExportedCallback on_exported_callback);
  95. // Requests to unexport the method specified by |interface_name| and
  96. // |method_name|. See also UnexportMethodAndBlock().
  97. //
  98. // |on_unexported_callback| is called when the method is unexported or
  99. // failed to be unexported, in the origin thread.
  100. //
  101. // Must be called in the origin thread.
  102. virtual void UnexportMethod(const std::string& interface_name,
  103. const std::string& method_name,
  104. OnUnexportedCallback on_unexported_callback);
  105. // Requests to send the signal from this object. The signal will be sent
  106. // synchronously if this method is called from the message loop in the D-Bus
  107. // thread and asynchronously otherwise.
  108. virtual void SendSignal(Signal* signal);
  109. // Unregisters the object from the bus. The Bus object will take care of
  110. // unregistering so you don't have to do this manually.
  111. //
  112. // BLOCKING CALL.
  113. virtual void Unregister();
  114. protected:
  115. // This is protected, so we can define sub classes.
  116. virtual ~ExportedObject();
  117. private:
  118. friend class base::RefCountedThreadSafe<ExportedObject>;
  119. // Helper function for ExportMethod().
  120. void ExportMethodInternal(const std::string& interface_name,
  121. const std::string& method_name,
  122. const MethodCallCallback& method_call_callback,
  123. OnExportedCallback exported_callback);
  124. // Helper function for UnexportMethod().
  125. void UnexportMethodInternal(const std::string& interface_name,
  126. const std::string& method_name,
  127. OnUnexportedCallback unexported_callback);
  128. // Called when the object is exported.
  129. void OnExported(OnExportedCallback on_exported_callback,
  130. const std::string& interface_name,
  131. const std::string& method_name,
  132. bool success);
  133. // Called when a method is unexported.
  134. void OnUnexported(OnExportedCallback on_unexported_callback,
  135. const std::string& interface_name,
  136. const std::string& method_name,
  137. bool success);
  138. // Helper function for SendSignal().
  139. void SendSignalInternal(base::TimeTicks start_time,
  140. DBusMessage* signal_message);
  141. // Registers this object to the bus.
  142. // Returns true on success, or the object is already registered.
  143. //
  144. // BLOCKING CALL.
  145. bool Register();
  146. // Handles the incoming request messages and dispatches to the exported
  147. // methods.
  148. DBusHandlerResult HandleMessage(DBusConnection* connection,
  149. DBusMessage* raw_message);
  150. // Runs the method. Helper function for HandleMessage().
  151. void RunMethod(const MethodCallCallback& method_call_callback,
  152. std::unique_ptr<MethodCall> method_call,
  153. base::TimeTicks start_time);
  154. // Callback invoked by service provider to send a response to a method call.
  155. // Can be called immediately from a MethodCallCallback to implement a
  156. // synchronous service or called later to implement an asynchronous service.
  157. void SendResponse(base::TimeTicks start_time,
  158. std::unique_ptr<MethodCall> method_call,
  159. std::unique_ptr<Response> response);
  160. // Called on completion of the method run from SendResponse().
  161. // Takes ownership of |method_call| and |response|.
  162. void OnMethodCompleted(std::unique_ptr<MethodCall> method_call,
  163. std::unique_ptr<Response> response,
  164. base::TimeTicks start_time);
  165. // Called when the object is unregistered.
  166. void OnUnregistered(DBusConnection* connection);
  167. // Redirects the function call to HandleMessage().
  168. static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
  169. DBusMessage* raw_message,
  170. void* user_data);
  171. // Redirects the function call to OnUnregistered().
  172. static void OnUnregisteredThunk(DBusConnection* connection,
  173. void* user_data);
  174. scoped_refptr<Bus> bus_;
  175. ObjectPath object_path_;
  176. bool object_is_registered_;
  177. // The method table where keys are absolute method names (i.e. interface
  178. // name + method name), and values are the corresponding callbacks.
  179. typedef std::map<std::string, MethodCallCallback> MethodTable;
  180. MethodTable method_table_;
  181. };
  182. } // namespace dbus
  183. #endif // DBUS_EXPORTED_OBJECT_H_