| Index: content/child/child_thread.cc
|
| diff --git a/content/child/child_thread.cc b/content/child/child_thread.cc
|
| index 3ecdb584d8e5b3af784ac98a45eeb9aa531daab0..e549023114e643d1bac601c074058e2042fa2f0b 100644
|
| --- a/content/child/child_thread.cc
|
| +++ b/content/child/child_thread.cc
|
| @@ -13,6 +13,7 @@
|
| #include "base/basictypes.h"
|
| #include "base/command_line.h"
|
| #include "base/debug/leak_annotations.h"
|
| +#include "base/id_map.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop.h"
|
| @@ -39,6 +40,7 @@
|
| #include "content/child/thread_safe_sender.h"
|
| #include "content/child/websocket_dispatcher.h"
|
| #include "content/common/child_process_messages.h"
|
| +#include "content/common/message_port_messages.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "ipc/ipc_logging.h"
|
| #include "ipc/ipc_switches.h"
|
| @@ -193,6 +195,62 @@ void QuitMainThreadMessageLoop() {
|
|
|
| } // namespace
|
|
|
| +MessagePortBypassFilter::MessagePortBypassFilter(
|
| + base::SingleThreadTaskRunner* ipc_task_runner)
|
| + : ipc_task_runner_(ipc_task_runner),
|
| + child_thread_loop_(base::MessageLoopProxy::current()) {}
|
| +
|
| +MessagePortBypassFilter::~MessagePortBypassFilter() {}
|
| +
|
| +bool MessagePortBypassFilter::OnMessageReceived(const IPC::Message& message) {
|
| + DCHECK(ipc_task_runner_->BelongsToCurrentThread());
|
| + IPC::Listener* listener = routes_.Lookup(message.routing_id());
|
| + if (!listener)
|
| + return false;
|
| + if (message.type() != MessagePortMsg_Message::ID)
|
| + return false;
|
| + return listener->OnMessageReceived(message);
|
| +}
|
| +
|
| +bool MessagePortBypassFilter::GetSupportedMessageClasses(
|
| + std::vector<uint32>* supported_message_classes) const {
|
| + supported_message_classes->push_back(MessagePortMsgStart);
|
| + return true;
|
| +}
|
| +
|
| +void MessagePortBypassFilter::AddRoute(int32 routing_id,
|
| + IPC::Listener* listener) {
|
| + DCHECK(child_thread_loop_->BelongsToCurrentThread());
|
| + ipc_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &MessagePortBypassFilter::AddRouteOnIO, this, routing_id, listener));
|
| +}
|
| +
|
| +void MessagePortBypassFilter::AddRouteOnIO(int32 routing_id,
|
| + IPC::Listener* listener) {
|
| + DCHECK(ipc_task_runner_->BelongsToCurrentThread());
|
| + routes_.AddWithID(listener, routing_id);
|
| +}
|
| +
|
| +void MessagePortBypassFilter::RemoveRoute(int32 routing_id,
|
| + const base::Closure& callback) {
|
| + DCHECK(child_thread_loop_->BelongsToCurrentThread());
|
| + ipc_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&MessagePortBypassFilter::RemoveRouteOnIO,
|
| + this,
|
| + routing_id,
|
| + callback));
|
| +}
|
| +
|
| +void MessagePortBypassFilter::RemoveRouteOnIO(int32 routing_id,
|
| + const base::Closure& callback) {
|
| + DCHECK(ipc_task_runner_->BelongsToCurrentThread());
|
| + routes_.Remove(routing_id);
|
| + child_thread_loop_->PostTask(FROM_HERE, callback);
|
| +}
|
| +
|
| ChildThread::ChildThreadMessageRouter::ChildThreadMessageRouter(
|
| IPC::Sender* sender)
|
| : sender_(sender) {}
|
| @@ -263,6 +321,8 @@ void ChildThread::Init() {
|
| new QuotaMessageFilter(thread_safe_sender_.get());
|
| quota_dispatcher_.reset(new QuotaDispatcher(thread_safe_sender_.get(),
|
| quota_message_filter_.get()));
|
| + message_port_bypass_filter_ = new MessagePortBypassFilter(
|
| + ChildProcess::current()->io_message_loop_proxy());
|
|
|
| channel_->AddFilter(histogram_message_filter_.get());
|
| channel_->AddFilter(sync_message_filter_.get());
|
| @@ -271,6 +331,7 @@ void ChildThread::Init() {
|
| channel_->AddFilter(resource_message_filter_.get());
|
| channel_->AddFilter(quota_message_filter_->GetFilter());
|
| channel_->AddFilter(service_worker_message_filter_->GetFilter());
|
| + channel_->AddFilter(message_port_bypass_filter_.get());
|
|
|
| // In single process mode we may already have a power monitor
|
| if (!base::PowerMonitor::Get()) {
|
|
|