geolocation_permission_context.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/geolocation/geolocation_permission_context.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/l10n_util.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/resource_bundle.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h" 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/browser_thread.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extensions_service.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/geolocation/geolocation_content_settings_map.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/geolocation/geolocation_dispatcher_host.h" 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/geolocation/geolocation_provider.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_process_host.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host_notification_task.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/infobar_delegate.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_util.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class controls the geolocation infobar queue per profile, and it's an 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// internal class to GeolocationPermissionContext. 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// An alternate approach would be to have this queue per tab, and use 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notifications to broadcast when permission is set / listen to notification to 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// cancel pending requests. This may be specially useful if there are other 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// things listening for such notifications. 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For the time being this class is self-contained and it doesn't seem pulling 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the notification infrastructure would simplify. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GeolocationInfoBarQueueController { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationInfoBarQueueController( 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationPermissionContext* geolocation_permission_context, 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile); 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~GeolocationInfoBarQueueController(); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The InfoBar will be displayed immediately if the tab is not already 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // displaying one, otherwise it'll be queued. 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CreateInfoBarRequest( 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& emebedder); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancels a specific infobar request. 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CancelInfoBarRequest( 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called by the InfoBarDelegate to notify it's closed. It'll display a new 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // InfoBar if there's any request pending for this tab. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnInfoBarClosed( 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called by the InfoBarDelegate to notify permission has been set. 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It'll notify and dismiss any other pending InfoBar request for the same 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |requesting_frame| and embedder. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnPermissionSet( 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& embedder, bool allowed); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct PendingInfoBarRequest; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<PendingInfoBarRequest> PendingInfoBarRequests; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shows the first pending infobar for this tab. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ShowQueuedInfoBar(int render_process_id, int render_view_id); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancels an InfoBar request and returns the next iterator position. 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingInfoBarRequest>::iterator CancelInfoBarRequestInternal( 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingInfoBarRequest>::iterator i); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationPermissionContext* const geolocation_permission_context_; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* const profile_; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Contains all pending infobar requests. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingInfoBarRequests pending_infobar_requests_; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is the delegate used to display the confirmation info bar. 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationConfirmInfoBarDelegate( 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents, GeolocationInfoBarQueueController* controller, 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame_url, 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& display_languages) 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ConfirmInfoBarDelegate(tab_contents), 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_(tab_contents), 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_(controller), 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id_(render_process_id), 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_id_(render_view_id), 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_id_(bridge_id), 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame_url_(requesting_frame_url), 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch display_languages_(display_languages) { 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ConfirmInfoBarDelegate 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void InfoBarClosed() { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_->OnInfoBarClosed(render_process_id_, render_view_id_, 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_id_); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual Type GetInfoBarType() { return PAGE_ACTION_TYPE; } 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Accept() { return OnPermissionSet(true); } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Cancel() { return OnPermissionSet(false); } 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int GetButtons() const { return BUTTON_OK | BUTTON_CANCEL; } 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual string16 GetButtonLabel(InfoBarButton button) const { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (button) { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case BUTTON_OK: 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return l10n_util::GetStringUTF16(IDS_GEOLOCATION_ALLOW_BUTTON); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case BUTTON_CANCEL: 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return l10n_util::GetStringUTF16(IDS_GEOLOCATION_DENY_BUTTON); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All buttons are labeled above. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Bad button id " << button; 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return string16(); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual string16 GetMessageText() const { 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return l10n_util::GetStringFUTF16( 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_GEOLOCATION_INFOBAR_QUESTION, 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::FormatUrl(requesting_frame_url_.GetOrigin(), display_languages_)); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual SkBitmap* GetIcon() const { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceBundle::GetSharedInstance().GetBitmapNamed( 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_GEOLOCATION_INFOBAR_ICON); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual string16 GetLinkText() { 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return l10n_util::GetStringUTF16(IDS_LEARN_MORE); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool LinkClicked(WindowOpenDisposition disposition) { 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ignore the click dispostion and always open in a new top level tab. 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_->OpenURL( 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL(l10n_util::GetStringUTF8(IDS_LEARN_MORE_GEOLOCATION_URL)), GURL(), 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NEW_FOREGROUND_TAB, PageTransition::LINK); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // Do not dismiss the info bar. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool OnPermissionSet(bool confirm) { 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_->OnPermissionSet( 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id_, render_view_id_, bridge_id_, requesting_frame_url_, 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_->GetURL(), confirm); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents_; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationInfoBarQueueController* controller_; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id_; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_view_id_; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bridge_id_; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL requesting_frame_url_; 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string display_languages_; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(GeolocationConfirmInfoBarDelegate); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct GeolocationInfoBarQueueController::PendingInfoBarRequest { 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_view_id; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bridge_id; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL requesting_frame; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL embedder; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If non-NULL, it's the current geolocation infobar for this tab. 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InfoBarDelegate* infobar_delegate; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsForTab(int p_render_process_id, int p_render_view_id) const { 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return render_process_id == p_render_process_id && 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_id == p_render_view_id; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsForPair(const GURL& p_requesting_frame, const GURL& p_embedder) const { 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return requesting_frame == p_requesting_frame && 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch embedder == p_embedder; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool Equals(int p_render_process_id, 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int p_render_view_id, 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int p_bridge_id) const { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IsForTab(p_render_process_id, p_render_view_id) && 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_id == p_bridge_id; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationInfoBarQueueController::GeolocationInfoBarQueueController( 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationPermissionContext* geolocation_permission_context, 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : geolocation_permission_context_(geolocation_permission_context), 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_(profile) { 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::CreateInfoBarRequest( 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& embedder) { 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This makes sure that no duplicates are added to 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |pending_infobar_requests_| as an artificial permission request may 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // already exist in the queue as per 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // GeolocationPermissionContext::StartUpdatingRequested 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // See http://crbug.com/51899 for more details. 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(joth): Once we have CLIENT_BASED_GEOLOCATION and 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // WTF_USE_PREEMPT_GEOLOCATION_PERMISSION set in WebKit we should be able to 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // just use a DCHECK to check if a duplicate is attempting to be added. 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while (i != pending_infobar_requests_.end()) { 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (i->Equals(render_process_id, render_view_id, bridge_id)) { 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The request already exists. 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(i->IsForPair(requesting_frame, embedder)); 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++i; 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingInfoBarRequest pending_infobar_request; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.render_process_id = render_process_id; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.render_view_id = render_view_id; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.bridge_id = bridge_id; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.requesting_frame = requesting_frame; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.embedder = embedder; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.infobar_delegate = NULL; 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_requests_.push_back(pending_infobar_request); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowQueuedInfoBar(render_process_id, render_view_id); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::CancelInfoBarRequest( 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end(); ++i) { 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->Equals(render_process_id, render_view_id, bridge_id)) { 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelInfoBarRequestInternal(i); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::OnInfoBarClosed( 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end(); ++i) { 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->Equals(render_process_id, render_view_id, bridge_id)) { 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_requests_.erase(i); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowQueuedInfoBar(render_process_id, render_view_id); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::OnPermissionSet( 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& embedder, bool allowed) { 264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Persist the permission. 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ContentSetting content_setting = 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetGeolocationContentSettingsMap()->SetContentSetting( 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame.GetOrigin(), embedder.GetOrigin(), content_setting); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now notify all pending requests that the permission has been set. 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end();) { 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->IsForPair(requesting_frame, embedder)) { 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // There was a pending request for the same [frame, embedder]. 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->Equals(render_process_id, render_view_id, bridge_id)) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The request that set permission will be removed by TabContents 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // itself, that is, we should not try to cancel the infobar that has 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // just notified us. 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i->infobar_delegate = NULL; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancel it first, and then notify the permission. 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: if the pending request had an infobar, TabContents will 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // eventually close it and we will pump the queue via OnInfoBarClosed(). 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingInfoBarRequest other_request = *i; 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i = CancelInfoBarRequestInternal(i); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_permission_context_->NotifyPermissionSet( 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other_request.render_process_id, other_request.render_view_id, 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other_request.bridge_id, other_request.requesting_frame, allowed); 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++i; 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::ShowQueuedInfoBar( 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id) { 2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TabContents* tab_contents = 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tab_util::GetTabContentsByID(render_process_id, render_view_id); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i != pending_infobar_requests_.end();) { 3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!i->IsForTab(render_process_id, render_view_id)) { 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++i; 3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!tab_contents) { 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i = pending_infobar_requests_.erase(i); 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Check if already displayed. 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (i->infobar_delegate) 3123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 3133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i->infobar_delegate = new GeolocationConfirmInfoBarDelegate( 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tab_contents, this, 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick render_process_id, render_view_id, 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i->bridge_id, i->requesting_frame, 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tab_contents->AddInfoBar(i->infobar_delegate); 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<GeolocationInfoBarQueueController::PendingInfoBarRequest>::iterator 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationInfoBarQueueController::CancelInfoBarRequestInternal( 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingInfoBarRequest>::iterator i) { 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(i->render_process_id, i->render_view_id); 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tab_contents && i->infobar_delegate) { 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TabContents will destroy the InfoBar, which will remove from our vector 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // asynchronously. 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents->RemoveInfoBar(i->infobar_delegate); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ++i; 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove it directly from the pending vector. 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return pending_infobar_requests_.erase(i); 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationPermissionContext::GeolocationPermissionContext( 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_infobar_queue_controller_( 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new GeolocationInfoBarQueueController(this, profile))) { 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationPermissionContext::~GeolocationPermissionContext() { 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::RequestGeolocationPermission( 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::UI, FROM_HERE, 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GeolocationPermissionContext::RequestGeolocationPermission, 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id, requesting_frame)); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionsService* extensions = profile_->GetExtensionsService(); 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extensions) { 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Extension* ext = extensions->GetExtensionByURL(requesting_frame); 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ext) 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ext = extensions->GetExtensionByWebExtent(requesting_frame); 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ext && ext->HasApiPermission(Extension::kGeolocationPermission)) { 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionProcessManager* epm = profile_->GetExtensionProcessManager(); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderProcessHost* process = epm->GetExtensionProcess(requesting_frame); 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (process && process->id() == render_process_id) { 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, true); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(render_process_id, render_view_id); 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tab_contents) { 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The tab may have gone away, or the request may not be from a tab at all. 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Attempt to use geolocation tabless renderer: " 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << render_process_id << "," << render_view_id << "," << bridge_id 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " (can't prompt user without a visible tab)"; 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, false); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL embedder = tab_contents->GetURL(); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!requesting_frame.is_valid() || !embedder.is_valid()) { 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Attempt to use geolocation from an invalid URL: " 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << requesting_frame << "," << embedder 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " (geolocation is not supported in popups)"; 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, false); 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ContentSetting content_setting = 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetGeolocationContentSettingsMap()->GetContentSetting( 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, embedder); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (content_setting == CONTENT_SETTING_BLOCK) { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, false); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (content_setting == CONTENT_SETTING_ALLOW) { 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, true); 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { // setting == ask. Prompt the user. 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_infobar_queue_controller_->CreateInfoBarRequest( 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id, requesting_frame, 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch embedder); 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::CancelGeolocationPermissionRequest( 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid GeolocationPermissionContext::StartUpdatingRequested( 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note we cannot store the arbitrator as a member as it is not thread safe. 428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GeolocationProvider* provider = GeolocationProvider::GetInstance(); 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WebKit will not request permission until it has received a valid 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // location, but the google network location provider will not give a 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // valid location until the user has granted permission. So we cut the Gordian 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Knot by reusing the the 'start updating' request to also trigger 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a 'permission request' should the provider still be awaiting permission. 435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!provider->HasPermissionBeenGranted()) { 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestGeolocationPermission(render_process_id, render_view_id, bridge_id, 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame); 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::StopUpdatingRequested( 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::NotifyPermissionSet( 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, bool allowed) { 449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(render_process_id, render_view_id); 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TabContents may have gone away (or not exists for extension). 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tab_contents) { 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabSpecificContentSettings* content_settings = 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents->GetTabSpecificContentSettings(); 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(), 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allowed); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CallRenderViewHost( 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &RenderViewHost::Send, 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new ViewMsg_Geolocation_PermissionSet(render_view_id, bridge_id, 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allowed)); 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (allowed) { 468731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::IO, FROM_HERE, 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GeolocationPermissionContext::NotifyArbitratorPermissionGranted, 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame)); 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::NotifyArbitratorPermissionGranted( 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 478731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 479731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GeolocationProvider::GetInstance()->OnPermissionGranted(requesting_frame); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::CancelPendingInfoBarRequest( 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 484731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 485731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 486731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::UI, FROM_HERE, 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GeolocationPermissionContext::CancelPendingInfoBarRequest, 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id)); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_infobar_queue_controller_->CancelInfoBarRequest( 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 496