Home | History | Annotate | Download | only in app_window
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "extensions/browser/app_window/app_web_contents_helper.h"
      6 
      7 #include "base/strings/stringprintf.h"
      8 #include "content/public/browser/native_web_keyboard_event.h"
      9 #include "content/public/browser/page_navigator.h"
     10 #include "content/public/browser/render_view_host.h"
     11 #include "content/public/browser/web_contents.h"
     12 #include "extensions/browser/app_window/app_delegate.h"
     13 #include "extensions/browser/extension_registry.h"
     14 #include "extensions/browser/suggest_permission_util.h"
     15 #include "extensions/common/extension_messages.h"
     16 #include "extensions/common/permissions/api_permission.h"
     17 
     18 namespace extensions {
     19 
     20 AppWebContentsHelper::AppWebContentsHelper(
     21     content::BrowserContext* browser_context,
     22     const std::string& extension_id,
     23     content::WebContents* web_contents,
     24     AppDelegate* app_delegate)
     25     : browser_context_(browser_context),
     26       extension_id_(extension_id),
     27       web_contents_(web_contents),
     28       app_delegate_(app_delegate) {
     29 }
     30 
     31 // static
     32 bool AppWebContentsHelper::ShouldSuppressGestureEvent(
     33     const blink::WebGestureEvent& event) {
     34   // Disable pinch zooming in app windows.
     35   return event.type == blink::WebGestureEvent::GesturePinchBegin ||
     36          event.type == blink::WebGestureEvent::GesturePinchUpdate ||
     37          event.type == blink::WebGestureEvent::GesturePinchEnd;
     38 }
     39 
     40 content::WebContents* AppWebContentsHelper::OpenURLFromTab(
     41     const content::OpenURLParams& params) const {
     42   // Don't allow the current tab to be navigated. It would be nice to map all
     43   // anchor tags (even those without target="_blank") to new tabs, but right
     44   // now we can't distinguish between those and <meta> refreshes or window.href
     45   // navigations, which we don't want to allow.
     46   // TOOD(mihaip): Can we check for user gestures instead?
     47   WindowOpenDisposition disposition = params.disposition;
     48   if (disposition == CURRENT_TAB) {
     49     AddMessageToDevToolsConsole(
     50         content::CONSOLE_MESSAGE_LEVEL_ERROR,
     51         base::StringPrintf(
     52             "Can't open same-window link to \"%s\"; try target=\"_blank\".",
     53             params.url.spec().c_str()));
     54     return NULL;
     55   }
     56 
     57   // These dispositions aren't really navigations.
     58   if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK ||
     59       disposition == IGNORE_ACTION) {
     60     return NULL;
     61   }
     62 
     63   content::WebContents* contents =
     64       app_delegate_->OpenURLFromTab(browser_context_, web_contents_, params);
     65   if (!contents) {
     66     AddMessageToDevToolsConsole(
     67         content::CONSOLE_MESSAGE_LEVEL_ERROR,
     68         base::StringPrintf(
     69             "Can't navigate to \"%s\"; apps do not support navigation.",
     70             params.url.spec().c_str()));
     71   }
     72 
     73   return contents;
     74 }
     75 
     76 void AppWebContentsHelper::RequestToLockMouse() const {
     77   const Extension* extension = GetExtension();
     78   if (!extension)
     79     return;
     80 
     81   bool has_permission = IsExtensionWithPermissionOrSuggestInConsole(
     82       APIPermission::kPointerLock,
     83       extension,
     84       web_contents_->GetRenderViewHost());
     85 
     86   web_contents_->GotResponseToLockMouseRequest(has_permission);
     87 }
     88 
     89 void AppWebContentsHelper::RequestMediaAccessPermission(
     90     const content::MediaStreamRequest& request,
     91     const content::MediaResponseCallback& callback) const {
     92   const Extension* extension = GetExtension();
     93   if (!extension)
     94     return;
     95 
     96   app_delegate_->RequestMediaAccessPermission(
     97       web_contents_, request, callback, extension);
     98 }
     99 
    100 bool AppWebContentsHelper::CheckMediaAccessPermission(
    101     const GURL& security_origin,
    102     content::MediaStreamType type) const {
    103   const Extension* extension = GetExtension();
    104   if (!extension)
    105     return false;
    106 
    107   return app_delegate_->CheckMediaAccessPermission(
    108       web_contents_, security_origin, type, extension);
    109 }
    110 
    111 const Extension* AppWebContentsHelper::GetExtension() const {
    112   return ExtensionRegistry::Get(browser_context_)
    113       ->enabled_extensions()
    114       .GetByID(extension_id_);
    115 }
    116 
    117 void AppWebContentsHelper::AddMessageToDevToolsConsole(
    118     content::ConsoleMessageLevel level,
    119     const std::string& message) const {
    120   content::RenderViewHost* rvh = web_contents_->GetRenderViewHost();
    121   rvh->Send(new ExtensionMsg_AddMessageToConsole(
    122       rvh->GetRoutingID(), level, message));
    123 }
    124 
    125 }  // namespace extensions
    126