geolocation_permission_context.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
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" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chrome_thread.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extensions_service.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/geolocation/geolocation_content_settings_map.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/geolocation/geolocation_dispatcher_host.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/geolocation/location_arbitrator.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/pref_service.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_process_host.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host_notification_task.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/infobar_delegate.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_util.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class controls the geolocation infobar queue per profile, and it's an 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// internal class to GeolocationPermissionContext. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// An alternate approach would be to have this queue per tab, and use 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notifications to broadcast when permission is set / listen to notification to 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// cancel pending requests. This may be specially useful if there are other 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// things listening for such notifications. 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For the time being this class is self-contained and it doesn't seem pulling 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the notification infrastructure would simplify. 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GeolocationInfoBarQueueController { 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationInfoBarQueueController( 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationPermissionContext* geolocation_permission_context, 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile); 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~GeolocationInfoBarQueueController(); 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The InfoBar will be displayed immediately if the tab is not already 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // displaying one, otherwise it'll be queued. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CreateInfoBarRequest( 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& emebedder); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancels a specific infobar request. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CancelInfoBarRequest( 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called by the InfoBarDelegate to notify it's closed. It'll display a new 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // InfoBar if there's any request pending for this tab. 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnInfoBarClosed( 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called by the InfoBarDelegate to notify permission has been set. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It'll notify and dismiss any other pending InfoBar request for the same 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |requesting_frame| and embedder. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnPermissionSet( 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& embedder, bool allowed); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct PendingInfoBarRequest; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<PendingInfoBarRequest> PendingInfoBarRequests; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shows the first pending infobar for this tab. 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ShowQueuedInfoBar(int render_process_id, int render_view_id); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancels an InfoBar request and returns the next iterator position. 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingInfoBarRequest>::iterator CancelInfoBarRequestInternal( 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingInfoBarRequest>::iterator i); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationPermissionContext* const geolocation_permission_context_; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* const profile_; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Contains all pending infobar requests. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingInfoBarRequests pending_infobar_requests_; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is the delegate used to display the confirmation info bar. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationConfirmInfoBarDelegate( 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents, GeolocationInfoBarQueueController* controller, 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame_url, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::wstring& display_languages) 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ConfirmInfoBarDelegate(tab_contents), 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_(tab_contents), 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_(controller), 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id_(render_process_id), 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_id_(render_view_id), 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_id_(bridge_id), 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame_url_(requesting_frame_url), 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch display_languages_(display_languages) { 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ConfirmInfoBarDelegate 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void InfoBarClosed() { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_->OnInfoBarClosed(render_process_id_, render_view_id_, 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_id_); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual Type GetInfoBarType() { return PAGE_ACTION_TYPE; } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Accept() { return OnPermissionSet(true); } 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Cancel() { return OnPermissionSet(false); } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int GetButtons() const { return BUTTON_OK | BUTTON_CANCEL; } 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual std::wstring GetButtonLabel(InfoBarButton button) const { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (button) { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case BUTTON_OK: 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return l10n_util::GetString(IDS_GEOLOCATION_ALLOW_BUTTON); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case BUTTON_CANCEL: 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return l10n_util::GetString(IDS_GEOLOCATION_DENY_BUTTON); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All buttons are labeled above. 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Bad button id " << button; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return L""; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual std::wstring GetMessageText() const { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return l10n_util::GetStringF( 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_GEOLOCATION_INFOBAR_QUESTION, 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::FormatUrl(requesting_frame_url_.GetOrigin(), display_languages_)); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual SkBitmap* GetIcon() const { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceBundle::GetSharedInstance().GetBitmapNamed( 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_GEOLOCATION_INFOBAR_ICON); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual std::wstring GetLinkText() { 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return l10n_util::GetString(IDS_LEARN_MORE); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool LinkClicked(WindowOpenDisposition disposition) { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ignore the click dispostion and always open in a new top level tab. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_->OpenURL( 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL(l10n_util::GetStringUTF8(IDS_LEARN_MORE_GEOLOCATION_URL)), GURL(), 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NEW_FOREGROUND_TAB, PageTransition::LINK); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // Do not dismiss the info bar. 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool OnPermissionSet(bool confirm) { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_->OnPermissionSet( 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id_, render_view_id_, bridge_id_, requesting_frame_url_, 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents_->GetURL(), confirm); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents_; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationInfoBarQueueController* controller_; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id_; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_view_id_; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bridge_id_; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL requesting_frame_url_; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::wstring display_languages_; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(GeolocationConfirmInfoBarDelegate); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct GeolocationInfoBarQueueController::PendingInfoBarRequest { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_view_id; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bridge_id; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL requesting_frame; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL embedder; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If non-NULL, it's the current geolocation infobar for this tab. 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InfoBarDelegate* infobar_delegate; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsForTab(int p_render_process_id, int p_render_view_id) const { 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return render_process_id == p_render_process_id && 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_id == p_render_view_id; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsForPair(const GURL& p_requesting_frame, const GURL& p_embedder) const { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return requesting_frame == p_requesting_frame && 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch embedder == p_embedder; 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool Equals(int p_render_process_id, 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int p_render_view_id, 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int p_bridge_id) const { 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IsForTab(p_render_process_id, p_render_view_id) && 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_id == p_bridge_id; 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationInfoBarQueueController::GeolocationInfoBarQueueController( 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationPermissionContext* geolocation_permission_context, 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : geolocation_permission_context_(geolocation_permission_context), 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_(profile) { 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::CreateInfoBarRequest( 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& embedder) { 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingInfoBarRequest pending_infobar_request; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.render_process_id = render_process_id; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.render_view_id = render_view_id; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.bridge_id = bridge_id; 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.requesting_frame = requesting_frame; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.embedder = embedder; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_request.infobar_delegate = NULL; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_requests_.push_back(pending_infobar_request); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowQueuedInfoBar(render_process_id, render_view_id); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::CancelInfoBarRequest( 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end(); ++i) { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->Equals(render_process_id, render_view_id, bridge_id)) { 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelInfoBarRequestInternal(i); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::OnInfoBarClosed( 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end(); ++i) { 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->Equals(render_process_id, render_view_id, bridge_id)) { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_infobar_requests_.erase(i); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowQueuedInfoBar(render_process_id, render_view_id); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::OnPermissionSet( 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, const GURL& embedder, bool allowed) { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Persist the permission. 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ContentSetting content_setting = 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetGeolocationContentSettingsMap()->SetContentSetting( 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame.GetOrigin(), embedder.GetOrigin(), content_setting); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now notify all pending requests that the permission has been set. 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end();) { 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->IsForPair(requesting_frame, embedder)) { 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // There was a pending request for the same [frame, embedder]. 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->Equals(render_process_id, render_view_id, bridge_id)) { 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The request that set permission will be removed by TabContents 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // itself, that is, we should not try to cancel the infobar that has 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // just notified us. 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i->infobar_delegate = NULL; 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancel it first, and then notify the permission. 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: if the pending request had an infobar, TabContents will 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // eventually close it and we will pump the queue via OnInfoBarClosed(). 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingInfoBarRequest other_request = *i; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i = CancelInfoBarRequestInternal(i); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_permission_context_->NotifyPermissionSet( 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other_request.render_process_id, other_request.render_view_id, 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other_request.bridge_id, other_request.requesting_frame, allowed); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++i; 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationInfoBarQueueController::ShowQueuedInfoBar( 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id) { 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != pending_infobar_requests_.end(); ++i) { 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->IsForTab(render_process_id, render_view_id)) { 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if already displayed. 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->infobar_delegate) 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(render_process_id, render_view_id); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i->infobar_delegate = 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new GeolocationConfirmInfoBarDelegate( 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents, this, 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i->bridge_id, i->requesting_frame, 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF8ToWide(profile_->GetPrefs()->GetString( 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs::kAcceptLanguages))); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents->AddInfoBar(i->infobar_delegate); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<GeolocationInfoBarQueueController::PendingInfoBarRequest>::iterator 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationInfoBarQueueController::CancelInfoBarRequestInternal( 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingInfoBarRequest>::iterator i) { 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(i->render_process_id, i->render_view_id); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tab_contents && i->infobar_delegate) { 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TabContents will destroy the InfoBar, which will remove from our vector 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // asynchronously. 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents->RemoveInfoBar(i->infobar_delegate); 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ++i; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove it directly from the pending vector. 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return pending_infobar_requests_.erase(i); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationPermissionContext::GeolocationPermissionContext( 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_infobar_queue_controller_( 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new GeolocationInfoBarQueueController(this, profile))) { 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationPermissionContext::~GeolocationPermissionContext() { 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::RequestGeolocationPermission( 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeThread::PostTask( 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeThread::UI, FROM_HERE, 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GeolocationPermissionContext::RequestGeolocationPermission, 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id, requesting_frame)); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionsService* extensions = profile_->GetExtensionsService(); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extensions) { 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Extension* ext = extensions->GetExtensionByURL(requesting_frame); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ext) 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ext = extensions->GetExtensionByWebExtent(requesting_frame); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ext && ext->HasApiPermission(Extension::kGeolocationPermission)) { 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionProcessManager* epm = profile_->GetExtensionProcessManager(); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderProcessHost* process = epm->GetExtensionProcess(requesting_frame); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (process && process->id() == render_process_id) { 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, true); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(render_process_id, render_view_id); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tab_contents) { 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The tab may have gone away, or the request may not be from a tab at all. 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Attempt to use geolocation tabless renderer: " 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << render_process_id << "," << render_view_id << "," << bridge_id 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " (can't prompt user without a visible tab)"; 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, false); 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL embedder = tab_contents->GetURL(); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!requesting_frame.is_valid() || !embedder.is_valid()) { 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Attempt to use geolocation from an invalid URL: " 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << requesting_frame << "," << embedder 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " (geolocation is not supported in popups)"; 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, false); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ContentSetting content_setting = 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetGeolocationContentSettingsMap()->GetContentSetting( 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, embedder); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (content_setting == CONTENT_SETTING_BLOCK) { 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, false); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (content_setting == CONTENT_SETTING_ALLOW) { 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame, true); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { // setting == ask. Prompt the user. 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_infobar_queue_controller_->CreateInfoBarRequest( 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id, requesting_frame, 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch embedder); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::CancelGeolocationPermissionRequest( 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGeolocationArbitrator* GeolocationPermissionContext::StartUpdatingRequested( 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note we cannot store the arbitrator as a member as it is not thread safe. 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationArbitrator* arbitrator = GeolocationArbitrator::GetInstance(); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WebKit will not request permission until it has received a valid 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // location, but the google network location provider will not give a 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // valid location until the user has granted permission. So we cut the Gordian 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Knot by reusing the the 'start updating' request to also trigger 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a 'permission request' should the provider still be awaiting permission. 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!arbitrator->HasPermissionBeenGranted()) { 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestGeolocationPermission(render_process_id, render_view_id, bridge_id, 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame); 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return arbitrator; 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::StopUpdatingRequested( 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::NotifyPermissionSet( 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id, 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame, bool allowed) { 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_util::GetTabContentsByID(render_process_id, render_view_id); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TabContents may have gone away (or not exists for extension). 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tab_contents) { 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabSpecificContentSettings* content_settings = 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents->GetTabSpecificContentSettings(); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(), 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allowed); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CallRenderViewHost( 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &RenderViewHost::Send, 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new ViewMsg_Geolocation_PermissionSet(render_view_id, bridge_id, 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allowed)); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (allowed) { 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeThread::PostTask( 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeThread::IO, FROM_HERE, 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GeolocationPermissionContext::NotifyArbitratorPermissionGranted, 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_frame)); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::NotifyArbitratorPermissionGranted( 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& requesting_frame) { 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeolocationArbitrator::GetInstance()->OnPermissionGranted(requesting_frame); 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GeolocationPermissionContext::CancelPendingInfoBarRequest( 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id, int render_view_id, int bridge_id) { 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeThread::PostTask( 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeThread::UI, FROM_HERE, 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GeolocationPermissionContext::CancelPendingInfoBarRequest, 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id)); 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch geolocation_infobar_queue_controller_->CancelInfoBarRequest( 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_process_id, render_view_id, bridge_id); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 475