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