| Index: chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragment.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragment.java
|
| index db814e177579224e59d5c75287a42953ea916b85..fe3e11a73e8a1e8c106540ea0c400ad0ec8b0291 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragment.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragment.java
|
| @@ -4,70 +4,60 @@
|
|
|
| package org.chromium.chrome.browser.preferences.privacy;
|
|
|
| -import android.app.Dialog;
|
| -import android.app.DialogFragment;
|
| import android.app.ProgressDialog;
|
| -import android.content.DialogInterface;
|
| -import android.content.res.Resources;
|
| import android.os.Bundle;
|
| -import android.support.v7.app.AlertDialog;
|
| -import android.text.SpannableString;
|
| -import android.text.TextPaint;
|
| -import android.text.method.LinkMovementMethod;
|
| -import android.text.style.ClickableSpan;
|
| -import android.view.View;
|
| -import android.view.ViewGroup;
|
| -import android.widget.AdapterView;
|
| -import android.widget.AdapterView.OnItemClickListener;
|
| -import android.widget.ArrayAdapter;
|
| -import android.widget.Button;
|
| -import android.widget.CheckedTextView;
|
| -import android.widget.LinearLayout;
|
| -import android.widget.TextView;
|
| +import android.preference.CheckBoxPreference;
|
| +import android.preference.Preference;
|
| +import android.preference.PreferenceFragment;
|
|
|
| import org.chromium.base.VisibleForTesting;
|
| import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.BrowsingDataType;
|
| +import org.chromium.chrome.browser.preferences.ButtonPreference;
|
| import org.chromium.chrome.browser.preferences.PrefServiceBridge;
|
| -import org.chromium.chrome.browser.preferences.Preferences;
|
| import org.chromium.chrome.browser.preferences.privacy.BrowsingDataCounterBridge.BrowsingDataCounterCallback;
|
| -import org.chromium.chrome.browser.signin.AccountManagementFragment;
|
| import org.chromium.sync.signin.ChromeSigninController;
|
| -import org.chromium.ui.text.SpanApplier;
|
| -import org.chromium.ui.widget.Toast;
|
|
|
| +import java.util.Arrays;
|
| import java.util.EnumSet;
|
|
|
| /**
|
| * Modal dialog with options for selection the type of browsing data
|
| * to clear (history, cookies), triggered from a preference.
|
| */
|
| -public class ClearBrowsingDataDialogFragment extends DialogFragment
|
| - implements PrefServiceBridge.OnClearBrowsingDataListener, DialogInterface.OnClickListener {
|
| +public class ClearBrowsingDataDialogFragment extends PreferenceFragment
|
| + implements PrefServiceBridge.OnClearBrowsingDataListener,
|
| + Preference.OnPreferenceClickListener {
|
| /**
|
| * Represents a single item in the dialog.
|
| */
|
| - private static class Item implements BrowsingDataCounterCallback {
|
| + private static class Item implements BrowsingDataCounterCallback,
|
| + Preference.OnPreferenceClickListener {
|
| + private final ClearBrowsingDataDialogFragment mParent;
|
| private final DialogOption mOption;
|
| - private String mTitle;
|
| - private String mCounterText;
|
| - private boolean mSelected;
|
| - private boolean mEnabled;
|
| - private ArrayAdapter<Item> mParentAdapter;
|
| + private final CheckBoxPreference mCheckbox;
|
| private BrowsingDataCounterBridge mCounter;
|
|
|
| - public Item(DialogOption option,
|
| - String title,
|
| + public Item(ClearBrowsingDataDialogFragment parent,
|
| + DialogOption option,
|
| + CheckBoxPreference checkbox,
|
| boolean selected,
|
| boolean enabled) {
|
| super();
|
| + mParent = parent;
|
| mOption = option;
|
| - mTitle = title;
|
| - mSelected = selected;
|
| - mEnabled = enabled;
|
| - mCounterText = "";
|
| - mParentAdapter = null;
|
| mCounter = new BrowsingDataCounterBridge(this, mOption.getDataType());
|
| + mCheckbox = checkbox;
|
| +
|
| + // Due to the connection with BrowsingDataCounter, the state of this preference is
|
| + // kept in the native PrefService, and need not be duplicated in SharedPreferences.
|
| + // Therefore, from SharedPreferences's perspective, this preference is not persistent.
|
| + mCheckbox.setPersistent(false);
|
| +
|
| + mCheckbox.setOnPreferenceClickListener(this);
|
| + mCheckbox.setEnabled(enabled);
|
| + mCheckbox.setChecked(enabled && selected);
|
| + mCheckbox.setSummaryOff(""); // No summary when unchecked.
|
| }
|
|
|
| public void destroy() {
|
| @@ -78,107 +68,60 @@ public class ClearBrowsingDataDialogFragment extends DialogFragment
|
| return mOption;
|
| }
|
|
|
| - @Override
|
| - public String toString() {
|
| - return mTitle;
|
| - }
|
| -
|
| public boolean isSelected() {
|
| - return mSelected;
|
| + return mCheckbox.isChecked();
|
| }
|
|
|
| - public void toggle() {
|
| - mSelected = !mSelected;
|
| - PrefServiceBridge.getInstance().setBrowsingDataDeletionPreference(
|
| - mOption.getDataType(), mSelected);
|
| -
|
| - // Counter text is only shown with selected items.
|
| - if (!mSelected) mCounterText = "";
|
| - }
|
| -
|
| - public boolean isEnabled() {
|
| - return mEnabled;
|
| - }
|
| -
|
| - public String getCounterText() {
|
| - return mCounterText;
|
| - }
|
| + @Override
|
| + public boolean onPreferenceClick(Preference preference) {
|
| + assert mCheckbox == preference;
|
|
|
| - public void setParentAdapter(ArrayAdapter<Item> adapter) {
|
| - mParentAdapter = adapter;
|
| + mParent.updateButtonState();
|
| + PrefServiceBridge.getInstance().setBrowsingDataDeletionPreference(
|
| + mOption.getDataType(), mCheckbox.isChecked());
|
| + return true;
|
| }
|
|
|
| @Override
|
| public void onCounterFinished(String result) {
|
| - mCounterText = result;
|
| -
|
| - if (mParentAdapter != null) mParentAdapter.notifyDataSetChanged();
|
| + mCheckbox.setSummaryOn(result);
|
| }
|
| }
|
|
|
| - private class ClearBrowsingDataAdapter extends ArrayAdapter<Item> {
|
| - private ClearBrowsingDataAdapter(Item[] items) {
|
| - super(getActivity(), R.layout.clear_browsing_data_dialog_item, R.id.title, items);
|
| - for (Item item : items) item.setParentAdapter(this);
|
| - }
|
| + private static final String PREF_HISTORY = "clear_browsing_data_history_checkbox";
|
| + private static final String PREF_CACHE = "clear_browsing_data_cache_checkbox";
|
| + private static final String PREF_COOKIES = "clear_browsing_data_cookies_checkbox";
|
| + private static final String PREF_PASSWORDS = "clear_browsing_data_passwords_checkbox";
|
| + private static final String PREF_FORM_DATA = "clear_browsing_data_form_data_checkbox";
|
| + private static final String PREF_BOOKMARKS = "clear_browsing_data_bookmarks_checkbox";
|
|
|
| - @Override
|
| - public boolean hasStableIds() {
|
| - return true;
|
| - }
|
| -
|
| - @Override
|
| - public View getView(int position, View convertView, ViewGroup parent) {
|
| - LinearLayout view = (LinearLayout) super.getView(position, convertView, parent);
|
| - CheckedTextView radioButton = (CheckedTextView) view.findViewById(R.id.title);
|
| - radioButton.setChecked(getItem(position).isSelected());
|
| - radioButton.setEnabled(getItem(position).isEnabled());
|
| - TextView counter = (TextView) view.findViewById(R.id.summary);
|
| - String counterText = getItem(position).getCounterText();
|
| - counter.setText(counterText);
|
| -
|
| - // Remove the counter if the text is empty, so when the counters experiment is
|
| - // disabled, it doesn't break alignment.
|
| - counter.setVisibility(counterText.isEmpty() ? View.GONE : View.VISIBLE);
|
| -
|
| - return view;
|
| - }
|
| + private static final String PREF_FOOTNOTE = "clear_browsing_data_footnote";
|
| + private static final String PREF_FOOTNOTE_SYNCED = "clear_browsing_data_footnote_synced";
|
|
|
| - public void onClick(int position) {
|
| - if (!getItem(position).isEnabled()) {
|
| - // Currently only the history deletion can be disabled.
|
| - Toast.makeText(getActivity(), R.string.can_not_clear_browsing_history_toast,
|
| - Toast.LENGTH_SHORT).show();
|
| - return;
|
| - }
|
| - getItem(position).toggle();
|
| - updateButtonState();
|
| - notifyDataSetChanged();
|
| - }
|
| - }
|
| + /** The "Clear" button preference. Referenced in tests. */
|
| + public static final String PREF_CLEAR_BUTTON = "clear_browsing_data_clear_button";
|
|
|
| - /** The tag used when showing the clear browsing fragment. */
|
| - public static final String FRAGMENT_TAG = "ClearBrowsingDataDialogFragment";
|
| + /** The tag used for logging. */
|
| + public static final String TAG = "ClearBrowsingDataDialogFragment";
|
|
|
| /**
|
| * Enum for Dialog options to be displayed in the dialog.
|
| */
|
| public enum DialogOption {
|
| - CLEAR_HISTORY(BrowsingDataType.HISTORY, R.string.clear_history_title),
|
| - CLEAR_CACHE(BrowsingDataType.CACHE, R.string.clear_cache_title),
|
| - CLEAR_COOKIES_AND_SITE_DATA(BrowsingDataType.COOKIES,
|
| - R.string.clear_cookies_and_site_data_title),
|
| - CLEAR_PASSWORDS(BrowsingDataType.PASSWORDS, R.string.clear_passwords_title),
|
| - CLEAR_FORM_DATA(BrowsingDataType.FORM_DATA, R.string.clear_formdata_title),
|
| + CLEAR_HISTORY(BrowsingDataType.HISTORY, PREF_HISTORY),
|
| + CLEAR_CACHE(BrowsingDataType.CACHE, PREF_CACHE),
|
| + CLEAR_COOKIES_AND_SITE_DATA(BrowsingDataType.COOKIES, PREF_COOKIES),
|
| + CLEAR_PASSWORDS(BrowsingDataType.PASSWORDS, PREF_PASSWORDS),
|
| + CLEAR_FORM_DATA(BrowsingDataType.FORM_DATA, PREF_FORM_DATA),
|
| // Clear bookmarks is only used by ClearSyncData dialog.
|
| - CLEAR_BOOKMARKS_DATA(BrowsingDataType.BOOKMARKS, R.string.clear_bookmarks_title);
|
| + CLEAR_BOOKMARKS_DATA(BrowsingDataType.BOOKMARKS, PREF_BOOKMARKS);
|
|
|
| private final int mDataType;
|
| - private final int mResourceId;
|
| + private final String mPreferenceKey;
|
|
|
| - private DialogOption(int dataType, int resourceId) {
|
| + private DialogOption(int dataType, String preferenceKey) {
|
| mDataType = dataType;
|
| - mResourceId = resourceId;
|
| + mPreferenceKey = preferenceKey;
|
| }
|
|
|
| public int getDataType() {
|
| @@ -186,16 +129,14 @@ public class ClearBrowsingDataDialogFragment extends DialogFragment
|
| }
|
|
|
| /**
|
| - * @return resource id of the Dialog option.
|
| + * @return String The key of the corresponding preference.
|
| */
|
| - public int getResourceId() {
|
| - return mResourceId;
|
| + public String getPreferenceKey() {
|
| + return mPreferenceKey;
|
| }
|
| }
|
|
|
| - private AlertDialog mDialog;
|
| private ProgressDialog mProgressDialog;
|
| - private ClearBrowsingDataAdapter mAdapter;
|
| private boolean mCanDeleteBrowsingHistory;
|
| private Item[] mItems;
|
|
|
| @@ -221,9 +162,9 @@ public class ClearBrowsingDataDialogFragment extends DialogFragment
|
| }
|
|
|
| protected void dismissProgressDialog() {
|
| - android.util.Log.i(FRAGMENT_TAG, "in dismissProgressDialog");
|
| + android.util.Log.i(TAG, "in dismissProgressDialog");
|
| if (mProgressDialog != null && mProgressDialog.isShowing()) {
|
| - android.util.Log.i(FRAGMENT_TAG, "progress dialog dismissed");
|
| + android.util.Log.i(TAG, "progress dialog dismissed");
|
| mProgressDialog.dismiss();
|
| }
|
| mProgressDialog = null;
|
| @@ -257,94 +198,71 @@ public class ClearBrowsingDataDialogFragment extends DialogFragment
|
| @Override
|
| public void onBrowsingDataCleared() {
|
| dismissProgressDialog();
|
| + getActivity().finish();
|
| }
|
|
|
| @Override
|
| - public void onClick(DialogInterface dialog, int whichButton) {
|
| - if (whichButton == AlertDialog.BUTTON_POSITIVE) {
|
| + public boolean onPreferenceClick(Preference preference) {
|
| + if (preference.getKey().equals(PREF_CLEAR_BUTTON)) {
|
| dismissProgressDialog();
|
| onOptionSelected();
|
| }
|
| + return true;
|
| }
|
|
|
| /**
|
| * Disable the "Clear" button if none of the options are selected. Otherwise, enable it.
|
| */
|
| private void updateButtonState() {
|
| - Button clearButton = mDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
| + ButtonPreference clearButton = (ButtonPreference) findPreference(PREF_CLEAR_BUTTON);
|
| if (clearButton == null) return;
|
| boolean isEnabled = !getSelectedOptions().isEmpty();
|
| clearButton.setEnabled(isEnabled);
|
| -
|
| - // Work around a bug in the app compat library where disabled buttons in alert dialogs
|
| - // don't look disabled on pre-L devices. See: http://crbug.com/550784
|
| - // TODO(newt): remove this workaround when the app compat library is fixed (b/26017217)
|
| - clearButton.setTextColor(isEnabled ? 0xFF4285F4 : 0x335A5A5A);
|
| }
|
|
|
| @Override
|
| - public Dialog onCreateDialog(Bundle savedInstanceState) {
|
| + public void onCreate(Bundle savedInstanceState) {
|
| + super.onCreate(savedInstanceState);
|
| mCanDeleteBrowsingHistory = PrefServiceBridge.getInstance().canDeleteBrowsingHistory();
|
| + addPreferencesFromResource(R.xml.clear_browsing_data_dialog);
|
|
|
| DialogOption[] options = getDialogOptions();
|
| mItems = new Item[options.length];
|
| - Resources resources = getResources();
|
| for (int i = 0; i < options.length; i++) {
|
| // It is possible to disable the deletion of browsing history.
|
| boolean enabled = options[i] != DialogOption.CLEAR_HISTORY || mCanDeleteBrowsingHistory;
|
|
|
| mItems[i] = new Item(
|
| + this,
|
| options[i],
|
| - resources.getString(options[i].getResourceId()),
|
| + (CheckBoxPreference) findPreference(options[i].getPreferenceKey()),
|
| isOptionSelectedByDefault(options[i]),
|
| enabled);
|
| }
|
| - mAdapter = new ClearBrowsingDataAdapter(mItems);
|
| - final AlertDialog.Builder builder =
|
| - new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme)
|
| - .setTitle(R.string.clear_browsing_data_title)
|
| - .setPositiveButton(R.string.clear_data_delete, this)
|
| - .setNegativeButton(R.string.cancel, this)
|
| - .setAdapter(mAdapter, null); // OnClickListener is registered manually.
|
|
|
| + // Not all checkboxes defined in the layout are necessarily handled by this class
|
| + // or a particular subclass. Hide those that are not.
|
| + EnumSet<DialogOption> unbound_options = EnumSet.allOf(DialogOption.class);
|
| + unbound_options.removeAll(Arrays.asList(getDialogOptions()));
|
| + for (DialogOption option : unbound_options) {
|
| + getPreferenceScreen().removePreference(findPreference(option.getPreferenceKey()));
|
| + }
|
| +
|
| + // The "Clear" button.
|
| + ButtonPreference clearButton = (ButtonPreference) findPreference(PREF_CLEAR_BUTTON);
|
| + clearButton.setOnPreferenceClickListener(this);
|
| + clearButton.setShouldDisableView(true);
|
| +
|
| + // Only one footnote should be shown, the unsynced or synced version, depending on whether
|
| + // the user is signed in.
|
| if (ChromeSigninController.get(getActivity()).isSignedIn()) {
|
| - final String message = getString(R.string.clear_cookies_no_sign_out_summary);
|
| - final SpannableString messageWithLink = SpanApplier.applySpans(message,
|
| - new SpanApplier.SpanInfo("<link>", "</link>", new ClickableSpan() {
|
| - @Override
|
| - public void onClick(View widget) {
|
| - dismiss();
|
| - Preferences prefActivity = (Preferences) getActivity();
|
| - prefActivity.startFragment(AccountManagementFragment.class.getName(),
|
| - null);
|
| - }
|
| -
|
| - // Change link formatting to use no underline
|
| - @Override
|
| - public void updateDrawState(TextPaint textPaint) {
|
| - textPaint.setColor(textPaint.linkColor);
|
| - textPaint.setUnderlineText(false);
|
| - }
|
| - }));
|
| -
|
| - View view = getActivity().getLayoutInflater().inflate(
|
| - R.layout.single_line_bottom_text_dialog, null);
|
| - TextView summaryView = (TextView) view.findViewById(R.id.summary);
|
| - summaryView.setText(messageWithLink);
|
| - summaryView.setMovementMethod(LinkMovementMethod.getInstance());
|
| - builder.setView(view);
|
| + getPreferenceScreen().removePreference(findPreference(PREF_FOOTNOTE));
|
| + } else {
|
| + getPreferenceScreen().removePreference(findPreference(PREF_FOOTNOTE_SYNCED));
|
| }
|
|
|
| - mDialog = builder.create();
|
| - mDialog.getListView().setOnItemClickListener(new OnItemClickListener() {
|
| - @Override
|
| - public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
| - // The present behaviour of AlertDialog is to dismiss after the onClick event.
|
| - // Hence we are manually overriding this outside the builder.
|
| - mAdapter.onClick(position);
|
| - }
|
| - });
|
| - return mDialog;
|
| + // Activity title.
|
| + getActivity().setTitle(R.string.clear_browsing_data_title);
|
| }
|
|
|
| @Override
|
| @@ -373,7 +291,7 @@ public class ClearBrowsingDataDialogFragment extends DialogFragment
|
| protected final void showProgressDialog() {
|
| if (getActivity() == null) return;
|
|
|
| - android.util.Log.i(FRAGMENT_TAG, "progress dialog shown");
|
| + android.util.Log.i(TAG, "progress dialog shown");
|
| mProgressDialog = ProgressDialog.show(getActivity(),
|
| getActivity().getString(R.string.clear_browsing_data_progress_title),
|
| getActivity().getString(R.string.clear_browsing_data_progress_message), true,
|
|
|