1 // Copyright 2015 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 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_ 7 8 #include <memory> 9 #include <string> 10 #include <utility> 11 12 #include "base/bind.h" 13 #include "base/callback.h" 14 #include "base/logging.h" 15 #include "base/macros.h" 16 #include "base/memory/ptr_util.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/sequenced_task_runner.h" 19 #include "base/single_thread_task_runner.h" 20 #include "mojo/public/cpp/bindings/bindings_export.h" 21 #include "mojo/public/cpp/bindings/connection_error_callback.h" 22 #include "mojo/public/cpp/bindings/filter_chain.h" 23 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" 24 #include "mojo/public/cpp/bindings/interface_id.h" 25 #include "mojo/public/cpp/bindings/interface_ptr.h" 26 #include "mojo/public/cpp/bindings/interface_ptr_info.h" 27 #include "mojo/public/cpp/bindings/interface_request.h" 28 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" 29 #include "mojo/public/cpp/bindings/message_header_validator.h" 30 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 31 #include "mojo/public/cpp/system/core.h" 32 33 namespace mojo { 34 namespace internal { 35 36 class MOJO_CPP_BINDINGS_EXPORT BindingStateBase { 37 public: 38 BindingStateBase(); 39 ~BindingStateBase(); 40 41 void AddFilter(std::unique_ptr<MessageReceiver> filter); 42 43 bool HasAssociatedInterfaces() const; 44 45 void PauseIncomingMethodCallProcessing(); 46 void ResumeIncomingMethodCallProcessing(); 47 48 bool WaitForIncomingMethodCall( 49 MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE); 50 51 void Close(); 52 void CloseWithReason(uint32_t custom_reason, const std::string& description); 53 RaiseError()54 void RaiseError() { endpoint_client_->RaiseError(); } 55 set_connection_error_handler(base::OnceClosure error_handler)56 void set_connection_error_handler(base::OnceClosure error_handler) { 57 DCHECK(is_bound()); 58 endpoint_client_->set_connection_error_handler(std::move(error_handler)); 59 } 60 set_connection_error_with_reason_handler(ConnectionErrorWithReasonCallback error_handler)61 void set_connection_error_with_reason_handler( 62 ConnectionErrorWithReasonCallback error_handler) { 63 DCHECK(is_bound()); 64 endpoint_client_->set_connection_error_with_reason_handler( 65 std::move(error_handler)); 66 } 67 is_bound()68 bool is_bound() const { return !!router_; } 69 handle()70 MessagePipeHandle handle() const { 71 DCHECK(is_bound()); 72 return router_->handle(); 73 } 74 75 ReportBadMessageCallback GetBadMessageCallback(); 76 77 void FlushForTesting(); 78 79 void EnableTestingMode(); 80 81 scoped_refptr<internal::MultiplexRouter> RouterForTesting(); 82 83 protected: 84 void BindInternal(ScopedMessagePipeHandle handle, 85 scoped_refptr<base::SingleThreadTaskRunner> runner, 86 const char* interface_name, 87 std::unique_ptr<MessageReceiver> request_validator, 88 bool passes_associated_kinds, 89 bool has_sync_methods, 90 MessageReceiverWithResponderStatus* stub, 91 uint32_t interface_version); 92 93 scoped_refptr<internal::MultiplexRouter> router_; 94 std::unique_ptr<InterfaceEndpointClient> endpoint_client_; 95 96 base::WeakPtrFactory<BindingStateBase> weak_ptr_factory_; 97 }; 98 99 template <typename Interface, typename ImplRefTraits> 100 class BindingState : public BindingStateBase { 101 public: 102 using ImplPointerType = typename ImplRefTraits::PointerType; 103 BindingState(ImplPointerType impl)104 explicit BindingState(ImplPointerType impl) { 105 stub_.set_sink(std::move(impl)); 106 } 107 ~BindingState()108 ~BindingState() { Close(); } 109 Bind(ScopedMessagePipeHandle handle,scoped_refptr<base::SingleThreadTaskRunner> runner)110 void Bind(ScopedMessagePipeHandle handle, 111 scoped_refptr<base::SingleThreadTaskRunner> runner) { 112 BindingStateBase::BindInternal( 113 std::move(handle), runner, Interface::Name_, 114 std::make_unique<typename Interface::RequestValidator_>(), 115 Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_, &stub_, 116 Interface::Version_); 117 } 118 Unbind()119 InterfaceRequest<Interface> Unbind() { 120 endpoint_client_.reset(); 121 InterfaceRequest<Interface> request(router_->PassMessagePipe()); 122 router_ = nullptr; 123 return request; 124 } 125 impl()126 Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); } SwapImplForTesting(ImplPointerType new_impl)127 ImplPointerType SwapImplForTesting(ImplPointerType new_impl) { 128 Interface* old_impl = impl(); 129 stub_.set_sink(std::move(new_impl)); 130 return old_impl; 131 } 132 133 private: 134 typename Interface::template Stub_<ImplRefTraits> stub_; 135 136 DISALLOW_COPY_AND_ASSIGN(BindingState); 137 }; 138 139 } // namesapce internal 140 } // namespace mojo 141 142 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_ 143