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