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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 const WebRect& clip_rect, | 435 const WebRect& clip_rect, |
436 const WebVector<WebRect>& cut_outs_rects, | 436 const WebVector<WebRect>& cut_outs_rects, |
437 bool is_visible) { | 437 bool is_visible) { |
438 int old_width = width(); | 438 int old_width = width(); |
439 int old_height = height(); | 439 int old_height = height(); |
440 plugin_rect_ = window_rect; | 440 plugin_rect_ = window_rect; |
441 if (old_width == window_rect.width && | 441 if (old_width == window_rect.width && |
442 old_height == window_rect.height) { | 442 old_height == window_rect.height) { |
443 return; | 443 return; |
444 } | 444 } |
445 // Until an actual navigation occurs, there is no browser side embedder | |
446 // present to notify about geometry updates. In this case, after we've updated | |
447 // the BrowserPlugin's state we are done and can return immediately. | |
448 if (!navigate_src_sent_) | |
449 return; | |
450 | 445 |
451 const size_t stride = skia::PlatformCanvas::StrideForWidth(window_rect.width); | 446 const size_t stride = skia::PlatformCanvas::StrideForWidth(window_rect.width); |
452 // Make sure the size of the damage buffer is at least four bytes so that we | 447 // Make sure the size of the damage buffer is at least four bytes so that we |
453 // can fit in a magic word to verify that the memory is shared correctly. | 448 // can fit in a magic word to verify that the memory is shared correctly. |
454 size_t size = | 449 size_t size = |
455 std::max(sizeof(unsigned int), | 450 std::max(sizeof(unsigned int), |
456 static_cast<size_t>(window_rect.height * | 451 static_cast<size_t>(window_rect.height * |
457 stride * | 452 stride * |
458 GetDeviceScaleFactor() * | 453 GetDeviceScaleFactor() * |
459 GetDeviceScaleFactor())); | 454 GetDeviceScaleFactor())); |
460 | 455 |
461 // Don't drop the old damage buffer until after we've made sure that the | 456 // Don't drop the old damage buffer until after we've made sure that the |
462 // browser process has dropped it. | 457 // browser process has dropped it. |
| 458 TransportDIB* new_damage_buffer = CreateTransportDIB(size); |
| 459 pending_resize_params_.reset(); |
| 460 |
| 461 scoped_ptr<BrowserPluginHostMsg_ResizeGuest_Params> params( |
| 462 new BrowserPluginHostMsg_ResizeGuest_Params); |
| 463 params->damage_buffer_id = new_damage_buffer->id(); |
| 464 #if defined(OS_MACOSX) |
| 465 // |damage_buffer_id| is not enough to retrieve the damage buffer (on browser |
| 466 // side) since we don't let the browser cache the damage buffer. We need a |
| 467 // handle to the damage buffer for this. |
| 468 params->damage_buffer_handle = new_damage_buffer->handle(); |
| 469 #endif |
| 470 #if defined(OS_WIN) |
| 471 params->damage_buffer_size = size; |
| 472 #endif |
| 473 params->width = window_rect.width; |
| 474 params->height = window_rect.height; |
| 475 params->resize_pending = resize_pending_; |
| 476 params->scale_factor = GetDeviceScaleFactor(); |
| 477 |
| 478 if (navigate_src_sent_) { |
| 479 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ResizeGuest( |
| 480 render_view_->GetRoutingID(), |
| 481 instance_id_, |
| 482 *params)); |
| 483 resize_pending_ = true; |
| 484 } else { |
| 485 // Until an actual navigation occurs, there is no browser side embedder |
| 486 // present to notify about geometry updates. In this case, after we've |
| 487 // updated the BrowserPlugin's state we are done and we do not send a resize |
| 488 // message to the browser. |
| 489 pending_resize_params_.reset(params.release()); |
| 490 } |
| 491 if (damage_buffer_) |
| 492 FreeDamageBuffer(); |
| 493 damage_buffer_ = new_damage_buffer; |
| 494 } |
| 495 |
| 496 void BrowserPlugin::FreeDamageBuffer() { |
| 497 DCHECK(damage_buffer_); |
| 498 #if defined(OS_MACOSX) |
| 499 // We don't need to (nor we should) send ViewHostMsg_FreeTransportDIB |
| 500 // message to the browser to free the damage buffer since we manage the |
| 501 // damage buffer ourselves. |
| 502 delete damage_buffer_; |
| 503 #else |
| 504 RenderProcess::current()->FreeTransportDIB(damage_buffer_); |
| 505 damage_buffer_ = NULL; |
| 506 #endif |
| 507 } |
| 508 |
| 509 BrowserPluginHostMsg_ResizeGuest_Params* |
| 510 BrowserPlugin::GetPendingResizeParams() { |
| 511 if (pending_resize_params_.get()) { |
| 512 resize_pending_ = true; |
| 513 return pending_resize_params_.release(); |
| 514 } else { |
| 515 BrowserPluginHostMsg_ResizeGuest_Params* params = |
| 516 new BrowserPluginHostMsg_ResizeGuest_Params; |
| 517 |
| 518 // We don't have a pending resize to send, so we send an invalid transport |
| 519 // dib Id. |
| 520 params->damage_buffer_id = TransportDIB::Id(); |
| 521 params->width = width(); |
| 522 params->height = height(); |
| 523 params->resize_pending = false; |
| 524 return params; |
| 525 } |
| 526 } |
| 527 |
| 528 TransportDIB* BrowserPlugin::CreateTransportDIB(const size_t size) { |
| 529 #if defined(OS_MACOSX) |
| 530 TransportDIB::Handle handle; |
| 531 // On OSX we don't let the browser manage the transport dib. We manage the |
| 532 // deletion of the dib in FreeDamageBuffer(). |
| 533 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB( |
| 534 size, |
| 535 false, // cache in browser. |
| 536 &handle); |
463 TransportDIB* new_damage_buffer = NULL; | 537 TransportDIB* new_damage_buffer = NULL; |
464 #if defined(OS_WIN) | 538 if (BrowserPluginManager::Get()->Send(msg) && handle.fd >= 0) |
465 size_t allocation_granularity = base::SysInfo::VMAllocationGranularity(); | 539 new_damage_buffer = TransportDIB::Map(handle); |
466 size_t shared_mem_size = size / allocation_granularity + 1; | |
467 shared_mem_size = shared_mem_size * allocation_granularity; | |
468 | |
469 base::SharedMemory shared_mem; | |
470 if (!shared_mem.CreateAnonymous(shared_mem_size)) | |
471 NOTREACHED() << "Unable to create shared memory of size:" << size; | |
472 new_damage_buffer = TransportDIB::Map(shared_mem.handle()); | |
473 #else | 540 #else |
474 new_damage_buffer = RenderProcess::current()->CreateTransportDIB(size); | 541 TransportDIB* new_damage_buffer = |
| 542 RenderProcess::current()->CreateTransportDIB(size); |
475 #endif | 543 #endif |
476 if (!new_damage_buffer) | 544 if (!new_damage_buffer) |
477 NOTREACHED() << "Unable to create damage buffer"; | 545 NOTREACHED() << "Unable to create damage buffer"; |
| 546 #if defined(OS_WIN) |
| 547 // Windows does not map the buffer by default. |
| 548 CHECK(new_damage_buffer->Map()); |
| 549 #endif |
478 DCHECK(new_damage_buffer->memory()); | 550 DCHECK(new_damage_buffer->memory()); |
479 // Insert the magic word. | 551 // Insert the magic word. |
480 *static_cast<unsigned int*>(new_damage_buffer->memory()) = 0xdeadbeef; | 552 *static_cast<unsigned int*>(new_damage_buffer->memory()) = 0xdeadbeef; |
481 | 553 return new_damage_buffer; |
482 BrowserPluginHostMsg_ResizeGuest_Params params; | |
483 params.damage_buffer_id = new_damage_buffer->id(); | |
484 #if defined(OS_WIN) | |
485 params.damage_buffer_size = size; | |
486 #endif | |
487 params.width = window_rect.width; | |
488 params.height = window_rect.height; | |
489 params.resize_pending = resize_pending_; | |
490 params.scale_factor = GetDeviceScaleFactor(); | |
491 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ResizeGuest( | |
492 render_view_->GetRoutingID(), | |
493 instance_id_, | |
494 params)); | |
495 resize_pending_ = true; | |
496 | |
497 if (damage_buffer_) { | |
498 RenderProcess::current()->FreeTransportDIB(damage_buffer_); | |
499 damage_buffer_ = NULL; | |
500 } | |
501 damage_buffer_ = new_damage_buffer; | |
502 } | 554 } |
503 | 555 |
504 void BrowserPlugin::updateFocus(bool focused) { | 556 void BrowserPlugin::updateFocus(bool focused) { |
505 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetFocus( | 557 BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetFocus( |
506 render_view_->GetRoutingID(), | 558 render_view_->GetRoutingID(), |
507 instance_id_, | 559 instance_id_, |
508 focused)); | 560 focused)); |
509 } | 561 } |
510 | 562 |
511 void BrowserPlugin::updateVisibility(bool visible) { | 563 void BrowserPlugin::updateVisibility(bool visible) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 void* notify_data) { | 604 void* notify_data) { |
553 } | 605 } |
554 | 606 |
555 void BrowserPlugin::didFailLoadingFrameRequest( | 607 void BrowserPlugin::didFailLoadingFrameRequest( |
556 const WebKit::WebURL& url, | 608 const WebKit::WebURL& url, |
557 void* notify_data, | 609 void* notify_data, |
558 const WebKit::WebURLError& error) { | 610 const WebKit::WebURLError& error) { |
559 } | 611 } |
560 | 612 |
561 } // namespace content | 613 } // namespace content |
OLD | NEW |