1 // Copyright 2016 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 #include "mojo/public/cpp/bindings/lib/binding_state.h"
6 #include "mojo/public/cpp/bindings/lib/task_runner_helper.h"
7 #include "mojo/public/cpp/bindings/mojo_buildflags.h"
8
9 #if BUILDFLAG(MOJO_RANDOM_DELAYS_ENABLED)
10 #include "mojo/public/cpp/bindings/lib/test_random_mojo_delays.h"
11 #endif
12
13 namespace mojo {
14 namespace internal {
15
16 BindingStateBase::BindingStateBase() = default;
17
18 BindingStateBase::~BindingStateBase() = default;
19
SetFilter(std::unique_ptr<MessageFilter> filter)20 void BindingStateBase::SetFilter(std::unique_ptr<MessageFilter> filter) {
21 DCHECK(endpoint_client_);
22 endpoint_client_->SetFilter(std::move(filter));
23 }
24
HasAssociatedInterfaces() const25 bool BindingStateBase::HasAssociatedInterfaces() const {
26 return router_ ? router_->HasAssociatedEndpoints() : false;
27 }
28
PauseIncomingMethodCallProcessing()29 void BindingStateBase::PauseIncomingMethodCallProcessing() {
30 DCHECK(router_);
31 router_->PauseIncomingMethodCallProcessing();
32 }
33
ResumeIncomingMethodCallProcessing()34 void BindingStateBase::ResumeIncomingMethodCallProcessing() {
35 DCHECK(router_);
36 router_->ResumeIncomingMethodCallProcessing();
37 }
38
WaitForIncomingMethodCall()39 bool BindingStateBase::WaitForIncomingMethodCall() {
40 DCHECK(router_);
41 return router_->WaitForIncomingMessage();
42 }
43
PauseRemoteCallbacksUntilFlushCompletes(PendingFlush flush)44 void BindingStateBase::PauseRemoteCallbacksUntilFlushCompletes(
45 PendingFlush flush) {
46 router_->PausePeerUntilFlushCompletes(std::move(flush));
47 }
48
FlushAsync(AsyncFlusher flusher)49 void BindingStateBase::FlushAsync(AsyncFlusher flusher) {
50 router_->FlushAsync(std::move(flusher));
51 }
52
Close()53 void BindingStateBase::Close() {
54 if (!router_)
55 return;
56
57 weak_ptr_factory_.InvalidateWeakPtrs();
58
59 endpoint_client_.reset();
60 router_->CloseMessagePipe();
61 router_ = nullptr;
62 }
63
CloseWithReason(uint32_t custom_reason,const std::string & description)64 void BindingStateBase::CloseWithReason(uint32_t custom_reason,
65 const std::string& description) {
66 if (endpoint_client_)
67 endpoint_client_->CloseWithReason(custom_reason, description);
68
69 Close();
70 }
71
GetBadMessageCallback()72 ReportBadMessageCallback BindingStateBase::GetBadMessageCallback() {
73 return base::BindOnce(
74 [](ReportBadMessageCallback inner_callback,
75 base::WeakPtr<BindingStateBase> binding, const std::string& error) {
76 std::move(inner_callback).Run(error);
77 if (binding)
78 binding->Close();
79 },
80 mojo::GetBadMessageCallback(), weak_ptr_factory_.GetWeakPtr());
81 }
82
FlushForTesting()83 void BindingStateBase::FlushForTesting() {
84 endpoint_client_->FlushForTesting();
85 }
86
EnableBatchDispatch()87 void BindingStateBase::EnableBatchDispatch() {
88 DCHECK(is_bound());
89 router_->EnableBatchDispatch();
90 }
91
EnableTestingMode()92 void BindingStateBase::EnableTestingMode() {
93 DCHECK(is_bound());
94 router_->EnableTestingMode();
95 }
96
RouterForTesting()97 scoped_refptr<internal::MultiplexRouter> BindingStateBase::RouterForTesting() {
98 return router_;
99 }
100
BindInternal(PendingReceiverState * receiver_state,scoped_refptr<base::SequencedTaskRunner> runner,const char * interface_name,std::unique_ptr<MessageReceiver> request_validator,bool passes_associated_kinds,bool has_sync_methods,MessageReceiverWithResponderStatus * stub,uint32_t interface_version)101 void BindingStateBase::BindInternal(
102 PendingReceiverState* receiver_state,
103 scoped_refptr<base::SequencedTaskRunner> runner,
104 const char* interface_name,
105 std::unique_ptr<MessageReceiver> request_validator,
106 bool passes_associated_kinds,
107 bool has_sync_methods,
108 MessageReceiverWithResponderStatus* stub,
109 uint32_t interface_version) {
110 DCHECK(!is_bound()) << "Attempting to bind interface that is already bound: "
111 << interface_name;
112
113 auto sequenced_runner =
114 GetTaskRunnerToUseFromUserProvidedTaskRunner(std::move(runner));
115
116 MultiplexRouter::Config config =
117 passes_associated_kinds
118 ? MultiplexRouter::MULTI_INTERFACE
119 : (has_sync_methods
120 ? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
121 : MultiplexRouter::SINGLE_INTERFACE);
122 router_ = new MultiplexRouter(std::move(receiver_state->pipe), config, false,
123 sequenced_runner, interface_name);
124 router_->SetConnectionGroup(std::move(receiver_state->connection_group));
125
126 endpoint_client_.reset(new InterfaceEndpointClient(
127 router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), stub,
128 std::move(request_validator), has_sync_methods,
129 std::move(sequenced_runner), interface_version, interface_name));
130 endpoint_client_->SetIdleTrackingEnabledCallback(
131 base::BindOnce(&MultiplexRouter::SetConnectionGroup, router_));
132
133 #if BUILDFLAG(MOJO_RANDOM_DELAYS_ENABLED)
134 MakeBindingRandomlyPaused(base::SequencedTaskRunnerHandle::Get(),
135 weak_ptr_factory_.GetWeakPtr());
136 #endif
137 }
138
139 } // namespace internal
140 } // namespace mojo
141