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