| 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 |