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), | |
58 content_window_routing_id_(MSG_ROUTING_NONE), | 57 content_window_routing_id_(MSG_ROUTING_NONE), |
59 plugin_focused_(false), | 58 plugin_focused_(false), |
60 visible_(true), | 59 visible_(true), |
61 auto_navigate_(auto_navigate), | 60 auto_navigate_(auto_navigate), |
62 mouse_locked_(false), | 61 mouse_locked_(false), |
63 browser_plugin_manager_(render_view->GetBrowserPluginManager()), | 62 browser_plugin_manager_(render_view->GetBrowserPluginManager()), |
64 weak_ptr_factory_(this) { | 63 weak_ptr_factory_(this) { |
65 } | 64 } |
66 | 65 |
67 BrowserPlugin::~BrowserPlugin() { | 66 BrowserPlugin::~BrowserPlugin() { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 return false; | 136 return false; |
138 | 137 |
139 return container()->element().hasAttribute( | 138 return container()->element().hasAttribute( |
140 blink::WebString::fromUTF8(attribute_name)); | 139 blink::WebString::fromUTF8(attribute_name)); |
141 } | 140 } |
142 | 141 |
143 bool BrowserPlugin::GetAllowTransparencyAttribute() const { | 142 bool BrowserPlugin::GetAllowTransparencyAttribute() const { |
144 return HasDOMAttribute(browser_plugin::kAttributeAllowTransparency); | 143 return HasDOMAttribute(browser_plugin::kAttributeAllowTransparency); |
145 } | 144 } |
146 | 145 |
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 | |
207 void BrowserPlugin::ParseAllowTransparencyAttribute() { | 146 void BrowserPlugin::ParseAllowTransparencyAttribute() { |
208 if (!HasGuestInstanceID()) | 147 if (!HasGuestInstanceID()) |
209 return; | 148 return; |
210 | 149 |
211 bool opaque = !GetAllowTransparencyAttribute(); | 150 bool opaque = !GetAllowTransparencyAttribute(); |
212 | 151 |
213 if (compositing_helper_) | 152 if (compositing_helper_) |
214 compositing_helper_->SetContentsOpaque(opaque); | 153 compositing_helper_->SetContentsOpaque(opaque); |
215 | 154 |
216 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque( | 155 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque( |
217 render_view_routing_id_, | 156 render_view_routing_id_, |
218 guest_instance_id_, | 157 guest_instance_id_, |
219 opaque)); | 158 opaque)); |
220 } | 159 } |
221 | 160 |
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 | |
267 void BrowserPlugin::Attach(int guest_instance_id, | 161 void BrowserPlugin::Attach(int guest_instance_id, |
268 scoped_ptr<base::DictionaryValue> extra_params) { | 162 scoped_ptr<base::DictionaryValue> extra_params) { |
269 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); | 163 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); |
270 | 164 |
271 // If this BrowserPlugin is already attached to a guest, then kill the guest. | 165 // If this BrowserPlugin is already attached to a guest, then kill the guest. |
272 if (HasGuestInstanceID()) { | 166 if (HasGuestInstanceID()) { |
273 if (guest_instance_id == guest_instance_id_) | 167 if (guest_instance_id == guest_instance_id_) |
274 return; | 168 return; |
275 guest_crashed_ = false; | 169 guest_crashed_ = false; |
276 EnableCompositing(false); | 170 EnableCompositing(false); |
277 if (compositing_helper_) { | 171 if (compositing_helper_) { |
278 compositing_helper_->OnContainerDestroy(); | 172 compositing_helper_->OnContainerDestroy(); |
279 compositing_helper_ = NULL; | 173 compositing_helper_ = NULL; |
280 } | 174 } |
281 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); | 175 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); |
282 browser_plugin_manager()->Send(new BrowserPluginHostMsg_PluginDestroyed( | 176 browser_plugin_manager()->Send(new BrowserPluginHostMsg_PluginDestroyed( |
283 render_view_routing_id_, guest_instance_id_)); | 177 render_view_routing_id_, guest_instance_id_)); |
284 } | 178 } |
285 | 179 |
286 // This API may be called directly without setting the src attribute. | 180 // This API may be called directly without setting the src attribute. |
287 // In that case, we need to make sure we don't allocate another instance ID. | 181 // In that case, we need to make sure we don't allocate another instance ID. |
288 guest_instance_id_ = guest_instance_id; | 182 guest_instance_id_ = guest_instance_id; |
289 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); | 183 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); |
290 | 184 |
291 BrowserPluginHostMsg_Attach_Params attach_params; | 185 BrowserPluginHostMsg_Attach_Params attach_params; |
292 attach_params.focused = ShouldGuestBeFocused(); | 186 attach_params.focused = ShouldGuestBeFocused(); |
293 attach_params.visible = visible_; | 187 attach_params.visible = visible_; |
294 attach_params.opaque = !GetAllowTransparencyAttribute(); | 188 attach_params.opaque = !GetAllowTransparencyAttribute(); |
295 attach_params.origin = plugin_rect().origin(); | 189 attach_params.origin = plugin_rect().origin(); |
296 GetSizeParams(&attach_params.auto_size_params, | 190 GetSizeParams(&attach_params.resize_guest_params, false); |
297 &attach_params.resize_guest_params, | |
298 false); | |
299 | 191 |
300 browser_plugin_manager()->Send( | 192 browser_plugin_manager()->Send( |
301 new BrowserPluginHostMsg_Attach(render_view_routing_id_, | 193 new BrowserPluginHostMsg_Attach(render_view_routing_id_, |
302 guest_instance_id_, attach_params, | 194 guest_instance_id_, attach_params, |
303 *extra_params)); | 195 *extra_params)); |
304 } | 196 } |
305 | 197 |
306 void BrowserPlugin::DidCommitCompositorFrame() { | 198 void BrowserPlugin::DidCommitCompositorFrame() { |
307 if (compositing_helper_.get()) | 199 if (compositing_helper_.get()) |
308 compositing_helper_->DidCommitCompositorFrame(); | 200 compositing_helper_->DidCommitCompositorFrame(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 } | 305 } |
414 } | 306 } |
415 | 307 |
416 void BrowserPlugin::OnUpdateRect( | 308 void BrowserPlugin::OnUpdateRect( |
417 int guest_instance_id, | 309 int guest_instance_id, |
418 const BrowserPluginMsg_UpdateRect_Params& params) { | 310 const BrowserPluginMsg_UpdateRect_Params& params) { |
419 // Note that there is no need to send ACK for this message. | 311 // Note that there is no need to send ACK for this message. |
420 // If the guest has updated pixels then it is no longer crashed. | 312 // If the guest has updated pixels then it is no longer crashed. |
421 guest_crashed_ = false; | 313 guest_crashed_ = false; |
422 | 314 |
423 bool auto_size = GetAutoSizeAttribute(); | |
424 // We receive a resize ACK in regular mode, but not in autosize. | 315 // We receive a resize ACK in regular mode, but not in autosize. |
425 // In Compositing mode, we need to do it here so we can continue sending | 316 // In Compositing mode, we need to do it here so we can continue sending |
426 // resize messages when needed. | 317 // resize messages when needed. |
427 if (params.is_resize_ack || (auto_size || is_auto_size_state_dirty_)) | 318 if (params.is_resize_ack) |
428 paint_ack_received_ = true; | 319 paint_ack_received_ = true; |
429 | 320 |
430 bool was_auto_size_state_dirty = auto_size && is_auto_size_state_dirty_; | 321 if (params.view_size.width() == width() && |
431 is_auto_size_state_dirty_ = false; | 322 params.view_size.height() == height()) { |
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); | |
438 return; | 323 return; |
439 } | 324 } |
440 | 325 |
441 if (auto_size && (params.view_size != last_view_size_)) | 326 BrowserPluginHostMsg_ResizeGuest_Params resize_params; |
442 last_view_size_ = params.view_size; | 327 PopulateResizeGuestParameters(&resize_params, plugin_size(), false); |
443 | 328 paint_ack_received_ = false; |
444 BrowserPluginHostMsg_AutoSize_Params auto_size_params; | 329 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( |
445 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; | 330 render_view_routing_id_, |
446 | 331 guest_instance_id_, |
447 // BrowserPluginHostMsg_UpdateRect_ACK is used by both the compositing and | 332 resize_params)); |
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(); | |
470 } | 333 } |
471 | 334 |
472 NPObject* BrowserPlugin::GetContentWindow() const { | 335 NPObject* BrowserPlugin::GetContentWindow() const { |
473 if (content_window_routing_id_ == MSG_ROUTING_NONE) | 336 if (content_window_routing_id_ == MSG_ROUTING_NONE) |
474 return NULL; | 337 return NULL; |
475 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID( | 338 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID( |
476 content_window_routing_id_); | 339 content_window_routing_id_); |
477 if (!guest_render_view) | 340 if (!guest_render_view) |
478 return NULL; | 341 return NULL; |
479 blink::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame(); | 342 blink::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame(); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 if (!attached()) | 540 if (!attached()) |
678 return; | 541 return; |
679 | 542 |
680 // In AutoSize mode, guests don't care when the BrowserPlugin container is | 543 // In AutoSize mode, guests don't care when the BrowserPlugin container is |
681 // resized. If |!paint_ack_received_|, then we are still waiting on a | 544 // resized. If |!paint_ack_received_|, then we are still waiting on a |
682 // previous resize to be ACK'ed and so we don't issue additional resizes | 545 // previous resize to be ACK'ed and so we don't issue additional resizes |
683 // until the previous one is ACK'ed. | 546 // until the previous one is ACK'ed. |
684 // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on | 547 // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on |
685 // resize. | 548 // resize. |
686 if (!paint_ack_received_ || | 549 if (!paint_ack_received_ || |
687 (old_width == window_rect.width && old_height == window_rect.height) || | 550 (old_width == window_rect.width && old_height == window_rect.height)) { |
688 GetAutoSizeAttribute()) { | |
689 // Let the browser know about the updated view rect. | 551 // Let the browser know about the updated view rect. |
690 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry( | 552 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry( |
691 render_view_routing_id_, guest_instance_id_, plugin_rect_)); | 553 render_view_routing_id_, guest_instance_id_, plugin_rect_)); |
692 return; | 554 return; |
693 } | 555 } |
694 | 556 |
695 BrowserPluginHostMsg_ResizeGuest_Params params; | 557 BrowserPluginHostMsg_ResizeGuest_Params params; |
696 PopulateResizeGuestParameters(¶ms, plugin_size(), false); | 558 PopulateResizeGuestParameters(¶ms, plugin_size(), false); |
697 paint_ack_received_ = false; | 559 paint_ack_received_ = false; |
698 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( | 560 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( |
699 render_view_routing_id_, | 561 render_view_routing_id_, |
700 guest_instance_id_, | 562 guest_instance_id_, |
701 params)); | 563 params)); |
702 } | 564 } |
703 | 565 |
704 void BrowserPlugin::PopulateResizeGuestParameters( | 566 void BrowserPlugin::PopulateResizeGuestParameters( |
705 BrowserPluginHostMsg_ResizeGuest_Params* params, | 567 BrowserPluginHostMsg_ResizeGuest_Params* params, |
706 const gfx::Size& view_size, | 568 const gfx::Size& view_size, |
707 bool needs_repaint) { | 569 bool needs_repaint) { |
708 params->size_changed = true; | 570 params->size_changed = true; |
709 params->view_size = view_size; | 571 params->view_size = view_size; |
710 params->repaint = needs_repaint; | 572 params->repaint = needs_repaint; |
711 params->scale_factor = GetDeviceScaleFactor(); | 573 params->scale_factor = GetDeviceScaleFactor(); |
712 if (last_device_scale_factor_ != params->scale_factor){ | 574 if (last_device_scale_factor_ != params->scale_factor) { |
713 DCHECK(params->repaint); | 575 DCHECK(params->repaint); |
714 last_device_scale_factor_ = params->scale_factor; | 576 last_device_scale_factor_ = params->scale_factor; |
715 } | 577 } |
716 } | 578 } |
717 | 579 |
718 void BrowserPlugin::GetSizeParams( | 580 void BrowserPlugin::GetSizeParams( |
719 BrowserPluginHostMsg_AutoSize_Params* auto_size_params, | |
720 BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params, | 581 BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params, |
721 bool needs_repaint) { | 582 bool needs_repaint) { |
722 if (auto_size_params) { | 583 gfx::Size view_size(width(), height()); |
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()); | |
729 if (view_size.IsEmpty()) | 584 if (view_size.IsEmpty()) |
730 return; | 585 return; |
731 paint_ack_received_ = false; | 586 paint_ack_received_ = false; |
732 PopulateResizeGuestParameters(resize_guest_params, view_size, needs_repaint); | 587 PopulateResizeGuestParameters(resize_guest_params, view_size, needs_repaint); |
733 } | 588 } |
734 | 589 |
735 void BrowserPlugin::updateFocus(bool focused) { | 590 void BrowserPlugin::updateFocus(bool focused) { |
736 plugin_focused_ = focused; | 591 plugin_focused_ = focused; |
737 UpdateGuestFocusState(); | 592 UpdateGuestFocusState(); |
738 } | 593 } |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 const blink::WebMouseEvent& event) { | 816 const blink::WebMouseEvent& event) { |
962 browser_plugin_manager()->Send( | 817 browser_plugin_manager()->Send( |
963 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, | 818 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, |
964 guest_instance_id_, | 819 guest_instance_id_, |
965 plugin_rect_, | 820 plugin_rect_, |
966 &event)); | 821 &event)); |
967 return true; | 822 return true; |
968 } | 823 } |
969 | 824 |
970 } // namespace content | 825 } // namespace content |
OLD | NEW |