15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/browser_plugin/browser_plugin_embedder.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/browser_plugin/browser_plugin_guest.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/browser_plugin/browser_plugin_constants.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/browser_plugin/browser_plugin_messages.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/drag_messages.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_context.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_plugin_guest_manager.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/content_browser_client.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/result_codes.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents) 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : WebContentsObserver(web_contents), 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) guest_drag_ending_(false), 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_(this) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserPluginEmbedder::~BrowserPluginEmbedder() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserPluginEmbedder* BrowserPluginEmbedder::Create( 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContentsImpl* web_contents) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new BrowserPluginEmbedder(web_contents); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPluginEmbedder::DragEnteredGuest(BrowserPluginGuest* guest) { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_dragging_over_ = guest->AsWeakPtr(); 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Avoid race conditions in switching between guests being hovered over by 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // only un-setting if the caller is marked as the guest being dragged over. 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (guest_dragging_over_.get() == guest) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_dragging_over_.reset(); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) { 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_started_drag_ = guest->AsWeakPtr(); 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) guest_drag_ending_ = false; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)WebContentsImpl* BrowserPluginEmbedder::GetWebContents() const { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return static_cast<WebContentsImpl*>(web_contents()); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)BrowserPluginGuestManager* 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)BrowserPluginEmbedder::GetBrowserPluginGuestManager() const { 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return GetWebContents()->GetBrowserContext()->GetGuestManager(); 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void BrowserPluginEmbedder::ClearGuestDragStateIfApplicable() { 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The order at which we observe SystemDragEnded() and DragSourceEndedAt() is 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // platform dependent. 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // In OSX, we see SystemDragEnded() first, where in aura, we see 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // DragSourceEndedAt() first. For this reason, we check if both methods were 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // called before resetting |guest_started_drag_|. 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (guest_drag_ending_) { 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (guest_started_drag_) 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) guest_started_drag_.reset(); 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) guest_drag_ending_ = true; 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserPluginEmbedder::DidSendScreenRectsCallback( 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) WebContents* guest_web_contents) { 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<RenderViewHostImpl*>( 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) guest_web_contents->GetRenderViewHost())->SendScreenRects(); 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Not handled => Iterate over all guests. 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BrowserPluginEmbedder::DidSendScreenRects() { 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetBrowserPluginGuestManager()->ForEachGuest( 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetWebContents(), base::Bind( 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &BrowserPluginEmbedder::DidSendScreenRectsCallback, 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this))); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool handled = true; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(BrowserPluginEmbedder, message) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Attach, OnAttach) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER_GENERIC(DragHostMsg_UpdateDragCursor, 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnUpdateDragCursor(&handled)); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_END_MESSAGE_MAP() 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return handled; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y, 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int screen_x, int screen_y, blink::WebDragOperation operation) { 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (guest_started_drag_) { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Point guest_offset = 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_started_drag_->GetScreenCoordinates(gfx::Point()); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(), 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_y - guest_offset.y(), screen_x, screen_y, operation); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ClearGuestDragStateIfApplicable(); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPluginEmbedder::SystemDragEnded() { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When the embedder's drag/drop operation ends, we need to pass the message 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to the guest that initiated the drag/drop operation. This will ensure that 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the guest's RVH state is reset properly. 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (guest_started_drag_) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_started_drag_->EndSystemDrag(); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guest_dragging_over_.reset(); 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ClearGuestDragStateIfApplicable(); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) { 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *handled = (guest_dragging_over_.get() != NULL); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BrowserPluginEmbedder::OnAttach( 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int browser_plugin_instance_id, 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const BrowserPluginHostMsg_Attach_Params& params) { 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WebContents* guest_web_contents = 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetBrowserPluginGuestManager()->GetGuestByInstanceID( 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetWebContents(), browser_plugin_instance_id); 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!guest_web_contents) 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserPluginGuest* guest = static_cast<WebContentsImpl*>(guest_web_contents) 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->GetBrowserPluginGuest(); 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci guest->Attach(browser_plugin_instance_id, GetWebContents(), params); 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool BrowserPluginEmbedder::HandleKeyboardEvent( 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const NativeWebKeyboardEvent& event) { 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if ((event.windowsKeyCode != ui::VKEY_ESCAPE) || 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (event.modifiers & blink::WebInputEvent::InputModifiers)) { 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool event_consumed = false; 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GetBrowserPluginGuestManager()->ForEachGuest( 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GetWebContents(), 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback, 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Unretained(this), 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &event_consumed)); 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return event_consumed; 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(bool* mouse_unlocked, 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) WebContents* guest) { 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *mouse_unlocked |= static_cast<WebContentsImpl*>(guest) 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ->GetBrowserPluginGuest() 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ->mouse_locked(); 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) guest->GotResponseToLockMouseRequest(false); 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Returns false to iterate over all guests. 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 177