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