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