xref: /aosp_15_r20/external/libchrome/mojo/public/cpp/bindings/binding.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 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 MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_
6*635a8641SAndroid Build Coastguard Worker #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <string>
9*635a8641SAndroid Build Coastguard Worker #include <utility>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/callback_forward.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
15*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/connection_error_callback.h"
16*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/interface_ptr.h"
17*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/interface_ptr_info.h"
18*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/interface_request.h"
19*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/lib/binding_state.h"
20*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
21*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/core.h"
22*635a8641SAndroid Build Coastguard Worker 
23*635a8641SAndroid Build Coastguard Worker namespace mojo {
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker class MessageReceiver;
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker // Represents the binding of an interface implementation to a message pipe.
28*635a8641SAndroid Build Coastguard Worker // When the |Binding| object is destroyed, the binding between the message pipe
29*635a8641SAndroid Build Coastguard Worker // and the interface is torn down and the message pipe is closed, leaving the
30*635a8641SAndroid Build Coastguard Worker // interface implementation in an unbound state. Once the |Binding| object is
31*635a8641SAndroid Build Coastguard Worker // destroyed, it is guaranteed that no more method calls are dispatched to the
32*635a8641SAndroid Build Coastguard Worker // implementation and the connection error handler (if registered) won't be
33*635a8641SAndroid Build Coastguard Worker // called.
34*635a8641SAndroid Build Coastguard Worker //
35*635a8641SAndroid Build Coastguard Worker // Example:
36*635a8641SAndroid Build Coastguard Worker //
37*635a8641SAndroid Build Coastguard Worker //   #include "foo.mojom.h"
38*635a8641SAndroid Build Coastguard Worker //
39*635a8641SAndroid Build Coastguard Worker //   class FooImpl : public Foo {
40*635a8641SAndroid Build Coastguard Worker //    public:
41*635a8641SAndroid Build Coastguard Worker //     explicit FooImpl(InterfaceRequest<Foo> request)
42*635a8641SAndroid Build Coastguard Worker //         : binding_(this, std::move(request)) {}
43*635a8641SAndroid Build Coastguard Worker //
44*635a8641SAndroid Build Coastguard Worker //     // Foo implementation here.
45*635a8641SAndroid Build Coastguard Worker //
46*635a8641SAndroid Build Coastguard Worker //    private:
47*635a8641SAndroid Build Coastguard Worker //     Binding<Foo> binding_;
48*635a8641SAndroid Build Coastguard Worker //   };
49*635a8641SAndroid Build Coastguard Worker //
50*635a8641SAndroid Build Coastguard Worker //   class MyFooFactory : public InterfaceFactory<Foo> {
51*635a8641SAndroid Build Coastguard Worker //    public:
52*635a8641SAndroid Build Coastguard Worker //     void Create(..., InterfaceRequest<Foo> request) override {
53*635a8641SAndroid Build Coastguard Worker //       auto f = new FooImpl(std::move(request));
54*635a8641SAndroid Build Coastguard Worker //       // Do something to manage the lifetime of |f|. Use StrongBinding<> to
55*635a8641SAndroid Build Coastguard Worker //       // delete FooImpl on connection errors.
56*635a8641SAndroid Build Coastguard Worker //     }
57*635a8641SAndroid Build Coastguard Worker //   };
58*635a8641SAndroid Build Coastguard Worker //
59*635a8641SAndroid Build Coastguard Worker // This class is thread hostile while bound to a message pipe. All calls to this
60*635a8641SAndroid Build Coastguard Worker // class must be from the sequence that bound it. The interface implementation's
61*635a8641SAndroid Build Coastguard Worker // methods will be called from the sequence that bound this. If a Binding is not
62*635a8641SAndroid Build Coastguard Worker // bound to a message pipe, it may be bound or destroyed on any sequence.
63*635a8641SAndroid Build Coastguard Worker //
64*635a8641SAndroid Build Coastguard Worker // When you bind this class to a message pipe, optionally you can specify a
65*635a8641SAndroid Build Coastguard Worker // base::SingleThreadTaskRunner. This task runner must belong to the same
66*635a8641SAndroid Build Coastguard Worker // thread. It will be used to dispatch incoming method calls and connection
67*635a8641SAndroid Build Coastguard Worker // error notification. It is useful when you attach multiple task runners to a
68*635a8641SAndroid Build Coastguard Worker // single thread for the purposes of task scheduling. Please note that
69*635a8641SAndroid Build Coastguard Worker // incoming synchrounous method calls may not be run from this task runner, when
70*635a8641SAndroid Build Coastguard Worker // they reenter outgoing synchrounous calls on the same thread.
71*635a8641SAndroid Build Coastguard Worker template <typename Interface,
72*635a8641SAndroid Build Coastguard Worker           typename ImplRefTraits = RawPtrImplRefTraits<Interface>>
73*635a8641SAndroid Build Coastguard Worker class Binding {
74*635a8641SAndroid Build Coastguard Worker  public:
75*635a8641SAndroid Build Coastguard Worker   using ImplPointerType = typename ImplRefTraits::PointerType;
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker   // Constructs an incomplete binding that will use the implementation |impl|.
78*635a8641SAndroid Build Coastguard Worker   // The binding may be completed with a subsequent call to the |Bind| method.
79*635a8641SAndroid Build Coastguard Worker   // Does not take ownership of |impl|, which must outlive the binding.
Binding(ImplPointerType impl)80*635a8641SAndroid Build Coastguard Worker   explicit Binding(ImplPointerType impl) : internal_state_(std::move(impl)) {}
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   // Constructs a completed binding of |impl| to the message pipe endpoint in
83*635a8641SAndroid Build Coastguard Worker   // |request|, taking ownership of the endpoint. Does not take ownership of
84*635a8641SAndroid Build Coastguard Worker   // |impl|, which must outlive the binding.
85*635a8641SAndroid Build Coastguard Worker   Binding(ImplPointerType impl,
86*635a8641SAndroid Build Coastguard Worker           InterfaceRequest<Interface> request,
87*635a8641SAndroid Build Coastguard Worker           scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr)
Binding(std::move (impl))88*635a8641SAndroid Build Coastguard Worker       : Binding(std::move(impl)) {
89*635a8641SAndroid Build Coastguard Worker     Bind(std::move(request), std::move(runner));
90*635a8641SAndroid Build Coastguard Worker   }
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker   // Tears down the binding, closing the message pipe and leaving the interface
93*635a8641SAndroid Build Coastguard Worker   // implementation unbound.
~Binding()94*635a8641SAndroid Build Coastguard Worker   ~Binding() {}
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker   // Completes a binding that was constructed with only an interface
97*635a8641SAndroid Build Coastguard Worker   // implementation by removing the message pipe endpoint from |request| and
98*635a8641SAndroid Build Coastguard Worker   // binding it to the previously specified implementation.
99*635a8641SAndroid Build Coastguard Worker   void Bind(InterfaceRequest<Interface> request,
100*635a8641SAndroid Build Coastguard Worker             scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) {
101*635a8641SAndroid Build Coastguard Worker     internal_state_.Bind(request.PassMessagePipe(), std::move(runner));
102*635a8641SAndroid Build Coastguard Worker   }
103*635a8641SAndroid Build Coastguard Worker 
104*635a8641SAndroid Build Coastguard Worker   // Adds a message filter to be notified of each incoming message before
105*635a8641SAndroid Build Coastguard Worker   // dispatch. If a filter returns |false| from Accept(), the message is not
106*635a8641SAndroid Build Coastguard Worker   // dispatched and the pipe is closed. Filters cannot be removed.
AddFilter(std::unique_ptr<MessageReceiver> filter)107*635a8641SAndroid Build Coastguard Worker   void AddFilter(std::unique_ptr<MessageReceiver> filter) {
108*635a8641SAndroid Build Coastguard Worker     DCHECK(is_bound());
109*635a8641SAndroid Build Coastguard Worker     internal_state_.AddFilter(std::move(filter));
110*635a8641SAndroid Build Coastguard Worker   }
111*635a8641SAndroid Build Coastguard Worker 
112*635a8641SAndroid Build Coastguard Worker   // Whether there are any associated interfaces running on the pipe currently.
HasAssociatedInterfaces()113*635a8641SAndroid Build Coastguard Worker   bool HasAssociatedInterfaces() const {
114*635a8641SAndroid Build Coastguard Worker     return internal_state_.HasAssociatedInterfaces();
115*635a8641SAndroid Build Coastguard Worker   }
116*635a8641SAndroid Build Coastguard Worker 
117*635a8641SAndroid Build Coastguard Worker   // Stops processing incoming messages until
118*635a8641SAndroid Build Coastguard Worker   // ResumeIncomingMethodCallProcessing(), or WaitForIncomingMethodCall().
119*635a8641SAndroid Build Coastguard Worker   // Outgoing messages are still sent.
120*635a8641SAndroid Build Coastguard Worker   //
121*635a8641SAndroid Build Coastguard Worker   // No errors are detected on the message pipe while paused.
122*635a8641SAndroid Build Coastguard Worker   //
123*635a8641SAndroid Build Coastguard Worker   // This method may only be called if the object has been bound to a message
124*635a8641SAndroid Build Coastguard Worker   // pipe and there are no associated interfaces running.
PauseIncomingMethodCallProcessing()125*635a8641SAndroid Build Coastguard Worker   void PauseIncomingMethodCallProcessing() {
126*635a8641SAndroid Build Coastguard Worker     CHECK(!HasAssociatedInterfaces());
127*635a8641SAndroid Build Coastguard Worker     internal_state_.PauseIncomingMethodCallProcessing();
128*635a8641SAndroid Build Coastguard Worker   }
ResumeIncomingMethodCallProcessing()129*635a8641SAndroid Build Coastguard Worker   void ResumeIncomingMethodCallProcessing() {
130*635a8641SAndroid Build Coastguard Worker     internal_state_.ResumeIncomingMethodCallProcessing();
131*635a8641SAndroid Build Coastguard Worker   }
132*635a8641SAndroid Build Coastguard Worker 
133*635a8641SAndroid Build Coastguard Worker   // Blocks the calling sequence until either a call arrives on the previously
134*635a8641SAndroid Build Coastguard Worker   // bound message pipe, the deadline is exceeded, or an error occurs. Returns
135*635a8641SAndroid Build Coastguard Worker   // true if a method was successfully read and dispatched.
136*635a8641SAndroid Build Coastguard Worker   //
137*635a8641SAndroid Build Coastguard Worker   // This method may only be called if the object has been bound to a message
138*635a8641SAndroid Build Coastguard Worker   // pipe. This returns once a message is received either on the master
139*635a8641SAndroid Build Coastguard Worker   // interface or any associated interfaces.
140*635a8641SAndroid Build Coastguard Worker   bool WaitForIncomingMethodCall(
141*635a8641SAndroid Build Coastguard Worker       MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE) {
142*635a8641SAndroid Build Coastguard Worker     return internal_state_.WaitForIncomingMethodCall(deadline);
143*635a8641SAndroid Build Coastguard Worker   }
144*635a8641SAndroid Build Coastguard Worker 
145*635a8641SAndroid Build Coastguard Worker   // Closes the message pipe that was previously bound. Put this object into a
146*635a8641SAndroid Build Coastguard Worker   // state where it can be rebound to a new pipe.
Close()147*635a8641SAndroid Build Coastguard Worker   void Close() { internal_state_.Close(); }
148*635a8641SAndroid Build Coastguard Worker 
149*635a8641SAndroid Build Coastguard Worker   // Similar to the method above, but also specifies a disconnect reason.
CloseWithReason(uint32_t custom_reason,const std::string & description)150*635a8641SAndroid Build Coastguard Worker   void CloseWithReason(uint32_t custom_reason, const std::string& description) {
151*635a8641SAndroid Build Coastguard Worker     internal_state_.CloseWithReason(custom_reason, description);
152*635a8641SAndroid Build Coastguard Worker   }
153*635a8641SAndroid Build Coastguard Worker 
154*635a8641SAndroid Build Coastguard Worker   // Unbinds the underlying pipe from this binding and returns it so it can be
155*635a8641SAndroid Build Coastguard Worker   // used in another context, such as on another sequence or with a different
156*635a8641SAndroid Build Coastguard Worker   // implementation. Put this object into a state where it can be rebound to a
157*635a8641SAndroid Build Coastguard Worker   // new pipe.
158*635a8641SAndroid Build Coastguard Worker   //
159*635a8641SAndroid Build Coastguard Worker   // This method may only be called if the object has been bound to a message
160*635a8641SAndroid Build Coastguard Worker   // pipe and there are no associated interfaces running.
161*635a8641SAndroid Build Coastguard Worker   //
162*635a8641SAndroid Build Coastguard Worker   // TODO(yzshen): For now, users need to make sure there is no one holding
163*635a8641SAndroid Build Coastguard Worker   // on to associated interface endpoint handles at both sides of the
164*635a8641SAndroid Build Coastguard Worker   // message pipe in order to call this method. We need a way to forcefully
165*635a8641SAndroid Build Coastguard Worker   // invalidate associated interface endpoint handles.
Unbind()166*635a8641SAndroid Build Coastguard Worker   InterfaceRequest<Interface> Unbind() {
167*635a8641SAndroid Build Coastguard Worker     CHECK(!HasAssociatedInterfaces());
168*635a8641SAndroid Build Coastguard Worker     return internal_state_.Unbind();
169*635a8641SAndroid Build Coastguard Worker   }
170*635a8641SAndroid Build Coastguard Worker 
171*635a8641SAndroid Build Coastguard Worker   // Sets an error handler that will be called if a connection error occurs on
172*635a8641SAndroid Build Coastguard Worker   // the bound message pipe.
173*635a8641SAndroid Build Coastguard Worker   //
174*635a8641SAndroid Build Coastguard Worker   // This method may only be called after this Binding has been bound to a
175*635a8641SAndroid Build Coastguard Worker   // message pipe. The error handler will be reset when this Binding is unbound
176*635a8641SAndroid Build Coastguard Worker   // or closed.
set_connection_error_handler(base::OnceClosure error_handler)177*635a8641SAndroid Build Coastguard Worker   void set_connection_error_handler(base::OnceClosure error_handler) {
178*635a8641SAndroid Build Coastguard Worker     DCHECK(is_bound());
179*635a8641SAndroid Build Coastguard Worker     internal_state_.set_connection_error_handler(std::move(error_handler));
180*635a8641SAndroid Build Coastguard Worker   }
181*635a8641SAndroid Build Coastguard Worker 
set_connection_error_with_reason_handler(ConnectionErrorWithReasonCallback error_handler)182*635a8641SAndroid Build Coastguard Worker   void set_connection_error_with_reason_handler(
183*635a8641SAndroid Build Coastguard Worker       ConnectionErrorWithReasonCallback error_handler) {
184*635a8641SAndroid Build Coastguard Worker     DCHECK(is_bound());
185*635a8641SAndroid Build Coastguard Worker     internal_state_.set_connection_error_with_reason_handler(
186*635a8641SAndroid Build Coastguard Worker         std::move(error_handler));
187*635a8641SAndroid Build Coastguard Worker   }
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   // Returns the interface implementation that was previously specified. Caller
190*635a8641SAndroid Build Coastguard Worker   // does not take ownership.
impl()191*635a8641SAndroid Build Coastguard Worker   Interface* impl() { return internal_state_.impl(); }
192*635a8641SAndroid Build Coastguard Worker 
193*635a8641SAndroid Build Coastguard Worker   // Indicates whether the binding has been completed (i.e., whether a message
194*635a8641SAndroid Build Coastguard Worker   // pipe has been bound to the implementation).
is_bound()195*635a8641SAndroid Build Coastguard Worker   bool is_bound() const { return internal_state_.is_bound(); }
196*635a8641SAndroid Build Coastguard Worker 
197*635a8641SAndroid Build Coastguard Worker   explicit operator bool() const { return internal_state_.is_bound(); }
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker   // Returns the value of the handle currently bound to this Binding which can
200*635a8641SAndroid Build Coastguard Worker   // be used to make explicit Wait/WaitMany calls. Requires that the Binding be
201*635a8641SAndroid Build Coastguard Worker   // bound. Ownership of the handle is retained by the Binding, it is not
202*635a8641SAndroid Build Coastguard Worker   // transferred to the caller.
handle()203*635a8641SAndroid Build Coastguard Worker   MessagePipeHandle handle() const { return internal_state_.handle(); }
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker   // Reports the currently dispatching Message as bad and closes this binding.
206*635a8641SAndroid Build Coastguard Worker   // Note that this is only legal to call from directly within the stack frame
207*635a8641SAndroid Build Coastguard Worker   // of a message dispatch. If you need to do asynchronous work before you can
208*635a8641SAndroid Build Coastguard Worker   // determine the legitimacy of a message, use GetBadMessageCallback() and
209*635a8641SAndroid Build Coastguard Worker   // retain its result until you're ready to invoke or discard it.
ReportBadMessage(const std::string & error)210*635a8641SAndroid Build Coastguard Worker   void ReportBadMessage(const std::string& error) {
211*635a8641SAndroid Build Coastguard Worker     GetBadMessageCallback().Run(error);
212*635a8641SAndroid Build Coastguard Worker   }
213*635a8641SAndroid Build Coastguard Worker 
214*635a8641SAndroid Build Coastguard Worker   // Acquires a callback which may be run to report the currently dispatching
215*635a8641SAndroid Build Coastguard Worker   // Message as bad and close this binding. Note that this is only legal to call
216*635a8641SAndroid Build Coastguard Worker   // from directly within the stack frame of a message dispatch, but the
217*635a8641SAndroid Build Coastguard Worker   // returned callback may be called exactly once any time thereafter to report
218*635a8641SAndroid Build Coastguard Worker   // the message as bad. This may only be called once per message. The returned
219*635a8641SAndroid Build Coastguard Worker   // callback must be called on the Binding's own sequence.
GetBadMessageCallback()220*635a8641SAndroid Build Coastguard Worker   ReportBadMessageCallback GetBadMessageCallback() {
221*635a8641SAndroid Build Coastguard Worker     return internal_state_.GetBadMessageCallback();
222*635a8641SAndroid Build Coastguard Worker   }
223*635a8641SAndroid Build Coastguard Worker 
224*635a8641SAndroid Build Coastguard Worker   // Sends a no-op message on the underlying message pipe and runs the current
225*635a8641SAndroid Build Coastguard Worker   // message loop until its response is received. This can be used in tests to
226*635a8641SAndroid Build Coastguard Worker   // verify that no message was sent on a message pipe in response to some
227*635a8641SAndroid Build Coastguard Worker   // stimulus.
FlushForTesting()228*635a8641SAndroid Build Coastguard Worker   void FlushForTesting() { internal_state_.FlushForTesting(); }
229*635a8641SAndroid Build Coastguard Worker 
230*635a8641SAndroid Build Coastguard Worker   // Exposed for testing, should not generally be used.
EnableTestingMode()231*635a8641SAndroid Build Coastguard Worker   void EnableTestingMode() { internal_state_.EnableTestingMode(); }
232*635a8641SAndroid Build Coastguard Worker 
RouterForTesting()233*635a8641SAndroid Build Coastguard Worker   scoped_refptr<internal::MultiplexRouter> RouterForTesting() {
234*635a8641SAndroid Build Coastguard Worker     return internal_state_.RouterForTesting();
235*635a8641SAndroid Build Coastguard Worker   }
236*635a8641SAndroid Build Coastguard Worker 
237*635a8641SAndroid Build Coastguard Worker   // Allows test code to swap the interface implementation.
SwapImplForTesting(ImplPointerType new_impl)238*635a8641SAndroid Build Coastguard Worker   ImplPointerType SwapImplForTesting(ImplPointerType new_impl) {
239*635a8641SAndroid Build Coastguard Worker     return internal_state_.SwapImplForTesting(new_impl);
240*635a8641SAndroid Build Coastguard Worker   }
241*635a8641SAndroid Build Coastguard Worker 
242*635a8641SAndroid Build Coastguard Worker   // DO NOT USE. Exposed only for internal use and for testing.
internal_state()243*635a8641SAndroid Build Coastguard Worker   internal::BindingState<Interface, ImplRefTraits>* internal_state() {
244*635a8641SAndroid Build Coastguard Worker     return &internal_state_;
245*635a8641SAndroid Build Coastguard Worker   }
246*635a8641SAndroid Build Coastguard Worker 
247*635a8641SAndroid Build Coastguard Worker  private:
248*635a8641SAndroid Build Coastguard Worker   internal::BindingState<Interface, ImplRefTraits> internal_state_;
249*635a8641SAndroid Build Coastguard Worker 
250*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Binding);
251*635a8641SAndroid Build Coastguard Worker };
252*635a8641SAndroid Build Coastguard Worker 
253*635a8641SAndroid Build Coastguard Worker }  // namespace mojo
254*635a8641SAndroid Build Coastguard Worker 
255*635a8641SAndroid Build Coastguard Worker #endif  // MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_
256