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..6159e13367cdaca937f84854742fb4687db9bbbe 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 |
newt (away)
2016/01/29 20:16:02
I'd call this "ClearBrowsingDataPreferences" to pa
msramek
2016/02/02 12:19:51
Done. Renamed this, the corresponding XML, and als
|
+ 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); |
newt (away)
2016/01/29 20:16:02
This might be too late to set persistent to false;
msramek
2016/02/02 12:19:51
Done.
I heard some vague plans about syncing pref
newt (away)
2016/02/02 19:35:03
These are good ideas. We already have Chrome-speci
|
+ |
+ mCheckbox.setOnPreferenceClickListener(this); |
+ mCheckbox.setEnabled(enabled); |
+ mCheckbox.setChecked(enabled && selected); |
newt (away)
2016/01/29 20:16:02
Are there any cases where a checkbox could be forc
msramek
2016/02/02 12:19:51
The only case for a disabled checkbox should be a
|
+ 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; |
- } |
+ private static final String PREF_FOOTNOTE = "clear_browsing_data_footnote"; |
+ private static final String PREF_FOOTNOTE_SYNCED = "clear_browsing_data_footnote_synced"; |
- @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; |
- } |
+ /** The "Clear" button preference. Referenced in tests. */ |
+ public static final String PREF_CLEAR_BUTTON = "clear_browsing_data_clear_button"; |
- 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 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; |
newt (away)
2016/01/29 20:16:02
you should only return true if the click was handl
msramek
2016/02/02 12:19:51
Done.
|
} |
/** |
* 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); |
newt (away)
2016/01/29 20:16:02
s/upbound_options/unboundOptions/
(checkstyle sho
msramek
2016/02/02 12:19:51
Done. If it's just a warning, I might have missed
|
+ 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 |
newt (away)
2016/01/29 20:16:02
Rather than removing one of these two preferences,
msramek
2016/02/02 12:19:51
Done. And actually, now that there's just one, let
|
+ // 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); |
newt (away)
2016/01/29 20:16:02
nit: move this to near the top of onCreate()
msramek
2016/02/02 12:19:51
Done.
|
} |
@Override |
@@ -357,6 +275,7 @@ public class ClearBrowsingDataDialogFragment extends DialogFragment |
@Override |
public void onDestroy() { |
super.onDestroy(); |
+ dismissProgressDialog(); |
for (Item item : mItems) { |
item.destroy(); |
} |
@@ -373,7 +292,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, |