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 if (channel_) { |
| 328 Channel::AssociatedInterfaceSupport* associated_interface_support = |
| 329 channel_->GetAssociatedInterfaceSupport(); |
| 330 if (associated_interface_support) { |
| 331 channel_associated_group_.reset(new mojo::AssociatedGroup( |
| 332 *associated_interface_support->GetAssociatedGroup())); |
| 333 } |
| 334 } |
| 335 |
299 channel_connected_called_ = true; | 336 channel_connected_called_ = true; |
300 if (listener_) | 337 if (listener_) |
301 listener_->OnChannelConnected(peer_pid_); | 338 listener_->OnChannelConnected(peer_pid_); |
302 } | 339 } |
303 | 340 |
304 // Called on the listener's thread | 341 // Called on the listener's thread |
305 void ChannelProxy::Context::OnDispatchError() { | 342 void ChannelProxy::Context::OnDispatchError() { |
306 if (listener_) | 343 if (listener_) |
307 listener_->OnChannelError(); | 344 listener_->OnChannelError(); |
308 } | 345 } |
(...skipping 25 matching lines...) Expand all Loading... |
334 | 371 |
335 ipc_task_runner()->PostTask( | 372 ipc_task_runner()->PostTask( |
336 FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this, | 373 FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this, |
337 base::Passed(base::WrapUnique(message)))); | 374 base::Passed(base::WrapUnique(message)))); |
338 } | 375 } |
339 | 376 |
340 bool ChannelProxy::Context::IsChannelSendThreadSafe() const { | 377 bool ChannelProxy::Context::IsChannelSendThreadSafe() const { |
341 return channel_send_thread_safe_; | 378 return channel_send_thread_safe_; |
342 } | 379 } |
343 | 380 |
| 381 // Called on the IPC::Channel thread |
| 382 void ChannelProxy::Context::GetRemoteAssociatedInterface( |
| 383 const std::string& name, |
| 384 mojo::ScopedInterfaceEndpointHandle handle) { |
| 385 if (!channel_) |
| 386 return; |
| 387 Channel::AssociatedInterfaceSupport* associated_interface_support = |
| 388 channel_->GetAssociatedInterfaceSupport(); |
| 389 DCHECK(associated_interface_support); |
| 390 associated_interface_support->GetGenericRemoteAssociatedInterface( |
| 391 name, std::move(handle)); |
| 392 } |
| 393 |
344 //----------------------------------------------------------------------------- | 394 //----------------------------------------------------------------------------- |
345 | 395 |
346 // static | 396 // static |
347 std::unique_ptr<ChannelProxy> ChannelProxy::Create( | 397 std::unique_ptr<ChannelProxy> ChannelProxy::Create( |
348 const IPC::ChannelHandle& channel_handle, | 398 const IPC::ChannelHandle& channel_handle, |
349 Channel::Mode mode, | 399 Channel::Mode mode, |
350 Listener* listener, | 400 Listener* listener, |
351 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { | 401 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { |
352 std::unique_ptr<ChannelProxy> channel( | 402 std::unique_ptr<ChannelProxy> channel( |
353 new ChannelProxy(listener, ipc_task_runner)); | 403 new ChannelProxy(listener, ipc_task_runner)); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 } | 522 } |
473 | 523 |
474 void ChannelProxy::RemoveFilter(MessageFilter* filter) { | 524 void ChannelProxy::RemoveFilter(MessageFilter* filter) { |
475 DCHECK(CalledOnValidThread()); | 525 DCHECK(CalledOnValidThread()); |
476 | 526 |
477 context_->ipc_task_runner()->PostTask( | 527 context_->ipc_task_runner()->PostTask( |
478 FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(), | 528 FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(), |
479 base::RetainedRef(filter))); | 529 base::RetainedRef(filter))); |
480 } | 530 } |
481 | 531 |
| 532 void ChannelProxy::AddGenericAssociatedInterfaceForIOThread( |
| 533 const std::string& name, |
| 534 const GenericAssociatedInterfaceFactory& factory) { |
| 535 DCHECK(CalledOnValidThread()); |
| 536 DCHECK(!did_init_); |
| 537 context_->io_thread_interfaces_.insert({ name, factory }); |
| 538 } |
| 539 |
| 540 void ChannelProxy::AddGenericAssociatedInterface( |
| 541 const std::string& name, |
| 542 const GenericAssociatedInterfaceFactory& factory) { |
| 543 DCHECK(CalledOnValidThread()); |
| 544 DCHECK(!did_init_); |
| 545 context_->proxy_thread_interfaces_.insert({ name, factory }); |
| 546 } |
| 547 |
| 548 mojo::AssociatedGroup* ChannelProxy::GetAssociatedGroup() { |
| 549 return context_->channel_associated_group_.get(); |
| 550 } |
| 551 |
| 552 void ChannelProxy::GetGenericRemoteAssociatedInterface( |
| 553 const std::string& name, |
| 554 mojo::ScopedInterfaceEndpointHandle handle) { |
| 555 context_->ipc_task_runner()->PostTask( |
| 556 FROM_HERE, base::Bind(&Context::GetRemoteAssociatedInterface, |
| 557 context_.get(), name, base::Passed(&handle))); |
| 558 } |
| 559 |
482 void ChannelProxy::ClearIPCTaskRunner() { | 560 void ChannelProxy::ClearIPCTaskRunner() { |
483 DCHECK(CalledOnValidThread()); | 561 DCHECK(CalledOnValidThread()); |
484 | 562 |
485 context()->ClearIPCTaskRunner(); | 563 context()->ClearIPCTaskRunner(); |
486 } | 564 } |
487 | 565 |
488 base::ProcessId ChannelProxy::GetPeerPID() const { | 566 base::ProcessId ChannelProxy::GetPeerPID() const { |
489 return context_->peer_pid_; | 567 return context_->peer_pid_; |
490 } | 568 } |
491 | 569 |
(...skipping 23 matching lines...) Expand all Loading... |
515 return channel->TakeClientFileDescriptor(); | 593 return channel->TakeClientFileDescriptor(); |
516 } | 594 } |
517 #endif | 595 #endif |
518 | 596 |
519 void ChannelProxy::OnChannelInit() { | 597 void ChannelProxy::OnChannelInit() { |
520 } | 598 } |
521 | 599 |
522 //----------------------------------------------------------------------------- | 600 //----------------------------------------------------------------------------- |
523 | 601 |
524 } // namespace IPC | 602 } // namespace IPC |
OLD | NEW |