Commit 520572ab authored by Andy Paicu's avatar Andy Paicu Committed by Commit Bot

Add a checkbox that gives users control over the notifications quiet ui

This CL adds a checkbox that will display the current state of the
notifications prompt quiet UI, which the user can then enable/disable
at will.

The quiet UI can be automatically-enabled by embargo-logic.

Bug: 1014874
Change-Id: Ia5e68877acf4b4dce82fe4eb1679706c62c7f9de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1930820Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarFinnur Thorarinsson <finnur@chromium.org>
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720430}
parent c51b9f5e
...@@ -26,6 +26,13 @@ ...@@ -26,6 +26,13 @@
android:summary="@string/block_third_party_cookies_summary" android:summary="@string/block_third_party_cookies_summary"
android:defaultValue="true" android:defaultValue="true"
android:persistent="false" /> android:persistent="false" />
<!-- A checkbox for enabling a quiet ui for notification prompts. Only shown in the Notifications category. -->
<org.chromium.chrome.browser.settings.ChromeBaseCheckBoxPreference
android:key="notifications_quiet_ui"
android:title="@string/website_settings_category_notifications_quiet"
android:summary="@string/website_settings_category_notifications_quiet_summary_enabled"
android:defaultValue="false"
android:persistent="false" />
<!-- A toggle for enabling vibration in notifications. --> <!-- A toggle for enabling vibration in notifications. -->
<org.chromium.chrome.browser.settings.ChromeBaseCheckBoxPreference <org.chromium.chrome.browser.settings.ChromeBaseCheckBoxPreference
android:key="notifications_vibrate" android:key="notifications_vibrate"
......
...@@ -116,6 +116,9 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -116,6 +116,9 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
private List<WebsitePreference> mWebsites; private List<WebsitePreference> mWebsites;
// Whether tri-state ContentSetting is required. // Whether tri-state ContentSetting is required.
private boolean mRequiresTriStateSetting; private boolean mRequiresTriStateSetting;
// Locally-saved reference to the "notifications_quiet_ui" preference to allow hiding/showing
// it.
private ChromeBaseCheckBoxPreference mNotificationsQuietUiPref;
@Nullable @Nullable
private Set<String> mSelectedDomains; private Set<String> mSelectedDomains;
...@@ -128,6 +131,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -128,6 +131,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
// Keys for category-specific preferences (toggle, link, button etc.), dynamically shown. // Keys for category-specific preferences (toggle, link, button etc.), dynamically shown.
public static final String THIRD_PARTY_COOKIES_TOGGLE_KEY = "third_party_cookies"; public static final String THIRD_PARTY_COOKIES_TOGGLE_KEY = "third_party_cookies";
public static final String NOTIFICATIONS_VIBRATE_TOGGLE_KEY = "notifications_vibrate"; public static final String NOTIFICATIONS_VIBRATE_TOGGLE_KEY = "notifications_vibrate";
public static final String NOTIFICATIONS_QUIET_UI_TOGGLE_KEY = "notifications_quiet_ui";
public static final String EXPLAIN_PROTECTED_MEDIA_KEY = "protected_content_learn_more"; public static final String EXPLAIN_PROTECTED_MEDIA_KEY = "protected_content_learn_more";
private static final String ADD_EXCEPTION_KEY = "add_exception"; private static final String ADD_EXCEPTION_KEY = "add_exception";
...@@ -476,7 +480,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -476,7 +480,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
if (type == SiteSettingsCategory.Type.COOKIES) { if (type == SiteSettingsCategory.Type.COOKIES) {
updateThirdPartyCookiesCheckBox(); updateThirdPartyCookiesCheckBox();
} else if (type == SiteSettingsCategory.Type.NOTIFICATIONS) { } else if (type == SiteSettingsCategory.Type.NOTIFICATIONS) {
updateNotificationsVibrateCheckBox(); updateNotificationsSecondaryControls();
} }
break; break;
} }
...@@ -519,6 +523,8 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -519,6 +523,8 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
} else if (NOTIFICATIONS_VIBRATE_TOGGLE_KEY.equals(preference.getKey())) { } else if (NOTIFICATIONS_VIBRATE_TOGGLE_KEY.equals(preference.getKey())) {
PrefServiceBridge.getInstance().setBoolean( PrefServiceBridge.getInstance().setBoolean(
Pref.NOTIFICATIONS_VIBRATE_ENABLED, (boolean) newValue); Pref.NOTIFICATIONS_VIBRATE_ENABLED, (boolean) newValue);
} else if (NOTIFICATIONS_QUIET_UI_TOGGLE_KEY.equals(preference.getKey())) {
WebsitePreferenceBridge.setQuietNotificationsUiEnabled((boolean) newValue);
} }
return true; return true;
} }
...@@ -823,6 +829,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -823,6 +829,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
(TriStateSiteSettingsPreference) screen.findPreference(TRI_STATE_TOGGLE_KEY); (TriStateSiteSettingsPreference) screen.findPreference(TRI_STATE_TOGGLE_KEY);
Preference thirdPartyCookies = screen.findPreference(THIRD_PARTY_COOKIES_TOGGLE_KEY); Preference thirdPartyCookies = screen.findPreference(THIRD_PARTY_COOKIES_TOGGLE_KEY);
Preference notificationsVibrate = screen.findPreference(NOTIFICATIONS_VIBRATE_TOGGLE_KEY); Preference notificationsVibrate = screen.findPreference(NOTIFICATIONS_VIBRATE_TOGGLE_KEY);
Preference notificationsQuietUi = screen.findPreference(NOTIFICATIONS_QUIET_UI_TOGGLE_KEY);
Preference explainProtectedMediaKey = screen.findPreference(EXPLAIN_PROTECTED_MEDIA_KEY); Preference explainProtectedMediaKey = screen.findPreference(EXPLAIN_PROTECTED_MEDIA_KEY);
PreferenceGroup allowedGroup = (PreferenceGroup) screen.findPreference(ALLOWED_GROUP); PreferenceGroup allowedGroup = (PreferenceGroup) screen.findPreference(ALLOWED_GROUP);
PreferenceGroup blockedGroup = (PreferenceGroup) screen.findPreference(BLOCKED_GROUP); PreferenceGroup blockedGroup = (PreferenceGroup) screen.findPreference(BLOCKED_GROUP);
...@@ -854,6 +861,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -854,6 +861,7 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
if (hideSecondaryToggles) { if (hideSecondaryToggles) {
screen.removePreference(thirdPartyCookies); screen.removePreference(thirdPartyCookies);
screen.removePreference(notificationsVibrate); screen.removePreference(notificationsVibrate);
screen.removePreference(notificationsQuietUi);
screen.removePreference(explainProtectedMediaKey); screen.removePreference(explainProtectedMediaKey);
screen.removePreference(allowedGroup); screen.removePreference(allowedGroup);
screen.removePreference(blockedGroup); screen.removePreference(blockedGroup);
...@@ -871,13 +879,19 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -871,13 +879,19 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
screen.removePreference(thirdPartyCookies); screen.removePreference(thirdPartyCookies);
} }
// Configure/hide the notifications vibrate toggle, as needed. // Configure/hide the notifications secondary controls, as needed.
if (mCategory.showSites(SiteSettingsCategory.Type.NOTIFICATIONS) if (mCategory.showSites(SiteSettingsCategory.Type.NOTIFICATIONS)) {
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
notificationsVibrate.setOnPreferenceChangeListener(this); notificationsVibrate.setOnPreferenceChangeListener(this);
updateNotificationsVibrateCheckBox(); } else {
screen.removePreference(notificationsVibrate);
}
notificationsQuietUi.setOnPreferenceChangeListener(this);
updateNotificationsSecondaryControls();
} else { } else {
screen.removePreference(notificationsVibrate); screen.removePreference(notificationsVibrate);
screen.removePreference(notificationsQuietUi);
} }
// Only show the link that explains protected content settings when needed. // Only show the link that explains protected content settings when needed.
...@@ -984,13 +998,32 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat ...@@ -984,13 +998,32 @@ public class SingleCategoryPreferences extends PreferenceFragmentCompat
Pref.BLOCK_THIRD_PARTY_COOKIES)); Pref.BLOCK_THIRD_PARTY_COOKIES));
} }
private void updateNotificationsVibrateCheckBox() { private void updateNotificationsSecondaryControls() {
ChromeBaseCheckBoxPreference preference = Boolean categoryEnabled =
WebsitePreferenceBridge.isCategoryEnabled(ContentSettingsType.NOTIFICATIONS);
// The notifications vibrate checkbox.
ChromeBaseCheckBoxPreference vibrate_pref =
(ChromeBaseCheckBoxPreference) getPreferenceScreen().findPreference( (ChromeBaseCheckBoxPreference) getPreferenceScreen().findPreference(
NOTIFICATIONS_VIBRATE_TOGGLE_KEY); NOTIFICATIONS_VIBRATE_TOGGLE_KEY);
if (preference != null) { if (vibrate_pref != null) vibrate_pref.setEnabled(categoryEnabled);
preference.setEnabled(
WebsitePreferenceBridge.isCategoryEnabled(ContentSettingsType.NOTIFICATIONS)); // The notifications quiet ui checkbox.
ChromeBaseCheckBoxPreference quiet_ui_pref =
(ChromeBaseCheckBoxPreference) getPreferenceScreen().findPreference(
NOTIFICATIONS_QUIET_UI_TOGGLE_KEY);
if (categoryEnabled) {
if (quiet_ui_pref == null) {
getPreferenceScreen().addPreference(mNotificationsQuietUiPref);
quiet_ui_pref = (ChromeBaseCheckBoxPreference) getPreferenceScreen().findPreference(
NOTIFICATIONS_QUIET_UI_TOGGLE_KEY);
}
quiet_ui_pref.setChecked(WebsitePreferenceBridge.isQuietNotificationsUiEnabled());
} else if (quiet_ui_pref != null) {
// Save a reference to allow re-adding it to the screen.
mNotificationsQuietUiPref = quiet_ui_pref;
getPreferenceScreen().removePreference(quiet_ui_pref);
} }
} }
......
...@@ -10,6 +10,7 @@ import org.chromium.base.Callback; ...@@ -10,6 +10,7 @@ import org.chromium.base.Callback;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.browser.ContentSettingsType; import org.chromium.chrome.browser.ContentSettingsType;
import org.chromium.chrome.browser.profiles.Profile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -517,6 +518,18 @@ public class WebsitePreferenceBridge { ...@@ -517,6 +518,18 @@ public class WebsitePreferenceBridge {
contentSettingType, pattern, setting); contentSettingType, pattern, setting);
} }
public static boolean isQuietNotificationsUiEnabled() {
return WebsitePreferenceBridgeJni.get().getQuietNotificationsUiEnabled(getProfile());
}
public static void setQuietNotificationsUiEnabled(boolean enabled) {
WebsitePreferenceBridgeJni.get().setQuietNotificationsUiEnabled(getProfile(), enabled);
}
private static Profile getProfile() {
return Profile.getLastUsedProfile().getOriginalProfile();
}
@VisibleForTesting @VisibleForTesting
@NativeMethods @NativeMethods
public interface Natives { public interface Natives {
...@@ -608,5 +621,7 @@ public class WebsitePreferenceBridge { ...@@ -608,5 +621,7 @@ public class WebsitePreferenceBridge {
void setNfcEnabled(boolean enabled); void setNfcEnabled(boolean enabled);
void setSensorsEnabled(boolean enabled); void setSensorsEnabled(boolean enabled);
void setSoundEnabled(boolean enabled); void setSoundEnabled(boolean enabled);
boolean getQuietNotificationsUiEnabled(Profile profile);
void setQuietNotificationsUiEnabled(Profile profile, boolean enabled);
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.settings.website; package org.chromium.chrome.browser.settings.website;
import android.os.Build;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
...@@ -206,6 +207,22 @@ public class SiteSettingsPreferencesTest { ...@@ -206,6 +207,22 @@ public class SiteSettingsPreferencesTest {
preferenceActivity.finish(); preferenceActivity.finish();
} }
private void setGlobalTriStateToggleForCategory(
final @SiteSettingsCategory.Type int type, final int newValue) {
final Preferences preferenceActivity =
SiteSettingsTestUtils.startSiteSettingsCategory(type);
TestThreadUtils.runOnUiThreadBlocking(() -> {
SingleCategoryPreferences preferences =
(SingleCategoryPreferences) preferenceActivity.getMainFragment();
TriStateSiteSettingsPreference triStateToggle =
(TriStateSiteSettingsPreference) preferences.findPreference(
SingleCategoryPreferences.TRI_STATE_TOGGLE_KEY);
preferences.onPreferenceChange(triStateToggle, newValue);
});
preferenceActivity.finish();
}
private void setEnablePopups(final boolean enabled) { private void setEnablePopups(final boolean enabled) {
setGlobalToggleForCategory(SiteSettingsCategory.Type.POPUPS, enabled); setGlobalToggleForCategory(SiteSettingsCategory.Type.POPUPS, enabled);
...@@ -442,6 +459,20 @@ public class SiteSettingsPreferencesTest { ...@@ -442,6 +459,20 @@ public class SiteSettingsPreferencesTest {
String[] binaryToggleWithAllowed = new String[] {"binary_toggle", "allowed_group"}; String[] binaryToggleWithAllowed = new String[] {"binary_toggle", "allowed_group"};
String[] cookie = new String[] {"binary_toggle", "third_party_cookies", "add_exception"}; String[] cookie = new String[] {"binary_toggle", "third_party_cookies", "add_exception"};
String[] protectedMedia = new String[] {"tri_state_toggle", "protected_content_learn_more"}; String[] protectedMedia = new String[] {"tri_state_toggle", "protected_content_learn_more"};
String[] notifications_enabled;
String[] notifications_disabled;
// The "notifications_vibrate" option has been removed in Android O but is present in
// earlier versions.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
notifications_enabled = new String[] {"binary_toggle", "notifications_quiet_ui",
"notifications_vibrate", "allowed_group"};
notifications_disabled =
new String[] {"binary_toggle", "notifications_vibrate", "allowed_group"};
} else {
notifications_enabled =
new String[] {"binary_toggle", "notifications_quiet_ui", "allowed_group"};
notifications_disabled = binaryToggleWithAllowed;
}
HashMap<Integer, Pair<String[], String[]>> testCases = HashMap<Integer, Pair<String[], String[]>> testCases =
new HashMap<Integer, Pair<String[], String[]>>(); new HashMap<Integer, Pair<String[], String[]>>();
...@@ -461,10 +492,8 @@ public class SiteSettingsPreferencesTest { ...@@ -461,10 +492,8 @@ public class SiteSettingsPreferencesTest {
testCases.put(SiteSettingsCategory.Type.MICROPHONE, new Pair<>(binaryToggle, binaryToggle)); testCases.put(SiteSettingsCategory.Type.MICROPHONE, new Pair<>(binaryToggle, binaryToggle));
testCases.put(SiteSettingsCategory.Type.NFC, new Pair<>(binaryToggle, binaryToggle)); testCases.put(SiteSettingsCategory.Type.NFC, new Pair<>(binaryToggle, binaryToggle));
testCases.put(SiteSettingsCategory.Type.NOTIFICATIONS, testCases.put(SiteSettingsCategory.Type.NOTIFICATIONS,
new Pair<>(binaryToggleWithAllowed, binaryToggleWithAllowed)); new Pair<>(notifications_disabled, notifications_enabled));
testCases.put(SiteSettingsCategory.Type.POPUPS, new Pair<>(binaryToggle, binaryToggle)); testCases.put(SiteSettingsCategory.Type.POPUPS, new Pair<>(binaryToggle, binaryToggle));
testCases.put(SiteSettingsCategory.Type.PROTECTED_MEDIA,
new Pair<>(protectedMedia, protectedMedia));
testCases.put(SiteSettingsCategory.Type.SENSORS, new Pair<>(binaryToggle, binaryToggle)); testCases.put(SiteSettingsCategory.Type.SENSORS, new Pair<>(binaryToggle, binaryToggle));
testCases.put(SiteSettingsCategory.Type.SOUND, testCases.put(SiteSettingsCategory.Type.SOUND,
new Pair<>(binaryToggleWithException, binaryToggleWithException)); new Pair<>(binaryToggleWithException, binaryToggleWithException));
...@@ -475,12 +504,24 @@ public class SiteSettingsPreferencesTest { ...@@ -475,12 +504,24 @@ public class SiteSettingsPreferencesTest {
for (@SiteSettingsCategory.Type int key = 0; key < SiteSettingsCategory.Type.NUM_ENTRIES; for (@SiteSettingsCategory.Type int key = 0; key < SiteSettingsCategory.Type.NUM_ENTRIES;
++key) { ++key) {
// Protected media has a tri-state global toggle so it needs to be handled slightly
// differently.
if (key == SiteSettingsCategory.Type.PROTECTED_MEDIA) {
setGlobalTriStateToggleForCategory(key, ContentSettingValues.ALLOW);
checkPreferencesForCategory(key, protectedMedia);
setGlobalTriStateToggleForCategory(key, ContentSettingValues.ASK);
checkPreferencesForCategory(key, protectedMedia);
setGlobalTriStateToggleForCategory(key, ContentSettingValues.BLOCK);
checkPreferencesForCategory(key, protectedMedia);
continue;
}
Pair<String[], String[]> values = testCases.get(key); Pair<String[], String[]> values = testCases.get(key);
if (key == SiteSettingsCategory.Type.ALL_SITES if (key == SiteSettingsCategory.Type.ALL_SITES
|| key == SiteSettingsCategory.Type.USE_STORAGE) { || key == SiteSettingsCategory.Type.USE_STORAGE) {
checkPreferencesForCategory(key, values.first); checkPreferencesForCategory(key, values.first);
return; continue;
} }
// Disable the category and check for the right preferences. // Disable the category and check for the right preferences.
......
...@@ -31,11 +31,13 @@ ...@@ -31,11 +31,13 @@
#include "chrome/browser/engagement/important_sites_util.h" #include "chrome/browser/engagement/important_sites_util.h"
#include "chrome/browser/media/android/cdm/media_drm_license_manager.h" #include "chrome/browser/media/android/cdm/media_drm_license_manager.h"
#include "chrome/browser/notifications/notification_permission_context.h" #include "chrome/browser/notifications/notification_permission_context.h"
#include "chrome/browser/permissions/adaptive_notification_permission_ui_selector.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker.h" #include "chrome/browser/permissions/permission_decision_auto_blocker.h"
#include "chrome/browser/permissions/permission_manager.h" #include "chrome/browser/permissions/permission_manager.h"
#include "chrome/browser/permissions/permission_uma_util.h" #include "chrome/browser/permissions/permission_uma_util.h"
#include "chrome/browser/permissions/permission_util.h" #include "chrome/browser/permissions/permission_util.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/storage/storage_info_fetcher.h" #include "chrome/browser/storage/storage_info_fetcher.h"
#include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context.h"
...@@ -1257,6 +1259,29 @@ static jboolean JNI_WebsitePreferenceBridge_GetMicManagedByCustodian( ...@@ -1257,6 +1259,29 @@ static jboolean JNI_WebsitePreferenceBridge_GetMicManagedByCustodian(
ContentSettingsType::MEDIASTREAM_MIC); ContentSettingsType::MEDIASTREAM_MIC);
} }
static jboolean JNI_WebsitePreferenceBridge_GetQuietNotificationsUiEnabled(
JNIEnv* env,
const JavaParamRef<jobject>& jprofile) {
return AdaptiveNotificationPermissionUiSelector::GetForProfile(
ProfileAndroid::FromProfileAndroid(jprofile))
->ShouldShowQuietUi();
}
static void JNI_WebsitePreferenceBridge_SetQuietNotificationsUiEnabled(
JNIEnv* env,
const JavaParamRef<jobject>& jprofile,
jboolean enabled) {
if (enabled) {
AdaptiveNotificationPermissionUiSelector::GetForProfile(
ProfileAndroid::FromProfileAndroid(jprofile))
->EnableQuietUi();
} else {
AdaptiveNotificationPermissionUiSelector::GetForProfile(
ProfileAndroid::FromProfileAndroid(jprofile))
->DisableQuietUi();
}
}
// static // static
void WebsitePreferenceBridge::GetAndroidPermissionsForContentSetting( void WebsitePreferenceBridge::GetAndroidPermissionsForContentSetting(
ContentSettingsType content_settings_type, ContentSettingsType content_settings_type,
......
...@@ -1136,13 +1136,13 @@ Your Google account may have other forms of browsing history like searches and a ...@@ -1136,13 +1136,13 @@ Your Google account may have other forms of browsing history like searches and a
Ask before allowing sites to know your location (recommended) Ask before allowing sites to know your location (recommended)
</message> </message>
<message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_ASK" desc="Summary text explaining that sites need to ask for permission before sending notifications."> <message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_ASK" desc="Summary text explaining that sites need to ask for permission before sending notifications.">
Ask before sending New sites you visit can ask to send you notifications
</message> </message>
<message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_QUIET" desc="A setting that, if turned on will enable a quieter permission prompt for notifications."> <message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_QUIET" desc="A setting that, if turned on will enable a quieter permission prompt for notifications.">
Show prompts quietly Inform quietly
</message> </message>
<message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_QUIET_SUMMARY_ENABLED" desc="A summary explaining how quiet notifications work, when the setting is enabled."> <message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_QUIET_SUMMARY_ENABLED" desc="A summary explaining how quiet notifications work, when the setting is enabled.">
Sites will be blocked from asking to show you notifications. If a site requests notifications, an infobar will appear at the bottom of the page. Block sites from interrupting you when asking for notifications, and inform quietly instead
</message> </message>
<message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_QUIET_SUMMARY_DISABLED" desc="A summary explaining how quiet notifications work, when the setting is disabled."> <message name="IDS_WEBSITE_SETTINGS_CATEGORY_NOTIFICATIONS_QUIET_SUMMARY_DISABLED" desc="A summary explaining how quiet notifications work, when the setting is disabled.">
Enable to automatically block sites from asking to show you notifications. If a site requests notifications, an infobar will appear at the bottom of the page. Enable to automatically block sites from asking to show you notifications. If a site requests notifications, an infobar will appear at the bottom of the page.
......
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