xref: /aosp_15_r20/external/cronet/ipc/ipc_channel_proxy.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_proxy.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
19*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
20*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_factory.h"
21*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_listener.h"
22*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_logging.h"
23*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_message_macros.h"
24*6777b538SAndroid Build Coastguard Worker #include "ipc/message_filter.h"
25*6777b538SAndroid Build Coastguard Worker #include "ipc/message_filter_router.h"
26*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker namespace IPC {
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
31*6777b538SAndroid Build Coastguard Worker 
Context(Listener * listener,const scoped_refptr<base::SingleThreadTaskRunner> & ipc_task_runner,const scoped_refptr<base::SingleThreadTaskRunner> & listener_task_runner)32*6777b538SAndroid Build Coastguard Worker ChannelProxy::Context::Context(
33*6777b538SAndroid Build Coastguard Worker     Listener* listener,
34*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
35*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& listener_task_runner)
36*6777b538SAndroid Build Coastguard Worker     : default_listener_task_runner_(listener_task_runner),
37*6777b538SAndroid Build Coastguard Worker       listener_(listener),
38*6777b538SAndroid Build Coastguard Worker       ipc_task_runner_(ipc_task_runner),
39*6777b538SAndroid Build Coastguard Worker       channel_connected_called_(false),
40*6777b538SAndroid Build Coastguard Worker       message_filter_router_(new MessageFilterRouter()),
41*6777b538SAndroid Build Coastguard Worker       peer_pid_(base::kNullProcessId) {
42*6777b538SAndroid Build Coastguard Worker   DCHECK(ipc_task_runner_.get());
43*6777b538SAndroid Build Coastguard Worker   // The Listener thread where Messages are handled must be a separate thread
44*6777b538SAndroid Build Coastguard Worker   // to avoid oversubscribing the IO thread. If you trigger this error, you
45*6777b538SAndroid Build Coastguard Worker   // need to either:
46*6777b538SAndroid Build Coastguard Worker   // 1) Create the ChannelProxy on a different thread, or
47*6777b538SAndroid Build Coastguard Worker   // 2) Just use Channel
48*6777b538SAndroid Build Coastguard Worker   // We make an exception for NULL listeners.
49*6777b538SAndroid Build Coastguard Worker   DCHECK(!listener ||
50*6777b538SAndroid Build Coastguard Worker          (ipc_task_runner_.get() != default_listener_task_runner_.get()));
51*6777b538SAndroid Build Coastguard Worker }
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker ChannelProxy::Context::~Context() = default;
54*6777b538SAndroid Build Coastguard Worker 
ClearIPCTaskRunner()55*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::ClearIPCTaskRunner() {
56*6777b538SAndroid Build Coastguard Worker   ipc_task_runner_.reset();
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
CreateChannel(std::unique_ptr<ChannelFactory> factory)59*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::CreateChannel(
60*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<ChannelFactory> factory) {
61*6777b538SAndroid Build Coastguard Worker   base::AutoLock channel_lock(channel_lifetime_lock_);
62*6777b538SAndroid Build Coastguard Worker   DCHECK(!channel_);
63*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(factory->GetIPCTaskRunner(), ipc_task_runner_);
64*6777b538SAndroid Build Coastguard Worker   channel_ = factory->BuildChannel(this);
65*6777b538SAndroid Build Coastguard Worker   channel_->SetUrgentMessageObserver(urgent_message_observer_);
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker   Channel::AssociatedInterfaceSupport* support =
68*6777b538SAndroid Build Coastguard Worker       channel_->GetAssociatedInterfaceSupport();
69*6777b538SAndroid Build Coastguard Worker   if (support) {
70*6777b538SAndroid Build Coastguard Worker     thread_safe_channel_ = support->CreateThreadSafeChannel();
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker     base::AutoLock filter_lock(pending_filters_lock_);
73*6777b538SAndroid Build Coastguard Worker     for (auto& entry : pending_io_thread_interfaces_)
74*6777b538SAndroid Build Coastguard Worker       support->AddGenericAssociatedInterface(entry.first, entry.second);
75*6777b538SAndroid Build Coastguard Worker     pending_io_thread_interfaces_.clear();
76*6777b538SAndroid Build Coastguard Worker   }
77*6777b538SAndroid Build Coastguard Worker }
78*6777b538SAndroid Build Coastguard Worker 
TryFilters(const Message & message)79*6777b538SAndroid Build Coastguard Worker bool ChannelProxy::Context::TryFilters(const Message& message) {
80*6777b538SAndroid Build Coastguard Worker   DCHECK(message_filter_router_);
81*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
82*6777b538SAndroid Build Coastguard Worker   Logging* logger = Logging::GetInstance();
83*6777b538SAndroid Build Coastguard Worker   if (logger->Enabled())
84*6777b538SAndroid Build Coastguard Worker     logger->OnPreDispatchMessage(message);
85*6777b538SAndroid Build Coastguard Worker #endif
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker   if (message_filter_router_->TryFilters(message)) {
88*6777b538SAndroid Build Coastguard Worker     if (message.dispatch_error()) {
89*6777b538SAndroid Build Coastguard Worker       GetTaskRunner(message.routing_id())
90*6777b538SAndroid Build Coastguard Worker           ->PostTask(FROM_HERE, base::BindOnce(&Context::OnDispatchBadMessage,
91*6777b538SAndroid Build Coastguard Worker                                                this, message));
92*6777b538SAndroid Build Coastguard Worker     }
93*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
94*6777b538SAndroid Build Coastguard Worker     if (logger->Enabled())
95*6777b538SAndroid Build Coastguard Worker       logger->OnPostDispatchMessage(message);
96*6777b538SAndroid Build Coastguard Worker #endif
97*6777b538SAndroid Build Coastguard Worker     return true;
98*6777b538SAndroid Build Coastguard Worker   }
99*6777b538SAndroid Build Coastguard Worker   return false;
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
PauseChannel()103*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::PauseChannel() {
104*6777b538SAndroid Build Coastguard Worker   DCHECK(channel_);
105*6777b538SAndroid Build Coastguard Worker   channel_->Pause();
106*6777b538SAndroid Build Coastguard Worker }
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
UnpauseChannel(bool flush)109*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::UnpauseChannel(bool flush) {
110*6777b538SAndroid Build Coastguard Worker   DCHECK(channel_);
111*6777b538SAndroid Build Coastguard Worker   channel_->Unpause(flush);
112*6777b538SAndroid Build Coastguard Worker }
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
FlushChannel()115*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::FlushChannel() {
116*6777b538SAndroid Build Coastguard Worker   DCHECK(channel_);
117*6777b538SAndroid Build Coastguard Worker   channel_->Flush();
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnMessageReceived(const Message & message)121*6777b538SAndroid Build Coastguard Worker bool ChannelProxy::Context::OnMessageReceived(const Message& message) {
122*6777b538SAndroid Build Coastguard Worker   // First give a chance to the filters to process this message.
123*6777b538SAndroid Build Coastguard Worker   if (!TryFilters(message))
124*6777b538SAndroid Build Coastguard Worker     OnMessageReceivedNoFilter(message);
125*6777b538SAndroid Build Coastguard Worker   return true;
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnMessageReceivedNoFilter(const Message & message)129*6777b538SAndroid Build Coastguard Worker bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
130*6777b538SAndroid Build Coastguard Worker   GetTaskRunner(message.routing_id())
131*6777b538SAndroid Build Coastguard Worker       ->PostTask(FROM_HERE,
132*6777b538SAndroid Build Coastguard Worker                  base::BindOnce(&Context::OnDispatchMessage, this, message));
133*6777b538SAndroid Build Coastguard Worker   return true;
134*6777b538SAndroid Build Coastguard Worker }
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnChannelConnected(int32_t peer_pid)137*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnChannelConnected(int32_t peer_pid) {
138*6777b538SAndroid Build Coastguard Worker   // We cache off the peer_pid so it can be safely accessed from both threads.
139*6777b538SAndroid Build Coastguard Worker   {
140*6777b538SAndroid Build Coastguard Worker     base::AutoLock l(peer_pid_lock_);
141*6777b538SAndroid Build Coastguard Worker     peer_pid_ = peer_pid;
142*6777b538SAndroid Build Coastguard Worker   }
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker   // Add any pending filters.  This avoids a race condition where someone
145*6777b538SAndroid Build Coastguard Worker   // creates a ChannelProxy, calls AddFilter, and then right after starts the
146*6777b538SAndroid Build Coastguard Worker   // peer process.  The IO thread could receive a message before the task to add
147*6777b538SAndroid Build Coastguard Worker   // the filter is run on the IO thread.
148*6777b538SAndroid Build Coastguard Worker   OnAddFilter();
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker   // See above comment about using default_listener_task_runner_ here.
151*6777b538SAndroid Build Coastguard Worker   default_listener_task_runner_->PostTask(
152*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::OnDispatchConnected, this));
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnChannelError()156*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnChannelError() {
157*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < filters_.size(); ++i)
158*6777b538SAndroid Build Coastguard Worker     filters_[i]->OnChannelError();
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   // See above comment about using default_listener_task_runner_ here.
161*6777b538SAndroid Build Coastguard Worker   default_listener_task_runner_->PostTask(
162*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::OnDispatchError, this));
163*6777b538SAndroid Build Coastguard Worker }
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)166*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnAssociatedInterfaceRequest(
167*6777b538SAndroid Build Coastguard Worker     const std::string& interface_name,
168*6777b538SAndroid Build Coastguard Worker     mojo::ScopedInterfaceEndpointHandle handle) {
169*6777b538SAndroid Build Coastguard Worker   default_listener_task_runner_->PostTask(
170*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::OnDispatchAssociatedInterfaceRequest,
171*6777b538SAndroid Build Coastguard Worker                                 this, interface_name, std::move(handle)));
172*6777b538SAndroid Build Coastguard Worker }
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnChannelOpened()175*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnChannelOpened() {
176*6777b538SAndroid Build Coastguard Worker   DCHECK(channel_);
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   // Assume a reference to ourselves on behalf of this thread.  This reference
179*6777b538SAndroid Build Coastguard Worker   // will be released when we are closed.
180*6777b538SAndroid Build Coastguard Worker   AddRef();
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   if (!channel_->Connect()) {
183*6777b538SAndroid Build Coastguard Worker     OnChannelError();
184*6777b538SAndroid Build Coastguard Worker     return;
185*6777b538SAndroid Build Coastguard Worker   }
186*6777b538SAndroid Build Coastguard Worker 
187*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < filters_.size(); ++i)
188*6777b538SAndroid Build Coastguard Worker     filters_[i]->OnFilterAdded(channel_.get());
189*6777b538SAndroid Build Coastguard Worker }
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnChannelClosed()192*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnChannelClosed() {
193*6777b538SAndroid Build Coastguard Worker   // It's okay for IPC::ChannelProxy::Close to be called more than once, which
194*6777b538SAndroid Build Coastguard Worker   // would result in this branch being taken.
195*6777b538SAndroid Build Coastguard Worker   if (!channel_)
196*6777b538SAndroid Build Coastguard Worker     return;
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker   for (auto& filter : pending_filters_) {
199*6777b538SAndroid Build Coastguard Worker     filter->OnChannelClosing();
200*6777b538SAndroid Build Coastguard Worker     filter->OnFilterRemoved();
201*6777b538SAndroid Build Coastguard Worker   }
202*6777b538SAndroid Build Coastguard Worker   for (auto& filter : filters_) {
203*6777b538SAndroid Build Coastguard Worker     filter->OnChannelClosing();
204*6777b538SAndroid Build Coastguard Worker     filter->OnFilterRemoved();
205*6777b538SAndroid Build Coastguard Worker   }
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker   // We don't need the filters anymore.
208*6777b538SAndroid Build Coastguard Worker   message_filter_router_->Clear();
209*6777b538SAndroid Build Coastguard Worker   filters_.clear();
210*6777b538SAndroid Build Coastguard Worker   // We don't need the lock, because at this point, the listener thread can't
211*6777b538SAndroid Build Coastguard Worker   // access it any more.
212*6777b538SAndroid Build Coastguard Worker   pending_filters_.clear();
213*6777b538SAndroid Build Coastguard Worker 
214*6777b538SAndroid Build Coastguard Worker   ClearChannel();
215*6777b538SAndroid Build Coastguard Worker 
216*6777b538SAndroid Build Coastguard Worker   // Balance with the reference taken during startup.  This may result in
217*6777b538SAndroid Build Coastguard Worker   // self-destruction.
218*6777b538SAndroid Build Coastguard Worker   Release();
219*6777b538SAndroid Build Coastguard Worker }
220*6777b538SAndroid Build Coastguard Worker 
Clear()221*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::Clear() {
222*6777b538SAndroid Build Coastguard Worker   listener_ = nullptr;
223*6777b538SAndroid Build Coastguard Worker }
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnSendMessage(std::unique_ptr<Message> message)226*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnSendMessage(std::unique_ptr<Message> message) {
227*6777b538SAndroid Build Coastguard Worker   if (!channel_) {
228*6777b538SAndroid Build Coastguard Worker     OnChannelClosed();
229*6777b538SAndroid Build Coastguard Worker     return;
230*6777b538SAndroid Build Coastguard Worker   }
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   if (!channel_->Send(message.release()))
233*6777b538SAndroid Build Coastguard Worker     OnChannelError();
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker 
236*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnAddFilter()237*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnAddFilter() {
238*6777b538SAndroid Build Coastguard Worker   // Our OnChannelConnected method has not yet been called, so we can't be
239*6777b538SAndroid Build Coastguard Worker   // sure that channel_ is valid yet. When OnChannelConnected *is* called,
240*6777b538SAndroid Build Coastguard Worker   // it invokes OnAddFilter, so any pending filter(s) will be added at that
241*6777b538SAndroid Build Coastguard Worker   // time.
242*6777b538SAndroid Build Coastguard Worker   // No lock necessary for |peer_pid_| because it is only modified on this
243*6777b538SAndroid Build Coastguard Worker   // thread.
244*6777b538SAndroid Build Coastguard Worker   if (peer_pid_ == base::kNullProcessId)
245*6777b538SAndroid Build Coastguard Worker     return;
246*6777b538SAndroid Build Coastguard Worker 
247*6777b538SAndroid Build Coastguard Worker   std::vector<scoped_refptr<MessageFilter> > new_filters;
248*6777b538SAndroid Build Coastguard Worker   {
249*6777b538SAndroid Build Coastguard Worker     base::AutoLock auto_lock(pending_filters_lock_);
250*6777b538SAndroid Build Coastguard Worker     new_filters.swap(pending_filters_);
251*6777b538SAndroid Build Coastguard Worker   }
252*6777b538SAndroid Build Coastguard Worker 
253*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < new_filters.size(); ++i) {
254*6777b538SAndroid Build Coastguard Worker     filters_.push_back(new_filters[i]);
255*6777b538SAndroid Build Coastguard Worker 
256*6777b538SAndroid Build Coastguard Worker     message_filter_router_->AddFilter(new_filters[i].get());
257*6777b538SAndroid Build Coastguard Worker 
258*6777b538SAndroid Build Coastguard Worker     // The channel has already been created and connected, so we need to
259*6777b538SAndroid Build Coastguard Worker     // inform the filters right now.
260*6777b538SAndroid Build Coastguard Worker     new_filters[i]->OnFilterAdded(channel_.get());
261*6777b538SAndroid Build Coastguard Worker     new_filters[i]->OnChannelConnected(peer_pid_);
262*6777b538SAndroid Build Coastguard Worker   }
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread
OnRemoveFilter(MessageFilter * filter)266*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnRemoveFilter(MessageFilter* filter) {
267*6777b538SAndroid Build Coastguard Worker   // No lock necessary for |peer_pid_| because it is only modified on this
268*6777b538SAndroid Build Coastguard Worker   // thread.
269*6777b538SAndroid Build Coastguard Worker   if (peer_pid_ == base::kNullProcessId) {
270*6777b538SAndroid Build Coastguard Worker     // The channel is not yet connected, so any filters are still pending.
271*6777b538SAndroid Build Coastguard Worker     base::AutoLock auto_lock(pending_filters_lock_);
272*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < pending_filters_.size(); ++i) {
273*6777b538SAndroid Build Coastguard Worker       if (pending_filters_[i].get() == filter) {
274*6777b538SAndroid Build Coastguard Worker         filter->OnFilterRemoved();
275*6777b538SAndroid Build Coastguard Worker         pending_filters_.erase(pending_filters_.begin() + i);
276*6777b538SAndroid Build Coastguard Worker         return;
277*6777b538SAndroid Build Coastguard Worker       }
278*6777b538SAndroid Build Coastguard Worker     }
279*6777b538SAndroid Build Coastguard Worker     return;
280*6777b538SAndroid Build Coastguard Worker   }
281*6777b538SAndroid Build Coastguard Worker   if (!channel_)
282*6777b538SAndroid Build Coastguard Worker     return;  // The filters have already been deleted.
283*6777b538SAndroid Build Coastguard Worker 
284*6777b538SAndroid Build Coastguard Worker   message_filter_router_->RemoveFilter(filter);
285*6777b538SAndroid Build Coastguard Worker 
286*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < filters_.size(); ++i) {
287*6777b538SAndroid Build Coastguard Worker     if (filters_[i].get() == filter) {
288*6777b538SAndroid Build Coastguard Worker       filter->OnFilterRemoved();
289*6777b538SAndroid Build Coastguard Worker       filters_.erase(filters_.begin() + i);
290*6777b538SAndroid Build Coastguard Worker       return;
291*6777b538SAndroid Build Coastguard Worker     }
292*6777b538SAndroid Build Coastguard Worker   }
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker   NOTREACHED() << "filter to be removed not found";
295*6777b538SAndroid Build Coastguard Worker }
296*6777b538SAndroid Build Coastguard Worker 
297*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread
AddFilter(MessageFilter * filter)298*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::AddFilter(MessageFilter* filter) {
299*6777b538SAndroid Build Coastguard Worker   base::AutoLock auto_lock(pending_filters_lock_);
300*6777b538SAndroid Build Coastguard Worker   pending_filters_.push_back(base::WrapRefCounted(filter));
301*6777b538SAndroid Build Coastguard Worker   ipc_task_runner_->PostTask(FROM_HERE,
302*6777b538SAndroid Build Coastguard Worker                              base::BindOnce(&Context::OnAddFilter, this));
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker 
305*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread
OnDispatchMessage(const Message & message)306*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnDispatchMessage(const Message& message) {
307*6777b538SAndroid Build Coastguard Worker   if (!listener_)
308*6777b538SAndroid Build Coastguard Worker     return;
309*6777b538SAndroid Build Coastguard Worker 
310*6777b538SAndroid Build Coastguard Worker   OnDispatchConnected();
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
313*6777b538SAndroid Build Coastguard Worker   Logging* logger = Logging::GetInstance();
314*6777b538SAndroid Build Coastguard Worker   if (message.type() == IPC_LOGGING_ID) {
315*6777b538SAndroid Build Coastguard Worker     logger->OnReceivedLoggingMessage(message);
316*6777b538SAndroid Build Coastguard Worker     return;
317*6777b538SAndroid Build Coastguard Worker   }
318*6777b538SAndroid Build Coastguard Worker 
319*6777b538SAndroid Build Coastguard Worker   if (logger->Enabled())
320*6777b538SAndroid Build Coastguard Worker     logger->OnPreDispatchMessage(message);
321*6777b538SAndroid Build Coastguard Worker #endif
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   listener_->OnMessageReceived(message);
324*6777b538SAndroid Build Coastguard Worker   if (message.dispatch_error())
325*6777b538SAndroid Build Coastguard Worker     listener_->OnBadMessageReceived(message);
326*6777b538SAndroid Build Coastguard Worker 
327*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
328*6777b538SAndroid Build Coastguard Worker   if (logger->Enabled())
329*6777b538SAndroid Build Coastguard Worker     logger->OnPostDispatchMessage(message);
330*6777b538SAndroid Build Coastguard Worker #endif
331*6777b538SAndroid Build Coastguard Worker }
332*6777b538SAndroid Build Coastguard Worker 
333*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread.
AddListenerTaskRunner(int32_t routing_id,scoped_refptr<base::SingleThreadTaskRunner> task_runner)334*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::AddListenerTaskRunner(
335*6777b538SAndroid Build Coastguard Worker     int32_t routing_id,
336*6777b538SAndroid Build Coastguard Worker     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
337*6777b538SAndroid Build Coastguard Worker   DCHECK(default_listener_task_runner_->BelongsToCurrentThread());
338*6777b538SAndroid Build Coastguard Worker   DCHECK(task_runner);
339*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(listener_thread_task_runners_lock_);
340*6777b538SAndroid Build Coastguard Worker   if (!base::Contains(listener_thread_task_runners_, routing_id))
341*6777b538SAndroid Build Coastguard Worker     listener_thread_task_runners_.insert({routing_id, std::move(task_runner)});
342*6777b538SAndroid Build Coastguard Worker }
343*6777b538SAndroid Build Coastguard Worker 
344*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread.
RemoveListenerTaskRunner(int32_t routing_id)345*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::RemoveListenerTaskRunner(int32_t routing_id) {
346*6777b538SAndroid Build Coastguard Worker   DCHECK(default_listener_task_runner_->BelongsToCurrentThread());
347*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(listener_thread_task_runners_lock_);
348*6777b538SAndroid Build Coastguard Worker   listener_thread_task_runners_.erase(routing_id);
349*6777b538SAndroid Build Coastguard Worker }
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker // Called on the IPC::Channel thread.
352*6777b538SAndroid Build Coastguard Worker scoped_refptr<base::SingleThreadTaskRunner>
GetTaskRunner(int32_t routing_id)353*6777b538SAndroid Build Coastguard Worker ChannelProxy::Context::GetTaskRunner(int32_t routing_id) {
354*6777b538SAndroid Build Coastguard Worker   DCHECK(ipc_task_runner_->BelongsToCurrentThread());
355*6777b538SAndroid Build Coastguard Worker   if (routing_id == MSG_ROUTING_NONE)
356*6777b538SAndroid Build Coastguard Worker     return default_listener_task_runner_;
357*6777b538SAndroid Build Coastguard Worker 
358*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(listener_thread_task_runners_lock_);
359*6777b538SAndroid Build Coastguard Worker   auto task_runner = listener_thread_task_runners_.find(routing_id);
360*6777b538SAndroid Build Coastguard Worker   if (task_runner == listener_thread_task_runners_.end())
361*6777b538SAndroid Build Coastguard Worker     return default_listener_task_runner_;
362*6777b538SAndroid Build Coastguard Worker   DCHECK(task_runner->second);
363*6777b538SAndroid Build Coastguard Worker   return task_runner->second;
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker 
366*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread
OnDispatchConnected()367*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnDispatchConnected() {
368*6777b538SAndroid Build Coastguard Worker   if (channel_connected_called_)
369*6777b538SAndroid Build Coastguard Worker     return;
370*6777b538SAndroid Build Coastguard Worker 
371*6777b538SAndroid Build Coastguard Worker   base::ProcessId peer_pid;
372*6777b538SAndroid Build Coastguard Worker   {
373*6777b538SAndroid Build Coastguard Worker     base::AutoLock l(peer_pid_lock_);
374*6777b538SAndroid Build Coastguard Worker     peer_pid = peer_pid_;
375*6777b538SAndroid Build Coastguard Worker   }
376*6777b538SAndroid Build Coastguard Worker   channel_connected_called_ = true;
377*6777b538SAndroid Build Coastguard Worker   if (listener_)
378*6777b538SAndroid Build Coastguard Worker     listener_->OnChannelConnected(peer_pid);
379*6777b538SAndroid Build Coastguard Worker }
380*6777b538SAndroid Build Coastguard Worker 
381*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread
OnDispatchError()382*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnDispatchError() {
383*6777b538SAndroid Build Coastguard Worker   if (listener_)
384*6777b538SAndroid Build Coastguard Worker     listener_->OnChannelError();
385*6777b538SAndroid Build Coastguard Worker }
386*6777b538SAndroid Build Coastguard Worker 
387*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread
OnDispatchBadMessage(const Message & message)388*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) {
389*6777b538SAndroid Build Coastguard Worker   if (listener_)
390*6777b538SAndroid Build Coastguard Worker     listener_->OnBadMessageReceived(message);
391*6777b538SAndroid Build Coastguard Worker }
392*6777b538SAndroid Build Coastguard Worker 
393*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread
OnDispatchAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)394*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::OnDispatchAssociatedInterfaceRequest(
395*6777b538SAndroid Build Coastguard Worker     const std::string& interface_name,
396*6777b538SAndroid Build Coastguard Worker     mojo::ScopedInterfaceEndpointHandle handle) {
397*6777b538SAndroid Build Coastguard Worker   if (listener_)
398*6777b538SAndroid Build Coastguard Worker     listener_->OnAssociatedInterfaceRequest(interface_name, std::move(handle));
399*6777b538SAndroid Build Coastguard Worker }
400*6777b538SAndroid Build Coastguard Worker 
ClearChannel()401*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::ClearChannel() {
402*6777b538SAndroid Build Coastguard Worker   base::AutoLock l(channel_lifetime_lock_);
403*6777b538SAndroid Build Coastguard Worker   channel_.reset();
404*6777b538SAndroid Build Coastguard Worker }
405*6777b538SAndroid Build Coastguard Worker 
AddGenericAssociatedInterfaceForIOThread(const std::string & name,const GenericAssociatedInterfaceFactory & factory)406*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::AddGenericAssociatedInterfaceForIOThread(
407*6777b538SAndroid Build Coastguard Worker     const std::string& name,
408*6777b538SAndroid Build Coastguard Worker     const GenericAssociatedInterfaceFactory& factory) {
409*6777b538SAndroid Build Coastguard Worker   base::AutoLock channel_lock(channel_lifetime_lock_);
410*6777b538SAndroid Build Coastguard Worker   if (!channel_) {
411*6777b538SAndroid Build Coastguard Worker     base::AutoLock filter_lock(pending_filters_lock_);
412*6777b538SAndroid Build Coastguard Worker     pending_io_thread_interfaces_.emplace_back(name, factory);
413*6777b538SAndroid Build Coastguard Worker     return;
414*6777b538SAndroid Build Coastguard Worker   }
415*6777b538SAndroid Build Coastguard Worker   Channel::AssociatedInterfaceSupport* support =
416*6777b538SAndroid Build Coastguard Worker       channel_->GetAssociatedInterfaceSupport();
417*6777b538SAndroid Build Coastguard Worker   if (support)
418*6777b538SAndroid Build Coastguard Worker     support->AddGenericAssociatedInterface(name, factory);
419*6777b538SAndroid Build Coastguard Worker }
420*6777b538SAndroid Build Coastguard Worker 
Send(Message * message)421*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::Send(Message* message) {
422*6777b538SAndroid Build Coastguard Worker   ipc_task_runner()->PostTask(
423*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&ChannelProxy::Context::OnSendMessage, this,
424*6777b538SAndroid Build Coastguard Worker                                 base::WrapUnique(message)));
425*6777b538SAndroid Build Coastguard Worker }
426*6777b538SAndroid Build Coastguard Worker 
427*6777b538SAndroid Build Coastguard Worker // Called on the listener's thread.
SetUrgentMessageObserver(UrgentMessageObserver * observer)428*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Context::SetUrgentMessageObserver(
429*6777b538SAndroid Build Coastguard Worker     UrgentMessageObserver* observer) {
430*6777b538SAndroid Build Coastguard Worker   urgent_message_observer_ = observer;
431*6777b538SAndroid Build Coastguard Worker }
432*6777b538SAndroid Build Coastguard Worker 
433*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
434*6777b538SAndroid Build Coastguard Worker 
435*6777b538SAndroid Build Coastguard Worker // static
Create(const IPC::ChannelHandle & channel_handle,Channel::Mode mode,Listener * listener,const scoped_refptr<base::SingleThreadTaskRunner> & ipc_task_runner,const scoped_refptr<base::SingleThreadTaskRunner> & listener_task_runner)436*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ChannelProxy> ChannelProxy::Create(
437*6777b538SAndroid Build Coastguard Worker     const IPC::ChannelHandle& channel_handle,
438*6777b538SAndroid Build Coastguard Worker     Channel::Mode mode,
439*6777b538SAndroid Build Coastguard Worker     Listener* listener,
440*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
441*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& listener_task_runner) {
442*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ChannelProxy> channel(
443*6777b538SAndroid Build Coastguard Worker       new ChannelProxy(listener, ipc_task_runner, listener_task_runner));
444*6777b538SAndroid Build Coastguard Worker   channel->Init(channel_handle, mode, true);
445*6777b538SAndroid Build Coastguard Worker   return channel;
446*6777b538SAndroid Build Coastguard Worker }
447*6777b538SAndroid Build Coastguard Worker 
448*6777b538SAndroid Build Coastguard Worker // static
Create(std::unique_ptr<ChannelFactory> factory,Listener * listener,const scoped_refptr<base::SingleThreadTaskRunner> & ipc_task_runner,const scoped_refptr<base::SingleThreadTaskRunner> & listener_task_runner)449*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ChannelProxy> ChannelProxy::Create(
450*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<ChannelFactory> factory,
451*6777b538SAndroid Build Coastguard Worker     Listener* listener,
452*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
453*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& listener_task_runner) {
454*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ChannelProxy> channel(
455*6777b538SAndroid Build Coastguard Worker       new ChannelProxy(listener, ipc_task_runner, listener_task_runner));
456*6777b538SAndroid Build Coastguard Worker   channel->Init(std::move(factory), true);
457*6777b538SAndroid Build Coastguard Worker   return channel;
458*6777b538SAndroid Build Coastguard Worker }
459*6777b538SAndroid Build Coastguard Worker 
ChannelProxy(Context * context)460*6777b538SAndroid Build Coastguard Worker ChannelProxy::ChannelProxy(Context* context) : context_(context) {}
461*6777b538SAndroid Build Coastguard Worker 
ChannelProxy(Listener * listener,const scoped_refptr<base::SingleThreadTaskRunner> & ipc_task_runner,const scoped_refptr<base::SingleThreadTaskRunner> & listener_task_runner)462*6777b538SAndroid Build Coastguard Worker ChannelProxy::ChannelProxy(
463*6777b538SAndroid Build Coastguard Worker     Listener* listener,
464*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
465*6777b538SAndroid Build Coastguard Worker     const scoped_refptr<base::SingleThreadTaskRunner>& listener_task_runner)
466*6777b538SAndroid Build Coastguard Worker     : context_(new Context(listener, ipc_task_runner, listener_task_runner)) {}
467*6777b538SAndroid Build Coastguard Worker 
~ChannelProxy()468*6777b538SAndroid Build Coastguard Worker ChannelProxy::~ChannelProxy() {
469*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
470*6777b538SAndroid Build Coastguard Worker 
471*6777b538SAndroid Build Coastguard Worker   Close();
472*6777b538SAndroid Build Coastguard Worker }
473*6777b538SAndroid Build Coastguard Worker 
Init(const IPC::ChannelHandle & channel_handle,Channel::Mode mode,bool create_pipe_now)474*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle,
475*6777b538SAndroid Build Coastguard Worker                         Channel::Mode mode,
476*6777b538SAndroid Build Coastguard Worker                         bool create_pipe_now) {
477*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
478*6777b538SAndroid Build Coastguard Worker   // When we are creating a server on POSIX, we need its file descriptor
479*6777b538SAndroid Build Coastguard Worker   // to be created immediately so that it can be accessed and passed
480*6777b538SAndroid Build Coastguard Worker   // to other processes. Forcing it to be created immediately avoids
481*6777b538SAndroid Build Coastguard Worker   // race conditions that may otherwise arise.
482*6777b538SAndroid Build Coastguard Worker   if (mode & Channel::MODE_SERVER_FLAG) {
483*6777b538SAndroid Build Coastguard Worker     create_pipe_now = true;
484*6777b538SAndroid Build Coastguard Worker   }
485*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
486*6777b538SAndroid Build Coastguard Worker   Init(
487*6777b538SAndroid Build Coastguard Worker       ChannelFactory::Create(channel_handle, mode, context_->ipc_task_runner()),
488*6777b538SAndroid Build Coastguard Worker       create_pipe_now);
489*6777b538SAndroid Build Coastguard Worker }
490*6777b538SAndroid Build Coastguard Worker 
Init(std::unique_ptr<ChannelFactory> factory,bool create_pipe_now)491*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Init(std::unique_ptr<ChannelFactory> factory,
492*6777b538SAndroid Build Coastguard Worker                         bool create_pipe_now) {
493*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
494*6777b538SAndroid Build Coastguard Worker   DCHECK(!did_init_);
495*6777b538SAndroid Build Coastguard Worker 
496*6777b538SAndroid Build Coastguard Worker   if (create_pipe_now) {
497*6777b538SAndroid Build Coastguard Worker     // Create the channel immediately.  This effectively sets up the
498*6777b538SAndroid Build Coastguard Worker     // low-level pipe so that the client can connect.  Without creating
499*6777b538SAndroid Build Coastguard Worker     // the pipe immediately, it is possible for a listener to attempt
500*6777b538SAndroid Build Coastguard Worker     // to connect and get an error since the pipe doesn't exist yet.
501*6777b538SAndroid Build Coastguard Worker     context_->CreateChannel(std::move(factory));
502*6777b538SAndroid Build Coastguard Worker   } else {
503*6777b538SAndroid Build Coastguard Worker     context_->ipc_task_runner()->PostTask(
504*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
505*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&Context::CreateChannel, context_, std::move(factory)));
506*6777b538SAndroid Build Coastguard Worker   }
507*6777b538SAndroid Build Coastguard Worker 
508*6777b538SAndroid Build Coastguard Worker   // complete initialization on the background thread
509*6777b538SAndroid Build Coastguard Worker   context_->ipc_task_runner()->PostTask(
510*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::OnChannelOpened, context_));
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker   did_init_ = true;
513*6777b538SAndroid Build Coastguard Worker   OnChannelInit();
514*6777b538SAndroid Build Coastguard Worker }
515*6777b538SAndroid Build Coastguard Worker 
Pause()516*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Pause() {
517*6777b538SAndroid Build Coastguard Worker   context_->ipc_task_runner()->PostTask(
518*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::PauseChannel, context_));
519*6777b538SAndroid Build Coastguard Worker }
520*6777b538SAndroid Build Coastguard Worker 
Unpause(bool flush)521*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Unpause(bool flush) {
522*6777b538SAndroid Build Coastguard Worker   context_->ipc_task_runner()->PostTask(
523*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::UnpauseChannel, context_, flush));
524*6777b538SAndroid Build Coastguard Worker }
525*6777b538SAndroid Build Coastguard Worker 
Flush()526*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Flush() {
527*6777b538SAndroid Build Coastguard Worker   context_->ipc_task_runner()->PostTask(
528*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::FlushChannel, context_));
529*6777b538SAndroid Build Coastguard Worker }
530*6777b538SAndroid Build Coastguard Worker 
Close()531*6777b538SAndroid Build Coastguard Worker void ChannelProxy::Close() {
532*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
533*6777b538SAndroid Build Coastguard Worker 
534*6777b538SAndroid Build Coastguard Worker   // Clear the backpointer to the listener so that any pending calls to
535*6777b538SAndroid Build Coastguard Worker   // Context::OnDispatchMessage or OnDispatchError will be ignored.  It is
536*6777b538SAndroid Build Coastguard Worker   // possible that the channel could be closed while it is receiving messages!
537*6777b538SAndroid Build Coastguard Worker   context_->Clear();
538*6777b538SAndroid Build Coastguard Worker 
539*6777b538SAndroid Build Coastguard Worker   if (context_->ipc_task_runner()) {
540*6777b538SAndroid Build Coastguard Worker     context_->ipc_task_runner()->PostTask(
541*6777b538SAndroid Build Coastguard Worker         FROM_HERE, base::BindOnce(&Context::OnChannelClosed, context_));
542*6777b538SAndroid Build Coastguard Worker   }
543*6777b538SAndroid Build Coastguard Worker }
544*6777b538SAndroid Build Coastguard Worker 
Send(Message * message)545*6777b538SAndroid Build Coastguard Worker bool ChannelProxy::Send(Message* message) {
546*6777b538SAndroid Build Coastguard Worker   DCHECK(!message->is_sync()) << "Need to use IPC::SyncChannel";
547*6777b538SAndroid Build Coastguard Worker   SendInternal(message);
548*6777b538SAndroid Build Coastguard Worker   return true;
549*6777b538SAndroid Build Coastguard Worker }
550*6777b538SAndroid Build Coastguard Worker 
SendInternal(Message * message)551*6777b538SAndroid Build Coastguard Worker void ChannelProxy::SendInternal(Message* message) {
552*6777b538SAndroid Build Coastguard Worker   DCHECK(did_init_);
553*6777b538SAndroid Build Coastguard Worker 
554*6777b538SAndroid Build Coastguard Worker   // TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are
555*6777b538SAndroid Build Coastguard Worker   // tests that call Send() from a wrong thread. See http://crbug.com/163523.
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker #ifdef ENABLE_IPC_FUZZER
558*6777b538SAndroid Build Coastguard Worker   // In IPC fuzzing builds, it is possible to define a filter to apply to
559*6777b538SAndroid Build Coastguard Worker   // outgoing messages. It will either rewrite the message and return a new
560*6777b538SAndroid Build Coastguard Worker   // one, freeing the original, or return the message unchanged.
561*6777b538SAndroid Build Coastguard Worker   if (outgoing_message_filter())
562*6777b538SAndroid Build Coastguard Worker     message = outgoing_message_filter()->Rewrite(message);
563*6777b538SAndroid Build Coastguard Worker #endif
564*6777b538SAndroid Build Coastguard Worker 
565*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
566*6777b538SAndroid Build Coastguard Worker   Logging::GetInstance()->OnSendMessage(message);
567*6777b538SAndroid Build Coastguard Worker #endif
568*6777b538SAndroid Build Coastguard Worker 
569*6777b538SAndroid Build Coastguard Worker   context_->Send(message);
570*6777b538SAndroid Build Coastguard Worker }
571*6777b538SAndroid Build Coastguard Worker 
AddFilter(MessageFilter * filter)572*6777b538SAndroid Build Coastguard Worker void ChannelProxy::AddFilter(MessageFilter* filter) {
573*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
574*6777b538SAndroid Build Coastguard Worker 
575*6777b538SAndroid Build Coastguard Worker   context_->AddFilter(filter);
576*6777b538SAndroid Build Coastguard Worker }
577*6777b538SAndroid Build Coastguard Worker 
RemoveFilter(MessageFilter * filter)578*6777b538SAndroid Build Coastguard Worker void ChannelProxy::RemoveFilter(MessageFilter* filter) {
579*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
580*6777b538SAndroid Build Coastguard Worker 
581*6777b538SAndroid Build Coastguard Worker   context_->ipc_task_runner()->PostTask(
582*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(&Context::OnRemoveFilter, context_,
583*6777b538SAndroid Build Coastguard Worker                                 base::RetainedRef(filter)));
584*6777b538SAndroid Build Coastguard Worker }
585*6777b538SAndroid Build Coastguard Worker 
AddGenericAssociatedInterfaceForIOThread(const std::string & name,const GenericAssociatedInterfaceFactory & factory)586*6777b538SAndroid Build Coastguard Worker void ChannelProxy::AddGenericAssociatedInterfaceForIOThread(
587*6777b538SAndroid Build Coastguard Worker     const std::string& name,
588*6777b538SAndroid Build Coastguard Worker     const GenericAssociatedInterfaceFactory& factory) {
589*6777b538SAndroid Build Coastguard Worker   context()->AddGenericAssociatedInterfaceForIOThread(name, factory);
590*6777b538SAndroid Build Coastguard Worker }
591*6777b538SAndroid Build Coastguard Worker 
GetRemoteAssociatedInterface(mojo::GenericPendingAssociatedReceiver receiver)592*6777b538SAndroid Build Coastguard Worker void ChannelProxy::GetRemoteAssociatedInterface(
593*6777b538SAndroid Build Coastguard Worker     mojo::GenericPendingAssociatedReceiver receiver) {
594*6777b538SAndroid Build Coastguard Worker   DCHECK(did_init_);
595*6777b538SAndroid Build Coastguard Worker   context()->thread_safe_channel().GetAssociatedInterface(std::move(receiver));
596*6777b538SAndroid Build Coastguard Worker }
597*6777b538SAndroid Build Coastguard Worker 
ClearIPCTaskRunner()598*6777b538SAndroid Build Coastguard Worker void ChannelProxy::ClearIPCTaskRunner() {
599*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
600*6777b538SAndroid Build Coastguard Worker   context()->ClearIPCTaskRunner();
601*6777b538SAndroid Build Coastguard Worker }
602*6777b538SAndroid Build Coastguard Worker 
OnChannelInit()603*6777b538SAndroid Build Coastguard Worker void ChannelProxy::OnChannelInit() {
604*6777b538SAndroid Build Coastguard Worker }
605*6777b538SAndroid Build Coastguard Worker 
SetUrgentMessageObserver(UrgentMessageObserver * observer)606*6777b538SAndroid Build Coastguard Worker void ChannelProxy::SetUrgentMessageObserver(UrgentMessageObserver* observer) {
607*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
608*6777b538SAndroid Build Coastguard Worker   DCHECK(!did_init_);
609*6777b538SAndroid Build Coastguard Worker   context_->SetUrgentMessageObserver(observer);
610*6777b538SAndroid Build Coastguard Worker }
611*6777b538SAndroid Build Coastguard Worker 
612*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
613*6777b538SAndroid Build Coastguard Worker 
614*6777b538SAndroid Build Coastguard Worker }  // namespace IPC
615