| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/renderer/webplugin_delegate_proxy.h" | 5 #include "chrome/renderer/webplugin_delegate_proxy.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <atlbase.h> | 10 #include <atlbase.h> |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 int instance_id_; | 151 int instance_id_; |
| 152 int resource_id_; | 152 int resource_id_; |
| 153 GURL url_; | 153 GURL url_; |
| 154 bool notify_needed_; | 154 bool notify_needed_; |
| 155 intptr_t notify_data_; | 155 intptr_t notify_data_; |
| 156 // Set to true if the response expected is a multibyte response. | 156 // Set to true if the response expected is a multibyte response. |
| 157 // For e.g. response for a HTTP byte range request. | 157 // For e.g. response for a HTTP byte range request. |
| 158 bool multibyte_response_expected_; | 158 bool multibyte_response_expected_; |
| 159 }; | 159 }; |
| 160 | 160 |
| 161 WebPluginDelegateProxy* WebPluginDelegateProxy::Create( | |
| 162 const GURL& url, | |
| 163 const std::string& mime_type, | |
| 164 const std::string& clsid, | |
| 165 const base::WeakPtr<RenderView>& render_view) { | |
| 166 return new WebPluginDelegateProxy(mime_type, clsid, render_view); | |
| 167 } | |
| 168 | |
| 169 WebPluginDelegateProxy::WebPluginDelegateProxy( | 161 WebPluginDelegateProxy::WebPluginDelegateProxy( |
| 170 const std::string& mime_type, | 162 const std::string& mime_type, |
| 171 const std::string& clsid, | 163 const std::string& clsid, |
| 172 const base::WeakPtr<RenderView>& render_view) | 164 const base::WeakPtr<RenderView>& render_view) |
| 173 : render_view_(render_view), | 165 : render_view_(render_view), |
| 174 plugin_(NULL), | 166 plugin_(NULL), |
| 175 windowless_(false), | 167 windowless_(false), |
| 176 window_(NULL), | 168 window_(NULL), |
| 177 mime_type_(mime_type), | 169 mime_type_(mime_type), |
| 178 clsid_(clsid), | 170 clsid_(clsid), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 // Destroying the channel host is what releases the channel name -> FD | 210 // Destroying the channel host is what releases the channel name -> FD |
| 219 // association on POSIX, and if we ask for a new connection before it is | 211 // association on POSIX, and if we ask for a new connection before it is |
| 220 // released, the plugin will give us a new FD, and we'll assert when trying | 212 // released, the plugin will give us a new FD, and we'll assert when trying |
| 221 // to associate it with the channel name. | 213 // to associate it with the channel name. |
| 222 channel_host_ = NULL; | 214 channel_host_ = NULL; |
| 223 } | 215 } |
| 224 | 216 |
| 225 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 217 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 226 } | 218 } |
| 227 | 219 |
| 228 bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn, | 220 bool WebPluginDelegateProxy::Initialize(const GURL& url, |
| 229 char** argv, int argc, | 221 const std::vector<std::string>& arg_name
s, |
| 222 const std::vector<std::string>& arg_valu
es, |
| 230 webkit_glue::WebPlugin* plugin, | 223 webkit_glue::WebPlugin* plugin, |
| 231 bool load_manually) { | 224 bool load_manually) { |
| 232 IPC::ChannelHandle channel_handle; | 225 IPC::ChannelHandle channel_handle; |
| 233 FilePath plugin_path; | 226 WebPluginInfo info; |
| 234 if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin( | 227 if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin( |
| 235 url, mime_type_, clsid_, webkit_glue::GetWebKitLocale(), | 228 url, mime_type_, clsid_, webkit_glue::GetWebKitLocale(), |
| 236 &channel_handle, &plugin_path))) { | 229 &channel_handle, &info))) { |
| 237 return false; | 230 return false; |
| 238 } | 231 } |
| 239 | 232 |
| 240 #if defined(OS_POSIX) | 233 #if defined(OS_POSIX) |
| 241 if (channel_handle.name.empty()) { | 234 if (channel_handle.name.empty()) { |
| 242 // We got an invalid handle. Possibly the plugin process is stale? In any | 235 // We got an invalid handle. Possibly the plugin process is stale? In any |
| 243 // case, don't try to connect to it, the empty name represents the host | 236 // case, don't try to connect to it, the empty name represents the host |
| 244 // channel, and connecting to it again does bad things. | 237 // channel, and connecting to it again does bad things. |
| 245 return false; | 238 return false; |
| 246 } | 239 } |
| 247 | 240 |
| 248 // If we received a ChannelHandle, register it now. | 241 // If we received a ChannelHandle, register it now. |
| 249 if (channel_handle.socket.fd >= 0) | 242 if (channel_handle.socket.fd >= 0) |
| 250 IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); | 243 IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); |
| 251 #endif | 244 #endif |
| 252 | 245 |
| 253 scoped_refptr<PluginChannelHost> channel_host = | 246 scoped_refptr<PluginChannelHost> channel_host = |
| 254 PluginChannelHost::GetPluginChannelHost( | 247 PluginChannelHost::GetPluginChannelHost( |
| 255 channel_handle.name, ChildProcess::current()->io_message_loop()); | 248 channel_handle.name, ChildProcess::current()->io_message_loop()); |
| 256 if (!channel_host.get()) | 249 if (!channel_host.get()) |
| 257 return false; | 250 return false; |
| 258 | 251 |
| 259 int instance_id; | 252 int instance_id; |
| 260 bool result = channel_host->Send(new PluginMsg_CreateInstance( | 253 bool result = channel_host->Send(new PluginMsg_CreateInstance( |
| 261 mime_type_, &instance_id)); | 254 mime_type_, &instance_id)); |
| 262 if (!result) | 255 if (!result) |
| 263 return false; | 256 return false; |
| 264 | 257 |
| 265 plugin_path_ = plugin_path; | 258 info_ = info; |
| 266 channel_host_ = channel_host; | 259 channel_host_ = channel_host; |
| 267 instance_id_ = instance_id; | 260 instance_id_ = instance_id; |
| 268 | 261 |
| 269 channel_host_->AddRoute(instance_id_, this, false); | 262 channel_host_->AddRoute(instance_id_, this, false); |
| 270 | 263 |
| 271 // Now tell the PluginInstance in the plugin process to initialize. | 264 // Now tell the PluginInstance in the plugin process to initialize. |
| 272 PluginMsg_Init_Params params; | 265 PluginMsg_Init_Params params; |
| 273 params.containing_window = render_view_->host_window(); | 266 params.containing_window = render_view_->host_window(); |
| 274 params.url = url; | 267 params.url = url; |
| 275 params.page_url = page_url_; | 268 params.page_url = page_url_; |
| 276 for (int i = 0; i < argc; ++i) { | 269 params.arg_names = arg_names; |
| 277 params.arg_names.push_back(argn[i]); | 270 params.arg_values = arg_values; |
| 278 params.arg_values.push_back(argv[i]); | 271 for (size_t i = 0; i < arg_names.size(); ++i) { |
| 279 | 272 if (LowerCaseEqualsASCII(arg_names[i], "wmode") && |
| 280 if (LowerCaseEqualsASCII(params.arg_names.back(), "wmode") && | 273 LowerCaseEqualsASCII(arg_values[i], "transparent")) { |
| 281 LowerCaseEqualsASCII(params.arg_values.back(), "transparent")) { | |
| 282 transparent_ = true; | 274 transparent_ = true; |
| 283 } | 275 } |
| 284 } | 276 } |
| 285 params.load_manually = load_manually; | 277 params.load_manually = load_manually; |
| 286 #if defined(OS_WIN) | 278 #if defined(OS_WIN) |
| 287 params.modal_dialog_event = render_view_->modal_dialog_event()->handle(); | 279 params.modal_dialog_event = render_view_->modal_dialog_event()->handle(); |
| 288 #endif | 280 #endif |
| 289 | 281 |
| 290 plugin_ = plugin; | 282 plugin_ = plugin; |
| 291 | 283 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 } | 333 } |
| 342 | 334 |
| 343 void WebPluginDelegateProxy::DidFinishManualLoading() { | 335 void WebPluginDelegateProxy::DidFinishManualLoading() { |
| 344 Send(new PluginMsg_DidFinishManualLoading(instance_id_)); | 336 Send(new PluginMsg_DidFinishManualLoading(instance_id_)); |
| 345 } | 337 } |
| 346 | 338 |
| 347 void WebPluginDelegateProxy::DidManualLoadFail() { | 339 void WebPluginDelegateProxy::DidManualLoadFail() { |
| 348 Send(new PluginMsg_DidManualLoadFail(instance_id_)); | 340 Send(new PluginMsg_DidManualLoadFail(instance_id_)); |
| 349 } | 341 } |
| 350 | 342 |
| 351 FilePath WebPluginDelegateProxy::GetPluginPath() { | |
| 352 return plugin_path_; | |
| 353 } | |
| 354 | |
| 355 void WebPluginDelegateProxy::InstallMissingPlugin() { | 343 void WebPluginDelegateProxy::InstallMissingPlugin() { |
| 356 Send(new PluginMsg_InstallMissingPlugin(instance_id_)); | 344 Send(new PluginMsg_InstallMissingPlugin(instance_id_)); |
| 357 } | 345 } |
| 358 | 346 |
| 359 void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { | 347 void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { |
| 360 child_process_logging::ScopedActiveURLSetter url_setter(page_url_); | 348 child_process_logging::ScopedActiveURLSetter url_setter(page_url_); |
| 361 | 349 |
| 362 IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg) | 350 IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg) |
| 363 IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow) | 351 IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow) |
| 364 #if defined(OS_WIN) | 352 #if defined(OS_WIN) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 393 | 381 |
| 394 void WebPluginDelegateProxy::OnChannelError() { | 382 void WebPluginDelegateProxy::OnChannelError() { |
| 395 if (plugin_) { | 383 if (plugin_) { |
| 396 if (window_) { | 384 if (window_) { |
| 397 // The actual WebPluginDelegate never got a chance to tell the WebPlugin | 385 // The actual WebPluginDelegate never got a chance to tell the WebPlugin |
| 398 // its window was going away. Do it on its behalf. | 386 // its window was going away. Do it on its behalf. |
| 399 WillDestroyWindow(); | 387 WillDestroyWindow(); |
| 400 } | 388 } |
| 401 plugin_->Invalidate(); | 389 plugin_->Invalidate(); |
| 402 } | 390 } |
| 403 render_view_->PluginCrashed(GetProcessId(), plugin_path_); | 391 render_view_->PluginCrashed(GetProcessId(), info_.path); |
| 404 } | 392 } |
| 405 | 393 |
| 406 void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect, | 394 void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect, |
| 407 const gfx::Rect& clip_rect) { | 395 const gfx::Rect& clip_rect) { |
| 408 plugin_rect_ = window_rect; | 396 plugin_rect_ = window_rect; |
| 409 | 397 |
| 410 bool bitmaps_changed = false; | 398 bool bitmaps_changed = false; |
| 411 | 399 |
| 412 if (windowless_) { | 400 if (windowless_) { |
| 413 if (!backing_store_canvas_.get() || | 401 if (!backing_store_canvas_.get() || |
| 414 (window_rect.width() != backing_store_canvas_->getDevice()->width() || | 402 (window_rect.width() != backing_store_canvas_->getDevice()->width() || |
| 415 window_rect.height() != backing_store_canvas_->getDevice()->height()))
{ | 403 window_rect.height() != backing_store_canvas_->getDevice()->height()))
{ |
| 416 bitmaps_changed = true; | 404 bitmaps_changed = true; |
| 417 // Create a shared memory section that the plugin paints into | 405 // Create a shared memory section that the plugin paints into |
| 418 // asynchronously. | 406 // asynchronously. |
| 419 ResetWindowlessBitmaps(); | 407 ResetWindowlessBitmaps(); |
| 420 if (!window_rect.IsEmpty()) { | 408 if (!window_rect.IsEmpty()) { |
| 421 if (!CreateBitmap(&backing_store_, &backing_store_canvas_) || | 409 if (!CreateBitmap(&backing_store_, &backing_store_canvas_) || |
| 422 !CreateBitmap(&transport_store_, &transport_store_canvas_) || | 410 !CreateBitmap(&transport_store_, &transport_store_canvas_) || |
| 423 (transparent_ && | 411 (transparent_ && |
| 424 !CreateBitmap(&background_store_, &background_store_canvas_))) { | 412 !CreateBitmap(&background_store_, &background_store_canvas_))) { |
| 425 DCHECK(false); | 413 DCHECK(false); |
| 426 ResetWindowlessBitmaps(); | 414 ResetWindowlessBitmaps(); |
| 427 return; | 415 return; |
| 428 } | 416 } |
| 429 } | 417 } |
| 430 } | 418 } |
| 431 } | 419 } |
| 432 | 420 |
| 433 IPC::Message* msg = NULL; | 421 PluginMsg_UpdateGeometry_Param param; |
| 422 param.window_rect = window_rect; |
| 423 param.clip_rect = clip_rect; |
| 424 param.windowless_buffer = TransportDIB::DefaultHandleValue(); |
| 425 param.background_buffer = TransportDIB::DefaultHandleValue(); |
| 426 |
| 434 #if defined(OS_POSIX) | 427 #if defined(OS_POSIX) |
| 435 // If we're using POSIX mmap'd TransportDIBs, sending the handle across | 428 // If we're using POSIX mmap'd TransportDIBs, sending the handle across |
| 436 // IPC establishes a new mapping rather than just sending a window ID, | 429 // IPC establishes a new mapping rather than just sending a window ID, |
| 437 // so only do so if we've actually recreated the shared memory bitmaps. | 430 // so only do so if we've actually recreated the shared memory bitmaps. |
| 438 if (!bitmaps_changed) { | 431 if (bitmaps_changed) |
| 439 msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect, | 432 #endif |
| 440 TransportDIB::DefaultHandleValue(), TransportDIB::DefaultHandleValue()); | 433 { |
| 434 if (transport_store_.get()) { |
| 435 param.windowless_buffer = transport_store_->handle(); |
| 436 } else if (background_store_.get()) { |
| 437 param.background_buffer = background_store_->handle(); |
| 438 } |
| 439 } |
| 440 |
| 441 IPC::Message* msg; |
| 442 #if defined (OS_WIN) |
| 443 std::wstring filename = StringToLowerASCII(info_.path.BaseName().value()); |
| 444 if (info_.name.find(L"Windows Media Player") != std::wstring::npos) { |
| 445 // Need to update geometry synchronously with WMP, otherwise if a site |
| 446 // scripts the plugin to start playing while it's in the middle of handling |
| 447 // an update geometry message, videos don't play. See urls in bug 20260. |
| 448 msg = new PluginMsg_UpdateGeometrySync(instance_id_, param); |
| 441 } else | 449 } else |
| 442 #endif | 450 #endif |
| 443 if (transport_store_.get() && background_store_.get()) { | 451 { |
| 444 msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect, | 452 msg = new PluginMsg_UpdateGeometry(instance_id_, param); |
| 445 transport_store_->handle(), background_store_->handle()); | 453 msg->set_unblock(true); |
| 446 } else if (transport_store_.get()) { | |
| 447 msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect, | |
| 448 transport_store_->handle(), TransportDIB::DefaultHandleValue()); | |
| 449 } else { | |
| 450 msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect, | |
| 451 TransportDIB::DefaultHandleValue(), TransportDIB::DefaultHandleValue()); | |
| 452 } | 454 } |
| 453 | 455 |
| 454 msg->set_unblock(true); | |
| 455 Send(msg); | 456 Send(msg); |
| 456 } | 457 } |
| 457 | 458 |
| 458 #if defined(OS_MACOSX) | 459 #if defined(OS_MACOSX) |
| 459 static void ReleaseTransportDIB(TransportDIB *dib) { | 460 static void ReleaseTransportDIB(TransportDIB *dib) { |
| 460 if (dib) { | 461 if (dib) { |
| 461 IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id()); | 462 IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id()); |
| 462 RenderThread::current()->Send(msg); | 463 RenderThread::current()->Send(msg); |
| 463 } | 464 } |
| 464 } | 465 } |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 webkit_glue::WebPluginResourceClient* | 1053 webkit_glue::WebPluginResourceClient* |
| 1053 WebPluginDelegateProxy::CreateResourceClient( | 1054 WebPluginDelegateProxy::CreateResourceClient( |
| 1054 int resource_id, const GURL& url, bool notify_needed, | 1055 int resource_id, const GURL& url, bool notify_needed, |
| 1055 intptr_t notify_data, intptr_t npstream) { | 1056 intptr_t notify_data, intptr_t npstream) { |
| 1056 ResourceClientProxy* proxy = new ResourceClientProxy(channel_host_, | 1057 ResourceClientProxy* proxy = new ResourceClientProxy(channel_host_, |
| 1057 instance_id_); | 1058 instance_id_); |
| 1058 proxy->Initialize(resource_id, url, notify_needed, notify_data, npstream); | 1059 proxy->Initialize(resource_id, url, notify_needed, notify_data, npstream); |
| 1059 return proxy; | 1060 return proxy; |
| 1060 } | 1061 } |
| 1061 | 1062 |
| 1062 bool WebPluginDelegateProxy::IsWindowless() const { | |
| 1063 NOTREACHED(); | |
| 1064 return false; | |
| 1065 } | |
| 1066 | |
| 1067 gfx::Rect WebPluginDelegateProxy::GetRect() const { | |
| 1068 NOTREACHED(); | |
| 1069 return gfx::Rect(); | |
| 1070 } | |
| 1071 | |
| 1072 gfx::Rect WebPluginDelegateProxy::GetClipRect() const { | |
| 1073 NOTREACHED(); | |
| 1074 return gfx::Rect(); | |
| 1075 } | |
| 1076 | |
| 1077 int WebPluginDelegateProxy::GetQuirks() const { | |
| 1078 NOTREACHED(); | |
| 1079 return 0; | |
| 1080 } | |
| 1081 | |
| 1082 void WebPluginDelegateProxy::OnCancelDocumentLoad() { | 1063 void WebPluginDelegateProxy::OnCancelDocumentLoad() { |
| 1083 plugin_->CancelDocumentLoad(); | 1064 plugin_->CancelDocumentLoad(); |
| 1084 } | 1065 } |
| 1085 | 1066 |
| 1086 void WebPluginDelegateProxy::OnInitiateHTTPRangeRequest( | 1067 void WebPluginDelegateProxy::OnInitiateHTTPRangeRequest( |
| 1087 const std::string& url, const std::string& range_info, | 1068 const std::string& url, const std::string& range_info, |
| 1088 intptr_t existing_stream, bool notify_needed, intptr_t notify_data) { | 1069 intptr_t existing_stream, bool notify_needed, intptr_t notify_data) { |
| 1089 plugin_->InitiateHTTPRangeRequest(url.c_str(), range_info.c_str(), | 1070 plugin_->InitiateHTTPRangeRequest(url.c_str(), range_info.c_str(), |
| 1090 existing_stream, notify_needed, | 1071 existing_stream, notify_needed, |
| 1091 notify_data); | 1072 notify_data); |
| 1092 } | 1073 } |
| 1093 | 1074 |
| 1094 void WebPluginDelegateProxy::OnDeferResourceLoading(int resource_id, | 1075 void WebPluginDelegateProxy::OnDeferResourceLoading(int resource_id, |
| 1095 bool defer) { | 1076 bool defer) { |
| 1096 plugin_->SetDeferResourceLoading(resource_id, defer); | 1077 plugin_->SetDeferResourceLoading(resource_id, defer); |
| 1097 } | 1078 } |
| OLD | NEW |