| // Copyright 2018 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; |
| |
| import android.accounts.Account; |
| import android.app.Dialog; |
| import android.app.DialogFragment; |
| import android.app.FragmentManager; |
| import android.app.FragmentTransaction; |
| import android.content.Intent; |
| import android.content.res.Resources; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.preference.Preference; |
| import android.preference.PreferenceCategory; |
| import android.preference.PreferenceFragment; |
| import android.preference.PreferenceGroup; |
| import android.provider.Settings; |
| import android.support.annotation.IntDef; |
| import android.support.annotation.Nullable; |
| import android.support.v7.app.AlertDialog; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| |
| import org.chromium.base.BuildInfo; |
| import org.chromium.base.ContextUtils; |
| import org.chromium.base.VisibleForTesting; |
| import org.chromium.base.metrics.RecordHistogram; |
| import org.chromium.base.task.PostTask; |
| import org.chromium.chrome.R; |
| import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsEnabledStateUtils; |
| import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; |
| import org.chromium.chrome.browser.help.HelpAndFeedback; |
| import org.chromium.chrome.browser.invalidation.InvalidationController; |
| import org.chromium.chrome.browser.metrics.UmaSessionStats; |
| import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager; |
| import org.chromium.chrome.browser.profiles.Profile; |
| import org.chromium.chrome.browser.signin.SigninManager; |
| import org.chromium.chrome.browser.signin.SignoutReason; |
| import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge; |
| import org.chromium.chrome.browser.sync.GoogleServiceAuthError; |
| import org.chromium.chrome.browser.sync.ProfileSyncService; |
| import org.chromium.chrome.browser.sync.ui.PassphraseDialogFragment; |
| import org.chromium.chrome.browser.util.FeatureUtilities; |
| import org.chromium.chrome.browser.util.IntentUtils; |
| import org.chromium.components.signin.AccountManagerFacade; |
| import org.chromium.components.signin.ChromeSigninController; |
| import org.chromium.components.sync.AndroidSyncSettings; |
| import org.chromium.components.sync.ProtocolErrorClientAction; |
| import org.chromium.content_public.browser.UiThreadTaskTraits; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| |
| /** |
| * Settings fragment to enable Sync and other services that communicate with Google. |
| */ |
| public class SyncAndServicesPreferences extends PreferenceFragment |
| implements PassphraseDialogFragment.Listener, Preference.OnPreferenceChangeListener, |
| ProfileSyncService.SyncStateChangedListener, Preferences.OnBackPressedListener { |
| private static final String IS_FROM_SIGNIN_SCREEN = |
| "SyncAndServicesPreferences.isFromSigninScreen"; |
| |
| @VisibleForTesting |
| public static final String FRAGMENT_ENTER_PASSPHRASE = "enter_password"; |
| private static final String FRAGMENT_CANCEL_SYNC = "cancel_sync_dialog"; |
| |
| private static final String PREF_SIGNIN = "sign_in"; |
| |
| private static final String PREF_SYNC_CATEGORY = "sync_category"; |
| private static final String PREF_SYNC_ERROR_CARD = "sync_error_card"; |
| private static final String PREF_SYNC_REQUESTED = "sync_requested"; |
| |
| private static final String PREF_SERVICES_CATEGORY = "services_category"; |
| private static final String PREF_SEARCH_SUGGESTIONS = "search_suggestions"; |
| private static final String PREF_NETWORK_PREDICTIONS = "network_predictions"; |
| private static final String PREF_NAVIGATION_ERROR = "navigation_error"; |
| private static final String PREF_SAFE_BROWSING = "safe_browsing"; |
| private static final String PREF_SAFE_BROWSING_SCOUT_REPORTING = |
| "safe_browsing_scout_reporting"; |
| private static final String PREF_USAGE_AND_CRASH_REPORTING = "usage_and_crash_reports"; |
| private static final String PREF_URL_KEYED_ANONYMIZED_DATA = "url_keyed_anonymized_data"; |
| private static final String PREF_CONTEXTUAL_SEARCH = "contextual_search"; |
| private static final String PREF_CONTEXTUAL_SUGGESTIONS = "contextual_suggestions"; |
| |
| @IntDef({SyncError.NO_ERROR, SyncError.ANDROID_SYNC_DISABLED, SyncError.AUTH_ERROR, |
| SyncError.PASSPHRASE_REQUIRED, SyncError.CLIENT_OUT_OF_DATE, SyncError.OTHER_ERRORS}) |
| @Retention(RetentionPolicy.SOURCE) |
| private @interface SyncError { |
| int NO_ERROR = -1; |
| int ANDROID_SYNC_DISABLED = 0; |
| int AUTH_ERROR = 1; |
| int PASSPHRASE_REQUIRED = 2; |
| int CLIENT_OUT_OF_DATE = 3; |
| int OTHER_ERRORS = 128; |
| } |
| |
| private final ProfileSyncService mProfileSyncService = ProfileSyncService.get(); |
| private final PrefServiceBridge mPrefServiceBridge = PrefServiceBridge.getInstance(); |
| private final PrivacyPreferencesManager mPrivacyPrefManager = |
| PrivacyPreferencesManager.getInstance(); |
| private final ManagedPreferenceDelegate mManagedPreferenceDelegate = |
| createManagedPreferenceDelegate(); |
| |
| private boolean mIsFromSigninScreen; |
| |
| private SignInPreference mSigninPreference; |
| |
| private PreferenceCategory mSyncCategory; |
| private Preference mSyncErrorCard; |
| private ChromeSwitchPreference mSyncRequested; |
| |
| private ChromeSwitchPreference mSearchSuggestions; |
| private ChromeSwitchPreference mNetworkPredictions; |
| private ChromeSwitchPreference mNavigationError; |
| private ChromeSwitchPreference mSafeBrowsing; |
| private ChromeSwitchPreference mSafeBrowsingReporting; |
| private ChromeSwitchPreference mUsageAndCrashReporting; |
| private ChromeSwitchPreference mUrlKeyedAnonymizedData; |
| private @Nullable Preference mContextualSearch; |
| private @Nullable Preference mContextualSuggestions; |
| |
| private ProfileSyncService.SyncSetupInProgressHandle mSyncSetupInProgressHandle; |
| |
| private @SyncError int mCurrentSyncError = SyncError.NO_ERROR; |
| |
| /** |
| * Creates an argument bundle for this fragment. |
| * @param isFromSigninScreen Whether the screen is started from the sign-in screen. |
| */ |
| public static Bundle createArguments(boolean isFromSigninScreen) { |
| Bundle result = new Bundle(); |
| result.putBoolean(IS_FROM_SIGNIN_SCREEN, isFromSigninScreen); |
| return result; |
| } |
| |
| @Override |
| public void onCreate(@Nullable Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| mIsFromSigninScreen = |
| IntentUtils.safeGetBoolean(getArguments(), IS_FROM_SIGNIN_SCREEN, false); |
| |
| mPrivacyPrefManager.migrateNetworkPredictionPreferences(); |
| |
| getActivity().setTitle(R.string.prefs_sync_and_services); |
| setHasOptionsMenu(true); |
| |
| PreferenceUtils.addPreferencesFromResource(this, R.xml.sync_and_services_preferences); |
| |
| mSigninPreference = (SignInPreference) findPreference(PREF_SIGNIN); |
| mSigninPreference.setPersonalizedPromoEnabled(false); |
| |
| mSyncCategory = (PreferenceCategory) findPreference(PREF_SYNC_CATEGORY); |
| mSyncErrorCard = findPreference(PREF_SYNC_ERROR_CARD); |
| mSyncErrorCard.setOnPreferenceClickListener( |
| SyncPreferenceUtils.toOnClickListener(this, this::onSyncErrorCardClicked)); |
| mSyncRequested = (ChromeSwitchPreference) findPreference(PREF_SYNC_REQUESTED); |
| mSyncRequested.setOnPreferenceChangeListener(this); |
| |
| mSearchSuggestions = (ChromeSwitchPreference) findPreference(PREF_SEARCH_SUGGESTIONS); |
| mSearchSuggestions.setOnPreferenceChangeListener(this); |
| mSearchSuggestions.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| mNetworkPredictions = (ChromeSwitchPreference) findPreference(PREF_NETWORK_PREDICTIONS); |
| mNetworkPredictions.setOnPreferenceChangeListener(this); |
| mNetworkPredictions.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| mNavigationError = (ChromeSwitchPreference) findPreference(PREF_NAVIGATION_ERROR); |
| mNavigationError.setOnPreferenceChangeListener(this); |
| mNavigationError.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| mSafeBrowsing = (ChromeSwitchPreference) findPreference(PREF_SAFE_BROWSING); |
| mSafeBrowsing.setOnPreferenceChangeListener(this); |
| mSafeBrowsing.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| mSafeBrowsingReporting = |
| (ChromeSwitchPreference) findPreference(PREF_SAFE_BROWSING_SCOUT_REPORTING); |
| mSafeBrowsingReporting.setOnPreferenceChangeListener(this); |
| mSafeBrowsingReporting.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| mUsageAndCrashReporting = |
| (ChromeSwitchPreference) findPreference(PREF_USAGE_AND_CRASH_REPORTING); |
| mUsageAndCrashReporting.setOnPreferenceChangeListener(this); |
| mUsageAndCrashReporting.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| mUrlKeyedAnonymizedData = |
| (ChromeSwitchPreference) findPreference(PREF_URL_KEYED_ANONYMIZED_DATA); |
| mUrlKeyedAnonymizedData.setOnPreferenceChangeListener(this); |
| mUrlKeyedAnonymizedData.setManagedPreferenceDelegate(mManagedPreferenceDelegate); |
| |
| PreferenceCategory servicesCategory = |
| (PreferenceCategory) findPreference(PREF_SERVICES_CATEGORY); |
| mContextualSearch = findPreference(PREF_CONTEXTUAL_SEARCH); |
| if (!ContextualSearchFieldTrial.isEnabled()) { |
| removePreference(servicesCategory, mContextualSearch); |
| mContextualSearch = null; |
| } |
| |
| mContextualSuggestions = findPreference(PREF_CONTEXTUAL_SUGGESTIONS); |
| if (!FeatureUtilities.areContextualSuggestionsEnabled(getActivity()) |
| || !ContextualSuggestionsEnabledStateUtils.shouldShowSettings()) { |
| removePreference(servicesCategory, mContextualSuggestions); |
| mContextualSuggestions = null; |
| } |
| |
| // Prevent sync settings changes from taking effect until the user leaves this screen. |
| mSyncSetupInProgressHandle = mProfileSyncService.getSetupInProgressHandle(); |
| |
| updatePreferences(); |
| } |
| |
| @Override |
| public void onDestroy() { |
| super.onDestroy(); |
| mSyncSetupInProgressHandle.close(); |
| |
| if (mProfileSyncService.isSyncRequested()) { |
| InvalidationController.get().ensureStartedAndUpdateRegisteredTypes(); |
| } |
| } |
| |
| @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(R.drawable.ic_help_and_feedback); |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| if (item.getItemId() == android.R.id.home) { |
| if (!mIsFromSigninScreen) return false; // Let Preferences activity handle it. |
| showCancelSyncDialog(); |
| return true; |
| } else if (item.getItemId() == R.id.menu_id_targeted_help) { |
| HelpAndFeedback.getInstance(getActivity()) |
| .show(getActivity(), getString(R.string.help_context_sync_and_services), |
| Profile.getLastUsedProfile(), null); |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public void onStart() { |
| super.onStart(); |
| mProfileSyncService.addSyncStateChangedListener(this); |
| mSigninPreference.registerForUpdates(); |
| |
| if (!ChromeSigninController.get().isSignedIn()) { |
| // Don't show CancelSyncDialog. |
| mIsFromSigninScreen = false; |
| } |
| } |
| |
| @Override |
| public void onStop() { |
| super.onStop(); |
| |
| mSigninPreference.unregisterForUpdates(); |
| mProfileSyncService.removeSyncStateChangedListener(this); |
| } |
| |
| @Override |
| public void onResume() { |
| super.onResume(); |
| updatePreferences(); |
| } |
| |
| @Override |
| public boolean onPreferenceChange(Preference preference, Object newValue) { |
| String key = preference.getKey(); |
| if (PREF_SYNC_REQUESTED.equals(key)) { |
| assert canDisableSync(); |
| SyncPreferenceUtils.enableSync((boolean) newValue); |
| PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updatePreferences); |
| } else if (PREF_SEARCH_SUGGESTIONS.equals(key)) { |
| mPrefServiceBridge.setSearchSuggestEnabled((boolean) newValue); |
| } else if (PREF_SAFE_BROWSING.equals(key)) { |
| mPrefServiceBridge.setSafeBrowsingEnabled((boolean) newValue); |
| } else if (PREF_SAFE_BROWSING_SCOUT_REPORTING.equals(key)) { |
| mPrefServiceBridge.setSafeBrowsingExtendedReportingEnabled((boolean) newValue); |
| } else if (PREF_NETWORK_PREDICTIONS.equals(key)) { |
| mPrefServiceBridge.setNetworkPredictionEnabled((boolean) newValue); |
| recordNetworkPredictionEnablingUMA((boolean) newValue); |
| } else if (PREF_NAVIGATION_ERROR.equals(key)) { |
| mPrefServiceBridge.setResolveNavigationErrorEnabled((boolean) newValue); |
| } else if (PREF_USAGE_AND_CRASH_REPORTING.equals(key)) { |
| UmaSessionStats.changeMetricsReportingConsent((boolean) newValue); |
| } else if (PREF_URL_KEYED_ANONYMIZED_DATA.equals(key)) { |
| UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled( |
| (boolean) newValue); |
| } |
| return true; |
| } |
| |
| /** |
| * ProfileSyncService.SyncStateChangedListener implementation, listens to sync state changes. |
| * |
| * If the user has just turned on sync, this listener is needed in order to enable |
| * the encryption settings once the engine has initialized. |
| */ |
| @Override |
| public void syncStateChanged() { |
| updatePreferences(); |
| } |
| |
| /** Returns whether Sync can be disabled. */ |
| private boolean canDisableSync() { |
| return !Profile.getLastUsedProfile().isChild(); |
| } |
| |
| private void displayPassphraseDialog() { |
| FragmentTransaction ft = getFragmentManager().beginTransaction(); |
| PassphraseDialogFragment.newInstance(this).show(ft, FRAGMENT_ENTER_PASSPHRASE); |
| } |
| |
| private void closeDialogIfOpen(String tag) { |
| FragmentManager manager = getFragmentManager(); |
| if (manager == null) { |
| // Do nothing if the manager doesn't exist yet; see http://crbug.com/480544. |
| return; |
| } |
| DialogFragment df = (DialogFragment) manager.findFragmentByTag(tag); |
| if (df != null) { |
| df.dismiss(); |
| } |
| } |
| |
| /** Returns whether the passphrase successfully decrypted the pending keys. */ |
| private boolean handleDecryption(String passphrase) { |
| if (passphrase.isEmpty() || !mProfileSyncService.setDecryptionPassphrase(passphrase)) { |
| return false; |
| } |
| updatePreferences(); |
| return true; |
| } |
| |
| /** Callback for PassphraseDialogFragment.Listener */ |
| @Override |
| public boolean onPassphraseEntered(String passphrase) { |
| if (!mProfileSyncService.isEngineInitialized() |
| || !mProfileSyncService.isPassphraseRequiredForDecryption()) { |
| // If the engine was shut down since the dialog was opened, or the passphrase isn't |
| // required anymore, do nothing. |
| return false; |
| } |
| return handleDecryption(passphrase); |
| } |
| |
| /** Callback for PassphraseDialogFragment.Listener */ |
| @Override |
| public void onPassphraseCanceled() {} |
| |
| @SyncError |
| private int getSyncError() { |
| if (!AndroidSyncSettings.get().isMasterSyncEnabled()) { |
| return SyncError.ANDROID_SYNC_DISABLED; |
| } |
| |
| if (!AndroidSyncSettings.get().isChromeSyncEnabled()) { |
| return SyncError.NO_ERROR; |
| } |
| |
| if (mProfileSyncService.getAuthError() |
| == GoogleServiceAuthError.State.INVALID_GAIA_CREDENTIALS) { |
| return SyncError.AUTH_ERROR; |
| } |
| |
| if (mProfileSyncService.getProtocolErrorClientAction() |
| == ProtocolErrorClientAction.UPGRADE_CLIENT) { |
| return SyncError.CLIENT_OUT_OF_DATE; |
| } |
| |
| if (mProfileSyncService.getAuthError() != GoogleServiceAuthError.State.NONE |
| || mProfileSyncService.hasUnrecoverableError()) { |
| return SyncError.OTHER_ERRORS; |
| } |
| |
| if (mProfileSyncService.isEngineInitialized() |
| && mProfileSyncService.isPassphraseRequiredForDecryption()) { |
| return SyncError.PASSPHRASE_REQUIRED; |
| } |
| |
| return SyncError.NO_ERROR; |
| } |
| |
| /** |
| * Gets hint message to resolve sync error. |
| * @param error The sync error. |
| */ |
| private String getSyncErrorHint(@SyncError int error) { |
| Resources res = getActivity().getResources(); |
| switch (error) { |
| case SyncError.ANDROID_SYNC_DISABLED: |
| return res.getString(R.string.hint_android_sync_disabled); |
| case SyncError.AUTH_ERROR: |
| return res.getString(R.string.hint_sync_auth_error); |
| case SyncError.CLIENT_OUT_OF_DATE: |
| return res.getString( |
| R.string.hint_client_out_of_date, BuildInfo.getInstance().hostPackageLabel); |
| case SyncError.OTHER_ERRORS: |
| return res.getString(R.string.hint_other_sync_errors); |
| case SyncError.PASSPHRASE_REQUIRED: |
| return res.getString(R.string.hint_passphrase_required); |
| case SyncError.NO_ERROR: |
| default: |
| return null; |
| } |
| } |
| |
| private void onSyncErrorCardClicked() { |
| if (mCurrentSyncError == SyncError.NO_ERROR) { |
| return; |
| } |
| |
| if (mCurrentSyncError == SyncError.ANDROID_SYNC_DISABLED) { |
| IntentUtils.safeStartActivity(getActivity(), new Intent(Settings.ACTION_SYNC_SETTINGS)); |
| return; |
| } |
| |
| if (mCurrentSyncError == SyncError.AUTH_ERROR) { |
| AccountManagerFacade.get().updateCredentials( |
| ChromeSigninController.get().getSignedInUser(), getActivity(), null); |
| return; |
| } |
| |
| if (mCurrentSyncError == SyncError.CLIENT_OUT_OF_DATE) { |
| // Opens the client in play store for update. |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setData(Uri.parse("market://details?id=" |
| + ContextUtils.getApplicationContext().getPackageName())); |
| startActivity(intent); |
| return; |
| } |
| |
| if (mCurrentSyncError == SyncError.OTHER_ERRORS) { |
| final Account account = ChromeSigninController.get().getSignedInUser(); |
| // TODO(https://crbug.com/873116): Pass the correct reason for the signout. |
| SigninManager.get().signOut(SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, |
| () -> SigninManager.get().signIn(account, null, null)); |
| return; |
| } |
| |
| if (mCurrentSyncError == SyncError.PASSPHRASE_REQUIRED) { |
| displayPassphraseDialog(); |
| return; |
| } |
| } |
| |
| private void recordNetworkPredictionEnablingUMA(boolean enabled) { |
| // Report user turning on and off NetworkPrediction. |
| RecordHistogram.recordBooleanHistogram("PrefService.NetworkPredictionEnabled", enabled); |
| } |
| |
| private static void removePreference(PreferenceGroup from, Preference preference) { |
| boolean found = from.removePreference(preference); |
| assert found : "Don't have such preference! Preference key: " + preference.getKey(); |
| } |
| |
| private void updatePreferences() { |
| updateSyncPreferences(); |
| |
| mSearchSuggestions.setChecked(mPrefServiceBridge.isSearchSuggestEnabled()); |
| mNetworkPredictions.setChecked(mPrefServiceBridge.getNetworkPredictionEnabled()); |
| mNavigationError.setChecked(mPrefServiceBridge.isResolveNavigationErrorEnabled()); |
| mSafeBrowsing.setChecked(mPrefServiceBridge.isSafeBrowsingEnabled()); |
| mSafeBrowsingReporting.setChecked( |
| mPrefServiceBridge.isSafeBrowsingExtendedReportingEnabled()); |
| mUsageAndCrashReporting.setChecked( |
| mPrivacyPrefManager.isUsageAndCrashReportingPermittedByUser()); |
| mUrlKeyedAnonymizedData.setChecked( |
| UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionEnabled()); |
| |
| if (mContextualSearch != null) { |
| boolean isContextualSearchEnabled = !mPrefServiceBridge.isContextualSearchDisabled(); |
| mContextualSearch.setSummary( |
| isContextualSearchEnabled ? R.string.text_on : R.string.text_off); |
| } |
| |
| if (mContextualSuggestions != null) { |
| mContextualSuggestions.setSummary( |
| ContextualSuggestionsEnabledStateUtils.getEnabledState() ? R.string.text_on |
| : R.string.text_off); |
| } |
| } |
| |
| private void updateSyncPreferences() { |
| if (!mProfileSyncService.isEngineInitialized() |
| || !mProfileSyncService.isPassphraseRequiredForDecryption()) { |
| closeDialogIfOpen(FRAGMENT_ENTER_PASSPHRASE); |
| } |
| |
| if (!ChromeSigninController.get().isSignedIn()) { |
| getPreferenceScreen().removePreference(mSyncCategory); |
| return; |
| } |
| getPreferenceScreen().addPreference(mSyncCategory); |
| |
| mCurrentSyncError = getSyncError(); |
| if (mCurrentSyncError == SyncError.NO_ERROR) { |
| mSyncCategory.removePreference(mSyncErrorCard); |
| } else { |
| String summary = getSyncErrorHint(mCurrentSyncError); |
| mSyncErrorCard.setSummary(summary); |
| mSyncCategory.addPreference(mSyncErrorCard); |
| } |
| |
| mSyncRequested.setChecked(AndroidSyncSettings.get().isChromeSyncEnabled()); |
| mSyncRequested.setEnabled(canDisableSync()); |
| } |
| |
| private ManagedPreferenceDelegate createManagedPreferenceDelegate() { |
| return preference -> { |
| String key = preference.getKey(); |
| if (PREF_NAVIGATION_ERROR.equals(key)) { |
| return mPrefServiceBridge.isResolveNavigationErrorManaged(); |
| } |
| if (PREF_SEARCH_SUGGESTIONS.equals(key)) { |
| return mPrefServiceBridge.isSearchSuggestManaged(); |
| } |
| if (PREF_SAFE_BROWSING_SCOUT_REPORTING.equals(key)) { |
| return mPrefServiceBridge.isSafeBrowsingExtendedReportingManaged(); |
| } |
| if (PREF_SAFE_BROWSING.equals(key)) { |
| return mPrefServiceBridge.isSafeBrowsingManaged(); |
| } |
| if (PREF_NETWORK_PREDICTIONS.equals(key)) { |
| return mPrefServiceBridge.isNetworkPredictionManaged(); |
| } |
| if (PREF_USAGE_AND_CRASH_REPORTING.equals(key)) { |
| return mPrefServiceBridge.isMetricsReportingManaged(); |
| } |
| if (PREF_URL_KEYED_ANONYMIZED_DATA.equals(key)) { |
| return UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionManaged(); |
| } |
| return false; |
| }; |
| } |
| |
| @Override |
| public boolean onBackPressed() { |
| if (!mIsFromSigninScreen) return false; // Let parent activity handle it. |
| showCancelSyncDialog(); |
| return true; |
| } |
| |
| private void showCancelSyncDialog() { |
| CancelSyncDialog dialog = new CancelSyncDialog(); |
| dialog.setTargetFragment(this, 0); |
| dialog.show(getFragmentManager(), FRAGMENT_CANCEL_SYNC); |
| } |
| |
| private void cancelSync() { |
| SigninManager.get().signOut(SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, null, null); |
| getActivity().finish(); |
| } |
| |
| /** |
| * The dialog that offers the user to cancel sync. Only shown when |
| * {@link SyncAndServicesPreferences} is opened from the sign-in screen. Shown when the user |
| * tries to close the settings page without confirming settings. |
| */ |
| public static class CancelSyncDialog extends DialogFragment { |
| public CancelSyncDialog() { |
| // Fragment must have an empty public constructor |
| } |
| |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| return new AlertDialog.Builder(getActivity(), R.style.SigninAlertDialogTheme) |
| .setTitle(R.string.cancel_sync_dialog_title) |
| .setMessage(R.string.cancel_sync_dialog_message) |
| .setNegativeButton(R.string.back, (dialog, which) -> dialog.cancel()) |
| .setPositiveButton(R.string.cancel_sync_button, (dialog, which) -> cancelSync()) |
| .create(); |
| } |
| |
| public void cancelSync() { |
| SyncAndServicesPreferences fragment = (SyncAndServicesPreferences) getTargetFragment(); |
| fragment.cancelSync(); |
| } |
| } |
| } |