blob: a5657f82013dcf34a0053dd2706c1d9e4850c850 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.preferences.website;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.media.cdm.MediaDrmCredentialManager;
import org.chromium.chrome.browser.media.cdm.MediaDrmCredentialManager.MediaDrmCredentialManagerCallback;
import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
import org.chromium.chrome.browser.preferences.ChromeBasePreference;
import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
import org.chromium.chrome.browser.preferences.ExpandablePreferenceGroup;
import org.chromium.chrome.browser.preferences.LocationSettings;
import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate;
import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.PreferenceUtils;
import org.chromium.chrome.browser.preferences.ProtectedContentResetCredentialConfirmDialogFragment;
import org.chromium.chrome.browser.preferences.website.Website.StoredDataClearedCallback;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.widget.TintedDrawable;
import org.chromium.ui.widget.Toast;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Shows a list of sites in a particular Site Settings category. For example, this could show all
* the websites with microphone permissions. When the user selects a site, SingleWebsitePreferences
* is launched to allow the user to see or modify the settings for that particular website.
*/
public class SingleCategoryPreferences extends PreferenceFragment
implements OnPreferenceChangeListener, OnPreferenceClickListener,
AddExceptionPreference.SiteAddedCallback,
ProtectedContentResetCredentialConfirmDialogFragment.Listener,
View.OnClickListener {
// The key to use to pass which category this preference should display,
// e.g. Location/Popups/All sites (if blank).
public static final String EXTRA_CATEGORY = "category";
public static final String EXTRA_TITLE = "title";
// The view to show when the list is empty.
private TextView mEmptyView;
// The view for searching the list of items.
private SearchView mSearchView;
// The clear button displayed in the Storage view.
private Button mClearButton;
// The Site Settings Category we are showing.
private SiteSettingsCategory mCategory;
// If not blank, represents a substring to use to search for site names.
private String mSearch = "";
// Whether to group by allowed/blocked list.
private boolean mGroupByAllowBlock;
// Whether the Blocked list should be shown expanded.
private boolean mBlockListExpanded;
// Whether the Allowed list should be shown expanded.
private boolean mAllowListExpanded = true;
// Whether this is the first time this screen is shown.
private boolean mIsInitialRun = true;
// The number of sites that are on the Allowed list.
private int mAllowedSiteCount;
// The websites that are currently displayed to the user.
private List<WebsitePreference> mWebsites;
// Keys for individual preferences.
public static final String READ_WRITE_TOGGLE_KEY = "read_write_toggle";
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 EXPLAIN_PROTECTED_MEDIA_KEY = "protected_content_learn_more";
private static final String ADD_EXCEPTION_KEY = "add_exception";
// Keys for Allowed/Blocked preference groups/headers.
private static final String ALLOWED_GROUP = "allowed_group";
private static final String BLOCKED_GROUP = "blocked_group";
private void getInfoForOrigins() {
if (!mCategory.enabledInAndroid(getActivity())) {
// No need to fetch any data if we're not going to show it, but we do need to update
// the global toggle to reflect updates in Android settings (e.g. Location).
resetList();
return;
}
WebsitePermissionsFetcher fetcher =
new WebsitePermissionsFetcher(new ResultsPopulator(), false);
fetcher.fetchPreferencesForCategory(mCategory);
}
private void displayEmptyScreenMessage() {
if (mEmptyView != null) {
mEmptyView.setText(R.string.no_saved_website_settings);
}
}
private class ResultsPopulator implements WebsitePermissionsFetcher.WebsitePermissionsCallback {
@Override
public void onWebsitePermissionsAvailable(Collection<Website> sites) {
// This method may be called after the activity has been destroyed.
// In that case, bail out.
if (getActivity() == null) return;
mWebsites = null;
// Find origins matching the current search.
List<WebsitePreference> websites = new ArrayList<>();
for (Website site : sites) {
if (mSearch.isEmpty() || site.getTitle().contains(mSearch)) {
websites.add(new WebsitePreference(getActivity(), site, mCategory));
}
}
resetList();
Collections.sort(websites);
mAllowedSiteCount = 0;
int blocked = 0;
if (websites.size() > 0) {
if (!mGroupByAllowBlock) {
// We're not grouping sites into Allowed/Blocked lists, so show all in order
// (will be alphabetical).
for (WebsitePreference website : websites) {
getPreferenceScreen().addPreference(website);
}
} else {
// Group sites into Allowed/Blocked lists.
PreferenceGroup allowedGroup =
(PreferenceGroup) getPreferenceScreen().findPreference(
ALLOWED_GROUP);
PreferenceGroup blockedGroup =
(PreferenceGroup) getPreferenceScreen().findPreference(
BLOCKED_GROUP);
for (WebsitePreference website : websites) {
if (isOnBlockList(website)) {
blockedGroup.addPreference(website);
blocked += 1;
} else {
allowedGroup.addPreference(website);
mAllowedSiteCount += 1;
}
}
// For the ads permission, the Allowed list should appear first. Default
// collapsed settings should not change.
if (mCategory.showAdsSites()) {
blockedGroup.setOrder(allowedGroup.getOrder() + 1);
}
// The default, when the two lists are shown for the first time, is for the
// Blocked list to be collapsed and Allowed expanded -- because the data in
// the Allowed list is normally more useful than the data in the Blocked
// list. A collapsed initial Blocked list works well *except* when there's
// nothing in the Allowed list because then there's only Blocked items to
// show and it doesn't make sense for those items to be hidden. So, in that
// case (and only when the list is shown for the first time) do we ignore
// the collapsed directive. The user can still collapse and expand the
// Blocked list at will.
if (mIsInitialRun) {
if (allowedGroup.getPreferenceCount() == 0) mBlockListExpanded = true;
mIsInitialRun = false;
}
if (!mBlockListExpanded) {
blockedGroup.removeAll();
}
if (!mAllowListExpanded) {
allowedGroup.removeAll();
}
}
mWebsites = websites;
updateBlockedHeader(blocked);
ChromeSwitchPreference globalToggle = (ChromeSwitchPreference)
getPreferenceScreen().findPreference(READ_WRITE_TOGGLE_KEY);
updateAllowedHeader(mAllowedSiteCount,
(globalToggle != null ? globalToggle.isChecked() : true));
} else {
displayEmptyScreenMessage();
updateBlockedHeader(0);
updateAllowedHeader(0, true);
}
}
}
/**
* Returns whether a website is on the Blocked list for the category currently showing.
* @param website The website to check.
*/
private boolean isOnBlockList(WebsitePreference website) {
// This list is ordered alphabetically by permission.
if (mCategory.showAdsSites()) {
return website.site().getAdsPermission() == ContentSetting.BLOCK;
} else if (mCategory.showAutoplaySites()) {
return website.site().getAutoplayPermission() == ContentSetting.BLOCK;
} else if (mCategory.showBackgroundSyncSites()) {
return website.site().getBackgroundSyncPermission() == ContentSetting.BLOCK;
} else if (mCategory.showCameraSites()) {
return website.site().getCameraPermission() == ContentSetting.BLOCK;
} else if (mCategory.showClipboardSites()) {
return website.site().getClipboardPermission() == ContentSetting.BLOCK;
} else if (mCategory.showCookiesSites()) {
return website.site().getCookiePermission() == ContentSetting.BLOCK;
} else if (mCategory.showGeolocationSites()) {
return website.site().getGeolocationPermission() == ContentSetting.BLOCK;
} else if (mCategory.showJavaScriptSites()) {
return website.site().getJavaScriptPermission() == ContentSetting.BLOCK;
} else if (mCategory.showMicrophoneSites()) {
return website.site().getMicrophonePermission() == ContentSetting.BLOCK;
} else if (mCategory.showNotificationsSites()) {
return website.site().getNotificationPermission() == ContentSetting.BLOCK;
} else if (mCategory.showPopupSites()) {
return website.site().getPopupPermission() == ContentSetting.BLOCK;
} else if (mCategory.showProtectedMediaSites()) {
return website.site().getProtectedMediaIdentifierPermission() == ContentSetting.BLOCK;
} else if (mCategory.showSoundSites()) {
return website.site().getSoundPermission() == ContentSetting.BLOCK;
}
return false;
}
/**
* Update the Category Header for the Allowed list.
* @param numAllowed The number of sites that are on the Allowed list
* @param toggleValue The value the global toggle will have once precessing ends.
*/
private void updateAllowedHeader(int numAllowed, boolean toggleValue) {
ExpandablePreferenceGroup allowedGroup =
(ExpandablePreferenceGroup) getPreferenceScreen().findPreference(ALLOWED_GROUP);
if (numAllowed == 0) {
if (allowedGroup != null) getPreferenceScreen().removePreference(allowedGroup);
return;
}
if (!mGroupByAllowBlock) return;
// When the toggle is set to Blocked, the Allowed list header should read 'Exceptions', not
// 'Allowed' (because it shows exceptions from the rule).
int resourceId = toggleValue
? R.string.website_settings_allowed_group_heading
: R.string.website_settings_exceptions_group_heading;
// Set the title and arrow icons for the header.
allowedGroup.setGroupTitle(resourceId, numAllowed);
TintedDrawable icon = TintedDrawable.constructTintedDrawable(getResources(),
mAllowListExpanded ? R.drawable.ic_expanded : R.drawable.ic_collapsed);
allowedGroup.setExpanded(mAllowListExpanded);
allowedGroup.setIcon(icon);
}
private void updateBlockedHeader(int numBlocked) {
ExpandablePreferenceGroup blockedGroup =
(ExpandablePreferenceGroup) getPreferenceScreen().findPreference(BLOCKED_GROUP);
if (numBlocked == 0) {
if (blockedGroup != null) getPreferenceScreen().removePreference(blockedGroup);
return;
}
if (!mGroupByAllowBlock) return;
// Set the title and arrow icons for the header.
int resourceId = mCategory.showSoundSites()
? R.string.website_settings_blocked_group_heading_sound
: R.string.website_settings_blocked_group_heading;
blockedGroup.setGroupTitle(resourceId, numBlocked);
TintedDrawable icon = TintedDrawable.constructTintedDrawable(getResources(),
mBlockListExpanded ? R.drawable.ic_expanded : R.drawable.ic_collapsed);
blockedGroup.setExpanded(mBlockListExpanded);
blockedGroup.setIcon(icon);
}
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Read which category we should be showing.
String category = "";
if (getArguments() != null) {
category = getArguments().getString(EXTRA_CATEGORY, "");
mCategory = SiteSettingsCategory.fromString(category);
}
if (mCategory == null) {
mCategory = SiteSettingsCategory.fromString(SiteSettingsCategory.CATEGORY_ALL_SITES);
}
if (!mCategory.showStorageSites()) {
return super.onCreateView(inflater, container, savedInstanceState);
} else {
return inflater.inflate(R.layout.storage_preferences, container, false);
}
}
/**
* Returns the category being displayed. For testing.
*/
public SiteSettingsCategory getCategoryForTest() {
return mCategory;
}
/**
* This clears all the storage for websites that are displayed to the user. This happens
* asynchronously, and then we call {@link #getInfoForOrigins()} when we're done.
*/
public void clearStorage() {
if (mWebsites == null) {
return;
}
RecordUserAction.record("MobileSettingsStorageClearAll");
// The goal is to refresh the info for origins again after we've cleared all of them, so we
// wait until the last website is cleared to refresh the origin list.
final int[] numLeft = new int[1];
numLeft[0] = mWebsites.size();
for (int i = 0; i < mWebsites.size(); i++) {
WebsitePreference preference = mWebsites.get(i);
preference.site().clearAllStoredData(new StoredDataClearedCallback() {
@Override
public void onStoredDataCleared() {
if (--numLeft[0] <= 0) {
getInfoForOrigins();
}
}
});
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
PreferenceUtils.addPreferencesFromResource(this, R.xml.website_preferences);
ListView listView = (ListView) getView().findViewById(android.R.id.list);
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
listView.setEmptyView(mEmptyView);
listView.setDivider(null);
mClearButton = (Button) getView().findViewById(R.id.clear_button);
if (mClearButton != null) {
mClearButton.setOnClickListener(this);
}
String title = getArguments().getString(EXTRA_TITLE);
if (title != null) getActivity().setTitle(title);
configureGlobalToggles();
setHasOptionsMenu(true);
super.onActivityCreated(savedInstanceState);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.website_preferences_menu, menu);
MenuItem searchItem = menu.findItem(R.id.search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
SearchView.OnQueryTextListener queryTextListener =
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String query) {
if (query.equals(mSearch)) return true;
mSearch = query;
getInfoForOrigins();
return true;
}
};
mSearchView.setOnQueryTextListener(queryTextListener);
if (mCategory.showProtectedMediaSites()) {
// Add a menu item to reset protected media identifier device credentials.
MenuItem resetMenu =
menu.add(Menu.NONE, Menu.NONE, Menu.NONE, R.string.reset_device_credentials);
resetMenu.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
ProtectedContentResetCredentialConfirmDialogFragment
.newInstance(SingleCategoryPreferences.this)
.show(getFragmentManager(), null);
return true;
}
});
}
MenuItem help = menu.add(
Menu.NONE, R.id.menu_id_targeted_help, Menu.NONE, R.string.menu_help);
help.setIcon(R.drawable.ic_help_and_feedback);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_id_targeted_help) {
int helpContextResId = R.string.help_context_settings;
if (mCategory.showProtectedMediaSites()) {
helpContextResId = R.string.help_context_protected_content;
}
HelpAndFeedback.getInstance(getActivity()).show(
getActivity(), getString(helpContextResId), Profile.getLastUsedProfile(), null);
return true;
}
return false;
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
// Do not show the toast if the System Location setting is disabled.
if (getPreferenceScreen().findPreference(READ_WRITE_TOGGLE_KEY) != null
&& mCategory.isManaged()) {
showManagedToast();
return false;
}
if (!mSearch.isEmpty()) {
// Clear out any lingering searches, so that the full list is shown
// when coming back to this page.
mSearch = "";
mSearchView.setQuery("", false);
}
if (preference instanceof WebsitePreference) {
WebsitePreference website = (WebsitePreference) preference;
website.setFragment(SingleWebsitePreferences.class.getName());
// EXTRA_SITE re-uses already-fetched permissions, which we can only use if the Website
// was populated with data for all permission types.
if (mCategory.showAllSites()) {
website.putSiteIntoExtras(SingleWebsitePreferences.EXTRA_SITE);
} else {
website.putSiteAddressIntoExtras(SingleWebsitePreferences.EXTRA_SITE_ADDRESS);
}
}
return super.onPreferenceTreeClick(screen, preference);
}
/** OnClickListener for the clear button. We show an alert dialog to confirm the action */
@Override
public void onClick(View v) {
if (getActivity() == null || v != mClearButton) return;
long totalUsage = 0;
if (mWebsites != null) {
for (WebsitePreference preference : mWebsites) {
totalUsage += preference.site().getTotalUsage();
}
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setPositiveButton(R.string.storage_clear_dialog_clear_storage_option,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
clearStorage();
}
});
builder.setNegativeButton(R.string.cancel, null);
builder.setTitle(R.string.storage_clear_site_storage_title);
Resources res = getResources();
String dialogFormattedText = res.getString(R.string.storage_clear_dialog_text,
Formatter.formatShortFileSize(getActivity(), totalUsage));
builder.setMessage(dialogFormattedText);
builder.create().show();
}
// OnPreferenceChangeListener:
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (READ_WRITE_TOGGLE_KEY.equals(preference.getKey())) {
assert !mCategory.isManaged();
if (mCategory.showAdsSites()) {
PrefServiceBridge.getInstance().setAllowAdsEnabled((boolean) newValue);
} else if (mCategory.showAutoplaySites()) {
PrefServiceBridge.getInstance().setAutoplayEnabled((boolean) newValue);
} else if (mCategory.showBackgroundSyncSites()) {
PrefServiceBridge.getInstance().setBackgroundSyncEnabled((boolean) newValue);
} else if (mCategory.showCameraSites()) {
PrefServiceBridge.getInstance().setCameraEnabled((boolean) newValue);
} else if (mCategory.showClipboardSites()) {
PrefServiceBridge.getInstance().setClipboardEnabled((boolean) newValue);
} else if (mCategory.showCookiesSites()) {
PrefServiceBridge.getInstance().setAllowCookiesEnabled((boolean) newValue);
updateThirdPartyCookiesCheckBox();
} else if (mCategory.showGeolocationSites()) {
PrefServiceBridge.getInstance().setAllowLocationEnabled((boolean) newValue);
} else if (mCategory.showJavaScriptSites()) {
PrefServiceBridge.getInstance().setJavaScriptEnabled((boolean) newValue);
} else if (mCategory.showMicrophoneSites()) {
PrefServiceBridge.getInstance().setMicEnabled((boolean) newValue);
} else if (mCategory.showNotificationsSites()) {
PrefServiceBridge.getInstance().setNotificationsEnabled((boolean) newValue);
updateNotificationsVibrateCheckBox();
} else if (mCategory.showPopupSites()) {
PrefServiceBridge.getInstance().setAllowPopupsEnabled((boolean) newValue);
} else if (mCategory.showProtectedMediaSites()) {
PrefServiceBridge.getInstance().setProtectedMediaIdentifierEnabled(
(boolean) newValue);
} else if (mCategory.showSoundSites()) {
PrefServiceBridge.getInstance().setSoundEnabled((boolean) newValue);
}
// Categories that support adding exceptions also manage the 'Add site' preference.
if (mCategory.showAutoplaySites() || mCategory.showBackgroundSyncSites()
|| mCategory.showJavaScriptSites() || mCategory.showSoundSites()
|| mCategory.showClipboardSites()) {
if ((boolean) newValue) {
Preference addException = getPreferenceScreen().findPreference(
ADD_EXCEPTION_KEY);
if (addException != null) { // Can be null in testing.
getPreferenceScreen().removePreference(addException);
}
} else {
getPreferenceScreen().addPreference(
new AddExceptionPreference(getActivity(), ADD_EXCEPTION_KEY,
getAddExceptionDialogMessage(), this));
}
}
ChromeSwitchPreference globalToggle = (ChromeSwitchPreference)
getPreferenceScreen().findPreference(READ_WRITE_TOGGLE_KEY);
updateAllowedHeader(mAllowedSiteCount, !globalToggle.isChecked());
getInfoForOrigins();
} else if (THIRD_PARTY_COOKIES_TOGGLE_KEY.equals(preference.getKey())) {
PrefServiceBridge.getInstance().setBlockThirdPartyCookiesEnabled(!((boolean) newValue));
} else if (NOTIFICATIONS_VIBRATE_TOGGLE_KEY.equals(preference.getKey())) {
PrefServiceBridge.getInstance().setNotificationsVibrateEnabled((boolean) newValue);
}
return true;
}
private String getAddExceptionDialogMessage() {
int resource = 0;
if (mCategory.showAutoplaySites()) {
resource = R.string.website_settings_add_site_description_autoplay;
} else if (mCategory.showBackgroundSyncSites()) {
resource = R.string.website_settings_add_site_description_background_sync;
} else if (mCategory.showClipboardSites()) {
resource = PrefServiceBridge.getInstance().isClipboardEnabled()
? R.string.website_settings_add_site_description_clipboard_block
: R.string.website_settings_add_site_description_clipboard_allow;
} else if (mCategory.showJavaScriptSites()) {
resource = R.string.website_settings_add_site_description_javascript;
} else if (mCategory.showSoundSites()) {
resource = PrefServiceBridge.getInstance().isSoundEnabled()
? R.string.website_settings_add_site_description_sound_block
: R.string.website_settings_add_site_description_sound_allow;
}
assert resource > 0;
return getResources().getString(resource);
}
// OnPreferenceClickListener:
@Override
public boolean onPreferenceClick(Preference preference) {
if (ALLOWED_GROUP.equals(preference.getKey())) {
mAllowListExpanded = !mAllowListExpanded;
} else {
mBlockListExpanded = !mBlockListExpanded;
}
getInfoForOrigins();
return true;
}
@Override
public void onResume() {
super.onResume();
getInfoForOrigins();
}
// AddExceptionPreference.SiteAddedCallback:
@Override
public void onAddSite(String hostname) {
// The Sound content setting has exception lists for both BLOCK and ALLOW (others just
// have exceptions to ALLOW).
int setting =
(mCategory.showSoundSites() && PrefServiceBridge.getInstance().isSoundEnabled())
? ContentSetting.BLOCK.toInt()
: ContentSetting.ALLOW.toInt();
PrefServiceBridge.getInstance().nativeSetContentSettingForPattern(
mCategory.toContentSettingsType(), hostname, setting);
Toast.makeText(getActivity(),
String.format(getActivity().getString(
R.string.website_settings_add_site_toast),
hostname),
Toast.LENGTH_SHORT).show();
getInfoForOrigins();
if (mCategory.showSoundSites()) {
if (setting == ContentSetting.BLOCK.toInt()) {
RecordUserAction.record("SoundContentSetting.MuteBy.PatternException");
} else {
RecordUserAction.record("SoundContentSetting.UnmuteBy.PatternException");
}
}
}
/**
* Reset the preference screen an initialize it again.
*/
private void resetList() {
// This will remove the combo box at the top and all the sites listed below it.
getPreferenceScreen().removeAll();
// And this will add the filter preference back (combo box).
PreferenceUtils.addPreferencesFromResource(this, R.xml.website_preferences);
configureGlobalToggles();
if ((mCategory.showAutoplaySites() && !PrefServiceBridge.getInstance().isAutoplayEnabled())
|| (mCategory.showJavaScriptSites()
&& !PrefServiceBridge.getInstance().javaScriptEnabled())
|| mCategory.showSoundSites() || mCategory.showClipboardSites()
|| (mCategory.showBackgroundSyncSites()
&& !PrefServiceBridge.getInstance().isBackgroundSyncAllowed())) {
getPreferenceScreen().addPreference(
new AddExceptionPreference(getActivity(), ADD_EXCEPTION_KEY,
getAddExceptionDialogMessage(), this));
}
}
private void configureGlobalToggles() {
// Only some have a global toggle at the top.
ChromeSwitchPreference globalToggle = (ChromeSwitchPreference)
getPreferenceScreen().findPreference(READ_WRITE_TOGGLE_KEY);
// Configure/hide the third-party cookie toggle, as needed.
Preference thirdPartyCookies = getPreferenceScreen().findPreference(
THIRD_PARTY_COOKIES_TOGGLE_KEY);
if (mCategory.showCookiesSites()) {
thirdPartyCookies.setOnPreferenceChangeListener(this);
updateThirdPartyCookiesCheckBox();
} else {
getPreferenceScreen().removePreference(thirdPartyCookies);
}
// Configure/hide the notifications vibrate toggle, as needed.
Preference notificationsVibrate =
getPreferenceScreen().findPreference(NOTIFICATIONS_VIBRATE_TOGGLE_KEY);
if (mCategory.showNotificationsSites() && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
notificationsVibrate.setOnPreferenceChangeListener(this);
updateNotificationsVibrateCheckBox();
} else {
getPreferenceScreen().removePreference(notificationsVibrate);
}
// Show/hide the link that explains protected media settings, as needed.
if (!mCategory.showProtectedMediaSites()) {
getPreferenceScreen().removePreference(
getPreferenceScreen().findPreference(EXPLAIN_PROTECTED_MEDIA_KEY));
}
if (mCategory.showAllSites()
|| mCategory.showStorageSites()) {
getPreferenceScreen().removePreference(globalToggle);
getPreferenceScreen().removePreference(
getPreferenceScreen().findPreference(ALLOWED_GROUP));
getPreferenceScreen().removePreference(
getPreferenceScreen().findPreference(BLOCKED_GROUP));
} else {
// When this menu opens, make sure the Blocked list is collapsed.
if (!mGroupByAllowBlock) {
mBlockListExpanded = false;
mAllowListExpanded = true;
}
mGroupByAllowBlock = true;
PreferenceGroup allowedGroup =
(PreferenceGroup) getPreferenceScreen().findPreference(
ALLOWED_GROUP);
PreferenceGroup blockedGroup =
(PreferenceGroup) getPreferenceScreen().findPreference(
BLOCKED_GROUP);
if (mCategory.showPermissionBlockedMessage(getActivity())) {
getPreferenceScreen().removePreference(globalToggle);
getPreferenceScreen().removePreference(allowedGroup);
getPreferenceScreen().removePreference(blockedGroup);
// Show the link to system settings since permission is disabled.
ChromeBasePreference osWarning = new ChromeBasePreference(getActivity(), null);
ChromeBasePreference osWarningExtra = new ChromeBasePreference(getActivity(), null);
mCategory.configurePermissionIsOffPreferences(osWarning, osWarningExtra,
getActivity(), true);
if (osWarning.getTitle() != null) {
getPreferenceScreen().addPreference(osWarning);
}
if (osWarningExtra.getTitle() != null) {
getPreferenceScreen().addPreference(osWarningExtra);
}
} else {
allowedGroup.setOnPreferenceClickListener(this);
blockedGroup.setOnPreferenceClickListener(this);
// Determine what toggle to use and what it should display.
int contentType = mCategory.toContentSettingsType();
globalToggle.setOnPreferenceChangeListener(this);
globalToggle.setTitle(ContentSettingsResources.getTitle(contentType));
if (mCategory.showGeolocationSites()
&& PrefServiceBridge.getInstance().isLocationAllowedByPolicy()) {
globalToggle.setSummaryOn(
ContentSettingsResources.getGeolocationAllowedSummary());
} else {
globalToggle.setSummaryOn(
ContentSettingsResources.getEnabledSummary(contentType));
}
globalToggle.setSummaryOff(
ContentSettingsResources.getDisabledSummary(contentType));
globalToggle.setManagedPreferenceDelegate(new ManagedPreferenceDelegate() {
@Override
public boolean isPreferenceControlledByPolicy(Preference preference) {
// TODO(bauerb): Align the ManagedPreferenceDelegate and
// SiteSettingsCategory interfaces better to avoid this indirection.
return mCategory.isManaged() && !mCategory.isManagedByCustodian();
}
@Override
public boolean isPreferenceControlledByCustodian(Preference preference) {
return mCategory.isManagedByCustodian();
}
});
if (mCategory.showAdsSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().adsEnabled());
} else if (mCategory.showAutoplaySites()) {
globalToggle.setChecked(
PrefServiceBridge.getInstance().isAutoplayEnabled());
} else if (mCategory.showBackgroundSyncSites()) {
globalToggle.setChecked(
PrefServiceBridge.getInstance().isBackgroundSyncAllowed());
} else if (mCategory.showCameraSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().isCameraEnabled());
} else if (mCategory.showClipboardSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().isClipboardEnabled());
} else if (mCategory.showCookiesSites()) {
globalToggle.setChecked(
PrefServiceBridge.getInstance().isAcceptCookiesEnabled());
} else if (mCategory.showGeolocationSites()) {
globalToggle.setChecked(
LocationSettings.getInstance().isChromeLocationSettingEnabled());
} else if (mCategory.showJavaScriptSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().javaScriptEnabled());
} else if (mCategory.showMicrophoneSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().isMicEnabled());
} else if (mCategory.showNotificationsSites()) {
globalToggle.setChecked(
PrefServiceBridge.getInstance().isNotificationsEnabled());
} else if (mCategory.showPopupSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().popupsEnabled());
} else if (mCategory.showProtectedMediaSites()) {
globalToggle.setChecked(
PrefServiceBridge.getInstance().isProtectedMediaIdentifierEnabled());
} else if (mCategory.showSoundSites()) {
globalToggle.setChecked(PrefServiceBridge.getInstance().isSoundEnabled());
}
}
}
}
private void updateThirdPartyCookiesCheckBox() {
ChromeBaseCheckBoxPreference thirdPartyCookiesPref = (ChromeBaseCheckBoxPreference)
getPreferenceScreen().findPreference(THIRD_PARTY_COOKIES_TOGGLE_KEY);
thirdPartyCookiesPref.setChecked(
!PrefServiceBridge.getInstance().isBlockThirdPartyCookiesEnabled());
thirdPartyCookiesPref.setEnabled(PrefServiceBridge.getInstance().isAcceptCookiesEnabled());
thirdPartyCookiesPref.setManagedPreferenceDelegate(new ManagedPreferenceDelegate() {
@Override
public boolean isPreferenceControlledByPolicy(Preference preference) {
return PrefServiceBridge.getInstance().isBlockThirdPartyCookiesManaged();
}
});
}
private void updateNotificationsVibrateCheckBox() {
ChromeBaseCheckBoxPreference preference =
(ChromeBaseCheckBoxPreference) getPreferenceScreen().findPreference(
NOTIFICATIONS_VIBRATE_TOGGLE_KEY);
if (preference != null) {
preference.setEnabled(PrefServiceBridge.getInstance().isNotificationsEnabled());
}
}
private void showManagedToast() {
if (mCategory.isManagedByCustodian()) {
ManagedPreferencesUtils.showManagedByParentToast(getActivity());
} else {
ManagedPreferencesUtils.showManagedByAdministratorToast(getActivity());
}
}
// ProtectedContentResetCredentialConfirmDialogFragment.Listener:
@Override
public void resetDeviceCredential() {
MediaDrmCredentialManager.resetCredentials(new MediaDrmCredentialManagerCallback() {
@Override
public void onCredentialResetFinished(boolean succeeded) {
if (succeeded) return;
String message = getString(R.string.protected_content_reset_failed);
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
});
}
}