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