Commit b968c195 authored by Balazs Engedy's avatar Balazs Engedy Committed by Commit Bot

Add flavor of quiet UI to show on abusive sites.

This patch adds a flavor of the quiet notification permission UI to be
shown on sites known to trick or force users to accept the notification
permission.

Bug: 1081233
Change-Id: I4ed49fc1b260c261824efe7741f155ed2f7d643a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2199150Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768775}
parent 686f40af
...@@ -29,8 +29,14 @@ public class PermissionInfoBar ...@@ -29,8 +29,14 @@ public class PermissionInfoBar
/** The content settings types corresponding to the permission requested in this infobar. */ /** The content settings types corresponding to the permission requested in this infobar. */
protected int[] mContentSettingsTypes; protected int[] mContentSettingsTypes;
/** Whether the last clicked button was the "Manage" (secondary) button. */ /** Whether the secondary button should act as a "Manage" button to open settings. */
protected boolean mManageButtonLastClicked; protected boolean mSecondaryButtonShouldOpenSettings;
/**
* Whether the last clicked button opened settings, requiring the dialog to stay interactive
* when the user switches back.
*/
protected boolean mLastClickOpenedSettings;
/** Whether the infobar should be shown as a compact mini-infobar or a classic expanded one. */ /** Whether the infobar should be shown as a compact mini-infobar or a classic expanded one. */
private boolean mIsExpanded; private boolean mIsExpanded;
...@@ -46,12 +52,14 @@ public class PermissionInfoBar ...@@ -46,12 +52,14 @@ public class PermissionInfoBar
protected PermissionInfoBar(WindowAndroid window, int[] contentSettingsTypes, protected PermissionInfoBar(WindowAndroid window, int[] contentSettingsTypes,
int iconDrawableId, String compactMessage, String compactLinkText, String message, int iconDrawableId, String compactMessage, String compactLinkText, String message,
String description, String primaryButtonText, String secondaryButtonText) { String description, String primaryButtonText, String secondaryButtonText,
boolean secondaryButtonShouldOpenSettings) {
super(iconDrawableId, R.color.infobar_icon_drawable_color, null /* iconBitmap */, message, super(iconDrawableId, R.color.infobar_icon_drawable_color, null /* iconBitmap */, message,
null /* linkText */, primaryButtonText, secondaryButtonText); null /* linkText */, primaryButtonText, secondaryButtonText);
mWindow = window; mWindow = window;
mContentSettingsTypes = contentSettingsTypes; mContentSettingsTypes = contentSettingsTypes;
mManageButtonLastClicked = false; mSecondaryButtonShouldOpenSettings = secondaryButtonShouldOpenSettings;
mLastClickOpenedSettings = false;
mIsExpanded = false; mIsExpanded = false;
mCompactLinkText = compactLinkText; mCompactLinkText = compactLinkText;
mCompactMessage = compactMessage; mCompactMessage = compactMessage;
...@@ -75,12 +83,12 @@ public class PermissionInfoBar ...@@ -75,12 +83,12 @@ public class PermissionInfoBar
public boolean areControlsEnabled() { public boolean areControlsEnabled() {
// The controls need to be enbled after the user clicks `manage` since they will return to // The controls need to be enbled after the user clicks `manage` since they will return to
// the page and the infobar still needs to be kept active. // the page and the infobar still needs to be kept active.
return super.areControlsEnabled() || mManageButtonLastClicked; return super.areControlsEnabled() || mLastClickOpenedSettings;
} }
@Override @Override
public void onButtonClicked(final boolean isPrimaryButton) { public void onButtonClicked(final boolean isPrimaryButton) {
mManageButtonLastClicked = !isPrimaryButton; mLastClickOpenedSettings = false;
if (getContext() == null) { if (getContext() == null) {
onButtonClickedInternal(isPrimaryButton); onButtonClickedInternal(isPrimaryButton);
return; return;
...@@ -93,9 +101,10 @@ public class PermissionInfoBar ...@@ -93,9 +101,10 @@ public class PermissionInfoBar
mWindow, mContentSettingsTypes.clone(), this)) { mWindow, mContentSettingsTypes.clone(), this)) {
return; return;
} }
} else { } else if (mSecondaryButtonShouldOpenSettings) {
launchNotificationsSettingsPage(); launchNotificationsSettingsPage();
} }
onButtonClickedInternal(isPrimaryButton); onButtonClickedInternal(isPrimaryButton);
} }
...@@ -130,6 +139,7 @@ public class PermissionInfoBar ...@@ -130,6 +139,7 @@ public class PermissionInfoBar
} }
private void launchNotificationsSettingsPage() { private void launchNotificationsSettingsPage() {
mLastClickOpenedSettings = true;
Bundle fragmentArguments = new Bundle(); Bundle fragmentArguments = new Bundle();
fragmentArguments.putString(SingleCategorySettings.EXTRA_CATEGORY, fragmentArguments.putString(SingleCategorySettings.EXTRA_CATEGORY,
SiteSettingsCategory.preferenceKey(SiteSettingsCategory.Type.NOTIFICATIONS)); SiteSettingsCategory.preferenceKey(SiteSettingsCategory.Type.NOTIFICATIONS));
...@@ -147,15 +157,19 @@ public class PermissionInfoBar ...@@ -147,15 +157,19 @@ public class PermissionInfoBar
* @param compactLinkText Text of link displayed right to the message in compact state. * @param compactLinkText Text of link displayed right to the message in compact state.
* @param message Primary message in the extended state. * @param message Primary message in the extended state.
* @param description Secondary message (description) in the expanded state. * @param description Secondary message (description) in the expanded state.
* @param buttonOk String to display on the OK button. * @param primaryButtonText String to display on the primary button.
* @param buttonManage String to display on the Manage button. * @param secondaryButtonText String to display on the secondary button.
* @param secondaryButtonShouldOpenSettings Whether the secondary button should open site
* settings.
*/ */
@CalledByNative @CalledByNative
private static PermissionInfoBar create(WindowAndroid window, int[] contentSettingsTypes, private static PermissionInfoBar create(WindowAndroid window, int[] contentSettingsTypes,
int iconId, String compactMessage, String compactLinkText, String message, int iconId, String compactMessage, String compactLinkText, String message,
String description, String buttonOk, String buttonManage) { String description, String primaryButtonText, String secondaryButtonText,
boolean secondaryButtonShouldOpenSettings) {
PermissionInfoBar infoBar = new PermissionInfoBar(window, contentSettingsTypes, iconId, PermissionInfoBar infoBar = new PermissionInfoBar(window, contentSettingsTypes, iconId,
compactMessage, compactLinkText, message, description, buttonOk, buttonManage); compactMessage, compactLinkText, message, description, primaryButtonText,
secondaryButtonText, secondaryButtonShouldOpenSettings);
return infoBar; return infoBar;
} }
......
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/strings/grit/ui_strings.h" #include "ui/strings/grit/ui_strings.h"
namespace {
using QuietUiReason =
permissions::NotificationPermissionUiSelector::QuietUiReason;
} // namespace
GroupedPermissionInfoBarDelegate::~GroupedPermissionInfoBarDelegate() { GroupedPermissionInfoBarDelegate::~GroupedPermissionInfoBarDelegate() {
permissions::PermissionUmaUtil::RecordInfobarDetailsExpanded( permissions::PermissionUmaUtil::RecordInfobarDetailsExpanded(
details_expanded_); details_expanded_);
...@@ -59,25 +64,45 @@ base::string16 GroupedPermissionInfoBarDelegate::GetCompactLinkText() const { ...@@ -59,25 +64,45 @@ base::string16 GroupedPermissionInfoBarDelegate::GetCompactLinkText() const {
IDS_NOTIFICATION_QUIET_PERMISSION_MINI_INFOBAR_DETAILS_LINK); IDS_NOTIFICATION_QUIET_PERMISSION_MINI_INFOBAR_DETAILS_LINK);
} }
// TODO(crbug.com/1082737): Many methods of this class switches on the quiet UI
// reason. Refactor this into separate subclasses instead.
base::string16 GroupedPermissionInfoBarDelegate::GetDescriptionText() const { base::string16 GroupedPermissionInfoBarDelegate::GetDescriptionText() const {
auto* manager = permissions::PermissionRequestManager::FromWebContents( auto* manager = permissions::PermissionRequestManager::FromWebContents(
permission_prompt_->web_contents()); permission_prompt_->web_contents());
switch (manager->ReasonForUsingQuietUi()) { switch (manager->ReasonForUsingQuietUi()) {
case permissions::NotificationPermissionUiSelector::QuietUiReason:: case QuietUiReason::kEnabledInPrefs:
kEnabledInPrefs:
return l10n_util::GetStringUTF16( return l10n_util::GetStringUTF16(
IDS_NOTIFICATION_QUIET_PERMISSION_PROMPT_MESSAGE); IDS_NOTIFICATION_QUIET_PERMISSION_PROMPT_MESSAGE);
case permissions::NotificationPermissionUiSelector::QuietUiReason:: case QuietUiReason::kTriggeredByCrowdDeny:
kTriggeredByCrowdDeny:
return l10n_util::GetStringUTF16( return l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_CROWD_DENY_DESCRIPTION); IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_CROWD_DENY_DESCRIPTION);
case QuietUiReason::kTriggeredDueToAbusiveRequests:
return l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ABUSIVE_DESCRIPTION);
} }
NOTREACHED(); NOTREACHED();
return base::string16(); return base::string16();
} }
bool GroupedPermissionInfoBarDelegate::ShouldSecondaryButtonOpenSettings()
const {
auto* manager = permissions::PermissionRequestManager::FromWebContents(
permission_prompt_->web_contents());
switch (manager->ReasonForUsingQuietUi()) {
case QuietUiReason::kEnabledInPrefs:
case QuietUiReason::kTriggeredByCrowdDeny:
return true;
case QuietUiReason::kTriggeredDueToAbusiveRequests:
return false;
}
NOTREACHED();
return false;
}
int GroupedPermissionInfoBarDelegate::GetIconId() const { int GroupedPermissionInfoBarDelegate::GetIconId() const {
return IDR_ANDROID_INFOBAR_NOTIFICATIONS_OFF; return IDR_ANDROID_INFOBAR_NOTIFICATIONS_OFF;
} }
...@@ -99,14 +124,40 @@ base::string16 GroupedPermissionInfoBarDelegate::GetMessageText() const { ...@@ -99,14 +124,40 @@ base::string16 GroupedPermissionInfoBarDelegate::GetMessageText() const {
} }
bool GroupedPermissionInfoBarDelegate::Accept() { bool GroupedPermissionInfoBarDelegate::Accept() {
if (permission_prompt_) if (!permission_prompt_)
permission_prompt_->Accept(); return true;
auto* manager = permissions::PermissionRequestManager::FromWebContents(
permission_prompt_->web_contents());
switch (manager->ReasonForUsingQuietUi()) {
case QuietUiReason::kEnabledInPrefs:
case QuietUiReason::kTriggeredByCrowdDeny:
permission_prompt_->Accept();
break;
case QuietUiReason::kTriggeredDueToAbusiveRequests:
permission_prompt_->Deny();
break;
}
return true; return true;
} }
bool GroupedPermissionInfoBarDelegate::Cancel() { bool GroupedPermissionInfoBarDelegate::Cancel() {
// The infobar needs to be kept open after the "Manage" button is clicked. if (!permission_prompt_)
return false; return true;
auto* manager = permissions::PermissionRequestManager::FromWebContents(
permission_prompt_->web_contents());
switch (manager->ReasonForUsingQuietUi()) {
case QuietUiReason::kEnabledInPrefs:
case QuietUiReason::kTriggeredByCrowdDeny:
// The infobar needs to be kept open after the "Manage" button is clicked.
return false;
case QuietUiReason::kTriggeredDueToAbusiveRequests:
permission_prompt_->Accept();
return true;
}
NOTREACHED();
return true;
} }
// static // static
...@@ -146,10 +197,25 @@ int GroupedPermissionInfoBarDelegate::GetButtons() const { ...@@ -146,10 +197,25 @@ int GroupedPermissionInfoBarDelegate::GetButtons() const {
base::string16 GroupedPermissionInfoBarDelegate::GetButtonLabel( base::string16 GroupedPermissionInfoBarDelegate::GetButtonLabel(
InfoBarButton button) const { InfoBarButton button) const {
return l10n_util::GetStringUTF16( auto* manager = permissions::PermissionRequestManager::FromWebContents(
(button == BUTTON_OK) permission_prompt_->web_contents());
? IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ALLOW_BUTTON
: IDS_NOTIFICATION_BUTTON_MANAGE); switch (manager->ReasonForUsingQuietUi()) {
case QuietUiReason::kEnabledInPrefs:
case QuietUiReason::kTriggeredByCrowdDeny:
return l10n_util::GetStringUTF16(
(button == BUTTON_OK)
? IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ALLOW_BUTTON
: IDS_NOTIFICATION_BUTTON_MANAGE);
case QuietUiReason::kTriggeredDueToAbusiveRequests:
return l10n_util::GetStringUTF16(
(button == BUTTON_OK)
? IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_CONTINUE_BLOCKING_BUTTON
: IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_COMPACT_ALLOW_BUTTON);
}
NOTREACHED();
return base::string16();
} }
bool GroupedPermissionInfoBarDelegate::EqualsDelegate( bool GroupedPermissionInfoBarDelegate::EqualsDelegate(
......
...@@ -48,6 +48,9 @@ class GroupedPermissionInfoBarDelegate : public ConfirmInfoBarDelegate { ...@@ -48,6 +48,9 @@ class GroupedPermissionInfoBarDelegate : public ConfirmInfoBarDelegate {
// Returns the secondary string to show in the infobar in the expanded state. // Returns the secondary string to show in the infobar in the expanded state.
base::string16 GetDescriptionText() const; base::string16 GetDescriptionText() const;
// Whether the secondary button should open site settings.
bool ShouldSecondaryButtonOpenSettings() const;
// ConfirmInfoBarDelegate: // ConfirmInfoBarDelegate:
int GetIconId() const override; int GetIconId() const override;
bool LinkClicked(WindowOpenDisposition disposition) override; bool LinkClicked(WindowOpenDisposition disposition) override;
......
...@@ -30,8 +30,9 @@ ScopedJavaLocalRef<jobject> CreateRenderInfoBarHelper( ...@@ -30,8 +30,9 @@ ScopedJavaLocalRef<jobject> CreateRenderInfoBarHelper(
const base::string16& compact_link_text, const base::string16& compact_link_text,
const base::string16& message_text, const base::string16& message_text,
const base::string16& description_text, const base::string16& description_text,
const base::string16& ok_button_text, const base::string16& primary_button_text,
const base::string16& cancel_button_text, const base::string16& secondary_button_text,
bool secondary_button_should_open_settings,
const std::vector<int>& content_settings) { const std::vector<int>& content_settings) {
ScopedJavaLocalRef<jstring> compact_message_text_java = ScopedJavaLocalRef<jstring> compact_message_text_java =
base::android::ConvertUTF16ToJavaString(env, compact_message_text); base::android::ConvertUTF16ToJavaString(env, compact_message_text);
...@@ -41,17 +42,18 @@ ScopedJavaLocalRef<jobject> CreateRenderInfoBarHelper( ...@@ -41,17 +42,18 @@ ScopedJavaLocalRef<jobject> CreateRenderInfoBarHelper(
base::android::ConvertUTF16ToJavaString(env, message_text); base::android::ConvertUTF16ToJavaString(env, message_text);
ScopedJavaLocalRef<jstring> description_text_java = ScopedJavaLocalRef<jstring> description_text_java =
base::android::ConvertUTF16ToJavaString(env, description_text); base::android::ConvertUTF16ToJavaString(env, description_text);
ScopedJavaLocalRef<jstring> ok_button_text_java = ScopedJavaLocalRef<jstring> primary_button_text_java =
base::android::ConvertUTF16ToJavaString(env, ok_button_text); base::android::ConvertUTF16ToJavaString(env, primary_button_text);
ScopedJavaLocalRef<jstring> cancel_button_text_java = ScopedJavaLocalRef<jstring> secondary_button_text_java =
base::android::ConvertUTF16ToJavaString(env, cancel_button_text); base::android::ConvertUTF16ToJavaString(env, secondary_button_text);
ScopedJavaLocalRef<jintArray> content_settings_types = ScopedJavaLocalRef<jintArray> content_settings_types =
base::android::ToJavaIntArray(env, content_settings); base::android::ToJavaIntArray(env, content_settings);
return Java_PermissionInfoBar_create( return Java_PermissionInfoBar_create(
env, window, content_settings_types, enumerated_icon_id, env, window, content_settings_types, enumerated_icon_id,
compact_message_text_java, compact_link_text_java, message_text_java, compact_message_text_java, compact_link_text_java, message_text_java,
description_text_java, ok_button_text_java, cancel_button_text_java); description_text_java, primary_button_text_java,
secondary_button_text_java, secondary_button_should_open_settings);
} }
} // namespace } // namespace
...@@ -70,9 +72,12 @@ GroupedPermissionInfoBar::CreateRenderInfoBar(JNIEnv* env) { ...@@ -70,9 +72,12 @@ GroupedPermissionInfoBar::CreateRenderInfoBar(JNIEnv* env) {
base::string16 compact_link_text = delegate->GetCompactLinkText(); base::string16 compact_link_text = delegate->GetCompactLinkText();
base::string16 message_text = delegate->GetMessageText(); base::string16 message_text = delegate->GetMessageText();
base::string16 description_text = delegate->GetDescriptionText(); base::string16 description_text = delegate->GetDescriptionText();
base::string16 ok_button_text = GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK); base::string16 primary_button_text =
base::string16 cancel_button_text = GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK);
base::string16 secondary_button_text =
GetTextFor(ConfirmInfoBarDelegate::BUTTON_CANCEL); GetTextFor(ConfirmInfoBarDelegate::BUTTON_CANCEL);
const bool secondary_button_should_open_settings =
delegate->ShouldSecondaryButtonOpenSettings();
int permission_icon = int permission_icon =
ResourceMapper::MapToJavaDrawableId(delegate->GetIconId()); ResourceMapper::MapToJavaDrawableId(delegate->GetIconId());
...@@ -87,7 +92,8 @@ GroupedPermissionInfoBar::CreateRenderInfoBar(JNIEnv* env) { ...@@ -87,7 +92,8 @@ GroupedPermissionInfoBar::CreateRenderInfoBar(JNIEnv* env) {
env, permission_icon, env, permission_icon,
GetTab()->web_contents()->GetTopLevelNativeWindow()->GetJavaObject(), GetTab()->web_contents()->GetTopLevelNativeWindow()->GetJavaObject(),
compact_message_text, compact_link_text, message_text, description_text, compact_message_text, compact_link_text, message_text, description_text,
ok_button_text, cancel_button_text, content_settings_types); primary_button_text, secondary_button_text,
secondary_button_should_open_settings, content_settings_types);
} }
GroupedPermissionInfoBarDelegate* GroupedPermissionInfoBar::GetDelegate() { GroupedPermissionInfoBarDelegate* GroupedPermissionInfoBar::GetDelegate() {
......
...@@ -13,11 +13,16 @@ ...@@ -13,11 +13,16 @@
#include "components/google/core/common/google_util.h" #include "components/google/core/common/google_util.h"
#include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h"
// The URL for when the user clicks "learn more" on the mixed scripting page // The URL for when the user clicks "Learn more" on the mixed scripting page
// icon bubble. // icon bubble.
const char kInsecureScriptHelpUrl[] = constexpr char kInsecureScriptHelpUrl[] =
"https://support.google.com/chrome/?p=unauthenticated"; "https://support.google.com/chrome/?p=unauthenticated";
// The URL for when the user clicks the "Learn more" on the quiet notification
// permission prompt.
constexpr char kNotificationsHelpUrl[] =
"https://support.google.com/chrome/answer/3220216";
BrowserContentSettingBubbleModelDelegate:: BrowserContentSettingBubbleModelDelegate::
BrowserContentSettingBubbleModelDelegate(Browser* browser) BrowserContentSettingBubbleModelDelegate(Browser* browser)
: browser_(browser) {} : browser_(browser) {}
...@@ -57,6 +62,9 @@ void BrowserContentSettingBubbleModelDelegate::ShowLearnMorePage( ...@@ -57,6 +62,9 @@ void BrowserContentSettingBubbleModelDelegate::ShowLearnMorePage(
case ContentSettingsType::MIXEDSCRIPT: case ContentSettingsType::MIXEDSCRIPT:
learn_more_url = GURL(kInsecureScriptHelpUrl); learn_more_url = GURL(kInsecureScriptHelpUrl);
break; break;
case ContentSettingsType::NOTIFICATIONS:
learn_more_url = GURL(kNotificationsHelpUrl);
break;
default: default:
return; return;
} }
......
...@@ -85,6 +85,8 @@ using content_settings::TabSpecificContentSettings; ...@@ -85,6 +85,8 @@ using content_settings::TabSpecificContentSettings;
namespace { namespace {
using QuietUiReason = permissions::PermissionRequestManager::QuietUiReason;
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
static constexpr char kCameraSettingsURI[] = static constexpr char kCameraSettingsURI[] =
"x-apple.systempreferences:com.apple.preference.security?Privacy_" "x-apple.systempreferences:com.apple.preference.security?Privacy_"
...@@ -1622,30 +1624,48 @@ ContentSettingNotificationsBubbleModel::ContentSettingNotificationsBubbleModel( ...@@ -1622,30 +1624,48 @@ ContentSettingNotificationsBubbleModel::ContentSettingNotificationsBubbleModel(
: ContentSettingBubbleModel(delegate, web_contents) { : ContentSettingBubbleModel(delegate, web_contents) {
set_title(l10n_util::GetStringUTF16( set_title(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_TITLE)); IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_TITLE));
set_done_button_text(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ALLOW_BUTTON));
set_show_learn_more(false);
// TODO(crbug.com/1030633): This block is more defensive than it needs to be // TODO(crbug.com/1030633): This block is more defensive than it needs to be
// because ContentSettingImageModelBrowserTest exercises it without setting up // because ContentSettingImageModelBrowserTest exercises it without setting up
// the correct PermissionRequestManager state. Fix that. // the correct PermissionRequestManager state. Fix that.
permissions::PermissionRequestManager* manager = permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents); permissions::PermissionRequestManager::FromWebContents(web_contents);
int message_resource_id = if (!manager->ShouldCurrentRequestUseQuietUI())
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_DESCRIPTION; return;
if (manager->ShouldCurrentRequestUseQuietUI() && switch (manager->ReasonForUsingQuietUi()) {
manager->ReasonForUsingQuietUi() == case QuietUiReason::kEnabledInPrefs:
permissions::PermissionRequestManager::QuietUiReason:: set_message(l10n_util::GetStringUTF16(
kTriggeredByCrowdDeny) { IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_DESCRIPTION));
message_resource_id = set_done_button_text(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_CROWD_DENY_DESCRIPTION; IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ALLOW_BUTTON));
base::RecordAction( set_show_learn_more(false);
base::UserMetricsAction("Notifications.Quiet.StaticIconClicked")); base::RecordAction(
} else { base::UserMetricsAction("Notifications.Quiet.AnimatedIconClicked"));
base::RecordAction( break;
base::UserMetricsAction("Notifications.Quiet.AnimatedIconClicked")); case QuietUiReason::kTriggeredByCrowdDeny:
set_message(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_CROWD_DENY_DESCRIPTION));
set_done_button_text(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ALLOW_BUTTON));
set_show_learn_more(false);
base::RecordAction(
base::UserMetricsAction("Notifications.Quiet.StaticIconClicked"));
break;
case QuietUiReason::kTriggeredDueToAbusiveRequests:
set_message(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_ABUSIVE_DESCRIPTION));
// TODO(crbug.com/1082738): It is rather confusing to have the `Cancel`
// button allow the permission, but we want the primary to block.
set_cancel_button_text(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_COMPACT_ALLOW_BUTTON));
set_done_button_text(l10n_util::GetStringUTF16(
IDS_NOTIFICATIONS_QUIET_PERMISSION_BUBBLE_CONTINUE_BLOCKING_BUTTON));
set_show_learn_more(true);
set_manage_text_style(ManageTextStyle::kNone);
base::RecordAction(
base::UserMetricsAction("Notifications.Quiet.StaticIconClicked"));
break;
} }
set_message(l10n_util::GetStringUTF16(message_resource_id));
} }
ContentSettingNotificationsBubbleModel:: ContentSettingNotificationsBubbleModel::
...@@ -1664,13 +1684,46 @@ void ContentSettingNotificationsBubbleModel::OnManageButtonClicked() { ...@@ -1664,13 +1684,46 @@ void ContentSettingNotificationsBubbleModel::OnManageButtonClicked() {
base::UserMetricsAction("Notifications.Quiet.ManageClicked")); base::UserMetricsAction("Notifications.Quiet.ManageClicked"));
} }
void ContentSettingNotificationsBubbleModel::OnLearnMoreClicked() {
if (delegate())
delegate()->ShowLearnMorePage(ContentSettingsType::NOTIFICATIONS);
}
void ContentSettingNotificationsBubbleModel::OnDoneButtonClicked() { void ContentSettingNotificationsBubbleModel::OnDoneButtonClicked() {
permissions::PermissionRequestManager* manager = permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents()); permissions::PermissionRequestManager::FromWebContents(web_contents());
manager->Accept();
base::RecordAction( DCHECK(manager->ShouldCurrentRequestUseQuietUI());
base::UserMetricsAction("Notifications.Quiet.ShowForSiteClicked")); switch (manager->ReasonForUsingQuietUi()) {
case QuietUiReason::kEnabledInPrefs:
case QuietUiReason::kTriggeredByCrowdDeny:
manager->Accept();
base::RecordAction(
base::UserMetricsAction("Notifications.Quiet.ShowForSiteClicked"));
break;
case QuietUiReason::kTriggeredDueToAbusiveRequests:
manager->Deny();
base::RecordAction(base::UserMetricsAction(
"Notifications.Quiet.ContinueBlockingClicked"));
break;
}
}
void ContentSettingNotificationsBubbleModel::OnCancelButtonClicked() {
permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents());
switch (manager->ReasonForUsingQuietUi()) {
case QuietUiReason::kEnabledInPrefs:
case QuietUiReason::kTriggeredByCrowdDeny:
// No-op.
break;
case QuietUiReason::kTriggeredDueToAbusiveRequests:
manager->Accept();
base::RecordAction(
base::UserMetricsAction("Notifications.Quiet.ShowForSiteClicked"));
break;
}
} }
// ContentSettingBubbleModel --------------------------------------------------- // ContentSettingBubbleModel ---------------------------------------------------
......
...@@ -161,6 +161,7 @@ class ContentSettingBubbleModel { ...@@ -161,6 +161,7 @@ class ContentSettingBubbleModel {
MediaMenuMap media_menus; MediaMenuMap media_menus;
bool show_learn_more = false; bool show_learn_more = false;
base::string16 done_button_text; base::string16 done_button_text;
base::string16 cancel_button_text;
private: private:
DISALLOW_COPY_AND_ASSIGN(BubbleContent); DISALLOW_COPY_AND_ASSIGN(BubbleContent);
...@@ -191,6 +192,7 @@ class ContentSettingBubbleModel { ...@@ -191,6 +192,7 @@ class ContentSettingBubbleModel {
virtual void OnMediaMenuClicked(blink::mojom::MediaStreamType type, virtual void OnMediaMenuClicked(blink::mojom::MediaStreamType type,
const std::string& selected_device_id) {} const std::string& selected_device_id) {}
virtual void OnDoneButtonClicked() {} virtual void OnDoneButtonClicked() {}
virtual void OnCancelButtonClicked() {}
// Called by the view code when the bubble is closed // Called by the view code when the bubble is closed
virtual void CommitChanges() {} virtual void CommitChanges() {}
...@@ -273,6 +275,9 @@ class ContentSettingBubbleModel { ...@@ -273,6 +275,9 @@ class ContentSettingBubbleModel {
void set_done_button_text(const base::string16& done_button_text) { void set_done_button_text(const base::string16& done_button_text) {
bubble_content_.done_button_text = done_button_text; bubble_content_.done_button_text = done_button_text;
} }
void set_cancel_button_text(const base::string16& cancel_button_text) {
bubble_content_.cancel_button_text = cancel_button_text;
}
rappor::RapporServiceImpl* rappor_service() const { return rappor_service_; } rappor::RapporServiceImpl* rappor_service() const { return rappor_service_; }
private: private:
...@@ -423,7 +428,9 @@ class ContentSettingNotificationsBubbleModel ...@@ -423,7 +428,9 @@ class ContentSettingNotificationsBubbleModel
// ContentSettingBubbleModel: // ContentSettingBubbleModel:
void OnManageButtonClicked() override; void OnManageButtonClicked() override;
void OnLearnMoreClicked() override;
void OnDoneButtonClicked() override; void OnDoneButtonClicked() override;
void OnCancelButtonClicked() override;
ContentSettingNotificationsBubbleModel* AsNotificationsBubbleModel() override; ContentSettingNotificationsBubbleModel* AsNotificationsBubbleModel() override;
DISALLOW_COPY_AND_ASSIGN(ContentSettingNotificationsBubbleModel); DISALLOW_COPY_AND_ASSIGN(ContentSettingNotificationsBubbleModel);
......
...@@ -382,7 +382,11 @@ ContentSettingBubbleContents::ContentSettingBubbleContents( ...@@ -382,7 +382,11 @@ ContentSettingBubbleContents::ContentSettingBubbleContents(
DCHECK(content_setting_bubble_model_); DCHECK(content_setting_bubble_model_);
const base::string16& done_text = const base::string16& done_text =
content_setting_bubble_model_->bubble_content().done_button_text; content_setting_bubble_model_->bubble_content().done_button_text;
DialogDelegate::SetButtons(ui::DIALOG_BUTTON_OK); const base::string16& cancel_text =
content_setting_bubble_model_->bubble_content().cancel_button_text;
DialogDelegate::SetButtons(
cancel_text.empty() ? ui::DIALOG_BUTTON_OK
: (ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL));
DialogDelegate::SetButtonLabel( DialogDelegate::SetButtonLabel(
ui::DIALOG_BUTTON_OK, ui::DIALOG_BUTTON_OK,
done_text.empty() ? l10n_util::GetStringUTF16(IDS_DONE) : done_text); done_text.empty() ? l10n_util::GetStringUTF16(IDS_DONE) : done_text);
...@@ -390,6 +394,13 @@ ContentSettingBubbleContents::ContentSettingBubbleContents( ...@@ -390,6 +394,13 @@ ContentSettingBubbleContents::ContentSettingBubbleContents(
DialogDelegate::SetAcceptCallback( DialogDelegate::SetAcceptCallback(
base::BindOnce(&ContentSettingBubbleModel::OnDoneButtonClicked, base::BindOnce(&ContentSettingBubbleModel::OnDoneButtonClicked,
base::Unretained(content_setting_bubble_model_.get()))); base::Unretained(content_setting_bubble_model_.get())));
if (!cancel_text.empty()) {
DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, cancel_text);
DialogDelegate::SetCancelCallback(
base::BindOnce(&ContentSettingBubbleModel::OnCancelButtonClicked,
base::Unretained(content_setting_bubble_model_.get())));
}
} }
ContentSettingBubbleContents::~ContentSettingBubbleContents() { ContentSettingBubbleContents::~ContentSettingBubbleContents() {
......
...@@ -207,10 +207,12 @@ void ContentSettingBubbleDialogTest::ShowUi(const std::string& name) { ...@@ -207,10 +207,12 @@ void ContentSettingBubbleDialogTest::ShowUi(const std::string& name) {
if (base::StartsWith(name, "notifications_quiet", if (base::StartsWith(name, "notifications_quiet",
base::CompareCase::SENSITIVE)) { base::CompareCase::SENSITIVE)) {
TriggerQuietNotificationPermissionRequest( QuietUiReason reason = QuietUiReason::kEnabledInPrefs;
name == "notifications_quiet_crowd_deny" if (name == "notifications_quiet_crowd_deny")
? QuietUiReason::kTriggeredByCrowdDeny reason = QuietUiReason::kTriggeredByCrowdDeny;
: QuietUiReason::kEnabledInPrefs); else if (name == "notifications_quiet_abusive")
reason = QuietUiReason::kTriggeredDueToAbusiveRequests;
TriggerQuietNotificationPermissionRequest(reason);
ShowDialogBubble(ImageType::NOTIFICATIONS_QUIET_PROMPT); ShowDialogBubble(ImageType::NOTIFICATIONS_QUIET_PROMPT);
return; return;
} }
...@@ -322,3 +324,8 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleDialogTest, ...@@ -322,3 +324,8 @@ IN_PROC_BROWSER_TEST_F(ContentSettingBubbleDialogTest,
InvokeUi_notifications_quiet_crowd_deny) { InvokeUi_notifications_quiet_crowd_deny) {
ShowAndVerifyUi(); ShowAndVerifyUi();
} }
IN_PROC_BROWSER_TEST_F(ContentSettingBubbleDialogTest,
InvokeUi_notifications_quiet_abusive) {
ShowAndVerifyUi();
}
...@@ -24,6 +24,7 @@ class NotificationPermissionUiSelector { ...@@ -24,6 +24,7 @@ class NotificationPermissionUiSelector {
enum class QuietUiReason { enum class QuietUiReason {
kEnabledInPrefs, kEnabledInPrefs,
kTriggeredByCrowdDeny, kTriggeredByCrowdDeny,
kTriggeredDueToAbusiveRequests,
}; };
using DecisionMadeCallback = using DecisionMadeCallback =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment