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 22 matching lines...) Expand all Loading... |
33 #include "ui/events/keycodes/keyboard_codes.h" | 33 #include "ui/events/keycodes/keyboard_codes.h" |
34 | 34 |
35 using blink::WebCanvas; | 35 using blink::WebCanvas; |
36 using blink::WebPluginContainer; | 36 using blink::WebPluginContainer; |
37 using blink::WebPluginParams; | 37 using blink::WebPluginParams; |
38 using blink::WebPoint; | 38 using blink::WebPoint; |
39 using blink::WebRect; | 39 using blink::WebRect; |
40 using blink::WebURL; | 40 using blink::WebURL; |
41 using blink::WebVector; | 41 using blink::WebVector; |
42 | 42 |
| 43 namespace { |
| 44 typedef std::map<blink::WebPluginContainer*, content::BrowserPlugin*> |
| 45 PluginContainerMap; |
| 46 static base::LazyInstance<PluginContainerMap> g_plugin_container_map = |
| 47 LAZY_INSTANCE_INITIALIZER; |
| 48 |
| 49 } // namespace |
| 50 |
43 namespace content { | 51 namespace content { |
44 | 52 |
45 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view, | 53 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view, |
46 blink::WebFrame* frame, | 54 blink::WebFrame* frame, |
47 bool auto_navigate) | 55 bool auto_navigate) |
48 : guest_instance_id_(browser_plugin::kInstanceIDNone), | 56 : guest_instance_id_(browser_plugin::kInstanceIDNone), |
49 attached_(false), | 57 attached_(false), |
50 render_view_(render_view->AsWeakPtr()), | 58 render_view_(render_view->AsWeakPtr()), |
51 render_view_routing_id_(render_view->GetRoutingID()), | 59 render_view_routing_id_(render_view->GetRoutingID()), |
52 container_(NULL), | 60 container_(NULL), |
53 paint_ack_received_(true), | 61 paint_ack_received_(true), |
54 last_device_scale_factor_(GetDeviceScaleFactor()), | 62 last_device_scale_factor_(GetDeviceScaleFactor()), |
55 sad_guest_(NULL), | 63 sad_guest_(NULL), |
56 guest_crashed_(false), | 64 guest_crashed_(false), |
57 content_window_routing_id_(MSG_ROUTING_NONE), | 65 content_window_routing_id_(MSG_ROUTING_NONE), |
58 plugin_focused_(false), | 66 plugin_focused_(false), |
59 visible_(true), | 67 visible_(true), |
60 auto_navigate_(auto_navigate), | 68 auto_navigate_(auto_navigate), |
61 mouse_locked_(false), | 69 mouse_locked_(false), |
62 browser_plugin_manager_(render_view->GetBrowserPluginManager()), | 70 browser_plugin_manager_(render_view->GetBrowserPluginManager()), |
63 weak_ptr_factory_(this) { | 71 weak_ptr_factory_(this) { |
64 } | 72 } |
65 | 73 |
66 BrowserPlugin::~BrowserPlugin() { | 74 BrowserPlugin::~BrowserPlugin() { |
| 75 browser_plugin_manager()->RemoveBrowserPluginInternal( |
| 76 browser_plugin_instance_id_); |
67 // If the BrowserPlugin has never navigated then the browser process and | 77 // If the BrowserPlugin has never navigated then the browser process and |
68 // BrowserPluginManager don't know about it and so there is nothing to do | 78 // BrowserPluginManager don't know about it and so there is nothing to do |
69 // here. | 79 // here. |
70 if (!HasGuestInstanceID()) | 80 if (!HasGuestInstanceID()) |
71 return; | 81 return; |
72 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); | 82 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); |
73 browser_plugin_manager()->Send( | 83 browser_plugin_manager()->Send( |
74 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_, | 84 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_, |
75 guest_instance_id_)); | 85 guest_instance_id_)); |
76 } | 86 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 | 161 |
152 if (compositing_helper_) | 162 if (compositing_helper_) |
153 compositing_helper_->SetContentsOpaque(opaque); | 163 compositing_helper_->SetContentsOpaque(opaque); |
154 | 164 |
155 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque( | 165 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque( |
156 render_view_routing_id_, | 166 render_view_routing_id_, |
157 guest_instance_id_, | 167 guest_instance_id_, |
158 opaque)); | 168 opaque)); |
159 } | 169 } |
160 | 170 |
161 void BrowserPlugin::Attach(int guest_instance_id, | 171 void BrowserPlugin::Attach(int guest_instance_id) { |
162 scoped_ptr<base::DictionaryValue> extra_params) { | 172 CHECK_NE(browser_plugin::kInstanceIDNone, guest_instance_id); |
163 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); | |
164 | |
165 // If this BrowserPlugin is already attached to a guest, then kill the guest. | 173 // If this BrowserPlugin is already attached to a guest, then kill the guest. |
166 if (HasGuestInstanceID()) { | 174 if (HasGuestInstanceID()) { |
167 if (guest_instance_id == guest_instance_id_) | 175 if (guest_instance_id == guest_instance_id_) |
168 return; | 176 return; |
169 guest_crashed_ = false; | 177 guest_crashed_ = false; |
170 EnableCompositing(false); | 178 EnableCompositing(false); |
171 if (compositing_helper_) { | 179 if (compositing_helper_) { |
172 compositing_helper_->OnContainerDestroy(); | 180 compositing_helper_->OnContainerDestroy(); |
173 compositing_helper_ = NULL; | 181 compositing_helper_ = NULL; |
174 } | 182 } |
175 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); | 183 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); |
176 browser_plugin_manager()->Send(new BrowserPluginHostMsg_PluginDestroyed( | 184 browser_plugin_manager()->Send(new BrowserPluginHostMsg_PluginDestroyed( |
177 render_view_routing_id_, guest_instance_id_)); | 185 render_view_routing_id_, guest_instance_id_)); |
178 } | 186 } |
179 | 187 |
180 // 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. | |
182 guest_instance_id_ = guest_instance_id; | 188 guest_instance_id_ = guest_instance_id; |
183 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); | 189 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); |
184 | 190 |
185 BrowserPluginHostMsg_Attach_Params attach_params; | 191 BrowserPluginHostMsg_Attach_Params attach_params; |
186 attach_params.focused = ShouldGuestBeFocused(); | 192 attach_params.focused = ShouldGuestBeFocused(); |
187 attach_params.visible = visible_; | 193 attach_params.visible = visible_; |
188 attach_params.opaque = !GetAllowTransparencyAttribute(); | 194 attach_params.opaque = !GetAllowTransparencyAttribute(); |
189 attach_params.origin = plugin_rect().origin(); | 195 attach_params.origin = plugin_rect().origin(); |
190 GetSizeParams(&attach_params.resize_guest_params, false); | 196 GetSizeParams(&attach_params.resize_guest_params, false); |
191 | 197 |
192 browser_plugin_manager()->Send( | 198 browser_plugin_manager()->Send(new BrowserPluginHostMsg_Attach( |
193 new BrowserPluginHostMsg_Attach(render_view_routing_id_, | 199 render_view_routing_id_, |
194 guest_instance_id_, attach_params, | 200 browser_plugin_instance_id_, |
195 *extra_params)); | 201 attach_params)); |
196 } | 202 } |
197 | 203 |
198 void BrowserPlugin::DidCommitCompositorFrame() { | 204 void BrowserPlugin::DidCommitCompositorFrame() { |
199 if (compositing_helper_.get()) | 205 if (compositing_helper_.get()) |
200 compositing_helper_->DidCommitCompositorFrame(); | 206 compositing_helper_->DidCommitCompositorFrame(); |
201 } | 207 } |
202 | 208 |
203 void BrowserPlugin::OnAdvanceFocus(int guest_instance_id, bool reverse) { | 209 void BrowserPlugin::OnAdvanceFocus(int guest_instance_id, bool reverse) { |
204 DCHECK(render_view_.get()); | 210 DCHECK(render_view_.get()); |
205 render_view_->GetWebView()->advanceFocus(reverse); | 211 render_view_->GetWebView()->advanceFocus(reverse); |
206 } | 212 } |
207 | 213 |
208 void BrowserPlugin::OnAttachACK(int guest_instance_id) { | 214 void BrowserPlugin::OnAttachACK(int guest_instance_id) { |
| 215 DCHECK(!attached()); |
209 attached_ = true; | 216 attached_ = true; |
210 } | 217 } |
211 | 218 |
212 void BrowserPlugin::OnBuffersSwapped( | 219 void BrowserPlugin::OnBuffersSwapped( |
213 int instance_id, | 220 int instance_id, |
214 const FrameMsg_BuffersSwapped_Params& params) { | 221 const FrameMsg_BuffersSwapped_Params& params) { |
215 EnableCompositing(true); | 222 EnableCompositing(true); |
216 | 223 |
217 compositing_helper_->OnBuffersSwapped(params.size, | 224 compositing_helper_->OnBuffersSwapped(params.size, |
218 params.mailbox, | 225 params.mailbox, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 OnLockMouseACK(false); | 299 OnLockMouseACK(false); |
293 return; | 300 return; |
294 } | 301 } |
295 render_view_->mouse_lock_dispatcher()->UnlockMouse(this); | 302 render_view_->mouse_lock_dispatcher()->UnlockMouse(this); |
296 } | 303 } |
297 } | 304 } |
298 | 305 |
299 void BrowserPlugin::OnShouldAcceptTouchEvents(int guest_instance_id, | 306 void BrowserPlugin::OnShouldAcceptTouchEvents(int guest_instance_id, |
300 bool accept) { | 307 bool accept) { |
301 if (container()) { | 308 if (container()) { |
302 container()->requestTouchEventType(accept ? | 309 container()->requestTouchEventType( |
303 blink::WebPluginContainer::TouchEventRequestTypeRaw : | 310 accept ? WebPluginContainer::TouchEventRequestTypeRaw |
304 blink::WebPluginContainer::TouchEventRequestTypeNone); | 311 : WebPluginContainer::TouchEventRequestTypeNone); |
305 } | 312 } |
306 } | 313 } |
307 | 314 |
308 void BrowserPlugin::OnUpdateRect( | 315 void BrowserPlugin::OnUpdateRect( |
309 int guest_instance_id, | 316 int guest_instance_id, |
310 const BrowserPluginMsg_UpdateRect_Params& params) { | 317 const BrowserPluginMsg_UpdateRect_Params& params) { |
311 // Note that there is no need to send ACK for this message. | 318 // 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. | 319 // If the guest has updated pixels then it is no longer crashed. |
313 guest_crashed_ = false; | 320 guest_crashed_ = false; |
314 | 321 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 should_be_focused)); | 389 should_be_focused)); |
383 } | 390 } |
384 | 391 |
385 bool BrowserPlugin::ShouldGuestBeFocused() const { | 392 bool BrowserPlugin::ShouldGuestBeFocused() const { |
386 bool embedder_focused = false; | 393 bool embedder_focused = false; |
387 if (render_view_.get()) | 394 if (render_view_.get()) |
388 embedder_focused = render_view_->has_focus(); | 395 embedder_focused = render_view_->has_focus(); |
389 return plugin_focused_ && embedder_focused; | 396 return plugin_focused_ && embedder_focused; |
390 } | 397 } |
391 | 398 |
392 blink::WebPluginContainer* BrowserPlugin::container() const { | 399 WebPluginContainer* BrowserPlugin::container() const { |
393 return container_; | 400 return container_; |
394 } | 401 } |
395 | 402 |
396 bool BrowserPlugin::initialize(WebPluginContainer* container) { | 403 bool BrowserPlugin::initialize(WebPluginContainer* container) { |
397 if (!container) | 404 if (!container) |
398 return false; | 405 return false; |
399 | 406 |
400 // Tell |container| to allow this plugin to use script objects. | 407 // Tell |container| to allow this plugin to use script objects. |
401 npp_.reset(new NPP_t); | 408 npp_.reset(new NPP_t); |
402 container->allowScriptObjects(); | 409 container->allowScriptObjects(); |
403 | 410 |
404 bindings_.reset(new BrowserPluginBindings(this)); | 411 bindings_.reset(new BrowserPluginBindings(this)); |
405 container_ = container; | 412 container_ = container; |
406 container_->setWantsWheelEvents(true); | 413 container_->setWantsWheelEvents(true); |
407 // This is a way to notify observers of our attributes that we have the | 414 |
408 // bindings ready. This also means that this plugin is available in render | 415 g_plugin_container_map.Get().insert(std::make_pair(container_, this)); |
409 // tree. | 416 |
410 UpdateDOMAttribute("internalbindings", "true"); | 417 // This is a way to notify observers of our attributes that this plugin is |
| 418 // available in render tree. |
| 419 browser_plugin_instance_id_ = browser_plugin_manager()->GetNextInstanceID(); |
| 420 UpdateDOMAttribute("internalinstanceid", |
| 421 base::StringPrintf("%d", browser_plugin_instance_id_)); |
| 422 |
| 423 browser_plugin_manager()->AddBrowserPluginInternal( |
| 424 browser_plugin_instance_id_, this); |
411 return true; | 425 return true; |
412 } | 426 } |
413 | 427 |
414 void BrowserPlugin::EnableCompositing(bool enable) { | 428 void BrowserPlugin::EnableCompositing(bool enable) { |
415 bool enabled = !!compositing_helper_; | 429 bool enabled = !!compositing_helper_; |
416 if (enabled == enable) | 430 if (enabled == enable) |
417 return; | 431 return; |
418 | 432 |
419 if (enable) { | 433 if (enable) { |
420 DCHECK(!compositing_helper_.get()); | 434 DCHECK(!compositing_helper_.get()); |
(...skipping 12 matching lines...) Expand all Loading... |
433 } | 447 } |
434 } | 448 } |
435 | 449 |
436 void BrowserPlugin::destroy() { | 450 void BrowserPlugin::destroy() { |
437 // If the plugin was initialized then it has a valid |npp_| identifier, and | 451 // If the plugin was initialized then it has a valid |npp_| identifier, and |
438 // the |container_| must clear references to the plugin's script objects. | 452 // the |container_| must clear references to the plugin's script objects. |
439 DCHECK(!npp_ || container_); | 453 DCHECK(!npp_ || container_); |
440 if (container_) | 454 if (container_) |
441 container_->clearScriptObjects(); | 455 container_->clearScriptObjects(); |
442 | 456 |
| 457 // The BrowserPlugin's WebPluginContainer is deleted immediately after this |
| 458 // call returns, so let's not keep a reference to it around. |
| 459 g_plugin_container_map.Get().erase(container_); |
| 460 |
443 if (compositing_helper_.get()) | 461 if (compositing_helper_.get()) |
444 compositing_helper_->OnContainerDestroy(); | 462 compositing_helper_->OnContainerDestroy(); |
445 container_ = NULL; | 463 container_ = NULL; |
446 // Will be a no-op if the mouse is not currently locked. | 464 // Will be a no-op if the mouse is not currently locked. |
447 if (render_view_.get()) | 465 if (render_view_.get()) |
448 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this); | 466 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this); |
449 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 467 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
450 } | 468 } |
451 | 469 |
452 NPObject* BrowserPlugin::scriptableObject() { | 470 NPObject* BrowserPlugin::scriptableObject() { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 SkIntToScalar(plugin_rect_.height())); | 518 SkIntToScalar(plugin_rect_.height())); |
501 canvas->clipRect(image_data_rect); | 519 canvas->clipRect(image_data_rect); |
502 // Paint black or white in case we have nothing in our backing store or we | 520 // Paint black or white in case we have nothing in our backing store or we |
503 // need to show a gutter. | 521 // need to show a gutter. |
504 SkPaint paint; | 522 SkPaint paint; |
505 paint.setStyle(SkPaint::kFill_Style); | 523 paint.setStyle(SkPaint::kFill_Style); |
506 paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE); | 524 paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE); |
507 canvas->drawRect(image_data_rect, paint); | 525 canvas->drawRect(image_data_rect, paint); |
508 } | 526 } |
509 | 527 |
| 528 // static. |
| 529 BrowserPlugin* BrowserPlugin::FromNode(blink::WebNode& node) { |
| 530 blink::WebPluginContainer* container = node.pluginContainer(); |
| 531 if (!container) |
| 532 return NULL; |
| 533 |
| 534 PluginContainerMap* browser_plugins = g_plugin_container_map.Pointer(); |
| 535 PluginContainerMap::iterator it = browser_plugins->find(container); |
| 536 return it == browser_plugins->end() ? NULL : it->second; |
| 537 } |
| 538 |
510 // static | 539 // static |
511 bool BrowserPlugin::ShouldForwardToBrowserPlugin( | 540 bool BrowserPlugin::ShouldForwardToBrowserPlugin( |
512 const IPC::Message& message) { | 541 const IPC::Message& message) { |
513 switch (message.type()) { | 542 switch (message.type()) { |
514 case BrowserPluginMsg_AdvanceFocus::ID: | 543 case BrowserPluginMsg_AdvanceFocus::ID: |
515 case BrowserPluginMsg_Attach_ACK::ID: | |
516 case BrowserPluginMsg_BuffersSwapped::ID: | 544 case BrowserPluginMsg_BuffersSwapped::ID: |
517 case BrowserPluginMsg_CompositorFrameSwapped::ID: | 545 case BrowserPluginMsg_CompositorFrameSwapped::ID: |
518 case BrowserPluginMsg_CopyFromCompositingSurface::ID: | 546 case BrowserPluginMsg_CopyFromCompositingSurface::ID: |
519 case BrowserPluginMsg_GuestContentWindowReady::ID: | 547 case BrowserPluginMsg_GuestContentWindowReady::ID: |
520 case BrowserPluginMsg_GuestGone::ID: | 548 case BrowserPluginMsg_GuestGone::ID: |
521 case BrowserPluginMsg_SetCursor::ID: | 549 case BrowserPluginMsg_SetCursor::ID: |
522 case BrowserPluginMsg_SetMouseLock::ID: | 550 case BrowserPluginMsg_SetMouseLock::ID: |
523 case BrowserPluginMsg_ShouldAcceptTouchEvents::ID: | 551 case BrowserPluginMsg_ShouldAcceptTouchEvents::ID: |
524 case BrowserPluginMsg_UpdateRect::ID: | 552 case BrowserPluginMsg_UpdateRect::ID: |
525 return true; | 553 return true; |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 const blink::WebMouseEvent& event) { | 844 const blink::WebMouseEvent& event) { |
817 browser_plugin_manager()->Send( | 845 browser_plugin_manager()->Send( |
818 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, | 846 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, |
819 guest_instance_id_, | 847 guest_instance_id_, |
820 plugin_rect_, | 848 plugin_rect_, |
821 &event)); | 849 &event)); |
822 return true; | 850 return true; |
823 } | 851 } |
824 | 852 |
825 } // namespace content | 853 } // namespace content |
OLD | NEW |