Home | History | Annotate | Download | only in geolocation
      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 "chrome/browser/geolocation/geolocation_permission_context_extensions.h"
      6 
      7 #include "base/callback.h"
      8 
      9 #if defined(ENABLE_EXTENSIONS)
     10 #include "chrome/browser/content_settings/permission_request_id.h"
     11 #include "chrome/browser/extensions/suggest_permission_util.h"
     12 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "extensions/browser/extension_registry.h"
     15 #include "extensions/browser/process_map.h"
     16 #include "extensions/browser/view_type_utils.h"
     17 #include "extensions/common/extension.h"
     18 
     19 using extensions::APIPermission;
     20 using extensions::ExtensionRegistry;
     21 #endif
     22 
     23 GeolocationPermissionContextExtensions::
     24 GeolocationPermissionContextExtensions(Profile* profile)
     25     : profile_(profile) {
     26 }
     27 
     28 GeolocationPermissionContextExtensions::
     29 ~GeolocationPermissionContextExtensions() {
     30 }
     31 
     32 bool GeolocationPermissionContextExtensions::RequestPermission(
     33     content::WebContents* web_contents,
     34     const PermissionRequestID& request_id,
     35     int bridge_id,
     36     const GURL& requesting_frame,
     37     bool user_gesture,
     38     base::Callback<void(bool)> callback,
     39     bool* permission_set,
     40     bool* new_permission) {
     41 #if defined(ENABLE_EXTENSIONS)
     42   GURL requesting_frame_origin = requesting_frame.GetOrigin();
     43 
     44   WebViewGuest* guest = WebViewGuest::FromWebContents(web_contents);
     45   if (guest) {
     46     guest->RequestGeolocationPermission(bridge_id,
     47                                         requesting_frame,
     48                                         user_gesture,
     49                                         callback);
     50     *permission_set = false;
     51     *new_permission = false;
     52     return true;
     53   }
     54 
     55   ExtensionRegistry* extension_registry = ExtensionRegistry::Get(profile_);
     56   if (extension_registry) {
     57     const extensions::Extension* extension =
     58         extension_registry->enabled_extensions().GetExtensionOrAppByURL(
     59             requesting_frame_origin);
     60     if (IsExtensionWithPermissionOrSuggestInConsole(
     61             APIPermission::kGeolocation, extension,
     62             web_contents->GetRenderViewHost())) {
     63       // Make sure the extension is in the calling process.
     64       if (extensions::ProcessMap::Get(profile_)->Contains(
     65               extension->id(), request_id.render_process_id())) {
     66         *permission_set = true;
     67         *new_permission = true;
     68         return true;
     69       }
     70     }
     71   }
     72 
     73   if (extensions::GetViewType(web_contents) !=
     74       extensions::VIEW_TYPE_TAB_CONTENTS) {
     75     // The tab may have gone away, or the request may not be from a tab at all.
     76     // TODO(mpcomplete): the request could be from a background page or
     77     // extension popup (web_contents will have a different ViewType). But why do
     78     // we care? Shouldn't we still put an infobar up in the current tab?
     79     LOG(WARNING) << "Attempt to use geolocation tabless renderer: "
     80                  << request_id.ToString()
     81                  << " (can't prompt user without a visible tab)";
     82     *permission_set = true;
     83     *new_permission = false;
     84     return true;
     85   }
     86 #endif  // defined(ENABLE_EXTENSIONS)
     87   return false;
     88 }
     89 
     90 bool GeolocationPermissionContextExtensions::CancelPermissionRequest(
     91     content::WebContents* web_contents,
     92     int bridge_id) {
     93 #if defined(ENABLE_EXTENSIONS)
     94   WebViewGuest* guest =
     95       web_contents ? WebViewGuest::FromWebContents(web_contents) : NULL;
     96   if (guest) {
     97     guest->CancelGeolocationPermissionRequest(bridge_id);
     98     return true;
     99   }
    100 #endif  // defined(ENABLE_EXTENSIONS)
    101   return false;
    102 }
    103