OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/ipc_channel_proxy.h" | 5 #include "ipc/ipc_channel_proxy.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
17 #include "base/profiler/scoped_tracker.h" | 17 #include "base/profiler/scoped_tracker.h" |
18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
21 #include "ipc/ipc_channel_factory.h" | 21 #include "ipc/ipc_channel_factory.h" |
22 #include "ipc/ipc_listener.h" | 22 #include "ipc/ipc_listener.h" |
23 #include "ipc/ipc_logging.h" | 23 #include "ipc/ipc_logging.h" |
24 #include "ipc/ipc_message_macros.h" | 24 #include "ipc/ipc_message_macros.h" |
25 #include "ipc/message_filter.h" | 25 #include "ipc/message_filter.h" |
26 #include "ipc/message_filter_router.h" | 26 #include "ipc/message_filter_router.h" |
27 | 27 |
28 namespace IPC { | 28 namespace IPC { |
29 | 29 |
30 namespace { | |
31 | |
32 void BindAssociatedInterfaceOnTaskRunner( | |
33 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
34 const ChannelProxy::GenericAssociatedInterfaceFactory& factory, | |
35 mojo::ScopedInterfaceEndpointHandle handle) { | |
36 task_runner->PostTask(FROM_HERE, base::Bind(factory, base::Passed(&handle))); | |
37 } | |
38 | |
39 } // namespace | |
40 | |
30 //------------------------------------------------------------------------------ | 41 //------------------------------------------------------------------------------ |
31 | 42 |
32 ChannelProxy::Context::Context( | 43 ChannelProxy::Context::Context( |
33 Listener* listener, | 44 Listener* listener, |
34 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) | 45 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) |
35 : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 46 : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
36 listener_(listener), | 47 listener_(listener), |
37 ipc_task_runner_(ipc_task_runner), | 48 ipc_task_runner_(ipc_task_runner), |
38 channel_connected_called_(false), | 49 channel_connected_called_(false), |
39 channel_send_thread_safe_(false), | 50 channel_send_thread_safe_(false), |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 // will be released when we are closed. | 151 // will be released when we are closed. |
141 AddRef(); | 152 AddRef(); |
142 | 153 |
143 if (!channel_->Connect()) { | 154 if (!channel_->Connect()) { |
144 OnChannelError(); | 155 OnChannelError(); |
145 return; | 156 return; |
146 } | 157 } |
147 | 158 |
148 for (size_t i = 0; i < filters_.size(); ++i) | 159 for (size_t i = 0; i < filters_.size(); ++i) |
149 filters_[i]->OnFilterAdded(channel_.get()); | 160 filters_[i]->OnFilterAdded(channel_.get()); |
161 | |
162 Channel::AssociatedInterfaceSupport* support = | |
163 channel_->GetAssociatedInterfaceSupport(); | |
164 if (support) { | |
165 support->SetProxyTaskRunner(listener_task_runner_); | |
166 for (auto& entry : io_thread_interfaces_) | |
167 support->AddGenericAssociatedInterface(entry.first, entry.second); | |
168 for (auto& entry : proxy_thread_interfaces_) { | |
169 support->AddGenericAssociatedInterface( | |
170 entry.first, base::Bind(&BindAssociatedInterfaceOnTaskRunner, | |
171 listener_task_runner_, entry.second)); | |
172 } | |
173 } else { | |
174 // Sanity check to ensure nobody's expecting to use associated interfaces on | |
175 // a Channel that doesn't support them. | |
176 DCHECK(io_thread_interfaces_.empty() && proxy_thread_interfaces_.empty()); | |
177 } | |
150 } | 178 } |
151 | 179 |
152 // Called on the IPC::Channel thread | 180 // Called on the IPC::Channel thread |
153 void ChannelProxy::Context::OnChannelClosed() { | 181 void ChannelProxy::Context::OnChannelClosed() { |
154 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. | 182 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. |
155 tracked_objects::ScopedTracker tracking_profile( | 183 tracked_objects::ScopedTracker tracking_profile( |
156 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 184 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
157 "477117 ChannelProxy::Context::OnChannelClosed")); | 185 "477117 ChannelProxy::Context::OnChannelClosed")); |
158 // It's okay for IPC::ChannelProxy::Close to be called more than once, which | 186 // It's okay for IPC::ChannelProxy::Close to be called more than once, which |
159 // would result in this branch being taken. | 187 // would result in this branch being taken. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 if (logger->Enabled()) | 317 if (logger->Enabled()) |
290 logger->OnPostDispatchMessage(message, channel_id_); | 318 logger->OnPostDispatchMessage(message, channel_id_); |
291 #endif | 319 #endif |
292 } | 320 } |
293 | 321 |
294 // Called on the listener's thread | 322 // Called on the listener's thread |
295 void ChannelProxy::Context::OnDispatchConnected() { | 323 void ChannelProxy::Context::OnDispatchConnected() { |
296 if (channel_connected_called_) | 324 if (channel_connected_called_) |
297 return; | 325 return; |
298 | 326 |
327 Channel::AssociatedInterfaceSupport* associated_interface_support = | |
328 channel_->GetAssociatedInterfaceSupport(); | |
329 if (associated_interface_support) { | |
330 channel_associated_group_.reset(new mojo::AssociatedGroup( | |
331 *associated_interface_support->GetAssociatedGroup())); | |
332 } | |
333 | |
299 channel_connected_called_ = true; | 334 channel_connected_called_ = true; |
300 if (listener_) | 335 if (listener_) |
301 listener_->OnChannelConnected(peer_pid_); | 336 listener_->OnChannelConnected(peer_pid_); |
302 } | 337 } |
303 | 338 |
304 // Called on the listener's thread | 339 // Called on the listener's thread |
305 void ChannelProxy::Context::OnDispatchError() { | 340 void ChannelProxy::Context::OnDispatchError() { |
306 if (listener_) | 341 if (listener_) |
307 listener_->OnChannelError(); | 342 listener_->OnChannelError(); |
308 } | 343 } |
(...skipping 25 matching lines...) Expand all Loading... | |
334 | 369 |
335 ipc_task_runner()->PostTask( | 370 ipc_task_runner()->PostTask( |
336 FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this, | 371 FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this, |
337 base::Passed(base::WrapUnique(message)))); | 372 base::Passed(base::WrapUnique(message)))); |
338 } | 373 } |
339 | 374 |
340 bool ChannelProxy::Context::IsChannelSendThreadSafe() const { | 375 bool ChannelProxy::Context::IsChannelSendThreadSafe() const { |
341 return channel_send_thread_safe_; | 376 return channel_send_thread_safe_; |
342 } | 377 } |
343 | 378 |
379 // Called on the IPC::Channel thread | |
380 void ChannelProxy::Context::GetRemoteAssociatedInterface( | |
381 const std::string& name, | |
382 mojo::ScopedInterfaceEndpointHandle handle) { | |
383 if (!channel_) | |
384 return; | |
385 Channel::AssociatedInterfaceSupport* associated_interface_support = | |
386 channel_->GetAssociatedInterfaceSupport(); | |
387 DCHECK(associated_interface_support); | |
388 associated_interface_support->GetGenericRemoteAssociatedInterface( | |
389 name, std::move(handle)); | |
390 } | |
391 | |
344 //----------------------------------------------------------------------------- | 392 //----------------------------------------------------------------------------- |
345 | 393 |
346 // static | 394 // static |
347 std::unique_ptr<ChannelProxy> ChannelProxy::Create( | 395 std::unique_ptr<ChannelProxy> ChannelProxy::Create( |
348 const IPC::ChannelHandle& channel_handle, | 396 const IPC::ChannelHandle& channel_handle, |
349 Channel::Mode mode, | 397 Channel::Mode mode, |
350 Listener* listener, | 398 Listener* listener, |
351 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { | 399 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { |
352 std::unique_ptr<ChannelProxy> channel( | 400 std::unique_ptr<ChannelProxy> channel( |
353 new ChannelProxy(listener, ipc_task_runner)); | 401 new ChannelProxy(listener, ipc_task_runner)); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 } | 520 } |
473 | 521 |
474 void ChannelProxy::RemoveFilter(MessageFilter* filter) { | 522 void ChannelProxy::RemoveFilter(MessageFilter* filter) { |
475 DCHECK(CalledOnValidThread()); | 523 DCHECK(CalledOnValidThread()); |
476 | 524 |
477 context_->ipc_task_runner()->PostTask( | 525 context_->ipc_task_runner()->PostTask( |
478 FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(), | 526 FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(), |
479 base::RetainedRef(filter))); | 527 base::RetainedRef(filter))); |
480 } | 528 } |
481 | 529 |
530 void ChannelProxy::AddGenericAssociatedInterfaceForIOThread( | |
531 const std::string& name, | |
532 const GenericAssociatedInterfaceFactory& factory) { | |
533 DCHECK(CalledOnValidThread()); | |
534 DCHECK(!did_init_); | |
535 context_->io_thread_interfaces_.insert({ name, factory }); | |
536 } | |
537 | |
538 void ChannelProxy::AddGenericAssociatedInterface( | |
539 const std::string& name, | |
540 const GenericAssociatedInterfaceFactory& factory) { | |
541 DCHECK(CalledOnValidThread()); | |
542 DCHECK(!did_init_); | |
543 context_->proxy_thread_interfaces_.insert({ name, factory }); | |
544 } | |
545 | |
546 mojo::AssociatedGroup* ChannelProxy::GetAssociatedGroup() { | |
547 return context_->channel_associated_group_.get(); | |
548 } | |
549 | |
550 void ChannelProxy::GetGenericRemoteAssociatedInterface( | |
551 const std::string& name, | |
552 mojo::ScopedInterfaceEndpointHandle handle) { | |
553 context_->ipc_task_runner()->PostTask( | |
yzshen1
2016/07/13 23:25:09
Posting a task means the associated interface ptr
Ken Rockot(use gerrit already)
2016/07/14 00:39:09
Discussed offline, the endpoint's SendMessage ulti
| |
554 FROM_HERE, base::Bind(&Context::GetRemoteAssociatedInterface, | |
555 context_.get(), name, base::Passed(&handle))); | |
556 } | |
557 | |
482 void ChannelProxy::ClearIPCTaskRunner() { | 558 void ChannelProxy::ClearIPCTaskRunner() { |
483 DCHECK(CalledOnValidThread()); | 559 DCHECK(CalledOnValidThread()); |
484 | 560 |
485 context()->ClearIPCTaskRunner(); | 561 context()->ClearIPCTaskRunner(); |
486 } | 562 } |
487 | 563 |
488 base::ProcessId ChannelProxy::GetPeerPID() const { | 564 base::ProcessId ChannelProxy::GetPeerPID() const { |
489 return context_->peer_pid_; | 565 return context_->peer_pid_; |
490 } | 566 } |
491 | 567 |
(...skipping 23 matching lines...) Expand all Loading... | |
515 return channel->TakeClientFileDescriptor(); | 591 return channel->TakeClientFileDescriptor(); |
516 } | 592 } |
517 #endif | 593 #endif |
518 | 594 |
519 void ChannelProxy::OnChannelInit() { | 595 void ChannelProxy::OnChannelInit() { |
520 } | 596 } |
521 | 597 |
522 //----------------------------------------------------------------------------- | 598 //----------------------------------------------------------------------------- |
523 | 599 |
524 } // namespace IPC | 600 } // namespace IPC |
OLD | NEW |