diff options
Diffstat (limited to 'chrome')
23 files changed, 310 insertions, 130 deletions
diff --git a/chrome/browser/chrome_quota_permission_context.cc b/chrome/browser/chrome_quota_permission_context.cc index fc03747..f2ef8045 100644 --- a/chrome/browser/chrome_quota_permission_context.cc +++ b/chrome/browser/chrome_quota_permission_context.cc @@ -22,6 +22,7 @@ #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/l10n/l10n_util.h" #include "url/gurl.h" @@ -47,10 +48,11 @@ class QuotaPermissionRequest : public PermissionBubbleRequest { virtual ~QuotaPermissionRequest(); // PermissionBubbleRequest: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; @@ -80,6 +82,11 @@ QuotaPermissionRequest::QuotaPermissionRequest( QuotaPermissionRequest::~QuotaPermissionRequest() {} +int QuotaPermissionRequest::GetIconID() const { + // TODO(gbillock): get the proper image here + return IDR_INFOBAR_WARNING; +} + base::string16 QuotaPermissionRequest::GetMessageText() const { return l10n_util::GetStringFUTF16( (requested_quota_ > kRequestLargeQuotaThreshold ? @@ -92,12 +99,13 @@ base::string16 QuotaPermissionRequest::GetMessageTextFragment() const { return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT); } -base::string16 QuotaPermissionRequest::GetAlternateAcceptButtonText() const { - return base::string16(); +bool QuotaPermissionRequest::HasUserGesture() const { + // TODO(gbillock): plumb this through + return false; } -base::string16 QuotaPermissionRequest::GetAlternateDenyButtonText() const { - return base::string16(); +GURL QuotaPermissionRequest::GetRequestingHostname() const { + return origin_url_; } void QuotaPermissionRequest::PermissionGranted() { diff --git a/chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc b/chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc index 1930539..11c206f 100644 --- a/chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc +++ b/chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc @@ -8,6 +8,7 @@ #include "chrome/browser/custom_handlers/protocol_handler_registry.h" #include "content/public/browser/user_metrics.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" namespace { @@ -26,13 +27,21 @@ base::string16 GetProtocolName( RegisterProtocolHandlerPermissionRequest ::RegisterProtocolHandlerPermissionRequest( ProtocolHandlerRegistry* registry, - const ProtocolHandler& handler) + const ProtocolHandler& handler, + GURL url, + bool user_gesture) : registry_(registry), - handler_(handler) {} + handler_(handler), + url_(url), + user_gesture_(user_gesture) {} RegisterProtocolHandlerPermissionRequest:: ~RegisterProtocolHandlerPermissionRequest() {} +int RegisterProtocolHandlerPermissionRequest::GetIconID() const { + return IDR_REGISTER_PROTOCOL_HANDLER; +} + base::string16 RegisterProtocolHandlerPermissionRequest::GetMessageText() const { ProtocolHandler old_handler = registry_->GetHandlerFor(handler_.protocol()); @@ -56,16 +65,12 @@ RegisterProtocolHandlerPermissionRequest::GetMessageTextFragment() const { GetProtocolName(handler_), old_handler.title()); } -base::string16 RegisterProtocolHandlerPermissionRequest:: -GetAlternateAcceptButtonText() const { - return l10n_util::GetStringFUTF16(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT, - handler_.title()); +bool RegisterProtocolHandlerPermissionRequest::HasUserGesture() const { + return user_gesture_; } -base::string16 RegisterProtocolHandlerPermissionRequest:: -GetAlternateDenyButtonText() const { - return l10n_util::GetStringFUTF16(IDS_REGISTER_PROTOCOL_HANDLER_DENY, - handler_.title()); +GURL RegisterProtocolHandlerPermissionRequest::GetRequestingHostname() const { + return url_; } void RegisterProtocolHandlerPermissionRequest::PermissionGranted() { diff --git a/chrome/browser/custom_handlers/register_protocol_handler_permission_request.h b/chrome/browser/custom_handlers/register_protocol_handler_permission_request.h index 2486d38..151b9d7 100644 --- a/chrome/browser/custom_handlers/register_protocol_handler_permission_request.h +++ b/chrome/browser/custom_handlers/register_protocol_handler_permission_request.h @@ -18,14 +18,17 @@ class RegisterProtocolHandlerPermissionRequest public: RegisterProtocolHandlerPermissionRequest( ProtocolHandlerRegistry* registry, - const ProtocolHandler& handler); + const ProtocolHandler& handler, + GURL url, + bool user_gesture); virtual ~RegisterProtocolHandlerPermissionRequest(); // PermissionBubbleRequest: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; @@ -34,6 +37,8 @@ class RegisterProtocolHandlerPermissionRequest private: ProtocolHandlerRegistry* registry_; ProtocolHandler handler_; + GURL url_; + bool user_gesture_; DISALLOW_COPY_AND_ASSIGN(RegisterProtocolHandlerPermissionRequest); }; diff --git a/chrome/browser/download/download_permission_request.cc b/chrome/browser/download/download_permission_request.cc index b671114..18e1995 100644 --- a/chrome/browser/download/download_permission_request.cc +++ b/chrome/browser/download/download_permission_request.cc @@ -4,6 +4,7 @@ #include "chrome/browser/download/download_permission_request.h" +#include "content/public/browser/web_contents.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" @@ -14,6 +15,10 @@ DownloadPermissionRequest::DownloadPermissionRequest( DownloadPermissionRequest::~DownloadPermissionRequest() {} +int DownloadPermissionRequest::GetIconID() const { + return IDR_INFOBAR_MULTIPLE_DOWNLOADS; +} + base::string16 DownloadPermissionRequest::GetMessageText() const { return l10n_util::GetStringUTF16(IDS_MULTI_DOWNLOAD_WARNING); } @@ -22,12 +27,18 @@ base::string16 DownloadPermissionRequest::GetMessageTextFragment() const { return l10n_util::GetStringUTF16(IDS_MULTI_DOWNLOAD_PERMISSION_FRAGMENT); } -base::string16 DownloadPermissionRequest::GetAlternateAcceptButtonText() const { - return l10n_util::GetStringUTF16(IDS_MULTI_DOWNLOAD_WARNING_ALLOW); +bool DownloadPermissionRequest::HasUserGesture() const { + // TODO(gbillock): user gesture for multiple downloads is difficult to + // propagate, and the normal thing is that it is background. + return false; } -base::string16 DownloadPermissionRequest::GetAlternateDenyButtonText() const { - return l10n_util::GetStringUTF16(IDS_MULTI_DOWNLOAD_WARNING_DENY); +GURL DownloadPermissionRequest::GetRequestingHostname() const { + const content::WebContents* web_contents = host_->web_contents(); + if (web_contents) { + return web_contents->GetURL(); + } + return GURL(); } void DownloadPermissionRequest::PermissionGranted() { diff --git a/chrome/browser/download/download_permission_request.h b/chrome/browser/download/download_permission_request.h index 4337636..047c375 100644 --- a/chrome/browser/download/download_permission_request.h +++ b/chrome/browser/download/download_permission_request.h @@ -21,10 +21,11 @@ class DownloadPermissionRequest : public PermissionBubbleRequest { virtual ~DownloadPermissionRequest(); // PermisisonBubbleDelegate: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc index cf236ba..f9b4632 100644 --- a/chrome/browser/download/download_request_limiter_unittest.cc +++ b/chrome/browser/download/download_request_limiter_unittest.cc @@ -45,6 +45,8 @@ class FakePermissionBubbleView : public PermissionBubbleView { const std::vector<bool>& accept_state, bool customization_mode) OVERRIDE; + virtual bool CanAcceptRequestUpdate() OVERRIDE { return false; } + virtual void Hide() OVERRIDE {} private: diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc index 412793c..456b68c 100644 --- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc +++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc @@ -28,6 +28,7 @@ #include "extensions/browser/view_type_utils.h" #include "extensions/common/extension.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" @@ -45,10 +46,11 @@ class GeolocationPermissionRequest : public PermissionBubbleRequest { virtual ~GeolocationPermissionRequest(); // PermissionBubbleDelegate: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; @@ -76,6 +78,10 @@ GeolocationPermissionRequest::GeolocationPermissionRequest( GeolocationPermissionRequest::~GeolocationPermissionRequest() {} +int GeolocationPermissionRequest::GetIconID() const { + return IDR_GEOLOCATION_INFOBAR_ICON; +} + base::string16 GeolocationPermissionRequest::GetMessageText() const { return l10n_util::GetStringFUTF16(IDS_GEOLOCATION_INFOBAR_QUESTION, net::FormatUrl(requesting_frame_, display_languages_)); @@ -85,14 +91,13 @@ base::string16 GeolocationPermissionRequest::GetMessageTextFragment() const { return l10n_util::GetStringUTF16(IDS_GEOLOCATION_INFOBAR_PERMISSION_FRAGMENT); } -base::string16 -GeolocationPermissionRequest::GetAlternateAcceptButtonText() const { - return l10n_util::GetStringUTF16(IDS_GEOLOCATION_ALLOW_BUTTON); +bool GeolocationPermissionRequest::HasUserGesture() const { + // TODO(gbillock): plumb this through from GeolocationDispatcher. + return false; } -base::string16 -GeolocationPermissionRequest::GetAlternateDenyButtonText() const { - return l10n_util::GetStringUTF16(IDS_GEOLOCATION_DENY_BUTTON); +GURL GeolocationPermissionRequest::GetRequestingHostname() const { + return requesting_frame_; } void GeolocationPermissionRequest::PermissionGranted() { @@ -197,6 +202,7 @@ void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest( int render_view_id, int bridge_id, const GURL& requesting_frame) { + // TODO(gbillock): cancel permission bubble request. CancelPendingInfobarRequest(PermissionRequestID( render_process_id, render_view_id, bridge_id, 0)); } diff --git a/chrome/browser/media/chrome_midi_permission_context.cc b/chrome/browser/media/chrome_midi_permission_context.cc index 7abcaff..062be1c 100644 --- a/chrome/browser/media/chrome_midi_permission_context.cc +++ b/chrome/browser/media/chrome_midi_permission_context.cc @@ -17,6 +17,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" @@ -31,10 +32,11 @@ class MidiPermissionRequest : public PermissionBubbleRequest { virtual ~MidiPermissionRequest(); // PermissionBubbleDelegate: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; @@ -64,6 +66,10 @@ MidiPermissionRequest::MidiPermissionRequest( MidiPermissionRequest::~MidiPermissionRequest() {} +int MidiPermissionRequest::GetIconID() const { + return IDR_ALLOWED_MIDI_SYSEX; +} + base::string16 MidiPermissionRequest::GetMessageText() const { return l10n_util::GetStringFUTF16( IDS_MIDI_SYSEX_INFOBAR_QUESTION, @@ -74,12 +80,13 @@ base::string16 MidiPermissionRequest::GetMessageTextFragment() const { return l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_PERMISSION_FRAGMENT); } -base::string16 MidiPermissionRequest::GetAlternateAcceptButtonText() const { - return l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_ALLOW_BUTTON); +bool MidiPermissionRequest::HasUserGesture() const { + // TODO(gbillock): plumb through. + return false; } -base::string16 MidiPermissionRequest::GetAlternateDenyButtonText() const { - return l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_DENY_BUTTON); +GURL MidiPermissionRequest::GetRequestingHostname() const { + return requesting_frame_; } void MidiPermissionRequest::PermissionGranted() { diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc index 3b4e461..e4296ce 100644 --- a/chrome/browser/media/media_stream_devices_controller.cc +++ b/chrome/browser/media/media_stream_devices_controller.cc @@ -349,6 +349,13 @@ void MediaStreamDevicesController::Deny(bool update_content_setting) { cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>()); } +int MediaStreamDevicesController::GetIconID() const { + if (HasVideo()) + return IDR_INFOBAR_MEDIA_STREAM_CAMERA; + + return IDR_INFOBAR_MEDIA_STREAM_MIC; +} + base::string16 MediaStreamDevicesController::GetMessageText() const { int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; if (!HasAudio()) @@ -368,14 +375,13 @@ base::string16 MediaStreamDevicesController::GetMessageTextFragment() const { return l10n_util::GetStringUTF16(message_id); } -base::string16 -MediaStreamDevicesController::GetAlternateAcceptButtonText() const { - return l10n_util::GetStringUTF16(IDS_MEDIA_CAPTURE_ALLOW); +bool MediaStreamDevicesController::HasUserGesture() const { + // TODO(gbillock): plumb this through + return false; } -base::string16 -MediaStreamDevicesController::GetAlternateDenyButtonText() const { - return l10n_util::GetStringUTF16(IDS_MEDIA_CAPTURE_DENY); +GURL MediaStreamDevicesController::GetRequestingHostname() const { + return request_.security_origin; } void MediaStreamDevicesController::PermissionGranted() { diff --git a/chrome/browser/media/media_stream_devices_controller.h b/chrome/browser/media/media_stream_devices_controller.h index 2666882..1da55bd 100644 --- a/chrome/browser/media/media_stream_devices_controller.h +++ b/chrome/browser/media/media_stream_devices_controller.h @@ -72,10 +72,11 @@ class MediaStreamDevicesController : public PermissionBubbleRequest { void Deny(bool update_content_setting); // PermissionBubbleRequest: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc index 9dc9d98..2f82841 100644 --- a/chrome/browser/notifications/desktop_notification_service.cc +++ b/chrome/browser/notifications/desktop_notification_service.cc @@ -77,10 +77,11 @@ class NotificationPermissionRequest : public PermissionBubbleRequest { virtual ~NotificationPermissionRequest(); // PermissionBubbleDelegate: + virtual int GetIconID() const OVERRIDE; virtual base::string16 GetMessageText() const OVERRIDE; virtual base::string16 GetMessageTextFragment() const OVERRIDE; - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE; - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE; + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; virtual void PermissionGranted() OVERRIDE; virtual void PermissionDenied() OVERRIDE; virtual void Cancelled() OVERRIDE; @@ -126,6 +127,10 @@ NotificationPermissionRequest::NotificationPermissionRequest( NotificationPermissionRequest::~NotificationPermissionRequest() {} +int NotificationPermissionRequest::GetIconID() const { + return IDR_INFOBAR_DESKTOP_NOTIFICATIONS; +} + base::string16 NotificationPermissionRequest::GetMessageText() const { return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS, display_name_); @@ -136,14 +141,14 @@ NotificationPermissionRequest::GetMessageTextFragment() const { return l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSIONS_FRAGMENT); } -base::string16 -NotificationPermissionRequest::GetAlternateAcceptButtonText() const { - return l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSION_YES); +bool NotificationPermissionRequest::HasUserGesture() const { + // Currently notification permission requests are only issued on + // user gesture. + return true; } -base::string16 -NotificationPermissionRequest::GetAlternateDenyButtonText() const { - return l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSION_NO); +GURL NotificationPermissionRequest::GetRequestingHostname() const { + return origin_; } void NotificationPermissionRequest::PermissionGranted() { diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 71624dc..7eb07ea 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -1653,7 +1653,8 @@ void Browser::RegisterProtocolHandler(WebContents* web_contents, PermissionBubbleManager::FromWebContents(web_contents); if (PermissionBubbleManager::Enabled() && bubble_manager) { bubble_manager->AddRequest( - new RegisterProtocolHandlerPermissionRequest(registry, handler)); + new RegisterProtocolHandlerPermissionRequest(registry, handler, + url, user_gesture)); } else { RegisterProtocolHandlerInfoBarDelegate::Create( InfoBarService::FromWebContents(web_contents), registry, handler); diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h index 75df075..e063fc8 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h @@ -28,6 +28,7 @@ class PermissionBubbleCocoa : public PermissionBubbleView { bool customization_mode) OVERRIDE; virtual void Hide() OVERRIDE; virtual void SetDelegate(Delegate* delegate) OVERRIDE; + virtual bool CanAcceptRequestUpdate() OVERRIDE; // Called when |bubbleController_| is closing. void OnBubbleClosing(); diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm index c90c8db..3984236 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm @@ -54,6 +54,12 @@ void PermissionBubbleCocoa::SetDelegate(Delegate* delegate) { delegate_ = delegate; } +bool PermissionBubbleCocoa::CanAcceptRequestUpdate() { + // TODO(gbillock): implement. Should return true if the mouse is not over the + // dialog. + return false; +} + void PermissionBubbleCocoa::OnBubbleClosing() { bubbleController_ = nil; } diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc index 850544b..fc2852b 100644 --- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc +++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc @@ -158,26 +158,15 @@ PermissionsBubbleDelegateView::PermissionsBubbleDelegateView( button_layout->AddView(new views::View()); } - // Lay out the Deny/Allow buttons. Use custom text if there is only - // one permission request. - base::string16 deny_text; - base::string16 allow_text; - if (requests.size() == 1) { - deny_text = requests[0]->GetAlternateDenyButtonText(); - allow_text = requests[0]->GetAlternateAcceptButtonText(); - } - - if (deny_text.empty()) - deny_text = l10n_util::GetStringUTF16(IDS_PERMISSION_DENY); - if (allow_text.empty()) - allow_text = l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW); - + // Lay out the Deny/Allow buttons. + base::string16 deny_text = l10n_util::GetStringUTF16(IDS_PERMISSION_DENY); views::LabelButton* deny_button = new views::LabelButton(this, deny_text); deny_button->SetStyle(views::Button::STYLE_BUTTON); deny_button->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont)); button_layout->AddView(deny_button); deny_ = deny_button; + base::string16 allow_text = l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW); views::LabelButton* allow_button = new views::LabelButton(this, allow_text); allow_button->SetStyle(views::Button::STYLE_BUTTON); allow_button->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont)); @@ -269,6 +258,12 @@ void PermissionBubbleViewViews::Show( bubble_delegate->SizeToContents(); } +bool PermissionBubbleViewViews::CanAcceptRequestUpdate() { + // TODO(gbillock): support this. + // return bubble_delegate_ && bubble_delegate_->IsMouseHovered(); + return false; +} + void PermissionBubbleViewViews::Hide() { if (bubble_delegate_) { bubble_delegate_->Close(); diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.h b/chrome/browser/ui/views/website_settings/permissions_bubble_view.h index 991e70e..7a72075 100644 --- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.h +++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.h @@ -25,6 +25,7 @@ class PermissionBubbleViewViews : public PermissionBubbleView { virtual void Show(const std::vector<PermissionBubbleRequest*>& requests, const std::vector<bool>& accept_state, bool customization_mode) OVERRIDE; + virtual bool CanAcceptRequestUpdate() OVERRIDE; virtual void Hide() OVERRIDE; void Closing(); diff --git a/chrome/browser/ui/website_settings/mock_permission_bubble_request.cc b/chrome/browser/ui/website_settings/mock_permission_bubble_request.cc index 9c8770e..b7555fb 100644 --- a/chrome/browser/ui/website_settings/mock_permission_bubble_request.cc +++ b/chrome/browser/ui/website_settings/mock_permission_bubble_request.cc @@ -17,3 +17,15 @@ void MockPermissionBubbleRequest::SetText(const base::string16& text) { ON_CALL(*this, GetMessageText()).WillByDefault(testing::Return(text)); ON_CALL(*this, GetMessageTextFragment()).WillByDefault(testing::Return(text)); } + +int MockPermissionBubbleRequest::GetIconID() const { + return 0; +} + +bool MockPermissionBubbleRequest::HasUserGesture() const { + return false; +} + +GURL MockPermissionBubbleRequest::GetRequestingHostname() const { + return GURL("http://www.google.com"); +} diff --git a/chrome/browser/ui/website_settings/mock_permission_bubble_request.h b/chrome/browser/ui/website_settings/mock_permission_bubble_request.h index 0398d5d..fabaa88 100644 --- a/chrome/browser/ui/website_settings/mock_permission_bubble_request.h +++ b/chrome/browser/ui/website_settings/mock_permission_bubble_request.h @@ -8,16 +8,18 @@ #include "base/strings/string16.h" #include "chrome/browser/ui/website_settings/permission_bubble_request.h" #include "testing/gmock/include/gmock/gmock.h" +#include "url/gurl.h" class MockPermissionBubbleRequest : public PermissionBubbleRequest { public: explicit MockPermissionBubbleRequest(const std::string& text); virtual ~MockPermissionBubbleRequest(); + virtual int GetIconID() const OVERRIDE; MOCK_CONST_METHOD0(GetMessageText, base::string16()); MOCK_CONST_METHOD0(GetMessageTextFragment, base::string16()); - MOCK_CONST_METHOD0(GetAlternateAcceptButtonText, base::string16()); - MOCK_CONST_METHOD0(GetAlternateDenyButtonText, base::string16()); + virtual bool HasUserGesture() const OVERRIDE; + virtual GURL GetRequestingHostname() const OVERRIDE; MOCK_METHOD0(PermissionGranted, void()); MOCK_METHOD0(PermissionDenied, void()); MOCK_METHOD0(Cancelled, void()); diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.cc b/chrome/browser/ui/website_settings/permission_bubble_manager.cc index 09b2add..60202eb 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_manager.cc +++ b/chrome/browser/ui/website_settings/permission_bubble_manager.cc @@ -24,23 +24,65 @@ bool PermissionBubbleManager::Enabled() { switches::kEnablePermissionsBubbles); } + + +PermissionBubbleManager::PermissionBubbleManager( + content::WebContents* web_contents) + : content::WebContentsObserver(web_contents), + bubble_showing_(false), + view_(NULL), + customization_mode_(false) { + timer_.reset(new base::Timer(FROM_HERE, + base::TimeDelta::FromMilliseconds(kPermissionsCoalesceIntervalMs), + base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)), + false)); +} + +PermissionBubbleManager::~PermissionBubbleManager() { + if (view_ != NULL) + view_->SetDelegate(NULL); + + std::vector<PermissionBubbleRequest*>::iterator requests_iter; + for (requests_iter = requests_.begin(); + requests_iter != requests_.end(); + requests_iter++) { + (*requests_iter)->RequestFinished(); + } + for (requests_iter = queued_requests_.begin(); + requests_iter != queued_requests_.end(); + requests_iter++) { + (*requests_iter)->RequestFinished(); + } +} + void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { - // Don't re-add an existing request. + // Don't re-add an existing request or one with a duplicate text request. std::vector<PermissionBubbleRequest*>::iterator requests_iter; for (requests_iter = requests_.begin(); requests_iter != requests_.end(); requests_iter++) { if (*requests_iter == request) return; + // TODO(gbillock): worry about the requesting host name as well. + if ((*requests_iter)->GetMessageTextFragment() == + request->GetMessageTextFragment()) { + request->RequestFinished(); + return; + } + } + for (requests_iter = queued_requests_.begin(); + requests_iter != queued_requests_.end(); + requests_iter++) { + if (*requests_iter == request) + return; + if ((*requests_iter)->GetMessageTextFragment() == + request->GetMessageTextFragment()) { + request->RequestFinished(); + return; + } } if (bubble_showing_) { - for (requests_iter = queued_requests_.begin(); - requests_iter != queued_requests_.end(); - requests_iter++) { - if (*requests_iter == request) - return; - } queued_requests_.push_back(request); return; } @@ -54,6 +96,11 @@ void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { timer_->Reset(); } +void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) { + // TODO(gbillock): implement + NOTREACHED(); +} + void PermissionBubbleManager::SetView(PermissionBubbleView* view) { if (view == view_) return; @@ -78,26 +125,6 @@ void PermissionBubbleManager::SetView(PermissionBubbleView* view) { view_->Hide(); } -PermissionBubbleManager::PermissionBubbleManager( - content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), - bubble_showing_(false), - view_(NULL), - customization_mode_(false) { - timer_.reset(new base::Timer(FROM_HERE, - base::TimeDelta::FromMilliseconds(kPermissionsCoalesceIntervalMs), - base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)), - false)); -} - -PermissionBubbleManager::~PermissionBubbleManager() { - if (view_ != NULL) { - view_->SetDelegate(NULL); - view_->Hide(); - bubble_showing_ = false; - } -} - void PermissionBubbleManager::DidFinishLoad( int64 frame_id, const GURL& validated_url, diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.h b/chrome/browser/ui/website_settings/permission_bubble_manager.h index 0985025..d784541 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_manager.h +++ b/chrome/browser/ui/website_settings/permission_bubble_manager.h @@ -35,15 +35,25 @@ class PermissionBubbleManager virtual ~PermissionBubbleManager(); - // Add a new request to the permission bubble. Ownership of the request + // Adds a new request to the permission bubble. Ownership of the request // remains with the caller. The caller must arrange for the request to // outlive the PermissionBubbleManager. If a bubble is visible when this // call is made, the request will be queued up and shown after the current - // bubble closes. + // bubble closes. A request with message text identical to an outstanding + // request will receive a RequestFinished call immediately and not be added. virtual void AddRequest(PermissionBubbleRequest* request); - // Set the active view for the permission bubble. If this is NULL, it - // means the permission bubble is no longer showing. + // Cancels an outstanding request. This may have different effects depending + // on what is going on with the bubble. If the request is pending, it will be + // removed and never shown. If the request is showing, it will continue to be + // shown, but the user's action won't be reported back to the request object. + // In some circumstances, we can remove the request from the bubble, and may + // do so. The caller may delete the request after calling this method. + virtual void CancelRequest(PermissionBubbleRequest* request); + + // Sets the active view for the permission bubble. If this is NULL, it + // means any existing permission bubble can no longer be shown. Does not + // take ownership of the view. virtual void SetView(PermissionBubbleView* view) OVERRIDE; protected: diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc b/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc index 3e5a1c1..2cb4059 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc +++ b/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc @@ -16,24 +16,33 @@ namespace { class MockRequest : public PermissionBubbleRequest { public: - MockRequest() : granted_(false), cancelled_(false), finished_(false) {} + explicit MockRequest(const base::string16& message) + : message_(message), + granted_(false), + cancelled_(false), + finished_(false) {} + virtual ~MockRequest() {} // PermissionBubbleRequest: + virtual int GetIconID() const OVERRIDE { + return 5; + } + virtual base::string16 GetMessageText() const OVERRIDE { - return base::ASCIIToUTF16("test"); + return message_; } virtual base::string16 GetMessageTextFragment() const OVERRIDE { - return base::ASCIIToUTF16("test"); + return message_; } - virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE { - return base::ASCIIToUTF16("button"); + virtual bool HasUserGesture() const OVERRIDE { + return false; } - virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE { - return base::ASCIIToUTF16("button"); + virtual GURL GetRequestingHostname() const OVERRIDE { + return GURL("http://www.google.com/"); } virtual void PermissionGranted() OVERRIDE { @@ -53,6 +62,7 @@ class MockRequest : public PermissionBubbleRequest { finished_ = true; } + base::string16 message_; bool granted_; bool cancelled_; bool finished_; @@ -61,7 +71,7 @@ class MockRequest : public PermissionBubbleRequest { class MockView : public PermissionBubbleView { public: MockView() : shown_(false), delegate_(NULL) {} - ~MockView() {} + virtual ~MockView() {} void Clear() { shown_ = false; @@ -88,6 +98,10 @@ class MockView : public PermissionBubbleView { shown_ = false; } + virtual bool CanAcceptRequestUpdate() OVERRIDE { + return true; + } + bool shown_; Delegate* delegate_; std::vector<PermissionBubbleRequest*> permission_requests_; @@ -99,6 +113,11 @@ class MockView : public PermissionBubbleView { class PermissionBubbleManagerTest : public testing::Test { public: PermissionBubbleManagerTest(); + virtual ~PermissionBubbleManagerTest() {} + + virtual void TearDown() { + manager_.reset(); + } void ToggleAccept(int index, bool value) { manager_->ToggleAccept(index, value); @@ -123,7 +142,9 @@ class PermissionBubbleManagerTest : public testing::Test { }; PermissionBubbleManagerTest::PermissionBubbleManagerTest() - : manager_(new PermissionBubbleManager(NULL)), + : request1_(base::ASCIIToUTF16("test1")), + request2_(base::ASCIIToUTF16("test2")), + manager_(new PermissionBubbleManager(NULL)), ui_thread_(content::BrowserThread::UI, &message_loop_) { manager_->SetCoalesceIntervalForTesting(0); } @@ -302,3 +323,41 @@ TEST_F(PermissionBubbleManagerTest, SequentialRequests) { EXPECT_FALSE(view_.shown_); EXPECT_TRUE(request2_.granted_); } + +TEST_F(PermissionBubbleManagerTest, SameRequestRejected) { + manager_->SetView(&view_); + manager_->AddRequest(&request1_); + manager_->AddRequest(&request1_); + EXPECT_FALSE(request1_.finished_); + + WaitForCoalescing(); + EXPECT_TRUE(view_.shown_); + ASSERT_EQ(1u, view_.permission_requests_.size()); + EXPECT_EQ(&request1_, view_.permission_requests_[0]); +} + +TEST_F(PermissionBubbleManagerTest, DuplicateRequestRejected) { + manager_->SetView(&view_); + manager_->AddRequest(&request1_); + MockRequest dupe_request(base::ASCIIToUTF16("test1")); + manager_->AddRequest(&dupe_request); + EXPECT_TRUE(dupe_request.finished_); + EXPECT_FALSE(request1_.finished_); +} + +TEST_F(PermissionBubbleManagerTest, DuplicateQueuedRequest) { + manager_->SetView(&view_); + manager_->AddRequest(&request1_); + WaitForCoalescing(); + manager_->AddRequest(&request2_); + + MockRequest dupe_request(base::ASCIIToUTF16("test1")); + manager_->AddRequest(&dupe_request); + EXPECT_TRUE(dupe_request.finished_); + EXPECT_FALSE(request1_.finished_); + + MockRequest dupe_request2(base::ASCIIToUTF16("test2")); + manager_->AddRequest(&dupe_request2); + EXPECT_TRUE(dupe_request2.finished_); + EXPECT_FALSE(request2_.finished_); +} diff --git a/chrome/browser/ui/website_settings/permission_bubble_request.h b/chrome/browser/ui/website_settings/permission_bubble_request.h index 4beec27..8093515 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_request.h +++ b/chrome/browser/ui/website_settings/permission_bubble_request.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_REQUEST_H_ #include "base/strings/string16.h" +#include "url/gurl.h" // Describes the interface a feature utilizing permission bubbles should // implement. A class of this type is registered with the permission bubble @@ -19,31 +20,27 @@ class PermissionBubbleRequest { public: virtual ~PermissionBubbleRequest() {} + // The icon to use next to the message text fragment in the permission bubble. + // Must be a valid icon of size 16x16. (TODO(gbillock): tbd size) + virtual int GetIconID() const = 0; + // Returns the full prompt text for this permission. This is the only text // that will be shown in the single-permission case and should be phrased // positively as a complete sentence. virtual base::string16 GetMessageText() const = 0; // Returns the shortened prompt text for this permission. Must be phrased - // positively -- the permission bubble may coalesce different requests, and - // if it does, this text will be displayed next to a bullet or checkbox - // indicating the user grants the permission. + // as a heading, e.g. "Location", or "Camera". The permission bubble may + // coalesce different requests, and if it does, this text will be displayed + // next to an image and indicate the user grants the permission. virtual base::string16 GetMessageTextFragment() const = 0; - // May return alternative text for the accept button in the case where this - // single permission request is triggered in the bubble. If it returns an - // empty string the default is used. - // If the permission request is coalesced, the text will revert to the default - // "Accept"-alike, so the message text must be clear enough for users to - // understand even if this text is not used. - virtual base::string16 GetAlternateAcceptButtonText() const = 0; + // Get whether this request was accompanied by a user gesture. User gestured + // permissions requests will not be suppressed. + virtual bool HasUserGesture() const = 0; - // May return alternative text for the deny button in the case where this - // single permission request is triggered in the bubble. If it returns an - // empty string the default is used. This text may not be used at all, - // so the |GetMessageText()| prompt should be clear enough to convey the - // permission request with generic button text. - virtual base::string16 GetAlternateDenyButtonText() const = 0; + // Get the hostname on whose behalf this permission request is being made. + virtual GURL GetRequestingHostname() const = 0; // Called when the user has granted the requested permission. virtual void PermissionGranted() = 0; diff --git a/chrome/browser/ui/website_settings/permission_bubble_view.h b/chrome/browser/ui/website_settings/permission_bubble_view.h index b7d0199..5835a47 100644 --- a/chrome/browser/ui/website_settings/permission_bubble_view.h +++ b/chrome/browser/ui/website_settings/permission_bubble_view.h @@ -20,6 +20,8 @@ class PermissionBubbleView { // be persisted in the per-tab UI state. class Delegate { public: + virtual ~Delegate() {} + virtual void ToggleAccept(int index, bool new_value) = 0; virtual void SetCustomizationMode() = 0; virtual void Accept() = 0; @@ -28,14 +30,24 @@ class PermissionBubbleView { virtual void SetView(PermissionBubbleView* view) = 0; }; + virtual ~PermissionBubbleView() {} + // Sets the delegate which will receive UI events forwarded from the bubble. virtual void SetDelegate(Delegate* delegate) = 0; - // Causes the bubble to show up with the given contents. + // Causes the bubble to show up with the given contents. This method may be + // called with mostly-identical contents to the existing contents. This can + // happen, for instance, if a new permission is requested and + // CanAcceptRequestUpdate() is true. virtual void Show( const std::vector<PermissionBubbleRequest*>& requests, const std::vector<bool>& accept_state, - bool custommization_mode) = 0; + bool customization_mode) = 0; + + // Returns true if the view can accept a new Show() command to coalesce + // requests. Currently the policy is that this should return true if the view + // is being shown and the mouse is not over the view area (!IsMouseHovered). + virtual bool CanAcceptRequestUpdate() = 0; // Hides the permission bubble. virtual void Hide() = 0; |