Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "content/renderer/browser_plugin/browser_plugin.h" | 5 #include "content/renderer/browser_plugin/browser_plugin.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #if defined (OS_WIN) | 9 #if defined (OS_WIN) |
| 10 #include "base/sys_info.h" | 10 #include "base/sys_info.h" |
| 11 #endif | 11 #endif |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "content/common/browser_plugin_messages.h" | 13 #include "content/common/browser_plugin_messages.h" |
| 14 #include "content/common/view_messages.h" | |
| 14 #include "content/public/common/content_client.h" | 15 #include "content/public/common/content_client.h" |
| 15 #include "content/public/renderer/content_renderer_client.h" | 16 #include "content/public/renderer/content_renderer_client.h" |
| 16 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" | 17 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" |
| 17 #include "content/renderer/browser_plugin/browser_plugin_manager.h" | 18 #include "content/renderer/browser_plugin/browser_plugin_manager.h" |
| 18 #include "content/renderer/render_process_impl.h" | 19 #include "content/renderer/render_process_impl.h" |
| 19 #include "content/renderer/render_thread_impl.h" | 20 #include "content/renderer/render_thread_impl.h" |
| 20 #include "skia/ext/platform_canvas.h" | 21 #include "skia/ext/platform_canvas.h" |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 navigate_src_sent_(false), | 65 navigate_src_sent_(false), |
| 65 process_id_(-1), | 66 process_id_(-1), |
| 66 persist_storage_(false) { | 67 persist_storage_(false) { |
| 67 BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); | 68 BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); |
| 68 bindings_.reset(new BrowserPluginBindings(this)); | 69 bindings_.reset(new BrowserPluginBindings(this)); |
| 69 | 70 |
| 70 ParseAttributes(params); | 71 ParseAttributes(params); |
| 71 } | 72 } |
| 72 | 73 |
| 73 BrowserPlugin::~BrowserPlugin() { | 74 BrowserPlugin::~BrowserPlugin() { |
| 74 if (damage_buffer_) { | 75 if (damage_buffer_) |
| 75 RenderProcess::current()->FreeTransportDIB(damage_buffer_); | 76 FreeDamageBuffer(); |
| 76 damage_buffer_ = NULL; | |
| 77 } | |
| 78 RemoveEventListeners(); | 77 RemoveEventListeners(); |
| 79 BrowserPluginManager::Get()->RemoveBrowserPlugin(instance_id_); | 78 BrowserPluginManager::Get()->RemoveBrowserPlugin(instance_id_); |
| 80 BrowserPluginManager::Get()->Send( | 79 BrowserPluginManager::Get()->Send( |
| 81 new BrowserPluginHostMsg_PluginDestroyed( | 80 new BrowserPluginHostMsg_PluginDestroyed( |
| 82 render_view_->GetRoutingID(), | 81 render_view_->GetRoutingID(), |
| 83 instance_id_)); | 82 instance_id_)); |
| 84 } | 83 } |
| 85 | 84 |
| 86 void BrowserPlugin::Cleanup() { | 85 void BrowserPlugin::Cleanup() { |
| 87 if (damage_buffer_) { | 86 if (damage_buffer_) |
| 88 RenderProcess::current()->FreeTransportDIB(damage_buffer_); | 87 FreeDamageBuffer(); |
| 89 damage_buffer_ = NULL; | |
| 90 } | |
| 91 } | 88 } |
| 92 | 89 |
| 93 std::string BrowserPlugin::GetSrcAttribute() const { | 90 std::string BrowserPlugin::GetSrcAttribute() const { |
| 94 return src_; | 91 return src_; |
| 95 } | 92 } |
| 96 | 93 |
| 97 void BrowserPlugin::SetSrcAttribute(const std::string& src) { | 94 void BrowserPlugin::SetSrcAttribute(const std::string& src) { |
| 98 if (src == src_ && !guest_crashed_) | 95 if (src == src_ && !guest_crashed_) |
| 99 return; | 96 return; |
| 100 if (!src.empty() || navigate_src_sent_) { | 97 if (!src.empty() || navigate_src_sent_) { |
| 98 scoped_ptr<BrowserPluginHostMsg_ResizeGuest_Params> params( | |
| 99 GetPendingResizeParams()); | |
| 100 DCHECK(!params->resize_pending); | |
| 101 BrowserPluginManager::Get()->Send( | 101 BrowserPluginManager::Get()->Send( |
| 102 new BrowserPluginHostMsg_NavigateGuest( | 102 new BrowserPluginHostMsg_NavigateGuest( |
| 103 render_view_->GetRoutingID(), | 103 render_view_->GetRoutingID(), |
| 104 instance_id_, | 104 instance_id_, |
| 105 src, | 105 src, |
| 106 gfx::Size(width(), height()))); | 106 *params)); |
| 107 // Record that we sent a NavigateGuest message to embedder. Once we send | 107 // Record that we sent a NavigateGuest message to embedder. Once we send |
| 108 // such a message, subsequent SetSrcAttribute() calls must always send | 108 // such a message, subsequent SetSrcAttribute() calls must always send |
| 109 // NavigateGuest messages to the embedder (even if |src| is empty), so | 109 // NavigateGuest messages to the embedder (even if |src| is empty), so |
| 110 // resize works correctly for all cases (e.g. The embedder can reset the | 110 // resize works correctly for all cases (e.g. The embedder can reset the |
| 111 // guest's |src| to empty value, resize and then set the |src| to a | 111 // guest's |src| to empty value, resize and then set the |src| to a |
| 112 // non-empty value). | 112 // non-empty value). |
| 113 // Additionally, once this instance has navigated, the storage partition | 113 // Additionally, once this instance has navigated, the storage partition |
| 114 // cannot be changed, so this value is used for enforcing this. | 114 // cannot be changed, so this value is used for enforcing this. |
| 115 navigate_src_sent_ = true; | 115 navigate_src_sent_ = true; |
| 116 } | 116 } |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 const WebRect& clip_rect, | 405 const WebRect& clip_rect, |
| 406 const WebVector<WebRect>& cut_outs_rects, | 406 const WebVector<WebRect>& cut_outs_rects, |
| 407 bool is_visible) { | 407 bool is_visible) { |
| 408 int old_width = width(); | 408 int old_width = width(); |
| 409 int old_height = height(); | 409 int old_height = height(); |
| 410 plugin_rect_ = window_rect; | 410 plugin_rect_ = window_rect; |
| 411 if (old_width == window_rect.width && | 411 if (old_width == window_rect.width && |
| 412 old_height == window_rect.height) { | 412 old_height == window_rect.height) { |
| 413 return; | 413 return; |
| 414 } | 414 } |
| 415 // Until an actual navigation occurs, there is no browser side embedder | |
| 416 // present to notify about geometry updates. In this case, after we've updated | |
| 417 // the BrowserPlugin's state we are done and can return immediately. | |
| 418 if (!navigate_src_sent_) | |
| 419 return; | |
| 420 | 415 |
| 421 const size_t stride = skia::PlatformCanvas::StrideForWidth(window_rect.width); | 416 const size_t stride = skia::PlatformCanvas::StrideForWidth(window_rect.width); |
| 422 // Make sure the size of the damage buffer is at least four bytes so that we | 417 // Make sure the size of the damage buffer is at least four bytes so that we |
| 423 // can fit in a magic word to verify that the memory is shared correctly. | 418 // can fit in a magic word to verify that the memory is shared correctly. |
| 424 size_t size = | 419 size_t size = |
| 425 std::max(sizeof(unsigned int), | 420 std::max(sizeof(unsigned int), |
| 426 static_cast<size_t>(window_rect.height * | 421 static_cast<size_t>(window_rect.height * |
| 427 stride * | 422 stride * |
| 428 GetDeviceScaleFactor() * | 423 GetDeviceScaleFactor() * |
| 429 GetDeviceScaleFactor())); | 424 GetDeviceScaleFactor())); |
| 430 | 425 |
| 431 // Don't drop the old damage buffer until after we've made sure that the | 426 // Don't drop the old damage buffer until after we've made sure that the |
| 432 // browser process has dropped it. | 427 // browser process has dropped it. |
| 428 TransportDIB* new_damage_buffer = CreateTransportDIB(size); | |
| 429 pending_resize_params_.reset(); | |
| 430 | |
| 431 scoped_ptr<BrowserPluginHostMsg_ResizeGuest_Params> params( | |
| 432 new BrowserPluginHostMsg_ResizeGuest_Params); | |
| 433 params->damage_buffer_id = new_damage_buffer->id(); | |
| 434 #if defined(OS_MACOSX) | |
| 435 params->damage_buffer_handle = new_damage_buffer->handle(); | |
| 436 #endif | |
| 437 #if defined(OS_WIN) | |
| 438 params->damage_buffer_size = size; | |
| 439 #endif | |
| 440 params->width = window_rect.width; | |
| 441 params->height = window_rect.height; | |
| 442 params->resize_pending = resize_pending_; | |
| 443 params->scale_factor = GetDeviceScaleFactor(); | |
| 444 | |
| 445 if (navigate_src_sent_) { | |
| 446 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ResizeGuest( | |
| 447 render_view_->GetRoutingID(), | |
| 448 instance_id_, | |
| 449 *params)); | |
| 450 resize_pending_ = true; | |
| 451 } else { | |
| 452 // Until an actual navigation occurs, there is no browser side embedder | |
| 453 // present to notify about geometry updates. In this case, after we've | |
| 454 // updated the BrowserPlugin's state we are done and we do not send a resize | |
| 455 // message to the browser. | |
| 456 pending_resize_params_.reset(params.release()); | |
| 457 } | |
| 458 if (damage_buffer_) | |
| 459 FreeDamageBuffer(); | |
| 460 damage_buffer_ = new_damage_buffer; | |
| 461 } | |
| 462 | |
| 463 void BrowserPlugin::FreeDamageBuffer() { | |
| 464 DCHECK(damage_buffer_); | |
| 465 if (damage_buffer_) { | |
|
Fady Samuel
2012/09/28 23:46:48
No need for this guard if you already have the che
lazyboy
2012/09/29 00:50:06
Done. Thanks.
| |
| 466 #if defined(OS_MACOSX) | |
| 467 delete damage_buffer_; | |
| 468 #else | |
| 469 RenderProcess::current()->FreeTransportDIB(damage_buffer_); | |
| 470 damage_buffer_ = NULL; | |
| 471 #endif | |
| 472 } | |
| 473 } | |
| 474 | |
| 475 BrowserPluginHostMsg_ResizeGuest_Params* | |
| 476 BrowserPlugin::GetPendingResizeParams() { | |
| 477 if (pending_resize_params_.get()) { | |
| 478 resize_pending_ = true; | |
| 479 return pending_resize_params_.release(); | |
| 480 } else { | |
| 481 BrowserPluginHostMsg_ResizeGuest_Params* params = | |
| 482 new BrowserPluginHostMsg_ResizeGuest_Params; | |
| 483 | |
| 484 // We don't have a pending resize to send, so we send an invalid transport | |
| 485 // dib Id. | |
| 486 params->damage_buffer_id = TransportDIB::Id(); | |
| 487 params->width = width(); | |
| 488 params->height = height(); | |
| 489 params->resize_pending = false; | |
| 490 return params; | |
| 491 } | |
| 492 } | |
| 493 | |
| 494 TransportDIB* BrowserPlugin::CreateTransportDIB(const size_t size) { | |
| 495 #if defined(OS_MACOSX) | |
| 496 TransportDIB::Handle handle; | |
| 497 // On OSX we don't let the browser manage the transport dib. We manage the | |
| 498 // deletion of the dib in FreeDamageBuffer(). | |
| 499 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB( | |
| 500 size, | |
| 501 false, // cache in browser. | |
| 502 &handle); | |
| 433 TransportDIB* new_damage_buffer = NULL; | 503 TransportDIB* new_damage_buffer = NULL; |
| 434 #if defined(OS_WIN) | 504 if (BrowserPluginManager::Get()->Send(msg) && handle.fd >= 0) |
| 435 size_t allocation_granularity = base::SysInfo::VMAllocationGranularity(); | 505 new_damage_buffer = TransportDIB::Map(handle); |
| 436 size_t shared_mem_size = size / allocation_granularity + 1; | |
| 437 shared_mem_size = shared_mem_size * allocation_granularity; | |
| 438 | |
| 439 base::SharedMemory shared_mem; | |
| 440 if (!shared_mem.CreateAnonymous(shared_mem_size)) | |
| 441 NOTREACHED() << "Unable to create shared memory of size:" << size; | |
| 442 new_damage_buffer = TransportDIB::Map(shared_mem.handle()); | |
| 443 #else | 506 #else |
| 444 new_damage_buffer = RenderProcess::current()->CreateTransportDIB(size); | 507 TransportDIB* new_damage_buffer = |
| 508 RenderProcess::current()->CreateTransportDIB(size); | |
| 445 #endif | 509 #endif |
| 446 if (!new_damage_buffer) | 510 if (!new_damage_buffer) |
| 447 NOTREACHED() << "Unable to create damage buffer"; | 511 NOTREACHED() << "Unable to create damage buffer"; |
| 512 #if defined(OS_WIN) | |
| 513 // Windows does not map the buffer by default. | |
| 514 CHECK(new_damage_buffer->Map()); | |
| 515 #endif | |
| 448 DCHECK(new_damage_buffer->memory()); | 516 DCHECK(new_damage_buffer->memory()); |
| 449 // Insert the magic word. | 517 // Insert the magic word. |
| 450 *static_cast<unsigned int*>(new_damage_buffer->memory()) = 0xdeadbeef; | 518 *static_cast<unsigned int*>(new_damage_buffer->memory()) = 0xdeadbeef; |
| 451 | 519 return new_damage_buffer; |
| 452 BrowserPluginHostMsg_ResizeGuest_Params params; | |
| 453 params.damage_buffer_id = new_damage_buffer->id(); | |
| 454 #if defined(OS_WIN) | |
| 455 params.damage_buffer_size = size; | |
| 456 #endif | |
| 457 params.width = window_rect.width; | |
| 458 params.height = window_rect.height; | |
| 459 params.resize_pending = resize_pending_; | |
| 460 params.scale_factor = GetDeviceScaleFactor(); | |
| 461 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ResizeGuest( | |
| 462 render_view_->GetRoutingID(), | |
| 463 instance_id_, | |
| 464 params)); | |
| 465 resize_pending_ = true; | |
| 466 | |
| 467 if (damage_buffer_) { | |
| 468 RenderProcess::current()->FreeTransportDIB(damage_buffer_); | |
| 469 damage_buffer_ = NULL; | |
| 470 } | |
| 471 damage_buffer_ = new_damage_buffer; | |
| 472 } | 520 } |
| 473 | 521 |
| 474 void BrowserPlugin::updateFocus(bool focused) { | 522 void BrowserPlugin::updateFocus(bool focused) { |
| 475 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetFocus( | 523 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetFocus( |
| 476 render_view_->GetRoutingID(), | 524 render_view_->GetRoutingID(), |
| 477 instance_id_, | 525 instance_id_, |
| 478 focused)); | 526 focused)); |
| 479 } | 527 } |
| 480 | 528 |
| 481 void BrowserPlugin::updateVisibility(bool visible) { | 529 void BrowserPlugin::updateVisibility(bool visible) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 void* notify_data) { | 570 void* notify_data) { |
| 523 } | 571 } |
| 524 | 572 |
| 525 void BrowserPlugin::didFailLoadingFrameRequest( | 573 void BrowserPlugin::didFailLoadingFrameRequest( |
| 526 const WebKit::WebURL& url, | 574 const WebKit::WebURL& url, |
| 527 void* notify_data, | 575 void* notify_data, |
| 528 const WebKit::WebURLError& error) { | 576 const WebKit::WebURLError& error) { |
| 529 } | 577 } |
| 530 | 578 |
| 531 } // namespace content | 579 } // namespace content |
| OLD | NEW |