[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/renderer/pepper/pepper_in_process_router.h" |
| 6 | |
| 7 | #include "base/bind.h" |
[email protected] | aaf6889 | 2013-07-18 00:11:30 | [diff] [blame] | 8 | #include "base/message_loop/message_loop.h" |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 9 | #include "content/public/renderer/render_thread.h" |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 10 | #include "content/renderer/pepper/renderer_ppapi_host_impl.h" |
[email protected] | fb44cb0a | 2013-12-04 00:45:55 | [diff] [blame] | 11 | #include "content/renderer/render_frame_impl.h" |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 12 | #include "ipc/ipc_message.h" |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 13 | #include "ipc/ipc_sender.h" |
| 14 | #include "ppapi/proxy/ppapi_messages.h" |
| 15 | #include "ppapi/shared_impl/ppapi_globals.h" |
| 16 | #include "ppapi/shared_impl/resource_tracker.h" |
| 17 | |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 18 | using ppapi::UnpackMessage; |
| 19 | |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 20 | namespace content { |
| 21 | |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 22 | class PepperInProcessRouter::Channel : public IPC::Sender { |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 23 | public: |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 24 | Channel(const base::Callback<bool(IPC::Message*)>& callback) |
| 25 | : callback_(callback) {} |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 26 | |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 27 | virtual ~Channel() {} |
| 28 | |
| 29 | virtual bool Send(IPC::Message* message) OVERRIDE { |
| 30 | return callback_.Run(message); |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 31 | } |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 32 | |
| 33 | private: |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 34 | base::Callback<bool(IPC::Message*)> callback_; |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 35 | }; |
| 36 | |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 37 | PepperInProcessRouter::PepperInProcessRouter( |
| 38 | RendererPpapiHostImpl* host_impl) |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 39 | : host_impl_(host_impl), |
| 40 | pending_message_id_(0), |
| 41 | reply_result_(false), |
[email protected] | 69e797f | 2013-04-30 01:10:22 | [diff] [blame] | 42 | weak_factory_(this) { |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 43 | browser_channel_.reset( |
| 44 | new Channel(base::Bind(&PepperInProcessRouter::SendToBrowser, |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 45 | base::Unretained(this)))); |
| 46 | host_to_plugin_router_.reset( |
| 47 | new Channel(base::Bind(&PepperInProcessRouter::SendToPlugin, |
| 48 | base::Unretained(this)))); |
| 49 | plugin_to_host_router_.reset( |
| 50 | new Channel(base::Bind(&PepperInProcessRouter::SendToHost, |
| 51 | base::Unretained(this)))); |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | PepperInProcessRouter::~PepperInProcessRouter() { |
| 55 | } |
| 56 | |
| 57 | IPC::Sender* PepperInProcessRouter::GetPluginToRendererSender() { |
| 58 | return plugin_to_host_router_.get(); |
| 59 | } |
| 60 | |
| 61 | IPC::Sender* PepperInProcessRouter::GetRendererToPluginSender() { |
| 62 | return host_to_plugin_router_.get(); |
| 63 | } |
| 64 | |
[email protected] | 8dd2d2c | 2013-07-23 21:19:31 | [diff] [blame] | 65 | ppapi::proxy::Connection PepperInProcessRouter::GetPluginConnection( |
| 66 | PP_Instance instance) { |
| 67 | int routing_id = 0; |
[email protected] | fb44cb0a | 2013-12-04 00:45:55 | [diff] [blame] | 68 | RenderFrame* frame = host_impl_->GetRenderFrameForInstance(instance); |
| 69 | if (frame) |
[email protected] | 60eca4eb | 2013-12-06 00:02:16 | [diff] [blame^] | 70 | routing_id = frame->GetRoutingID(); |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 71 | return ppapi::proxy::Connection(browser_channel_.get(), |
[email protected] | 8dd2d2c | 2013-07-23 21:19:31 | [diff] [blame] | 72 | plugin_to_host_router_.get(), |
| 73 | routing_id); |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 74 | } |
| 75 | |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 76 | // static |
| 77 | bool PepperInProcessRouter::OnPluginMsgReceived(const IPC::Message& msg) { |
| 78 | // Emulate the proxy by dispatching the relevant message here. |
| 79 | ppapi::proxy::ResourceMessageReplyParams reply_params; |
| 80 | IPC::Message nested_msg; |
| 81 | |
| 82 | if (msg.type() == PpapiPluginMsg_ResourceReply::ID) { |
| 83 | // Resource reply from the renderer (no routing id). |
| 84 | if (!UnpackMessage<PpapiPluginMsg_ResourceReply>(msg, &reply_params, |
| 85 | &nested_msg)) { |
| 86 | NOTREACHED(); |
| 87 | return false; |
| 88 | } |
| 89 | } else if (msg.type() == PpapiHostMsg_InProcessResourceReply::ID) { |
| 90 | // Resource reply from the browser (has a routing id). |
| 91 | if (!UnpackMessage<PpapiHostMsg_InProcessResourceReply>(msg, &reply_params, |
| 92 | &nested_msg)) { |
| 93 | NOTREACHED(); |
| 94 | return false; |
| 95 | } |
| 96 | } else { |
| 97 | return false; |
| 98 | } |
| 99 | ppapi::Resource* resource = |
| 100 | ppapi::PpapiGlobals::Get()->GetResourceTracker()->GetResource( |
| 101 | reply_params.pp_resource()); |
| 102 | // If the resource doesn't exist, it may have been destroyed so just ignore |
| 103 | // the message. |
| 104 | if (resource) |
| 105 | resource->OnReplyReceived(reply_params, nested_msg); |
| 106 | return true; |
| 107 | } |
| 108 | |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 109 | bool PepperInProcessRouter::SendToHost(IPC::Message* msg) { |
| 110 | scoped_ptr<IPC::Message> message(msg); |
| 111 | |
| 112 | if (!message->is_sync()) { |
[email protected] | 165bae7 | 2013-09-11 20:08:06 | [diff] [blame] | 113 | // If this is a resource destroyed message, post a task to dispatch it. |
| 114 | // Dispatching it synchronously can cause the host to re-enter the proxy |
| 115 | // code while we're still in the resource destructor, leading to a crash. |
| 116 | // http://crbug.com/276368. |
| 117 | // This won't cause message reordering problems because the resource |
| 118 | // destroyed message is always the last one sent for a resource. |
| 119 | if (message->type() == PpapiHostMsg_ResourceDestroyed::ID) { |
| 120 | base::MessageLoop::current()->PostTask( |
| 121 | FROM_HERE, |
| 122 | base::Bind(&PepperInProcessRouter::DispatchHostMsg, |
| 123 | weak_factory_.GetWeakPtr(), |
| 124 | base::Owned(message.release()))); |
| 125 | return true; |
| 126 | } else { |
| 127 | bool result = host_impl_->GetPpapiHost()->OnMessageReceived(*message); |
| 128 | DCHECK(result) << "The message was not handled by the host."; |
| 129 | return true; |
| 130 | } |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | pending_message_id_ = IPC::SyncMessage::GetMessageId(*message); |
| 134 | reply_deserializer_.reset( |
| 135 | static_cast<IPC::SyncMessage*>(message.get())->GetReplyDeserializer()); |
| 136 | reply_result_ = false; |
| 137 | |
| 138 | bool result = host_impl_->GetPpapiHost()->OnMessageReceived(*message); |
| 139 | DCHECK(result) << "The message was not handled by the host."; |
| 140 | |
| 141 | pending_message_id_ = 0; |
| 142 | reply_deserializer_.reset(NULL); |
| 143 | return reply_result_; |
| 144 | } |
| 145 | |
| 146 | bool PepperInProcessRouter::SendToPlugin(IPC::Message* msg) { |
| 147 | scoped_ptr<IPC::Message> message(msg); |
[email protected] | c27f115 | 2012-10-16 20:23:48 | [diff] [blame] | 148 | CHECK(!msg->is_sync()); |
| 149 | if (IPC::SyncMessage::IsMessageReplyTo(*message, pending_message_id_)) { |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 150 | if (!msg->is_reply_error()) |
| 151 | reply_result_ = reply_deserializer_->SerializeOutputParameters(*message); |
| 152 | } else { |
| 153 | CHECK(!pending_message_id_); |
| 154 | // Dispatch plugin messages from the message loop. |
[email protected] | dd32b127 | 2013-05-04 14:17:11 | [diff] [blame] | 155 | base::MessageLoop::current()->PostTask( |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 156 | FROM_HERE, |
| 157 | base::Bind(&PepperInProcessRouter::DispatchPluginMsg, |
[email protected] | dd32b127 | 2013-05-04 14:17:11 | [diff] [blame] | 158 | weak_factory_.GetWeakPtr(), |
| 159 | base::Owned(message.release()))); |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 160 | } |
| 161 | return true; |
| 162 | } |
| 163 | |
[email protected] | 165bae7 | 2013-09-11 20:08:06 | [diff] [blame] | 164 | void PepperInProcessRouter::DispatchHostMsg(IPC::Message* msg) { |
| 165 | bool handled = host_impl_->GetPpapiHost()->OnMessageReceived(*msg); |
| 166 | DCHECK(handled); |
| 167 | } |
| 168 | |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 169 | void PepperInProcessRouter::DispatchPluginMsg(IPC::Message* msg) { |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 170 | bool handled = OnPluginMsgReceived(*msg); |
| 171 | DCHECK(handled); |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 172 | } |
| 173 | |
[email protected] | 0d586af | 2013-07-31 21:58:06 | [diff] [blame] | 174 | bool PepperInProcessRouter::SendToBrowser(IPC::Message *msg) { |
| 175 | return RenderThread::Get()->Send(msg); |
[email protected] | 5c96d9da | 2012-10-09 20:15:34 | [diff] [blame] | 176 | } |
| 177 | |
[email protected] | 93df81e | 2012-08-10 22:22:46 | [diff] [blame] | 178 | } // namespace content |