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