blob: 7ea054dc377d7be81165bd20bbcd94e134763f52 [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.privacy.settings;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableString;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.safe_browsing.metrics.SettingsAccessPoint;
import org.chromium.chrome.browser.safe_browsing.settings.SafeBrowsingSettingsFragment;
import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
import org.chromium.chrome.browser.sync.settings.GoogleServicesSettings;
import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings;
import org.chromium.chrome.browser.usage_stats.UsageStatsConsentDialog;
import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate;
import org.chromium.components.browser_ui.settings.SettingsUtils;
import org.chromium.components.prefs.PrefService;
import org.chromium.components.signin.identitymanager.ConsentLevel;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier;
/**
* Fragment to keep track of the all the privacy related preferences.
*/
public class PrivacySettings
extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener {
private static final String PREF_CAN_MAKE_PAYMENT = "can_make_payment";
private static final String PREF_NETWORK_PREDICTIONS = "preload_pages";
private static final String PREF_SECURE_DNS = "secure_dns";
private static final String PREF_USAGE_STATS = "usage_stats_reporting";
private static final String PREF_DO_NOT_TRACK = "do_not_track";
private static final String PREF_SAFE_BROWSING = "safe_browsing";
private static final String PREF_SYNC_AND_SERVICES_LINK = "sync_and_services_link";
private static final String PREF_CLEAR_BROWSING_DATA = "clear_browsing_data";
private static final String PREF_PRIVACY_SANDBOX = "privacy_sandbox";
private static final String[] NEW_PRIVACY_PREFERENCE_ORDER = {PREF_CLEAR_BROWSING_DATA,
PREF_SAFE_BROWSING, PREF_CAN_MAKE_PAYMENT, PREF_NETWORK_PREDICTIONS, PREF_USAGE_STATS,
PREF_SECURE_DNS, PREF_DO_NOT_TRACK, PREF_PRIVACY_SANDBOX, PREF_SYNC_AND_SERVICES_LINK};
private ManagedPreferenceDelegate mManagedPreferenceDelegate;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
PrivacyPreferencesManagerImpl privacyPrefManager =
PrivacyPreferencesManagerImpl.getInstance();
SettingsUtils.addPreferencesFromResource(this, R.xml.privacy_preferences);
assert NEW_PRIVACY_PREFERENCE_ORDER.length
== getPreferenceScreen().getPreferenceCount()
: "All preferences in the screen should be added in the new order list. "
+ "If you add a new preference, please also update "
+ "NEW_PRIVACY_PREFERENCE_ORDER.";
if (ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVACY_REORDERED_ANDROID)) {
for (int i = 0; i < NEW_PRIVACY_PREFERENCE_ORDER.length; i++) {
findPreference(NEW_PRIVACY_PREFERENCE_ORDER[i]).setOrder(i);
}
}
// Remove Privacy Sandbox settings if the corresponding flag is disabled.
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVACY_SANDBOX_SETTINGS)) {
getPreferenceScreen().removePreference(findPreference(PREF_PRIVACY_SANDBOX));
}
// If the flag for adding a "Safe Browsing" section UI is enabled, a "Safe Browsing" section
// will be added under this section and this section will be renamed to "Privacy and
// security". See (go/esb-clank-dd) for more context.
if (ChromeFeatureList.isEnabled(ChromeFeatureList.SAFE_BROWSING_SECTION_UI)) {
getActivity().setTitle(R.string.prefs_privacy_security);
Preference safeBrowsingPreference = findPreference(PREF_SAFE_BROWSING);
safeBrowsingPreference.setSummary(
SafeBrowsingSettingsFragment.getSafeBrowsingSummaryString(getContext()));
safeBrowsingPreference.setOnPreferenceClickListener((preference) -> {
preference.getExtras().putInt(SafeBrowsingSettingsFragment.ACCESS_POINT,
SettingsAccessPoint.PARENT_SETTINGS);
return false;
});
} else {
getActivity().setTitle(R.string.prefs_privacy);
getPreferenceScreen().removePreference(findPreference(PREF_SAFE_BROWSING));
}
setHasOptionsMenu(true);
mManagedPreferenceDelegate = createManagedPreferenceDelegate();
ChromeSwitchPreference canMakePaymentPref =
(ChromeSwitchPreference) findPreference(PREF_CAN_MAKE_PAYMENT);
canMakePaymentPref.setOnPreferenceChangeListener(this);
ChromeSwitchPreference networkPredictionPref =
(ChromeSwitchPreference) findPreference(PREF_NETWORK_PREDICTIONS);
networkPredictionPref.setChecked(
PrivacyPreferencesManagerImpl.getInstance().getNetworkPredictionEnabled());
networkPredictionPref.setOnPreferenceChangeListener(this);
networkPredictionPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
Preference secureDnsPref = findPreference(PREF_SECURE_DNS);
secureDnsPref.setVisible(SecureDnsSettings.isUiEnabled());
Preference syncAndServicesLink = findPreference(PREF_SYNC_AND_SERVICES_LINK);
syncAndServicesLink.setSummary(buildSyncAndServicesLink());
updateSummaries();
}
private SpannableString buildSyncAndServicesLink() {
SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) {
NoUnderlineClickableSpan syncAndServicesLink =
new NoUnderlineClickableSpan(getResources(), v -> {
settingsLauncher.launchSettingsActivity(getActivity(),
SyncAndServicesSettings.class,
SyncAndServicesSettings.createArguments(false));
});
return SpanApplier.applySpans(getString(R.string.privacy_sync_and_services_link_legacy),
new SpanApplier.SpanInfo("<link>", "</link>", syncAndServicesLink));
}
NoUnderlineClickableSpan servicesLink = new NoUnderlineClickableSpan(getResources(), v -> {
settingsLauncher.launchSettingsActivity(getActivity(), GoogleServicesSettings.class);
});
if (IdentityServicesProvider.get()
.getIdentityManager(Profile.getLastUsedRegularProfile())
.getPrimaryAccountInfo(ConsentLevel.SYNC)
== null) {
// Sync is off, show the string with one link to "Google Services".
return SpanApplier.applySpans(
getString(R.string.privacy_sync_and_services_link_sync_off),
new SpanApplier.SpanInfo("<link>", "</link>", servicesLink));
}
// Otherwise, show the string with both links to "Sync" and "Google Services".
NoUnderlineClickableSpan syncLink = new NoUnderlineClickableSpan(getResources(), v -> {
settingsLauncher.launchSettingsActivity(getActivity(), ManageSyncSettings.class,
ManageSyncSettings.createArguments(false));
});
return SpanApplier.applySpans(getString(R.string.privacy_sync_and_services_link_sync_on),
new SpanApplier.SpanInfo("<link1>", "</link1>", syncLink),
new SpanApplier.SpanInfo("<link2>", "</link2>", servicesLink));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = preference.getKey();
if (PREF_CAN_MAKE_PAYMENT.equals(key)) {
UserPrefs.get(Profile.getLastUsedRegularProfile())
.setBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED, (boolean) newValue);
} else if (PREF_NETWORK_PREDICTIONS.equals(key)) {
PrivacyPreferencesManagerImpl.getInstance().setNetworkPredictionEnabled(
(boolean) newValue);
}
return true;
}
@Override
public void onResume() {
super.onResume();
updateSummaries();
}
/**
* Updates the summaries for several preferences.
*/
public void updateSummaries() {
PrefService prefService = UserPrefs.get(Profile.getLastUsedRegularProfile());
ChromeSwitchPreference canMakePaymentPref =
(ChromeSwitchPreference) findPreference(PREF_CAN_MAKE_PAYMENT);
if (canMakePaymentPref != null) {
canMakePaymentPref.setChecked(prefService.getBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED));
}
Preference doNotTrackPref = findPreference(PREF_DO_NOT_TRACK);
if (doNotTrackPref != null) {
doNotTrackPref.setSummary(prefService.getBoolean(Pref.ENABLE_DO_NOT_TRACK)
? R.string.text_on
: R.string.text_off);
}
Preference secureDnsPref = findPreference(PREF_SECURE_DNS);
if (secureDnsPref != null && secureDnsPref.isVisible()) {
secureDnsPref.setSummary(SecureDnsSettings.getSummary(getContext()));
}
Preference safeBrowsingPreference = findPreference(PREF_SAFE_BROWSING);
if (safeBrowsingPreference != null && safeBrowsingPreference.isVisible()) {
safeBrowsingPreference.setSummary(
SafeBrowsingSettingsFragment.getSafeBrowsingSummaryString(getContext()));
}
Preference usageStatsPref = findPreference(PREF_USAGE_STATS);
if (usageStatsPref != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& prefService.getBoolean(Pref.USAGE_STATS_ENABLED)) {
usageStatsPref.setOnPreferenceClickListener(preference -> {
UsageStatsConsentDialog
.create(getActivity(), true,
(didConfirm) -> {
if (didConfirm) {
updateSummaries();
}
})
.show();
return true;
});
} else {
getPreferenceScreen().removePreference(usageStatsPref);
}
}
}
private ChromeManagedPreferenceDelegate createManagedPreferenceDelegate() {
return preference -> {
String key = preference.getKey();
if (PREF_NETWORK_PREDICTIONS.equals(key)) {
return PrivacyPreferencesManagerImpl.getInstance().isNetworkPredictionManaged();
}
return false;
};
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
MenuItem help =
menu.add(Menu.NONE, R.id.menu_id_targeted_help, Menu.NONE, R.string.menu_help);
help.setIcon(VectorDrawableCompat.create(
getResources(), R.drawable.ic_help_and_feedback, getActivity().getTheme()));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_id_targeted_help) {
HelpAndFeedbackLauncherImpl.getInstance().show(getActivity(),
getString(R.string.help_context_privacy), Profile.getLastUsedRegularProfile(),
null);
return true;
}
return false;
}
}