OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 bool auto_navigate) | 47 bool auto_navigate) |
48 : guest_instance_id_(browser_plugin::kInstanceIDNone), | 48 : guest_instance_id_(browser_plugin::kInstanceIDNone), |
49 attached_(false), | 49 attached_(false), |
50 render_view_(render_view->AsWeakPtr()), | 50 render_view_(render_view->AsWeakPtr()), |
51 render_view_routing_id_(render_view->GetRoutingID()), | 51 render_view_routing_id_(render_view->GetRoutingID()), |
52 container_(NULL), | 52 container_(NULL), |
53 paint_ack_received_(true), | 53 paint_ack_received_(true), |
54 last_device_scale_factor_(GetDeviceScaleFactor()), | 54 last_device_scale_factor_(GetDeviceScaleFactor()), |
55 sad_guest_(NULL), | 55 sad_guest_(NULL), |
56 guest_crashed_(false), | 56 guest_crashed_(false), |
| 57 is_auto_size_state_dirty_(false), |
57 content_window_routing_id_(MSG_ROUTING_NONE), | 58 content_window_routing_id_(MSG_ROUTING_NONE), |
58 plugin_focused_(false), | 59 plugin_focused_(false), |
59 visible_(true), | 60 visible_(true), |
60 auto_navigate_(auto_navigate), | 61 auto_navigate_(auto_navigate), |
61 mouse_locked_(false), | 62 mouse_locked_(false), |
62 browser_plugin_manager_(render_view->GetBrowserPluginManager()), | 63 browser_plugin_manager_(render_view->GetBrowserPluginManager()), |
63 weak_ptr_factory_(this) { | 64 weak_ptr_factory_(this) { |
64 } | 65 } |
65 | 66 |
66 BrowserPlugin::~BrowserPlugin() { | 67 BrowserPlugin::~BrowserPlugin() { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 return false; | 137 return false; |
137 | 138 |
138 return container()->element().hasAttribute( | 139 return container()->element().hasAttribute( |
139 blink::WebString::fromUTF8(attribute_name)); | 140 blink::WebString::fromUTF8(attribute_name)); |
140 } | 141 } |
141 | 142 |
142 bool BrowserPlugin::GetAllowTransparencyAttribute() const { | 143 bool BrowserPlugin::GetAllowTransparencyAttribute() const { |
143 return HasDOMAttribute(browser_plugin::kAttributeAllowTransparency); | 144 return HasDOMAttribute(browser_plugin::kAttributeAllowTransparency); |
144 } | 145 } |
145 | 146 |
| 147 bool BrowserPlugin::GetAutoSizeAttribute() const { |
| 148 return HasDOMAttribute(browser_plugin::kAttributeAutoSize); |
| 149 } |
| 150 |
| 151 int BrowserPlugin::GetMaxHeightAttribute() const { |
| 152 int max_height; |
| 153 base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMaxHeight), |
| 154 &max_height); |
| 155 return max_height; |
| 156 } |
| 157 |
| 158 int BrowserPlugin::GetMaxWidthAttribute() const { |
| 159 int max_width; |
| 160 base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMaxWidth), |
| 161 &max_width); |
| 162 return max_width; |
| 163 } |
| 164 |
| 165 int BrowserPlugin::GetMinHeightAttribute() const { |
| 166 int min_height; |
| 167 base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMinHeight), |
| 168 &min_height); |
| 169 return min_height; |
| 170 } |
| 171 |
| 172 int BrowserPlugin::GetMinWidthAttribute() const { |
| 173 int min_width; |
| 174 base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMinWidth), |
| 175 &min_width); |
| 176 return min_width; |
| 177 } |
| 178 |
| 179 int BrowserPlugin::GetAdjustedMaxHeight() const { |
| 180 int max_height = GetMaxHeightAttribute(); |
| 181 return max_height ? max_height : height(); |
| 182 } |
| 183 |
| 184 int BrowserPlugin::GetAdjustedMaxWidth() const { |
| 185 int max_width = GetMaxWidthAttribute(); |
| 186 return max_width ? max_width : width(); |
| 187 } |
| 188 |
| 189 int BrowserPlugin::GetAdjustedMinHeight() const { |
| 190 int min_height = GetMinHeightAttribute(); |
| 191 // FrameView.cpp does not allow this value to be <= 0, so when the value is |
| 192 // unset (or set to 0), we set it to the container size. |
| 193 min_height = min_height ? min_height : height(); |
| 194 // For autosize, minHeight should not be bigger than maxHeight. |
| 195 return std::min(min_height, GetAdjustedMaxHeight()); |
| 196 } |
| 197 |
| 198 int BrowserPlugin::GetAdjustedMinWidth() const { |
| 199 int min_width = GetMinWidthAttribute(); |
| 200 // FrameView.cpp does not allow this value to be <= 0, so when the value is |
| 201 // unset (or set to 0), we set it to the container size. |
| 202 min_width = min_width ? min_width : width(); |
| 203 // For autosize, minWidth should not be bigger than maxWidth. |
| 204 return std::min(min_width, GetAdjustedMaxWidth()); |
| 205 } |
| 206 |
146 void BrowserPlugin::ParseAllowTransparencyAttribute() { | 207 void BrowserPlugin::ParseAllowTransparencyAttribute() { |
147 if (!HasGuestInstanceID()) | 208 if (!HasGuestInstanceID()) |
148 return; | 209 return; |
149 | 210 |
150 bool opaque = !GetAllowTransparencyAttribute(); | 211 bool opaque = !GetAllowTransparencyAttribute(); |
151 | 212 |
152 if (compositing_helper_) | 213 if (compositing_helper_) |
153 compositing_helper_->SetContentsOpaque(opaque); | 214 compositing_helper_->SetContentsOpaque(opaque); |
154 | 215 |
155 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque( | 216 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque( |
156 render_view_routing_id_, | 217 render_view_routing_id_, |
157 guest_instance_id_, | 218 guest_instance_id_, |
158 opaque)); | 219 opaque)); |
159 } | 220 } |
160 | 221 |
| 222 void BrowserPlugin::ParseAutoSizeAttribute() { |
| 223 last_view_size_ = plugin_size(); |
| 224 is_auto_size_state_dirty_ = true; |
| 225 UpdateGuestAutoSizeState(GetAutoSizeAttribute()); |
| 226 } |
| 227 |
| 228 void BrowserPlugin::PopulateAutoSizeParameters( |
| 229 BrowserPluginHostMsg_AutoSize_Params* params, bool auto_size_enabled) { |
| 230 params->enable = auto_size_enabled; |
| 231 // No need to populate the params if autosize is off. |
| 232 if (auto_size_enabled) { |
| 233 params->max_size = gfx::Size(GetAdjustedMaxWidth(), GetAdjustedMaxHeight()); |
| 234 params->min_size = gfx::Size(GetAdjustedMinWidth(), GetAdjustedMinHeight()); |
| 235 |
| 236 if (max_auto_size_ != params->max_size) |
| 237 is_auto_size_state_dirty_ = true; |
| 238 |
| 239 max_auto_size_ = params->max_size; |
| 240 } else { |
| 241 max_auto_size_ = gfx::Size(); |
| 242 } |
| 243 } |
| 244 |
| 245 void BrowserPlugin::UpdateGuestAutoSizeState(bool auto_size_enabled) { |
| 246 // If we haven't yet heard back from the guest about the last resize request, |
| 247 // then we don't issue another request until we do in |
| 248 // BrowserPlugin::OnUpdateRect. |
| 249 if (!HasGuestInstanceID() || !paint_ack_received_) |
| 250 return; |
| 251 |
| 252 BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
| 253 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; |
| 254 if (auto_size_enabled) { |
| 255 GetSizeParams(&auto_size_params, &resize_guest_params, true); |
| 256 } else { |
| 257 GetSizeParams(NULL, &resize_guest_params, true); |
| 258 } |
| 259 paint_ack_received_ = false; |
| 260 browser_plugin_manager()->Send( |
| 261 new BrowserPluginHostMsg_SetAutoSize(render_view_routing_id_, |
| 262 guest_instance_id_, |
| 263 auto_size_params, |
| 264 resize_guest_params)); |
| 265 } |
| 266 |
161 void BrowserPlugin::Attach(int guest_instance_id, | 267 void BrowserPlugin::Attach(int guest_instance_id, |
162 scoped_ptr<base::DictionaryValue> extra_params) { | 268 scoped_ptr<base::DictionaryValue> extra_params) { |
163 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); | 269 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); |
164 | 270 |
165 // If this BrowserPlugin is already attached to a guest, then kill the guest. | 271 // If this BrowserPlugin is already attached to a guest, then kill the guest. |
166 if (HasGuestInstanceID()) { | 272 if (HasGuestInstanceID()) { |
167 if (guest_instance_id == guest_instance_id_) | 273 if (guest_instance_id == guest_instance_id_) |
168 return; | 274 return; |
169 guest_crashed_ = false; | 275 guest_crashed_ = false; |
170 EnableCompositing(false); | 276 EnableCompositing(false); |
171 if (compositing_helper_) { | 277 if (compositing_helper_) { |
172 compositing_helper_->OnContainerDestroy(); | 278 compositing_helper_->OnContainerDestroy(); |
173 compositing_helper_ = NULL; | 279 compositing_helper_ = NULL; |
174 } | 280 } |
175 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); | 281 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); |
176 browser_plugin_manager()->Send(new BrowserPluginHostMsg_PluginDestroyed( | 282 browser_plugin_manager()->Send(new BrowserPluginHostMsg_PluginDestroyed( |
177 render_view_routing_id_, guest_instance_id_)); | 283 render_view_routing_id_, guest_instance_id_)); |
178 } | 284 } |
179 | 285 |
180 // This API may be called directly without setting the src attribute. | 286 // This API may be called directly without setting the src attribute. |
181 // In that case, we need to make sure we don't allocate another instance ID. | 287 // In that case, we need to make sure we don't allocate another instance ID. |
182 guest_instance_id_ = guest_instance_id; | 288 guest_instance_id_ = guest_instance_id; |
183 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); | 289 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); |
184 | 290 |
185 BrowserPluginHostMsg_Attach_Params attach_params; | 291 BrowserPluginHostMsg_Attach_Params attach_params; |
186 attach_params.focused = ShouldGuestBeFocused(); | 292 attach_params.focused = ShouldGuestBeFocused(); |
187 attach_params.visible = visible_; | 293 attach_params.visible = visible_; |
188 attach_params.opaque = !GetAllowTransparencyAttribute(); | 294 attach_params.opaque = !GetAllowTransparencyAttribute(); |
189 attach_params.origin = plugin_rect().origin(); | 295 attach_params.origin = plugin_rect().origin(); |
190 GetSizeParams(&attach_params.resize_guest_params, false); | 296 GetSizeParams(&attach_params.auto_size_params, |
| 297 &attach_params.resize_guest_params, |
| 298 false); |
191 | 299 |
192 browser_plugin_manager()->Send( | 300 browser_plugin_manager()->Send( |
193 new BrowserPluginHostMsg_Attach(render_view_routing_id_, | 301 new BrowserPluginHostMsg_Attach(render_view_routing_id_, |
194 guest_instance_id_, attach_params, | 302 guest_instance_id_, attach_params, |
195 *extra_params)); | 303 *extra_params)); |
196 } | 304 } |
197 | 305 |
198 void BrowserPlugin::DidCommitCompositorFrame() { | 306 void BrowserPlugin::DidCommitCompositorFrame() { |
199 if (compositing_helper_.get()) | 307 if (compositing_helper_.get()) |
200 compositing_helper_->DidCommitCompositorFrame(); | 308 compositing_helper_->DidCommitCompositorFrame(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 } | 413 } |
306 } | 414 } |
307 | 415 |
308 void BrowserPlugin::OnUpdateRect( | 416 void BrowserPlugin::OnUpdateRect( |
309 int guest_instance_id, | 417 int guest_instance_id, |
310 const BrowserPluginMsg_UpdateRect_Params& params) { | 418 const BrowserPluginMsg_UpdateRect_Params& params) { |
311 // Note that there is no need to send ACK for this message. | 419 // Note that there is no need to send ACK for this message. |
312 // If the guest has updated pixels then it is no longer crashed. | 420 // If the guest has updated pixels then it is no longer crashed. |
313 guest_crashed_ = false; | 421 guest_crashed_ = false; |
314 | 422 |
| 423 bool auto_size = GetAutoSizeAttribute(); |
315 // We receive a resize ACK in regular mode, but not in autosize. | 424 // We receive a resize ACK in regular mode, but not in autosize. |
316 // In Compositing mode, we need to do it here so we can continue sending | 425 // In Compositing mode, we need to do it here so we can continue sending |
317 // resize messages when needed. | 426 // resize messages when needed. |
318 if (params.is_resize_ack) | 427 if (params.is_resize_ack || (auto_size || is_auto_size_state_dirty_)) |
319 paint_ack_received_ = true; | 428 paint_ack_received_ = true; |
320 | 429 |
321 if (params.view_size.width() == width() && | 430 bool was_auto_size_state_dirty = auto_size && is_auto_size_state_dirty_; |
322 params.view_size.height() == height()) { | 431 is_auto_size_state_dirty_ = false; |
| 432 |
| 433 if ((!auto_size && (width() != params.view_size.width() || |
| 434 height() != params.view_size.height())) || |
| 435 (auto_size && was_auto_size_state_dirty) || |
| 436 GetDeviceScaleFactor() != params.scale_factor) { |
| 437 UpdateGuestAutoSizeState(auto_size); |
323 return; | 438 return; |
324 } | 439 } |
325 | 440 |
326 BrowserPluginHostMsg_ResizeGuest_Params resize_params; | 441 if (auto_size && (params.view_size != last_view_size_)) |
327 PopulateResizeGuestParameters(&resize_params, plugin_size(), false); | 442 last_view_size_ = params.view_size; |
328 paint_ack_received_ = false; | 443 |
329 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( | 444 BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
330 render_view_routing_id_, | 445 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; |
331 guest_instance_id_, | 446 |
332 resize_params)); | 447 // BrowserPluginHostMsg_UpdateRect_ACK is used by both the compositing and |
| 448 // software paths to piggyback updated autosize parameters. |
| 449 if (auto_size) |
| 450 PopulateAutoSizeParameters(&auto_size_params, auto_size); |
| 451 |
| 452 browser_plugin_manager()->Send( |
| 453 new BrowserPluginHostMsg_SetAutoSize(render_view_routing_id_, |
| 454 guest_instance_id_, |
| 455 auto_size_params, |
| 456 resize_guest_params)); |
| 457 } |
| 458 |
| 459 void BrowserPlugin::ParseSizeContraintsChanged() { |
| 460 bool auto_size = GetAutoSizeAttribute(); |
| 461 if (auto_size) { |
| 462 is_auto_size_state_dirty_ = true; |
| 463 UpdateGuestAutoSizeState(true); |
| 464 } |
| 465 } |
| 466 |
| 467 bool BrowserPlugin::InAutoSizeBounds(const gfx::Size& size) const { |
| 468 return size.width() <= GetAdjustedMaxWidth() && |
| 469 size.height() <= GetAdjustedMaxHeight(); |
333 } | 470 } |
334 | 471 |
335 NPObject* BrowserPlugin::GetContentWindow() const { | 472 NPObject* BrowserPlugin::GetContentWindow() const { |
336 if (content_window_routing_id_ == MSG_ROUTING_NONE) | 473 if (content_window_routing_id_ == MSG_ROUTING_NONE) |
337 return NULL; | 474 return NULL; |
338 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID( | 475 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID( |
339 content_window_routing_id_); | 476 content_window_routing_id_); |
340 if (!guest_render_view) | 477 if (!guest_render_view) |
341 return NULL; | 478 return NULL; |
342 blink::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame(); | 479 blink::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame(); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 if (!attached()) | 677 if (!attached()) |
541 return; | 678 return; |
542 | 679 |
543 // In AutoSize mode, guests don't care when the BrowserPlugin container is | 680 // In AutoSize mode, guests don't care when the BrowserPlugin container is |
544 // resized. If |!paint_ack_received_|, then we are still waiting on a | 681 // resized. If |!paint_ack_received_|, then we are still waiting on a |
545 // previous resize to be ACK'ed and so we don't issue additional resizes | 682 // previous resize to be ACK'ed and so we don't issue additional resizes |
546 // until the previous one is ACK'ed. | 683 // until the previous one is ACK'ed. |
547 // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on | 684 // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on |
548 // resize. | 685 // resize. |
549 if (!paint_ack_received_ || | 686 if (!paint_ack_received_ || |
550 (old_width == window_rect.width && old_height == window_rect.height)) { | 687 (old_width == window_rect.width && old_height == window_rect.height) || |
| 688 GetAutoSizeAttribute()) { |
551 // Let the browser know about the updated view rect. | 689 // Let the browser know about the updated view rect. |
552 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry( | 690 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry( |
553 render_view_routing_id_, guest_instance_id_, plugin_rect_)); | 691 render_view_routing_id_, guest_instance_id_, plugin_rect_)); |
554 return; | 692 return; |
555 } | 693 } |
556 | 694 |
557 BrowserPluginHostMsg_ResizeGuest_Params params; | 695 BrowserPluginHostMsg_ResizeGuest_Params params; |
558 PopulateResizeGuestParameters(¶ms, plugin_size(), false); | 696 PopulateResizeGuestParameters(¶ms, plugin_size(), false); |
559 paint_ack_received_ = false; | 697 paint_ack_received_ = false; |
560 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( | 698 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( |
561 render_view_routing_id_, | 699 render_view_routing_id_, |
562 guest_instance_id_, | 700 guest_instance_id_, |
563 params)); | 701 params)); |
564 } | 702 } |
565 | 703 |
566 void BrowserPlugin::PopulateResizeGuestParameters( | 704 void BrowserPlugin::PopulateResizeGuestParameters( |
567 BrowserPluginHostMsg_ResizeGuest_Params* params, | 705 BrowserPluginHostMsg_ResizeGuest_Params* params, |
568 const gfx::Size& view_size, | 706 const gfx::Size& view_size, |
569 bool needs_repaint) { | 707 bool needs_repaint) { |
570 params->size_changed = true; | 708 params->size_changed = true; |
571 params->view_size = view_size; | 709 params->view_size = view_size; |
572 params->repaint = needs_repaint; | 710 params->repaint = needs_repaint; |
573 params->scale_factor = GetDeviceScaleFactor(); | 711 params->scale_factor = GetDeviceScaleFactor(); |
574 if (last_device_scale_factor_ != params->scale_factor) { | 712 if (last_device_scale_factor_ != params->scale_factor){ |
575 DCHECK(params->repaint); | 713 DCHECK(params->repaint); |
576 last_device_scale_factor_ = params->scale_factor; | 714 last_device_scale_factor_ = params->scale_factor; |
577 } | 715 } |
578 } | 716 } |
579 | 717 |
580 void BrowserPlugin::GetSizeParams( | 718 void BrowserPlugin::GetSizeParams( |
| 719 BrowserPluginHostMsg_AutoSize_Params* auto_size_params, |
581 BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params, | 720 BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params, |
582 bool needs_repaint) { | 721 bool needs_repaint) { |
583 gfx::Size view_size(width(), height()); | 722 if (auto_size_params) { |
| 723 PopulateAutoSizeParameters(auto_size_params, GetAutoSizeAttribute()); |
| 724 } else { |
| 725 max_auto_size_ = gfx::Size(); |
| 726 } |
| 727 gfx::Size view_size = (auto_size_params && auto_size_params->enable) ? |
| 728 auto_size_params->max_size : gfx::Size(width(), height()); |
584 if (view_size.IsEmpty()) | 729 if (view_size.IsEmpty()) |
585 return; | 730 return; |
586 paint_ack_received_ = false; | 731 paint_ack_received_ = false; |
587 PopulateResizeGuestParameters(resize_guest_params, view_size, needs_repaint); | 732 PopulateResizeGuestParameters(resize_guest_params, view_size, needs_repaint); |
588 } | 733 } |
589 | 734 |
590 void BrowserPlugin::updateFocus(bool focused) { | 735 void BrowserPlugin::updateFocus(bool focused) { |
591 plugin_focused_ = focused; | 736 plugin_focused_ = focused; |
592 UpdateGuestFocusState(); | 737 UpdateGuestFocusState(); |
593 } | 738 } |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 const blink::WebMouseEvent& event) { | 961 const blink::WebMouseEvent& event) { |
817 browser_plugin_manager()->Send( | 962 browser_plugin_manager()->Send( |
818 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, | 963 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, |
819 guest_instance_id_, | 964 guest_instance_id_, |
820 plugin_rect_, | 965 plugin_rect_, |
821 &event)); | 966 &event)); |
822 return true; | 967 return true; |
823 } | 968 } |
824 | 969 |
825 } // namespace content | 970 } // namespace content |
OLD | NEW |