15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "extensions/browser/app_window/app_web_contents_helper.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/stringprintf.h" 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h" 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/page_navigator.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/render_view_host.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents.h" 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "extensions/browser/app_window/app_delegate.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_registry.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "extensions/browser/suggest_permission_util.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/extension_messages.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace extensions { 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)AppWebContentsHelper::AppWebContentsHelper( 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserContext* browser_context, 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& extension_id, 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::WebContents* web_contents, 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AppDelegate* app_delegate) 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : browser_context_(browser_context), 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id_(extension_id), 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_contents_(web_contents), 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) app_delegate_(app_delegate) { 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool AppWebContentsHelper::ShouldSuppressGestureEvent( 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebGestureEvent& event) { 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Disable pinch zooming in app windows. 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return event.type == blink::WebGestureEvent::GesturePinchBegin || 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event.type == blink::WebGestureEvent::GesturePinchUpdate || 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event.type == blink::WebGestureEvent::GesturePinchEnd; 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)content::WebContents* AppWebContentsHelper::OpenURLFromTab( 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const content::OpenURLParams& params) const { 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Don't allow the current tab to be navigated. It would be nice to map all 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // anchor tags (even those without target="_blank") to new tabs, but right 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // now we can't distinguish between those and <meta> refreshes or window.href 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // navigations, which we don't want to allow. 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TOOD(mihaip): Can we check for user gestures instead? 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WindowOpenDisposition disposition = params.disposition; 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (disposition == CURRENT_TAB) { 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AddMessageToDevToolsConsole( 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::CONSOLE_MESSAGE_LEVEL_ERROR, 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::StringPrintf( 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Can't open same-window link to \"%s\"; try target=\"_blank\".", 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.url.spec().c_str())); 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // These dispositions aren't really navigations. 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK || 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) disposition == IGNORE_ACTION) { 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::WebContents* contents = 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) app_delegate_->OpenURLFromTab(browser_context_, web_contents_, params); 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!contents) { 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AddMessageToDevToolsConsole( 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::CONSOLE_MESSAGE_LEVEL_ERROR, 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::StringPrintf( 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Can't navigate to \"%s\"; apps do not support navigation.", 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.url.spec().c_str())); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return contents; 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppWebContentsHelper::RequestToLockMouse() const { 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const Extension* extension = GetExtension(); 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!extension) 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool has_permission = IsExtensionWithPermissionOrSuggestInConsole( 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) APIPermission::kPointerLock, 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension, 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_contents_->GetRenderViewHost()); 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_contents_->GotResponseToLockMouseRequest(has_permission); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppWebContentsHelper::RequestMediaAccessPermission( 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const content::MediaStreamRequest& request, 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const content::MediaResponseCallback& callback) const { 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const Extension* extension = GetExtension(); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!extension) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) app_delegate_->RequestMediaAccessPermission( 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_contents_, request, callback, extension); 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool AppWebContentsHelper::CheckMediaAccessPermission( 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& security_origin, 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::MediaStreamType type) const { 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Extension* extension = GetExtension(); 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extension) 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return app_delegate_->CheckMediaAccessPermission( 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_contents_, security_origin, type, extension); 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const Extension* AppWebContentsHelper::GetExtension() const { 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return ExtensionRegistry::Get(browser_context_) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->enabled_extensions() 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) .GetByID(extension_id_); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppWebContentsHelper::AddMessageToDevToolsConsole( 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::ConsoleMessageLevel level, 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& message) const { 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rvh->Send(new ExtensionMsg_AddMessageToConsole( 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rvh->GetRoutingID(), level, message)); 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace extensions 126