Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Use of this source code is governed by a BSD-style license that can be | |
| 2 // found in the LICENSE file. | |
| 3 | |
| 4 #include "content/renderer/browser_plugin/guest_to_embedder_channel.h" | |
| 5 | |
| 6 #include "base/process_util.h" | |
| 7 #include "content/common/browser_plugin_messages.h" | |
| 8 #include "content/common/child_process.h" | |
| 9 #include "content/renderer/browser_plugin/browser_plugin_var_serialization_rules .h" | |
| 10 #include "content/renderer/render_thread_impl.h" | |
| 11 #include "content/renderer/render_view_impl.h" | |
| 12 #include "ipc/ipc_message_macros.h" | |
|
jam
2012/05/16 02:22:40
nit: not needed
Fady Samuel
2012/05/16 04:43:54
Done.
| |
| 13 #include "ppapi/c/pp_bool.h" | |
| 14 #include "ppapi/c/pp_graphics_3d.h" | |
| 15 #include "ppapi/proxy/ppapi_command_buffer_proxy.h" | |
| 16 #include "ppapi/proxy/ppapi_messages.h" | |
| 17 #include "ppapi/shared_impl/api_id.h" | |
| 18 #include "ppapi/shared_impl/ppapi_globals.h" | |
| 19 #include "ppapi/shared_impl/var.h" | |
| 20 #include "webkit/plugins/ppapi/event_conversion.h" | |
| 21 | |
| 22 namespace content { | |
| 23 | |
| 24 GuestToEmbedderChannel::GuestToEmbedderChannel( | |
| 25 const std::string& embedder_channel_name) | |
| 26 : Dispatcher(NULL), | |
| 27 embedder_channel_name_(embedder_channel_name) { | |
| 28 SetSerializationRules(new BrowserPluginVarSerializationRules()); | |
| 29 } | |
| 30 | |
| 31 bool GuestToEmbedderChannel::OnMessageReceived(const IPC::Message& message) { | |
| 32 bool handled = true; | |
| 33 bool msg_is_ok = true; | |
| 34 IPC_BEGIN_MESSAGE_MAP_EX(GuestToEmbedderChannel, message, msg_is_ok) | |
| 35 IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnSupportsInterface) | |
| 36 IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnSetPreferences) | |
| 37 IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnReserveInstanceId) | |
| 38 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate, | |
| 39 OnDidCreate) | |
| 40 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidDestroy, | |
| 41 OnDidDestroy) | |
| 42 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView, | |
| 43 OnDidChangeView) | |
| 44 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus, | |
| 45 OnDidChangeFocus) | |
| 46 IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage, | |
| 47 OnHandleMessage) | |
| 48 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent, | |
| 49 OnHandleFilteredInputEvent) | |
| 50 IPC_MESSAGE_HANDLER(PpapiMsg_PPPGraphics3D_ContextLost, | |
| 51 OnContextLost) | |
| 52 // Have the super handle all other messages. | |
| 53 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 54 IPC_END_MESSAGE_MAP_EX() | |
| 55 | |
| 56 if (!msg_is_ok) { | |
| 57 // The message had a handler, but its deserialization failed. | |
| 58 // Kill the renderer to avoid potential spoofing attacks. | |
| 59 CHECK(false) << "Unable to deserialize message in ProxyChannel."; | |
|
jam
2012/05/16 02:22:40
you're in an untrusted process getting IPCs from a
Fady Samuel
2012/05/16 04:43:54
This is a copy-and-paste remnant. Removing.
This
| |
| 60 } | |
| 61 return handled; | |
| 62 } | |
| 63 | |
| 64 bool GuestToEmbedderChannel::Send(IPC::Message* message) { | |
| 65 // We always want guest->host messages to arrive in-order. If some sync | |
| 66 // and some async messages are sent in response to a synchronous | |
| 67 // host->guest call, the sync reply will be processed before the async | |
| 68 // reply, and everything will be confused. | |
| 69 // | |
| 70 // Allowing all async messages to unblock the renderer means more reentrancy | |
| 71 // there but gives correct ordering. | |
| 72 message->set_unblock(true); | |
| 73 return ProxyChannel::Send(message); | |
| 74 } | |
| 75 | |
| 76 void GuestToEmbedderChannel::OnChannelError() { | |
| 77 // We cannot destroy the GuestToEmbedderChannel here because a | |
| 78 // PpapiCommandBufferProxy may still refer to this object. | |
| 79 // However, we should not be using this channel again once we get a | |
| 80 // channel error so when remove it from the channel manager. | |
| 81 RenderThreadImpl::current()->browser_plugin_channel_manager()-> | |
| 82 RemoveChannelByName(embedder_channel_name_); | |
| 83 } | |
| 84 | |
| 85 bool GuestToEmbedderChannel::IsPlugin() const { | |
| 86 return true; | |
| 87 } | |
| 88 | |
| 89 WebGraphicsContext3DCommandBufferImpl* | |
| 90 GuestToEmbedderChannel::CreateWebGraphicsContext3D( | |
| 91 RenderViewImpl* render_view, | |
| 92 const WebKit::WebGraphicsContext3D::Attributes& attributes, | |
| 93 bool offscreen) { | |
| 94 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( | |
| 95 new WebGraphicsContext3DCommandBufferImpl( | |
| 96 0, GURL(), NULL, | |
| 97 render_view->AsWeakPtr())); | |
| 98 | |
| 99 // Special case: RenderView initialization has not yet completed. | |
| 100 if (!render_view->pp_instance()) | |
| 101 return context.release(); | |
| 102 | |
| 103 if (CreateGraphicsContext(context.get(), | |
| 104 attributes, | |
| 105 offscreen, | |
| 106 render_view)) | |
| 107 return context.release(); | |
| 108 | |
| 109 return NULL; | |
| 110 } | |
| 111 | |
| 112 void GuestToEmbedderChannel::IssueSwapBuffers( | |
| 113 const ppapi::HostResource& resource) { | |
| 114 Send(new PpapiHostMsg_PPBGraphics3D_SwapBuffers( | |
| 115 ppapi::API_ID_PPB_GRAPHICS_3D, resource)); | |
| 116 } | |
| 117 | |
| 118 bool GuestToEmbedderChannel::InitChannel( | |
| 119 const IPC::ChannelHandle& channel_handle) { | |
| 120 return ProxyChannel::InitWithChannel(&delegate_, channel_handle, false); | |
| 121 } | |
| 122 | |
| 123 void GuestToEmbedderChannel::OnSupportsInterface( | |
| 124 const std::string& interface_name, | |
| 125 bool* result) { | |
| 126 // TODO: This is a hack to avoid getting GetInstanceObject messages | |
| 127 // and failing a CHECK. A more correct solution is to implement | |
| 128 // VarSerializationRules for GuestToEmbedderChannel. | |
| 129 *result = interface_name.find("PPP_Instance_Private") == std::string::npos; | |
| 130 } | |
| 131 | |
| 132 void GuestToEmbedderChannel::OnSetPreferences(const ppapi::Preferences& prefs) { | |
| 133 // TODO(fsamuel): Do we care about these preferences? | |
| 134 // These look like some font stuff from WebPreferences. | |
| 135 // Perhaps this should be plumbed into our associated RenderView? | |
| 136 NOTIMPLEMENTED(); | |
| 137 } | |
| 138 | |
| 139 void GuestToEmbedderChannel::OnReserveInstanceId(PP_Instance instance, | |
| 140 bool* usable) { | |
| 141 *usable = | |
| 142 render_view_instances_.find(instance) == render_view_instances_.end(); | |
| 143 } | |
| 144 | |
| 145 void GuestToEmbedderChannel::RequestInputEvents(PP_Instance instance) { | |
| 146 // Request receipt of input events | |
| 147 Send(new PpapiHostMsg_PPBInstance_RequestInputEvents( | |
| 148 ppapi::API_ID_PPB_INSTANCE, instance, true, | |
| 149 PP_INPUTEVENT_CLASS_MOUSE | | |
| 150 PP_INPUTEVENT_CLASS_KEYBOARD | | |
| 151 PP_INPUTEVENT_CLASS_WHEEL | | |
| 152 PP_INPUTEVENT_CLASS_TOUCH)); | |
| 153 } | |
| 154 | |
| 155 bool GuestToEmbedderChannel::CreateGraphicsContext( | |
| 156 WebGraphicsContext3DCommandBufferImpl* context, | |
| 157 const WebKit::WebGraphicsContext3D::Attributes& attributes, | |
| 158 bool offscreen, | |
| 159 RenderViewImpl* render_view) { | |
| 160 std::vector<int32_t> attribs; | |
| 161 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); | |
| 162 | |
| 163 ppapi::HostResource resource; | |
| 164 DCHECK(render_view->pp_instance()); | |
| 165 // TODO(fsamuel): Support child contexts. | |
| 166 bool success = Send(new PpapiHostMsg_PPBGraphics3D_Create( | |
| 167 ppapi::API_ID_PPB_GRAPHICS_3D, | |
| 168 render_view->pp_instance(), | |
| 169 attribs, | |
| 170 &resource)); | |
| 171 if (!success || resource.is_null()) | |
| 172 return false; | |
| 173 if (!offscreen) { | |
| 174 PP_Bool result = PP_FALSE; | |
| 175 Send(new PpapiHostMsg_PPBInstance_BindGraphics( | |
| 176 ppapi::API_ID_PPB_INSTANCE, | |
| 177 render_view->pp_instance(), | |
| 178 resource, | |
| 179 &result)); | |
| 180 if (result != PP_TRUE) | |
| 181 return false; | |
| 182 } | |
| 183 | |
| 184 CommandBufferProxy* command_buffer = | |
| 185 new ppapi::proxy::PpapiCommandBufferProxy(resource, this); | |
| 186 command_buffer->Initialize(); | |
| 187 context->InitializeWithCommandBuffer( | |
| 188 command_buffer, | |
| 189 attributes, | |
| 190 false /* bind generates resources */); | |
| 191 render_view->set_host_resource(resource); | |
| 192 return true; | |
| 193 } | |
| 194 | |
| 195 void GuestToEmbedderChannel::AddGuest( | |
| 196 PP_Instance instance, | |
| 197 RenderViewImpl* render_view) { | |
| 198 DCHECK(instance); | |
| 199 DCHECK(render_view_instances_.find(instance) == render_view_instances_.end()); | |
| 200 render_view_instances_[instance] = render_view->AsWeakPtr(); | |
| 201 } | |
| 202 | |
| 203 | |
| 204 void GuestToEmbedderChannel::RemoveGuest(PP_Instance instance) { | |
| 205 DCHECK(render_view_instances_.find(instance) != render_view_instances_.end()); | |
| 206 render_view_instances_.erase(instance); | |
| 207 } | |
| 208 | |
| 209 void GuestToEmbedderChannel::OnDidCreate(PP_Instance instance, | |
| 210 const std::vector<std::string>& argn, | |
| 211 const std::vector<std::string>& argv, | |
| 212 PP_Bool* result) { | |
| 213 *result = PP_TRUE; | |
| 214 } | |
| 215 | |
| 216 void GuestToEmbedderChannel::OnDidDestroy(PP_Instance instance) { | |
| 217 RemoveGuest(instance); | |
| 218 } | |
| 219 | |
| 220 void GuestToEmbedderChannel::OnDidChangeView( | |
| 221 PP_Instance instance, | |
| 222 const ppapi::ViewData& new_data, | |
| 223 PP_Bool flash_fullscreen) { | |
| 224 // We can't do anything with this message if we don't have a render view | |
| 225 // yet. If we do have a RenderView then we need to tell the associated | |
| 226 // WebContentsObserver to resize. | |
| 227 if (render_view_instances_.find(instance) != render_view_instances_.end()) { | |
| 228 RenderViewImpl* render_view = render_view_instances_[instance]; | |
| 229 render_view->Send( | |
| 230 new BrowserPluginHostMsg_ResizeGuest( | |
| 231 render_view->GetRoutingID(), | |
| 232 new_data.rect.size.width, | |
| 233 new_data.rect.size.height)); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 void GuestToEmbedderChannel::OnDidChangeFocus(PP_Instance instance, | |
| 238 PP_Bool has_focus) { | |
| 239 NOTIMPLEMENTED(); | |
| 240 } | |
| 241 | |
| 242 void GuestToEmbedderChannel::OnHandleMessage( | |
| 243 PP_Instance instance, | |
| 244 ppapi::proxy::SerializedVarReceiveInput message_data) { | |
| 245 InstanceMap::iterator it = render_view_instances_.find(instance); | |
| 246 if (it == render_view_instances_.end()) | |
| 247 return; | |
| 248 | |
| 249 PP_Var received_var(message_data.Get(this)); | |
| 250 DCHECK(received_var.type == PP_VARTYPE_STRING); | |
| 251 ppapi::VarTracker* tracker = ppapi::PpapiGlobals::Get()->GetVarTracker(); | |
| 252 ppapi::StringVar* var = tracker->GetVar(received_var)->AsStringVar(); | |
| 253 DCHECK(var); | |
| 254 | |
| 255 RenderViewImpl* render_view = it->second; | |
| 256 render_view->Send( | |
| 257 new BrowserPluginHostMsg_NavigateFromGuest( | |
| 258 render_view->GetRoutingID(), | |
| 259 instance, | |
| 260 var->value())); | |
| 261 } | |
| 262 | |
| 263 void GuestToEmbedderChannel::OnHandleFilteredInputEvent( | |
| 264 PP_Instance instance, | |
| 265 const ppapi::InputEventData& data, | |
| 266 PP_Bool* result) { | |
| 267 DCHECK(render_view_instances_.find(instance) != render_view_instances_.end()); | |
| 268 | |
| 269 RenderViewImpl* render_view = render_view_instances_[instance]; | |
| 270 scoped_ptr<WebKit::WebInputEvent> web_input_event( | |
| 271 webkit::ppapi::CreateWebInputEvent(data)); | |
| 272 *result = PP_FromBool( | |
| 273 render_view->GetWebView()->handleInputEvent(*web_input_event)); | |
| 274 } | |
| 275 | |
| 276 void GuestToEmbedderChannel::OnContextLost(PP_Instance instance) { | |
| 277 InstanceMap::iterator it = render_view_instances_.begin(); | |
| 278 for (InstanceMap::iterator it = render_view_instances_.begin(); | |
| 279 it != render_view_instances_.end(); ++it) { | |
| 280 it->second->GetWebView()->loseCompositorContext(1); | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 } // namespace content | |
| OLD | NEW |