diff options
author | cramya@chromium.org <cramya@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 01:50:22 +0000 |
---|---|---|
committer | cramya@chromium.org <cramya@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 01:50:22 +0000 |
commit | 3ab14c6d0759b09bdfcbea1ba5dbef4e5cb67fbb (patch) | |
tree | 46d010065d6826e361d0b786d77d500c671cdc31 | |
parent | 4d884a2e092f3ad93ff68559c476cbe60aa44c96 (diff) | |
download | chromium_src-3ab14c6d0759b09bdfcbea1ba5dbef4e5cb67fbb.zip chromium_src-3ab14c6d0759b09bdfcbea1ba5dbef4e5cb67fbb.tar.gz chromium_src-3ab14c6d0759b09bdfcbea1ba5dbef4e5cb67fbb.tar.bz2 |
Refactor chrome_geolocation_permission_context.* in preperation for adding platform specific functionality.
Extract GeolocationConfirmInfobarDelegate into its own class to allow platform specific changes to the geolocation infobar.
Platform specific changes will be added in an upcoming CL (WIP CL http://codereview.chromium.org/11188020/).
BUG=152236
Review URL: https://chromiumcodereview.appspot.com/11183018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162608 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 382 insertions, 250 deletions
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc index 9964d30..adc4721 100644 --- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc +++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc @@ -30,18 +30,11 @@ using WebKit::WebSecurityOrigin; using content::BrowserThread; using content::WebContents; - // GeolocationPermissionContext ----------------------------------------------- -ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext( - Profile* profile) - : profile_(profile), - ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_( - new GeolocationInfoBarQueueController( - base::Bind( - &ChromeGeolocationPermissionContext::NotifyPermissionSet, - base::Unretained(this)), - profile))) { +ChromeGeolocationPermissionContext* ChromeGeolocationPermissionContext::Create( + Profile* profile) { + return new ChromeGeolocationPermissionContext(profile); } void ChromeGeolocationPermissionContext::RegisterUserPrefs( @@ -52,6 +45,11 @@ void ChromeGeolocationPermissionContext::RegisterUserPrefs( #endif } +ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext( + Profile* profile) + : profile_(profile) { +} + ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() { } @@ -67,15 +65,58 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission( requesting_frame, callback)); return; } + + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + WebContents* web_contents = + tab_util::GetWebContentsByID(render_process_id, render_view_id); + if (chrome::GetViewType(web_contents) != chrome::VIEW_TYPE_TAB_CONTENTS) { + // The tab may have gone away, or the request may not be from a tab at all. + // TODO(mpcomplete): the request could be from a background page or + // extension popup (tab_contents will have a different ViewType). But why do + // we care? Shouldn't we still put an infobar up in the current tab? + LOG(WARNING) << "Attempt to use geolocation tabless renderer: " + << render_process_id << "," << render_view_id << "," + << bridge_id << " (can't prompt user without a visible tab)"; + NotifyPermissionSet(render_process_id, render_view_id, bridge_id, + requesting_frame, callback, false); + return; + } + + GURL embedder = web_contents->GetURL(); + if (!requesting_frame.is_valid() || !embedder.is_valid()) { + LOG(WARNING) << "Attempt to use geolocation from an invalid URL: " + << requesting_frame << "," << embedder + << " (geolocation is not supported in popups)"; + NotifyPermissionSet(render_process_id, render_view_id, bridge_id, + requesting_frame, callback, false); + return; + } + + DecidePermission(render_process_id, render_view_id, bridge_id, + requesting_frame, embedder, callback); +} + +void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest( + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame) { + CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); +} + +void ChromeGeolocationPermissionContext::DecidePermission( + int render_process_id, int render_view_id, int bridge_id, + const GURL& requesting_frame, const GURL& embedder, + base::Callback<void(bool)> callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); #if defined(OS_ANDROID) // Check to see if the feature in its entirety has been disabled. // This must happen before other services (e.g. tabs, extensions) // get an opportunity to allow the geolocation request. - if (!profile_->GetPrefs()->GetBoolean(prefs::kGeolocationEnabled)) { - NotifyPermissionSet(render_process_id, render_view_id, bridge_id, - requesting_frame, callback, false); + if (!profile()->GetPrefs()->GetBoolean(prefs::kGeolocationEnabled)) { + PermissionDecided(render_process_id, render_view_id, bridge_id, + requesting_frame, embedder, callback, false); return; } #endif @@ -93,82 +134,50 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission( // Make sure the extension is in the calling process. if (extension_service->process_map()->Contains( extension->id(), render_process_id)) { - NotifyPermissionSet(render_process_id, render_view_id, bridge_id, - requesting_frame, callback, true); + PermissionDecided(render_process_id, render_view_id, bridge_id, + requesting_frame, embedder, callback, true); return; } } } - WebContents* web_contents = - tab_util::GetWebContentsByID(render_process_id, render_view_id); - if (chrome::GetViewType(web_contents) != chrome::VIEW_TYPE_TAB_CONTENTS) { - // The tab may have gone away, or the request may not be from a tab at all. - // TODO(mpcomplete): the request could be from a background page or - // extension popup (tab_contents will have a different ViewType). But why do - // we care? Shouldn't we still put an infobar up in the current tab? - LOG(WARNING) << "Attempt to use geolocation tabless renderer: " - << render_process_id << "," << render_view_id << "," - << bridge_id << " (can't prompt user without a visible tab)"; - NotifyPermissionSet(render_process_id, render_view_id, bridge_id, - requesting_frame, callback, false); - return; - } - - GURL embedder = web_contents->GetURL(); - if (!requesting_frame.is_valid() || !embedder.is_valid()) { - LOG(WARNING) << "Attempt to use geolocation from an invalid URL: " - << requesting_frame << "," << embedder - << " (geolocation is not supported in popups)"; - NotifyPermissionSet(render_process_id, render_view_id, bridge_id, - requesting_frame, callback, false); - return; - } - ContentSetting content_setting = profile_->GetHostContentSettingsMap()->GetContentSetting( requesting_frame, embedder, CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()); - if (content_setting == CONTENT_SETTING_BLOCK) { - NotifyPermissionSet(render_process_id, render_view_id, bridge_id, - requesting_frame, callback, false); - } else if (content_setting == CONTENT_SETTING_ALLOW) { - NotifyPermissionSet(render_process_id, render_view_id, bridge_id, - requesting_frame, callback, true); - } else { // setting == ask. Prompt the user. - geolocation_infobar_queue_controller_->CreateInfoBarRequest( - render_process_id, render_view_id, bridge_id, requesting_frame, - embedder, callback); + switch (content_setting) { + case CONTENT_SETTING_BLOCK: + PermissionDecided(render_process_id, render_view_id, bridge_id, + requesting_frame, embedder, callback, false); + break; + case CONTENT_SETTING_ALLOW: + PermissionDecided(render_process_id, render_view_id, bridge_id, + requesting_frame, embedder, callback, true); + break; + default: + // setting == ask. Prompt the user. + QueueController()->CreateInfoBarRequest( + render_process_id, render_view_id, bridge_id, requesting_frame, + embedder, base::Bind( + &ChromeGeolocationPermissionContext::NotifyPermissionSet, + base::Unretained(this), + render_process_id, render_view_id, bridge_id, requesting_frame, + callback)); } } -void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest( +void ChromeGeolocationPermissionContext::PermissionDecided( int render_process_id, int render_view_id, int bridge_id, - const GURL& requesting_frame) { - CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); -} - -void ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest( - int render_process_id, - int render_view_id, - int bridge_id) { - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind( - &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest, - this, render_process_id, render_view_id, bridge_id)); - return; - } - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - geolocation_infobar_queue_controller_->CancelInfoBarRequest( - render_process_id, - render_view_id, - bridge_id); + const GURL& requesting_frame, + const GURL& embedder, + base::Callback<void(bool)> callback, + bool allowed) { + NotifyPermissionSet(render_process_id, render_view_id, bridge_id, + requesting_frame, callback, allowed); } void ChromeGeolocationPermissionContext::NotifyPermissionSet( @@ -190,3 +199,36 @@ void ChromeGeolocationPermissionContext::NotifyPermissionSet( callback.Run(allowed); } + +GeolocationInfoBarQueueController* +ChromeGeolocationPermissionContext::QueueController() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!geolocation_infobar_queue_controller_) + geolocation_infobar_queue_controller_.reset(CreateQueueController()); + return geolocation_infobar_queue_controller_.get(); +} + +GeolocationInfoBarQueueController* +ChromeGeolocationPermissionContext::CreateQueueController() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + return new GeolocationInfoBarQueueController(profile()); +} + +void ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest( + int render_process_id, + int render_view_id, + int bridge_id) { + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind( + &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest, + this, render_process_id, render_view_id, bridge_id)); + return; + } + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + QueueController()->CancelInfoBarRequest( + render_process_id, + render_view_id, + bridge_id); +} diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.h b/chrome/browser/geolocation/chrome_geolocation_permission_context.h index d0f35ce..95f31e6 100644 --- a/chrome/browser/geolocation/chrome_geolocation_permission_context.h +++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.h @@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_GEOLOCATION_CHROME_GEOLOCATION_PERMISSION_CONTEXT_H_ #define CHROME_BROWSER_GEOLOCATION_CHROME_GEOLOCATION_PERMISSION_CONTEXT_H_ +#include <string> + #include "base/memory/scoped_ptr.h" #include "content/public/browser/geolocation_permission_context.h" @@ -18,7 +20,7 @@ class Profile; class ChromeGeolocationPermissionContext : public content::GeolocationPermissionContext { public: - explicit ChromeGeolocationPermissionContext(Profile* profile); + static ChromeGeolocationPermissionContext* Create(Profile* profile); static void RegisterUserPrefs(PrefService *user_prefs); @@ -35,17 +37,20 @@ class ChromeGeolocationPermissionContext int bridge_id, const GURL& requesting_frame) OVERRIDE; - private: + protected: + explicit ChromeGeolocationPermissionContext(Profile* profile); virtual ~ChromeGeolocationPermissionContext(); - // Removes any pending InfoBar request. - void CancelPendingInfoBarRequest(int render_process_id, - int render_view_id, - int bridge_id); + Profile* profile() const { return profile_; } + + // Return an instance of the infobar queue controller, creating it + // if necessary. + GeolocationInfoBarQueueController* QueueController(); // Notifies whether or not the corresponding bridge is allowed to use // geolocation via // GeolocationPermissionContext::SetGeolocationPermissionResponse(). + // Called on the UI thread. void NotifyPermissionSet(int render_process_id, int render_view_id, int bridge_id, @@ -53,6 +58,40 @@ class ChromeGeolocationPermissionContext base::Callback<void(bool)> callback, bool allowed); + // ChromeGeolocationPermissionContext implementation: + // Decide whether the geolocation permission should be granted. + // Calls PermissionDecided if permission can be decided non-interactively, + // or NotifyPermissionSet if permission decided by presenting an + // infobar to the user. Called on the UI thread. + virtual void DecidePermission(int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame, + const GURL& embedder, + base::Callback<void(bool)> callback); + + // Called when permission is granted without interactively asking + // the user. Can be overridden to introduce additional UI flow. + // Should ultimately ensure that NotifyPermissionSet is called. + // Called on the UI thread. + virtual void PermissionDecided(int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame, + const GURL& embedder, + base::Callback<void(bool)> callback, + bool allowed); + + // Create an InfoBarQueueController. overriden in derived classes to provide + // additional UI flow. Called on the UI thread. + virtual GeolocationInfoBarQueueController* CreateQueueController(); + + private: + // Removes any pending InfoBar request. + void CancelPendingInfoBarRequest(int render_process_id, + int render_view_id, + int bridge_id); + // This must only be accessed from the UI thread. Profile* const profile_; diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc index 2ea118e..231aeda 100644 --- a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc +++ b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc @@ -253,7 +253,7 @@ void GeolocationPermissionContextTests::SetUp() { TabSpecificContentSettings::CreateForWebContents(web_contents()); geolocation_permission_context_ = - new ChromeGeolocationPermissionContext(profile()); + ChromeGeolocationPermissionContext::Create(profile()); } void GeolocationPermissionContextTests::TearDown() { diff --git a/chrome/browser/geolocation/geolocation_confirm_infobar_delegate.cc b/chrome/browser/geolocation/geolocation_confirm_infobar_delegate.cc new file mode 100644 index 0000000..f1fe565 --- /dev/null +++ b/chrome/browser/geolocation/geolocation_confirm_infobar_delegate.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h" + +#include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h" +#include "chrome/browser/google/google_util.h" +#include "chrome/browser/infobars/infobar_tab_helper.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" +#include "grit/theme_resources.h" +#include "net/base/net_util.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +// GeolocationConfirmInfoBarDelegate ------------------------------------------ + +GeolocationConfirmInfoBarDelegate::GeolocationConfirmInfoBarDelegate( + InfoBarTabHelper* infobar_helper, + GeolocationInfoBarQueueController* controller, + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame_url, + const std::string& display_languages) + : ConfirmInfoBarDelegate(infobar_helper), + controller_(controller), + render_process_id_(render_process_id), + render_view_id_(render_view_id), + bridge_id_(bridge_id), + requesting_frame_url_(requesting_frame_url), + display_languages_(display_languages) { + const content::NavigationEntry* committed_entry = + infobar_helper->GetWebContents()->GetController().GetLastCommittedEntry(); + set_contents_unique_id(committed_entry ? committed_entry->GetUniqueID() : 0); +} + +gfx::Image* GeolocationConfirmInfoBarDelegate::GetIcon() const { + return &ResourceBundle::GetSharedInstance().GetNativeImageNamed( + IDR_GEOLOCATION_INFOBAR_ICON); +} + +InfoBarDelegate::Type + GeolocationConfirmInfoBarDelegate::GetInfoBarType() const { + return PAGE_ACTION_TYPE; +} + +string16 GeolocationConfirmInfoBarDelegate::GetMessageText() const { + return l10n_util::GetStringFUTF16(IDS_GEOLOCATION_INFOBAR_QUESTION, + net::FormatUrl(requesting_frame_url_.GetOrigin(), display_languages_)); +} + +string16 GeolocationConfirmInfoBarDelegate::GetButtonLabel( + InfoBarButton button) const { + return l10n_util::GetStringUTF16((button == BUTTON_OK) ? + IDS_GEOLOCATION_ALLOW_BUTTON : IDS_GEOLOCATION_DENY_BUTTON); +} + +void GeolocationConfirmInfoBarDelegate::SetPermission( + bool update_content_setting, bool allowed) { + controller_->OnPermissionSet( + render_process_id_, render_view_id_, bridge_id_, + requesting_frame_url_, + owner()->GetWebContents()->GetURL(), + update_content_setting, + allowed); +} + +bool GeolocationConfirmInfoBarDelegate::Accept() { + SetPermission(true, true); + return true; +} + +bool GeolocationConfirmInfoBarDelegate::Cancel() { + SetPermission(true, false); + return true; +} + +string16 GeolocationConfirmInfoBarDelegate::GetLinkText() const { + return l10n_util::GetStringUTF16(IDS_LEARN_MORE); +} + +bool GeolocationConfirmInfoBarDelegate::LinkClicked( + WindowOpenDisposition disposition) { + const char kGeolocationLearnMoreUrl[] = +#if defined(OS_CHROMEOS) + "https://www.google.com/support/chromeos/bin/answer.py?answer=142065"; +#else + "https://www.google.com/support/chrome/bin/answer.py?answer=142065"; +#endif + + content::OpenURLParams params( + google_util::AppendGoogleLocaleParam(GURL(kGeolocationLearnMoreUrl)), + content::Referrer(), + (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, + content::PAGE_TRANSITION_LINK, false); + owner()->GetWebContents()->OpenURL(params); + return false; // Do not dismiss the info bar. +} diff --git a/chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h b/chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h new file mode 100644 index 0000000..1df2644 --- /dev/null +++ b/chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h @@ -0,0 +1,59 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GEOLOCATION_GEOLOCATION_CONFIRM_INFOBAR_DELEGATE_H_ +#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_CONFIRM_INFOBAR_DELEGATE_H_ + +#include "chrome/browser/api/infobars/confirm_infobar_delegate.h" +#include "googleurl/src/gurl.h" + +#include <string> + +class GeolocationInfoBarQueueController; +class InfoBarTabHelper; + +// GeolocationInfoBarDelegates are created by the +// GeolocationInfoBarQueueController to control the display +// and handling of geolocation permission infobars to the user. +class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { + public: + GeolocationConfirmInfoBarDelegate( + InfoBarTabHelper* infobar_helper, + GeolocationInfoBarQueueController* controller, + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame_url, + const std::string& display_languages); + + int render_process_id() const { return render_process_id_; } + int render_view_id() const { return render_view_id_; } + + protected: + // ConfirmInfoBarDelegate: + virtual gfx::Image* GetIcon() const OVERRIDE; + virtual Type GetInfoBarType() const OVERRIDE; + virtual string16 GetMessageText() const OVERRIDE; + virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; + virtual bool Accept() OVERRIDE; + virtual bool Cancel() OVERRIDE; + virtual string16 GetLinkText() const OVERRIDE; + virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE; + + // Call back to the controller, to inform of the user's decision. + void SetPermission(bool update_content_setting, bool allowed); + + private: + GeolocationInfoBarQueueController* controller_; + int render_process_id_; + int render_view_id_; + int bridge_id_; + + GURL requesting_frame_url_; + std::string display_languages_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(GeolocationConfirmInfoBarDelegate); +}; + +#endif // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_CONFIRM_INFOBAR_DELEGATE_H_ diff --git a/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc b/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc index 6639adb..9bbe26c 100644 --- a/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc +++ b/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc @@ -4,9 +4,8 @@ #include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h" -#include "chrome/browser/api/infobars/confirm_infobar_delegate.h" #include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/browser/google/google_util.h" +#include "chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h" #include "chrome/browser/infobars/infobar.h" #include "chrome/browser/infobars/infobar_tab_helper.h" #include "chrome/browser/prefs/pref_service.h" @@ -16,145 +15,14 @@ #include "chrome/common/content_settings.h" #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/navigation_details.h" -#include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "net/base/net_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/l10n/l10n_util.h" using content::BrowserThread; -using content::NavigationEntry; -using content::OpenURLParams; -using content::Referrer; using content::WebContents; -// GeolocationConfirmInfoBarDelegate ------------------------------------------ - -namespace { - -class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { - public: - GeolocationConfirmInfoBarDelegate( - InfoBarTabHelper* infobar_helper, - GeolocationInfoBarQueueController* controller, - int render_process_id, - int render_view_id, - int bridge_id, - const GURL& requesting_frame_url, - const std::string& display_languages); - - int render_process_id() const { return render_process_id_; } - int render_view_id() const { return render_view_id_; } - - private: - - // ConfirmInfoBarDelegate: - virtual gfx::Image* GetIcon() const OVERRIDE; - virtual Type GetInfoBarType() const OVERRIDE; - virtual string16 GetMessageText() const OVERRIDE; - virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; - virtual bool Accept() OVERRIDE; - virtual bool Cancel() OVERRIDE; - virtual string16 GetLinkText() const OVERRIDE; - virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE; - - GeolocationInfoBarQueueController* controller_; - int render_process_id_; - int render_view_id_; - int bridge_id_; - - GURL requesting_frame_url_; - std::string display_languages_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(GeolocationConfirmInfoBarDelegate); -}; - -GeolocationConfirmInfoBarDelegate::GeolocationConfirmInfoBarDelegate( - InfoBarTabHelper* infobar_helper, - GeolocationInfoBarQueueController* controller, - int render_process_id, - int render_view_id, - int bridge_id, - const GURL& requesting_frame_url, - const std::string& display_languages) - : ConfirmInfoBarDelegate(infobar_helper), - controller_(controller), - render_process_id_(render_process_id), - render_view_id_(render_view_id), - bridge_id_(bridge_id), - requesting_frame_url_(requesting_frame_url), - display_languages_(display_languages) { - const NavigationEntry* committed_entry = - infobar_helper->GetWebContents()->GetController().GetLastCommittedEntry(); - set_contents_unique_id(committed_entry ? committed_entry->GetUniqueID() : 0); -} - -gfx::Image* GeolocationConfirmInfoBarDelegate::GetIcon() const { - return &ResourceBundle::GetSharedInstance().GetNativeImageNamed( - IDR_GEOLOCATION_INFOBAR_ICON); -} - -InfoBarDelegate::Type - GeolocationConfirmInfoBarDelegate::GetInfoBarType() const { - return PAGE_ACTION_TYPE; -} - -string16 GeolocationConfirmInfoBarDelegate::GetMessageText() const { - return l10n_util::GetStringFUTF16(IDS_GEOLOCATION_INFOBAR_QUESTION, - net::FormatUrl(requesting_frame_url_.GetOrigin(), display_languages_)); -} - -string16 GeolocationConfirmInfoBarDelegate::GetButtonLabel( - InfoBarButton button) const { - return l10n_util::GetStringUTF16((button == BUTTON_OK) ? - IDS_GEOLOCATION_ALLOW_BUTTON : IDS_GEOLOCATION_DENY_BUTTON); -} - -bool GeolocationConfirmInfoBarDelegate::Accept() { - controller_->OnPermissionSet(render_process_id_, render_view_id_, bridge_id_, - requesting_frame_url_, owner()->GetWebContents()->GetURL(), true); - return true; -} - -bool GeolocationConfirmInfoBarDelegate::Cancel() { - controller_->OnPermissionSet(render_process_id_, render_view_id_, bridge_id_, - requesting_frame_url_, owner()->GetWebContents()->GetURL(), - false); - return true; -} - -string16 GeolocationConfirmInfoBarDelegate::GetLinkText() const { - return l10n_util::GetStringUTF16(IDS_LEARN_MORE); -} - -bool GeolocationConfirmInfoBarDelegate::LinkClicked( - WindowOpenDisposition disposition) { - const char kGeolocationLearnMoreUrl[] = -#if defined(OS_CHROMEOS) - "https://www.google.com/support/chromeos/bin/answer.py?answer=142065"; -#else - "https://www.google.com/support/chrome/bin/answer.py?answer=142065"; -#endif - - OpenURLParams params( - google_util::AppendGoogleLocaleParam(GURL(kGeolocationLearnMoreUrl)), - Referrer(), - (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, - content::PAGE_TRANSITION_LINK, false); - owner()->GetWebContents()->OpenURL(params); - return false; // Do not dismiss the info bar. -} - -} // namespace - - // GeolocationInfoBarQueueController::PendingInfoBarRequest ------------------- struct GeolocationInfoBarQueueController::PendingInfoBarRequest { @@ -164,7 +32,7 @@ struct GeolocationInfoBarQueueController::PendingInfoBarRequest { int bridge_id, const GURL& requesting_frame, const GURL& embedder, - base::Callback<void(bool)> callback); + PermissionDecidedCallback callback); bool IsForTab(int p_render_process_id, int p_render_view_id) const; bool IsForPair(const GURL& p_requesting_frame, @@ -178,7 +46,7 @@ struct GeolocationInfoBarQueueController::PendingInfoBarRequest { int bridge_id; GURL requesting_frame; GURL embedder; - base::Callback<void(bool)> callback; + PermissionDecidedCallback callback; GeolocationConfirmInfoBarDelegate* infobar_delegate; }; @@ -188,7 +56,7 @@ GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest( int bridge_id, const GURL& requesting_frame, const GURL& embedder, - base::Callback<void(bool)> callback) + PermissionDecidedCallback callback) : render_process_id(render_process_id), render_view_id(render_view_id), bridge_id(bridge_id), @@ -253,10 +121,8 @@ bool GeolocationInfoBarQueueController::RequestEquals::operator()( // GeolocationInfoBarQueueController ------------------------------------------ GeolocationInfoBarQueueController::GeolocationInfoBarQueueController( - NotifyPermissionSetCallback notify_permission_set_callback, Profile* profile) - : notify_permission_set_callback_(notify_permission_set_callback), - profile_(profile) { + : profile_(profile) { } GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { @@ -268,7 +134,7 @@ void GeolocationInfoBarQueueController::CreateInfoBarRequest( int bridge_id, const GURL& requesting_frame, const GURL& embedder, - base::Callback<void(bool)> callback) { + PermissionDecidedCallback callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // We shouldn't get duplicate requests. @@ -319,18 +185,19 @@ void GeolocationInfoBarQueueController::OnPermissionSet( int bridge_id, const GURL& requesting_frame, const GURL& embedder, + bool update_content_setting, bool allowed) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - ContentSetting content_setting = - allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; - profile_->GetHostContentSettingsMap()->SetContentSetting( - ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), - ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), - CONTENT_SETTINGS_TYPE_GEOLOCATION, - std::string(), - content_setting); - + if (update_content_setting) { + ContentSetting content_setting = + allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; + profile_->GetHostContentSettingsMap()->SetContentSetting( + ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), + ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + content_setting); + } // Cancel this request first, then notify listeners. TODO(pkasting): Why // is this order important? PendingInfoBarRequests requests_to_notify; @@ -370,10 +237,7 @@ void GeolocationInfoBarQueueController::OnPermissionSet( // Send out the permission notifications. for (PendingInfoBarRequests::iterator i = requests_to_notify.begin(); i != requests_to_notify.end(); ++i ) { - notify_permission_set_callback_.Run( - i->render_process_id, i->render_view_id, - i->bridge_id, i->requesting_frame, - i->callback, allowed); + i->callback.Run(allowed); } } @@ -408,6 +272,24 @@ void GeolocationInfoBarQueueController::Observe( } } +GeolocationConfirmInfoBarDelegate* +GeolocationInfoBarQueueController::CreateInfoBarDelegate( + InfoBarTabHelper* infobar_helper, + GeolocationInfoBarQueueController* controller, + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame_url, + const std::string& display_languages) { + return new GeolocationConfirmInfoBarDelegate(infobar_helper, + controller, + render_process_id, + render_view_id, + bridge_id, + requesting_frame_url, + display_languages); +} + void GeolocationInfoBarQueueController::ShowQueuedInfoBar( int render_process_id, int render_view_id, @@ -419,7 +301,7 @@ void GeolocationInfoBarQueueController::ShowQueuedInfoBar( if (i->IsForTab(render_process_id, render_view_id) && !i->infobar_delegate) { RegisterForInfoBarNotifications(helper); - i->infobar_delegate = new GeolocationConfirmInfoBarDelegate( + i->infobar_delegate = CreateInfoBarDelegate( helper, this, render_process_id, render_view_id, i->bridge_id, i->requesting_frame, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); diff --git a/chrome/browser/geolocation/geolocation_infobar_queue_controller.h b/chrome/browser/geolocation/geolocation_infobar_queue_controller.h index dd8543d..10c6094 100644 --- a/chrome/browser/geolocation/geolocation_infobar_queue_controller.h +++ b/chrome/browser/geolocation/geolocation_infobar_queue_controller.h @@ -10,6 +10,7 @@ #include "content/public/browser/notification_registrar.h" class GURL; +class GeolocationConfirmInfoBarDelegate; class InfoBarTabHelper; class Profile; @@ -23,16 +24,9 @@ class Profile; // the notification infrastructure would simplify. class GeolocationInfoBarQueueController : content::NotificationObserver { public: - typedef base::Callback<void(int /* render_process_id */, - int /* render_view_id */, - int /* bridge_id */, - const GURL& /* requesting_frame */, - base::Callback<void(bool)> /* callback */, - bool /* allowed */)> NotifyPermissionSetCallback; - - GeolocationInfoBarQueueController( - NotifyPermissionSetCallback notify_permission_set_callback, - Profile* profile); + typedef base::Callback<void(bool /* allowed */)> PermissionDecidedCallback; + + explicit GeolocationInfoBarQueueController(Profile* profile); virtual ~GeolocationInfoBarQueueController(); // The InfoBar will be displayed immediately if the tab is not already @@ -41,8 +35,8 @@ class GeolocationInfoBarQueueController : content::NotificationObserver { int render_view_id, int bridge_id, const GURL& requesting_frame, - const GURL& emebedder, - base::Callback<void(bool)> callback); + const GURL& embedder, + PermissionDecidedCallback callback); // Cancels a specific infobar request. void CancelInfoBarRequest(int render_process_id, @@ -57,6 +51,7 @@ class GeolocationInfoBarQueueController : content::NotificationObserver { int bridge_id, const GURL& requesting_frame, const GURL& embedder, + bool update_content_setting, bool allowed); // content::NotificationObserver @@ -64,6 +59,19 @@ class GeolocationInfoBarQueueController : content::NotificationObserver { const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; + protected: + // Create an Infobar delegate to ask the whether the requesting frame + // url should be granted geolocation permission. Overrided in + // derived classes to implement alternative UI. + virtual GeolocationConfirmInfoBarDelegate* CreateInfoBarDelegate( + InfoBarTabHelper* infobar_helper, + GeolocationInfoBarQueueController* controller, + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame_url, + const std::string& display_languages); + private: struct PendingInfoBarRequest; class RequestEquals; @@ -86,7 +94,6 @@ class GeolocationInfoBarQueueController : content::NotificationObserver { content::NotificationRegistrar registrar_; - NotifyPermissionSetCallback notify_permission_set_callback_; Profile* const profile_; PendingInfoBarRequests pending_infobar_requests_; }; diff --git a/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc b/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc index 48515b5..c0d16e5 100644 --- a/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc +++ b/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc @@ -73,7 +73,6 @@ class ObservationCountingQueueController : ObservationCountingQueueController::ObservationCountingQueueController( Profile* profile) : GeolocationInfoBarQueueController( - base::Bind(&ObservationCountingQueueController::NotifyPermissionSet), profile), call_count_(0) { } diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 4705483..735cba8 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -851,7 +851,7 @@ content::GeolocationPermissionContext* ProfileImpl::GetGeolocationPermissionContext() { if (!geolocation_permission_context_.get()) { geolocation_permission_context_ = - new ChromeGeolocationPermissionContext(this); + ChromeGeolocationPermissionContext::Create(this); } return geolocation_permission_context_.get(); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c8ab673..4bece04 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -655,6 +655,8 @@ 'browser/geolocation/chrome_access_token_store.h', 'browser/geolocation/chrome_geolocation_permission_context.cc', 'browser/geolocation/chrome_geolocation_permission_context.h', + 'browser/geolocation/geolocation_confirm_infobar_delegate.cc', + 'browser/geolocation/geolocation_confirm_infobar_delegate.h', 'browser/geolocation/geolocation_infobar_queue_controller.cc', 'browser/geolocation/geolocation_infobar_queue_controller.h', 'browser/geolocation/geolocation_prefs.cc', diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index f6f5427..63eab1b 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -715,7 +715,7 @@ content::GeolocationPermissionContext* TestingProfile::GetGeolocationPermissionContext() { if (!geolocation_permission_context_.get()) { geolocation_permission_context_ = - new ChromeGeolocationPermissionContext(this); + ChromeGeolocationPermissionContext::Create(this); } return geolocation_permission_context_.get(); } |