backout 91e7ba697b14 (Bug 1001309) for test failures. r=backout
authorWes Johnston <wjohnston@mozilla.com>
Thu, 17 Jul 2014 09:10:43 -0700
changeset 216577 b3fb226d9f9cfe7c7a011cc84ebf85287b43eb6b
parent 216576 91e7ba697b14b450935c0161b23c07aeb93e8f2a
child 216578 4034177d4227c87e1c97e163cb5d1ab165d6330a
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1001309
milestone33.0a1
backs out91e7ba697b14b450935c0161b23c07aeb93e8f2a
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
backout 91e7ba697b14 (Bug 1001309) for test failures. r=backout
mobile/android/base/BrowserApp.java
mobile/android/base/GeckoApp.java
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/moz.build
mobile/android/base/preferences/AndroidImportPreference.java
mobile/android/base/preferences/ClearOnShutdownPref.java
mobile/android/base/preferences/GeckoPreferences.java
mobile/android/base/preferences/ListCheckboxPreference.java
mobile/android/base/preferences/MultiChoicePreference.java
mobile/android/base/preferences/MultiPrefMultiChoicePreference.java
mobile/android/base/preferences/PrivateDataPreference.java
mobile/android/base/resources/layout/preference_checkbox.xml
mobile/android/base/resources/values/arrays.xml
mobile/android/base/resources/values/attrs.xml
mobile/android/base/resources/xml-v11/preferences_customize.xml
mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml
mobile/android/base/resources/xml/preferences_customize.xml
mobile/android/base/resources/xml/preferences_privacy.xml
mobile/android/base/strings.xml.in
mobile/android/base/util/JSONUtils.java
mobile/android/base/util/PrefUtils.java
mobile/android/chrome/content/browser.js
mobile/android/modules/Sanitizer.jsm
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -6,21 +6,19 @@
 package org.mozilla.gecko;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.lang.Class;
 import java.lang.reflect.Method;
 import java.net.URLEncoder;
 import java.util.EnumSet;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Vector;
-import java.util.Set;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import org.mozilla.gecko.DynamicToolbar.PinReason;
 import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
 import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
 import org.mozilla.gecko.animation.PropertyAnimator;
@@ -49,33 +47,31 @@ import org.mozilla.gecko.home.BrowserSea
 import org.mozilla.gecko.home.HomeBanner;
 import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
 import org.mozilla.gecko.home.HomePanelsManager;
 import org.mozilla.gecko.home.SearchEngine;
 import org.mozilla.gecko.menu.GeckoMenu;
 import org.mozilla.gecko.menu.GeckoMenuItem;
 import org.mozilla.gecko.preferences.GeckoPreferences;
-import org.mozilla.gecko.preferences.ClearOnShutdownPref;
 import org.mozilla.gecko.prompts.Prompt;
 import org.mozilla.gecko.prompts.PromptListItem;
 import org.mozilla.gecko.sync.setup.SyncAccounts;
 import org.mozilla.gecko.tabspanel.TabsPanel;
 import org.mozilla.gecko.toolbar.AutocompleteHandler;
 import org.mozilla.gecko.toolbar.BrowserToolbar;
 import org.mozilla.gecko.toolbar.ToolbarProgressView;
 import org.mozilla.gecko.util.Clipboard;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GamepadUtils;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.NativeEventListener;
 import org.mozilla.gecko.util.NativeJSObject;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.MenuUtils;
-import org.mozilla.gecko.util.PrefUtils;
 import org.mozilla.gecko.util.StringUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.UiAsyncTask;
 import org.mozilla.gecko.widget.ButtonToast;
 import org.mozilla.gecko.widget.GeckoActionProvider;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -2405,21 +2401,19 @@ public class BrowserApp extends GeckoApp
         MenuItem share = aMenu.findItem(R.id.share);
         MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf);
         MenuItem charEncoding = aMenu.findItem(R.id.char_encoding);
         MenuItem findInPage = aMenu.findItem(R.id.find_in_page);
         MenuItem desktopMode = aMenu.findItem(R.id.desktop_mode);
         MenuItem enterGuestMode = aMenu.findItem(R.id.new_guest_session);
         MenuItem exitGuestMode = aMenu.findItem(R.id.exit_guest_session);
 
-        // Only show the "Quit" menu item on pre-ICS, television devices, or if the user has explicitly enabled the clear on shutdown pref.
+        // Only show the "Quit" menu item on pre-ICS or television devices.
         // In ICS+, it's easy to kill an app through the task switcher.
-        final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
-        final Set<String> clearItems = PrefUtils.getStringSet(prefs, ClearOnShutdownPref.PREF, new HashSet<String>());
-        aMenu.findItem(R.id.quit).setVisible(clearItems.size() > 0 || Build.VERSION.SDK_INT < 14 || HardwareUtils.isTelevision());
+        aMenu.findItem(R.id.quit).setVisible(Build.VERSION.SDK_INT < 14 || HardwareUtils.isTelevision());
 
         if (tab == null || tab.getURL() == null) {
             bookmark.setEnabled(false);
             back.setEnabled(false);
             forward.setEnabled(false);
             share.setEnabled(false);
             saveAsPDF.setEnabled(false);
             findInPage.setEnabled(false);
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -13,17 +13,16 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -42,29 +41,27 @@ import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.gfx.PluginLayer;
 import org.mozilla.gecko.health.HealthRecorder;
 import org.mozilla.gecko.health.SessionInformation;
 import org.mozilla.gecko.health.StubbedHealthRecorder;
 import org.mozilla.gecko.menu.GeckoMenu;
 import org.mozilla.gecko.menu.GeckoMenuInflater;
 import org.mozilla.gecko.menu.MenuPanel;
 import org.mozilla.gecko.mozglue.GeckoLoader;
-import org.mozilla.gecko.preferences.ClearOnShutdownPref;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.prompts.PromptService;
 import org.mozilla.gecko.updater.UpdateService;
 import org.mozilla.gecko.updater.UpdateServiceHelper;
 import org.mozilla.gecko.util.ActivityResultHandler;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.NativeEventListener;
 import org.mozilla.gecko.util.NativeJSObject;
-import org.mozilla.gecko.util.PrefUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.webapp.EventListener;
 import org.mozilla.gecko.webapp.UninstallListener;
 import org.mozilla.gecko.widget.ButtonToast;
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -461,33 +458,20 @@ public abstract class GeckoApp
 
         return super.onMenuOpened(featureId, menu);
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if (item.getItemId() == R.id.quit) {
             if (GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.GeckoRunning, GeckoThread.LaunchState.GeckoExiting)) {
-                final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
-                final Set<String> clearSet = PrefUtils.getStringSet(prefs, ClearOnShutdownPref.PREF, new HashSet<String>());
-
-                final JSONObject clearObj = new JSONObject();
-                for (String clear : clearSet) {
-                    try {
-                        clearObj.put(clear, true);
-                    } catch(JSONException ex) {
-                        Log.i(LOGTAG, "Error adding clear object " + clear);
-                    }
-                }
-
-                GeckoAppShell.notifyGeckoOfEvent(GeckoEvent.createBroadcastEvent("Browser:Quit", clearObj.toString()));
+                GeckoAppShell.notifyGeckoOfEvent(GeckoEvent.createBroadcastEvent("Browser:Quit", null));
             } else {
                 GeckoAppShell.systemExit();
             }
-
             return true;
         }
 
         return super.onOptionsItemSelected(item);
     }
 
     @Override
     public void onOptionsMenuClosed(Menu menu) {
@@ -607,17 +591,16 @@ public abstract class GeckoApp
             final NativeJSObject[] permissions = message.getObjectArray("permissions");
             showSiteSettingsDialog(host, permissions);
 
         } else if ("PrivateBrowsing:Data".equals(event)) {
             mPrivateBrowsingSession = message.optString("session", null);
 
         } else if ("Sanitize:ClearHistory".equals(event)) {
             handleClearHistory();
-            callback.sendSuccess(true);
 
         } else if ("Session:StatePurged".equals(event)) {
             onStatePurged();
 
         } else if ("Share:Text".equals(event)) {
             String text = message.getString("text");
             GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, "");
 
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -140,21 +140,17 @@
 <!ENTITY pref_donottrack_menu "Tracking">
 <!ENTITY pref_donottrack_disallow_tracking "Tell sites that I do not want to be tracked">
 <!ENTITY pref_donottrack_allow_tracking "Tell sites that I want to be tracked">
 <!ENTITY pref_donottrack_no_pref "Do not tell sites anything about my tracking preferences">
 
 <!ENTITY pref_char_encoding "Character encoding">
 <!ENTITY pref_char_encoding_on "Show menu">
 <!ENTITY pref_char_encoding_off "Don\'t show menu">
-<!ENTITY pref_clear_private_data2 "Clear now">
-<!ENTITY pref_clear_private_data_category "Clear private data">
-<!ENTITY pref_clear_on_exit_title "Always clear when quitting">
-<!ENTITY pref_clear_on_exit_summary "&brandShortName; will automatically clear your data whenever you select &quot;Quit&quot; from the main menu">
-<!ENTITY pref_clear_on_exit_dialog_title "Select which data to clear">
+<!ENTITY pref_clear_private_data "Clear private data">
 <!ENTITY pref_plugins "Plugins">
 <!ENTITY pref_plugins_enabled "Enabled">
 <!ENTITY pref_plugins_tap_to_play "Tap to play">
 <!ENTITY pref_plugins_disabled "Disabled">
 <!ENTITY pref_text_size "Text size">
 <!ENTITY pref_reflow_on_zoom4 "Text reflow">
 <!ENTITY pref_restore "Tabs">
 <!ENTITY pref_restore_always "Always restore">
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -66,17 +66,16 @@ gujar.sources += [
     'util/INIParser.java',
     'util/INISection.java',
     'util/JSONUtils.java',
     'util/MenuUtils.java',
     'util/NativeEventListener.java',
     'util/NativeJSContainer.java',
     'util/NativeJSObject.java',
     'util/NonEvictingLruCache.java',
-    'util/PrefUtils.java',
     'util/ProxySelector.java',
     'util/RawResource.java',
     'util/StringUtils.java',
     'util/ThreadUtils.java',
     'util/UiAsyncTask.java',
     'util/WebActivityMapper.java',
 ]
 gujar.extra_jars = [
@@ -330,28 +329,25 @@ gbjar.sources += [
     'NotificationHandler.java',
     'NotificationHelper.java',
     'NotificationService.java',
     'NSSBridge.java',
     'OrderedBroadcastHelper.java',
     'preferences/AlignRightLinkPreference.java',
     'preferences/AndroidImport.java',
     'preferences/AndroidImportPreference.java',
-    'preferences/ClearOnShutdownPref.java',
     'preferences/CustomListCategory.java',
     'preferences/CustomListPreference.java',
     'preferences/FontSizePreference.java',
     'preferences/GeckoPreferenceFragment.java',
     'preferences/GeckoPreferences.java',
     'preferences/LinkPreference.java',
-    'preferences/ListCheckboxPreference.java',
     'preferences/LocaleListPreference.java',
     'preferences/ModifiableHintPreference.java',
     'preferences/MultiChoicePreference.java',
-    'preferences/MultiPrefMultiChoicePreference.java',
     'preferences/PanelsPreference.java',
     'preferences/PanelsPreferenceCategory.java',
     'preferences/PrivateDataPreference.java',
     'preferences/SearchEnginePreference.java',
     'preferences/SearchPreferenceCategory.java',
     'preferences/SyncPreference.java',
     'PrefsHelper.java',
     'PrivateTab.java',
--- a/mobile/android/base/preferences/AndroidImportPreference.java
+++ b/mobile/android/base/preferences/AndroidImportPreference.java
@@ -3,24 +3,22 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.preferences;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.util.ThreadUtils;
 
-import java.util.Set;
-
 import android.app.ProgressDialog;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.util.Log;
 
-class AndroidImportPreference extends MultiPrefMultiChoicePreference {
+class AndroidImportPreference extends MultiChoicePreference {
     static final private String LOGTAG = "AndroidImport";
     private static final String PREF_KEY_PREFIX = "import_android.data.";
     private Context mContext;
 
     public AndroidImportPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
     }
@@ -30,25 +28,29 @@ class AndroidImportPreference extends Mu
         super.onDialogClosed(positiveResult);
 
         if (!positiveResult)
             return;
 
         boolean bookmarksChecked = false;
         boolean historyChecked = false;
 
-        Set<String> values = getValues();
+        CharSequence keys[] = getEntryKeys();
+        boolean values[] = getValues();
 
-        for (String value : values) {
-            // Import checkbox values are stored in Android prefs to
+        for (int i = 0; i < keys.length; i++) {
+            // Privacy pref checkbox values are stored in Android prefs to
             // remember their check states. The key names are import_android.data.X
-            String key = value.substring(PREF_KEY_PREFIX.length());
-            if ("bookmarks".equals(key)) {
+            String key = keys[i].toString().substring(PREF_KEY_PREFIX.length());
+            boolean value = values[i];
+
+            if (key.equals("bookmarks") && value) {
                 bookmarksChecked = true;
-            } else if ("history".equals(key)) {
+            }
+            if (key.equals("history") && value) {
                 historyChecked = true;
             }
         }
 
         runImport(bookmarksChecked, historyChecked);
     }
 
     protected void runImport(final boolean doBookmarks, final boolean doHistory) {
deleted file mode 100644
--- a/mobile/android/base/preferences/ClearOnShutdownPref.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.preferences;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.mozilla.gecko.GeckoSharedPrefs;
-import org.mozilla.gecko.util.PrefUtils;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.Preference;
-
-public class ClearOnShutdownPref implements GeckoPreferences.PrefHandler {
-    public static final String PREF = GeckoPreferences.NON_PREF_PREFIX + "history.clear_on_exit";
-
-    @Override
-    public void setupPref(Context context, Preference pref) {
-        // The pref is initialized asynchronously. Read the pref explicitly
-        // here to make sure we have the data.
-        final SharedPreferences prefs = GeckoSharedPrefs.forProfile(context);
-        final Set<String> clearItems = PrefUtils.getStringSet(prefs, PREF, new HashSet<String>());
-        ((ListCheckboxPreference) pref).setChecked(clearItems.size() > 0);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void onChange(Context context, Preference pref, Object newValue) {
-        final Set<String> vals = (Set<String>) newValue;
-        ((ListCheckboxPreference) pref).setChecked(vals.size() > 0);
-    }
-}
--- a/mobile/android/base/preferences/GeckoPreferences.java
+++ b/mobile/android/base/preferences/GeckoPreferences.java
@@ -1,20 +1,18 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.preferences;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 
 import org.json.JSONObject;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.BrowserLocaleManager;
 import org.mozilla.gecko.DataReportingNotification;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoActivityStatus;
@@ -89,17 +87,17 @@ OnSharedPreferenceChangeListener
 {
     private static final String LOGTAG = "GeckoPreferences";
 
     // We have a white background, which makes transitions on
     // some devices look bad. Don't use transitions on those
     // devices.
     private static final boolean NO_TRANSITIONS = HardwareUtils.IS_KINDLE_DEVICE;
 
-    public static final String NON_PREF_PREFIX = "android.not_a_preference.";
+    private static final String NON_PREF_PREFIX = "android.not_a_preference.";
     public static final String INTENT_EXTRA_RESOURCES = "resource";
     public static String PREFS_HEALTHREPORT_UPLOAD_ENABLED = NON_PREF_PREFIX + "healthreport.uploadEnabled";
 
     private static boolean sIsCharEncodingEnabled = false;
     private boolean mInitialized = false;
     private int mPrefsRequestId = 0;
     private PanelsPreferenceCategory mPanelsPreferenceCategory;
 
@@ -724,19 +722,16 @@ OnSharedPreferenceChangeListener
                     pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                         @Override
                         public boolean onPreferenceClick(Preference preference) {
                             Intent dialogIntent = new Intent(GeckoPreferences.this, HomePanelPicker.class);
                             startActivityForResultChoosingTransition(dialogIntent, HomePanelPicker.REQUEST_CODE_ADD_PANEL);
                             return true;
                         }
                     });
-                } else if (handlers.containsKey(key)) {
-                    PrefHandler handler = handlers.get(key);
-                    handler.setupPref(this, pref);
                 }
 
                 // Some Preference UI elements are not actually preferences,
                 // but they require a key to work correctly. For example,
                 // "Clear private data" requires a key for its state to be
                 // saved when the orientation changes. It uses the
                 // "android.not_a_preference.privacy.clear" key - which doesn't
                 // exist in Gecko - to satisfy this requirement.
@@ -996,30 +991,19 @@ OnSharedPreferenceChangeListener
         if (PREFS_BROWSER_LOCALE.equals(key)) {
             onLocaleSelected(BrowserLocaleManager.getLanguageTag(lastLocale),
                              sharedPreferences.getString(key, null));
         } else if (PREFS_SUGGESTED_SITES.equals(key)) {
             refreshSuggestedSites();
         }
     }
 
-    public interface PrefHandler {
-        public void setupPref(Context context, Preference pref);
-        public void onChange(Context context, Preference pref, Object newValue);
-    }
-
-    @SuppressWarnings("serial")
-    private Map<String, PrefHandler> handlers = new HashMap<String, PrefHandler>() {{
-        put(ClearOnShutdownPref.PREF, new ClearOnShutdownPref());
-    }};
-
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         final String prefName = preference.getKey();
-        Log.i(LOGTAG, "Changed " + prefName + " = " + newValue);
         if (PREFS_MP_ENABLED.equals(prefName)) {
             showDialog((Boolean) newValue ? DIALOG_CREATE_MASTER_PASSWORD : DIALOG_REMOVE_MASTER_PASSWORD);
 
             // We don't want the "use master password" pref to change until the
             // user has gone through the dialog.
             return false;
         }
 
@@ -1041,19 +1025,16 @@ OnSharedPreferenceChangeListener
             // The healthreport pref only lives in Android, so we do not persist
             // to Gecko, but we do broadcast intent to the health report
             // background uploader service, which will start or stop the
             // repeated background upload attempts.
             broadcastHealthReportUploadPref(this, ((Boolean) newValue).booleanValue());
         } else if (PREFS_GEO_REPORTING.equals(prefName)) {
             // Translate boolean value to int for geo reporting pref.
             newValue = ((Boolean) newValue) ? 1 : 0;
-        } else if (handlers.containsKey(prefName)) {
-            PrefHandler handler = handlers.get(prefName);
-            handler.onChange(this, preference, newValue);
         }
 
         // Send Gecko-side pref changes to Gecko
         if (isGeckoPref(prefName)) {
             PrefsHelper.setPref(prefName, newValue);
         }
 
         if (preference instanceof ListPreference) {
deleted file mode 100644
--- a/mobile/android/base/preferences/ListCheckboxPreference.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.preferences;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Checkable;
-
-import org.mozilla.gecko.R;
-
-/**
-  * This preference shows a checkbox on its left hand side, but will show a menu when clicked.
-  * Its used for preferences like "Clear on Exit" that have a boolean on-off state, but that represent
-  * multiple boolean options inside.
-  **/
-class ListCheckboxPreference extends MultiChoicePreference implements Checkable {
-    private static final String LOGTAG = "GeckoListCheckboxPreference";
-    private boolean checked;
-
-    public ListCheckboxPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setWidgetLayoutResource(R.layout.preference_checkbox);
-    }
-
-    @Override
-    public boolean isChecked() {
-        return checked;
-    }
-
-    @Override
-    protected void onBindView(View view) {
-        super.onBindView(view);
-
-        View checkboxView = view.findViewById(R.id.checkbox);
-        if (checkboxView != null && checkboxView instanceof Checkable) {
-            ((Checkable) checkboxView).setChecked(checked);
-        }
-    }
-
-    @Override
-    public void setChecked(boolean checked) {
-        boolean changed = checked != this.checked;
-        this.checked = checked;
-        if (changed) {
-            notifyDependencyChange(shouldDisableDependents());
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public void toggle() {
-        checked = !checked;
-    }
-}
--- a/mobile/android/base/preferences/MultiChoicePreference.java
+++ b/mobile/android/base/preferences/MultiChoicePreference.java
@@ -2,93 +2,88 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.preferences;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.GeckoSharedPrefs;
-import org.mozilla.gecko.util.PrefUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
+import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.TypedArray;
-import android.content.SharedPreferences;
 import android.preference.DialogPreference;
 import android.util.AttributeSet;
+import android.widget.Button;
 
-import java.util.HashSet;
-import java.util.Set;
-
-class MultiChoicePreference extends DialogPreference implements DialogInterface.OnMultiChoiceClickListener {
+class MultiChoicePreference extends DialogPreference {
     private static final String LOGTAG = "GeckoMultiChoicePreference";
 
     private boolean mValues[];
     private boolean mPrevValues[];
-    private CharSequence mEntryValues[];
+    private CharSequence mEntryKeys[];
     private CharSequence mEntries[];
     private CharSequence mInitialValues[];
 
     public MultiChoicePreference(Context context, AttributeSet attrs) {
         super(context, attrs);
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiChoicePreference);
         mEntries = a.getTextArray(R.styleable.MultiChoicePreference_entries);
-        mEntryValues = a.getTextArray(R.styleable.MultiChoicePreference_entryValues);
+        mEntryKeys = a.getTextArray(R.styleable.MultiChoicePreference_entryKeys);
         mInitialValues = a.getTextArray(R.styleable.MultiChoicePreference_initialValues);
         a.recycle();
 
         loadPersistedValues();
     }
 
     public MultiChoicePreference(Context context) {
         this(context, null);
     }
 
     /**
      * Sets the human-readable entries to be shown in the list. This will be
      * shown in subsequent dialogs.
      * <p>
      * Each entry must have a corresponding index in
-     * {@link #setEntryValues(CharSequence[])} and
+     * {@link #setEntryKeys(CharSequence[])} and
      * {@link #setInitialValues(CharSequence[])}.
-     *
+     * 
      * @param entries The entries.
      */
     public void setEntries(CharSequence[] entries) {
         mEntries = entries.clone();
     }
     
     /**
      * @param entriesResId The entries array as a resource.
      */
     public void setEntries(int entriesResId) {
         setEntries(getContext().getResources().getTextArray(entriesResId));
     }
 
     /**
-     * Sets the preference values for preferences shown in the list.
+     * Sets the preference keys for preferences shown in the list.
      *
-     * @param entryValues The entry values.
+     * @param entryKeys The entry keys.
      */
-    public void setEntryValues(CharSequence[] entryValues) {
-        mEntryValues = entryValues.clone();
+    public void setEntryKeys(CharSequence[] entryKeys) {
+        mEntryKeys = entryKeys.clone();
         loadPersistedValues();
     }
 
     /**
-     * Entry values define a separate pref for each row in the dialog.
-     *
-     * @param entryValuesResId The entryValues array as a resource.
+     * @param entryKeysResId The entryKeys array as a resource.
      */
-    public void setEntryValues(int entryValuesResId) {
-        setEntryValues(getContext().getResources().getTextArray(entryValuesResId));
+    public void setEntryKeys(int entryKeysResId) {
+        setEntryKeys(getContext().getResources().getTextArray(entryKeysResId));
     }
 
     /**
      * The array of initial entry values in this list. Each entryValue
      * corresponds to an entryKey. These values are used if a) the preference
      * isn't persisted, or b) the preference is persisted but hasn't yet been
      * set.
      *
@@ -111,78 +106,74 @@ class MultiChoicePreference extends Dial
      * 
      * @return The array of entries.
      */
     public CharSequence[] getEntries() {
         return mEntries.clone();
     }
 
     /**
-     * The list of values corresponding to each preference.
+     * The list of keys corresponding to each preference.
      * 
-     * @return The array of values.
+     * @return The array of keys.
      */
-    public CharSequence[] getEntryValues() {
-        return mEntryValues.clone();
+    public CharSequence[] getEntryKeys() {
+        return mEntryKeys.clone();
     }
 
     /**
      * The list of initial values for each preference. Each string in this list
      * should be either "true" or "false".
      * 
      * @return The array of initial values.
      */
     public CharSequence[] getInitialValues() {
         return mInitialValues.clone();
     }
 
-    public void setValue(final int i, final boolean value) {
-        mValues[i] = value;
-        mPrevValues = mValues.clone();
-    }
-
     /**
      * The list of values for each preference. These values are updated after
      * the dialog has been displayed.
      * 
      * @return The array of values.
      */
-    public Set<String> getValues() {
-        final Set<String> values = new HashSet<String>();
-
-        if (mValues == null) {
-            return values;
-        }
-
-        for (int i = 0; i < mValues.length; i++) {
-            if (mValues[i]) {
-                values.add(mEntryValues[i].toString());
-            }
-        }
-
-        return values;
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which, boolean val) {
+    public boolean[] getValues() {
+        return mValues.clone();
     }
 
     @Override
     protected void onPrepareDialogBuilder(Builder builder) {
-        if (mEntries == null || mInitialValues == null || mEntryValues == null) {
+        if (mEntries == null || mEntryKeys == null || mInitialValues == null) {
             throw new IllegalStateException(
-                    "MultiChoicePreference requires entries, entryValues, and initialValues arrays.");
+                    "MultiChoicePreference requires entries, entryKeys, and initialValues arrays.");
+        }
+
+        if (mEntries.length != mEntryKeys.length || mEntryKeys.length != mInitialValues.length) {
+            throw new IllegalStateException(
+                    "MultiChoicePreference entries, entryKeys, and initialValues arrays must be the same length");
         }
 
-        if (mEntries.length != mEntryValues.length || mEntries.length != mInitialValues.length) {
-            throw new IllegalStateException(
-                    "MultiChoicePreference entries, entryValues, and initialValues arrays must be the same length");
-        }
+        builder.setMultiChoiceItems(mEntries, mValues, new DialogInterface.OnMultiChoiceClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which, boolean val) {
+                // mValues is automatically updated when checkboxes are clicked
 
-        builder.setMultiChoiceItems(mEntries, mValues, this);
+                // enable positive button only if at least one item is checked
+                boolean enabled = false;
+                for (int i = 0; i < mValues.length; i++) {
+                    if (mValues[i]) {
+                        enabled = true;
+                        break;
+                    }
+                }
+                Button button = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
+                if (button.isEnabled() != enabled)
+                    button.setEnabled(enabled);
+            }
+        });
     }
 
     @Override
     protected void onDialogClosed(boolean positiveResult) {
         if (mPrevValues == null || mInitialValues == null) {
             // Initialization is done asynchronously, so these values may not
             // have been set before the dialog was closed.
             return;
@@ -191,81 +182,70 @@ class MultiChoicePreference extends Dial
         if (!positiveResult) {
             // user cancelled; reset checkbox values to their previous state
             mValues = mPrevValues.clone();
             return;
         } else {
             mPrevValues = mValues.clone();
         }
 
-        if (!callChangeListener(getValues())) {
-            return;
-        }
-
-        persist();
+        ThreadUtils.postToBackgroundThread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < mEntryKeys.length; i++) {
+                    String key = mEntryKeys[i].toString();
+                    persistBoolean(key, mValues[i]);
+                }
+            }
+        });
     }
 
-    /* Persists the current data stored by this pref to SharedPreferences. */
-    public boolean persist() {
+    protected boolean persistBoolean(String key, boolean value) {
         if (isPersistent()) {
-            final SharedPreferences.Editor edit = GeckoSharedPrefs.forProfile(getContext()).edit();
-            final boolean res = persist(edit);
-            edit.commit();
-            return res;
+            if (value == getPersistedBoolean(!value)) {
+                // It's already there, so the same as persisting
+                return true;
+            }
+            
+            GeckoSharedPrefs.forApp(getContext())
+                            .edit().putBoolean(key, value).commit();
+            return true;
         }
-
         return false;
     }
 
-    /* Internal persist method. Take an edit so that multiple prefs can be persisted in a single commit. */
-    protected boolean persist(SharedPreferences.Editor edit) {
-        if (isPersistent()) {
-            Set<String> vals = getValues();
-            PrefUtils.putStringSet(edit, getKey(), vals);
-            return true;
-        }
-
-        return false;
-    }
-
-    /* Returns a list of EntryValues that are currently enabled. */
-    public Set<String> getPersistedStrings(Set<String> defaultVal) {
-        if (!isPersistent()) {
-            return defaultVal;
-        }
-
-        final SharedPreferences prefs = GeckoSharedPrefs.forProfile(getContext());
-        return PrefUtils.getStringSet(prefs, getKey(), defaultVal);
+    protected boolean getPersistedBoolean(String key, boolean defaultReturnValue) {
+        if (!isPersistent())
+            return defaultReturnValue;
+        
+        return GeckoSharedPrefs.forApp(getContext())
+                               .getBoolean(key, defaultReturnValue);
     }
 
     /**
      * Loads persistent prefs from shared preferences. If the preferences
      * aren't persistent or haven't yet been stored, they will be set to their
      * initial values.
      */
-    protected void loadPersistedValues() {
-        final int entryCount = mInitialValues.length;
-        mValues = new boolean[entryCount];
+    private void loadPersistedValues() {
+        if (mEntryKeys == null || mInitialValues == null)
+            return;
 
-        if (entryCount != mEntries.length || entryCount != mEntryValues.length) {
+        final int entryCount = mEntryKeys.length;
+        if (entryCount != mEntries.length || entryCount != mInitialValues.length) {
             throw new IllegalStateException(
-                    "MultiChoicePreference entryValues and initialValues arrays must be the same length");
+                    "MultiChoicePreference entryKeys and initialValues arrays must be the same length");
         }
 
+        mValues = new boolean[entryCount];
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
-                final Set<String> stringVals = getPersistedStrings(null);
-
                 for (int i = 0; i < entryCount; i++) {
-                    if (stringVals != null) {
-                        mValues[i] = stringVals.contains(mEntryValues[i]);
-                    } else {
-                        final boolean defaultVal = mInitialValues[i].equals("true");
-                        mValues[i] = defaultVal;
-                    }
+                    String key = mEntryKeys[i].toString();
+                    boolean initialValue = mInitialValues[i].equals("true");
+                    mValues[i] = getPersistedBoolean(key, initialValue);
                 }
-
                 mPrevValues = mValues.clone();
             }
         });
     }
 }
deleted file mode 100644
--- a/mobile/android/base/preferences/MultiPrefMultiChoicePreference.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.preferences;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.GeckoSharedPrefs;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.TypedArray;
-import android.content.SharedPreferences;
-import android.widget.Button;
-import android.util.AttributeSet;
-import android.util.Log;
-
-import java.util.Set;
-
-/* Provides backwards compatibility for some old multi-choice pref types used by Gecko.
- * This will import the old data from the old prefs the first time it is run.
- */
-class MultiPrefMultiChoicePreference extends MultiChoicePreference {
-    private static final String LOGTAG = "GeckoMultiPrefPreference";
-    private static final String IMPORT_SUFFIX = "_imported_";
-    private final CharSequence[] keys;
-
-    public MultiPrefMultiChoicePreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiPrefMultiChoicePreference);
-        keys = a.getTextArray(R.styleable.MultiPrefMultiChoicePreference_entryKeys);
-        a.recycle();
-
-        loadPersistedValues();
-    }
-
-    // Helper method for reading a boolean pref.
-    private boolean getPersistedBoolean(SharedPreferences prefs, String key, boolean defaultReturnValue) {
-        if (!isPersistent()) {
-            return defaultReturnValue;
-        }
-
-        return prefs.getBoolean(key, defaultReturnValue);
-    }
-
-    // Overridden to do a one time import for the old preference type to the new one.
-    @Override
-    protected synchronized void loadPersistedValues() {
-        // This will load the new pref if it exists.
-        super.loadPersistedValues();
-
-        // First check if we've already done the import the old data. If so, nothing to load.
-        final SharedPreferences prefs = GeckoSharedPrefs.forApp(getContext());
-        final boolean imported = getPersistedBoolean(prefs, getKey() + IMPORT_SUFFIX, false);
-        if (imported) {
-            return;
-        }
-
-        // Load the data we'll need to find the old style prefs
-        final CharSequence[] init = getInitialValues();
-        final CharSequence[] entries = getEntries();
-        if (keys == null || init == null) {
-            return;
-        }
-
-        final int entryCount = keys.length;
-        if (entryCount != entries.length || entryCount != init.length) {
-            throw new IllegalStateException("MultiChoicePreference entryKeys and initialValues arrays must be the same length");
-        }
-
-        // Now iterate through the entries on a background thread.
-        final SharedPreferences.Editor edit = prefs.edit();
-        ThreadUtils.postToBackgroundThread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    // Use one editor to batch as many changes as we can.
-                    for (int i = 0; i < entryCount; i++) {
-                        String key = keys[i].toString();
-                        boolean initialValue = "true".equals(init[i]);
-                        boolean val = getPersistedBoolean(prefs, key, initialValue);
-
-                        // Save the pref and remove the old preference.
-                        setValue(i, val);
-                        edit.remove(key);
-                    }
-
-                    persist(edit);
-                    edit.putBoolean(getKey() + IMPORT_SUFFIX, true);
-                    edit.commit();
-                } catch(Exception ex) {
-                    Log.i(LOGTAG, "Err", ex);
-                }
-            }
-        });
-    }
-
-
-    @Override
-    public void onClick(DialogInterface dialog, int which, boolean val) {
-        // enable positive button only if at least one item is checked
-        boolean enabled = false;
-        final Set<String> values = getValues();
-
-        enabled = (values.size() > 0);
-        final Button button = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
-        if (button.isEnabled() != enabled) {
-            button.setEnabled(enabled);
-        }
-    }
-
-}
--- a/mobile/android/base/preferences/PrivateDataPreference.java
+++ b/mobile/android/base/preferences/PrivateDataPreference.java
@@ -8,52 +8,51 @@ package org.mozilla.gecko.preferences;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.util.Set;
-
 import android.content.Context;
 import android.util.AttributeSet;
 import android.util.Log;
 
-class PrivateDataPreference extends MultiPrefMultiChoicePreference {
+class PrivateDataPreference extends MultiChoicePreference {
     private static final String LOGTAG = "GeckoPrivateDataPreference";
     private static final String PREF_KEY_PREFIX = "private.data.";
 
     public PrivateDataPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
     protected void onDialogClosed(boolean positiveResult) {
         super.onDialogClosed(positiveResult);
 
-        if (!positiveResult) {
+        if (!positiveResult)
             return;
-        }
 
         Telemetry.sendUIEvent(TelemetryContract.Event.SANITIZE, TelemetryContract.Method.DIALOG, "settings");
 
-        final Set<String> values = getValues();
-        final JSONObject json = new JSONObject();
+        CharSequence keys[] = getEntryKeys();
+        boolean values[] = getValues();
+        JSONObject json = new JSONObject();
 
-        for (String value : values) {
+        for (int i = 0; i < keys.length; i++) {
             // Privacy pref checkbox values are stored in Android prefs to
             // remember their check states. The key names are private.data.X,
             // where X is a string from Gecko sanitization. This prefix is
             // removed here so we can send the values to Gecko, which then does
             // the sanitization for each key.
-            final String key = value.substring(PREF_KEY_PREFIX.length());
+            String key = keys[i].toString().substring(PREF_KEY_PREFIX.length());
+            boolean value = values[i];
             try {
-                json.put(key, true);
+                json.put(key, value);
             } catch (JSONException e) {
                 Log.e(LOGTAG, "JSON error", e);
             }
         }
 
         // clear private data in gecko
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Sanitize:ClearData", json.toString()));
     }
deleted file mode 100644
--- a/mobile/android/base/resources/layout/preference_checkbox.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 The Android Open Source Project
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- Layout used by CheckBoxPreference for the checkbox style. This is inflated
-     inside android.R.layout.preference. -->
-<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/checkbox"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:focusable="false"
-    android:clickable="false" />
--- a/mobile/android/base/resources/values/arrays.xml
+++ b/mobile/android/base/resources/values/arrays.xml
@@ -64,78 +64,54 @@
       <item>1</item>
       <item>2</item>
       <item>0</item>
     </string-array>
     <string-array name="pref_import_android_entries">
         <item>@string/bookmarks_title</item>
         <item>@string/history_title</item>
     </string-array>
-    <string-array name="pref_import_android_defaults">
+    <string-array name="pref_import_android_values">
         <item>true</item>
         <item>true</item>
     </string-array>
-    <string-array name="pref_import_android_values">
-        <item>android_import.data.bookmarks</item>
-        <item>android_import.data.history</item>
-    </string-array>
     <string-array name="pref_import_android_keys">
         <item>android_import.data.bookmarks</item>
         <item>android_import.data.history</item>
     </string-array>
     <string-array name="pref_private_data_entries">
         <item>@string/pref_private_data_history2</item>
         <item>@string/pref_private_data_downloadFiles2</item>
         <item>@string/pref_private_data_formdata</item>
         <item>@string/pref_private_data_cookies2</item>
         <item>@string/pref_private_data_passwords</item>
         <item>@string/pref_private_data_cache</item>
         <item>@string/pref_private_data_offlineApps</item>
         <item>@string/pref_private_data_siteSettings</item>
     </string-array>
-    <string-array name="pref_private_data_defaults">
+    <string-array name="pref_private_data_values">
         <item>true</item>
         <item>true</item>
         <item>true</item>
         <item>true</item>
         <item>true</item>
         <item>true</item>
         <item>true</item>
         <item>true</item>
     </string-array>
-    <string-array name="pref_private_data_values">
-        <item>private.data.history</item>
-        <item>private.data.downloadFiles</item>
-        <item>private.data.formdata</item>
-        <item>private.data.cookies_sessions</item>
-        <item>private.data.passwords</item>
-        <item>private.data.cache</item>
-        <item>private.data.offlineApps</item>
-        <item>private.data.siteSettings</item>
-    </string-array>
     <string-array name="pref_private_data_keys">
         <item>private.data.history</item>
         <item>private.data.downloadFiles</item>
         <item>private.data.formdata</item>
         <item>private.data.cookies_sessions</item>
         <item>private.data.passwords</item>
         <item>private.data.cache</item>
         <item>private.data.offlineApps</item>
         <item>private.data.siteSettings</item>
     </string-array>
-    <string-array name="pref_clear_on_exit_defaults">
-        <item>false</item>
-        <item>false</item>
-        <item>false</item>
-        <item>false</item>
-        <item>false</item>
-        <item>false</item>
-        <item>false</item>
-        <item>false</item>
-    </string-array>
     <string-array name="pref_restore_entries">
         <item>@string/pref_restore_always</item>
         <item>@string/pref_restore_quit</item>
     </string-array>
     <string-array name="pref_restore_values">
         <item>always</item>
         <item>quit</item>
     </string-array>
--- a/mobile/android/base/resources/values/attrs.xml
+++ b/mobile/android/base/resources/values/attrs.xml
@@ -79,24 +79,20 @@
     </declare-styleable>
 
     <declare-styleable name="FlowLayout">
         <attr name="spacing" format="dimension"/>
     </declare-styleable>
 
     <declare-styleable name="MultiChoicePreference">
         <attr name="entries" format="string"/>
-        <attr name="entryValues" format="string"/>
+        <attr name="entryKeys" format="string"/>
         <attr name="initialValues" format="string"/>
     </declare-styleable>
 
-    <declare-styleable name="MultiPrefMultiChoicePreference">
-        <attr name="entryKeys" format="string"/>
-    </declare-styleable>
-
     <declare-styleable name="BrowserToolbarCurve">
         <attr name="curveTowards">
             <flag name="none" value="0x00" />
             <flag name="left" value="0x01" />
             <flag name="right" value ="0x02" />
         </attr>
     </declare-styleable>
 
--- a/mobile/android/base/resources/xml-v11/preferences_customize.xml
+++ b/mobile/android/base/resources/xml-v11/preferences_customize.xml
@@ -28,19 +28,18 @@
                     android:defaultValue="quit"
                     android:entries="@array/pref_restore_entries"
                     android:entryValues="@array/pref_restore_values"
                     android:persistent="true" />
 
     <org.mozilla.gecko.preferences.AndroidImportPreference
                   android:key="android.not_a_preference.import_android"
                   gecko:entries="@array/pref_import_android_entries"
-                  gecko:entryValues="@array/pref_import_android_values"
-                  gecko:initialValues="@array/pref_import_android_defaults"
                   gecko:entryKeys="@array/pref_import_android_keys"
+                  gecko:initialValues="@array/pref_import_android_values"
                   android:title="@string/pref_import_android"
                   android:positiveButtonText="@string/bookmarkhistory_button_import"
                   android:negativeButtonText="@string/button_cancel"
                   android:persistent="false" />
 
    <ListPreference android:key="app.update.autodownload"
                    android:title="@string/pref_update_autodownload"
                    android:entries="@array/pref_update_autodownload_entries"
--- a/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml
+++ b/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml
@@ -35,18 +35,18 @@
                     android:defaultValue="quit"
                     android:entries="@array/pref_restore_entries"
                     android:entryValues="@array/pref_restore_values"
                     android:persistent="true" />
 
     <org.mozilla.gecko.preferences.AndroidImportPreference
             android:key="android.not_a_preference.import_android"
             gecko:entries="@array/pref_import_android_entries"
-            gecko:entryValues="@array/pref_import_android_values"
-            gecko:initialValues="@array/pref_import_android_defaults"
+            gecko:entryKeys="@array/pref_import_android_keys"
+            gecko:initialValues="@array/pref_import_android_values"
             android:title="@string/pref_import_android"
             android:positiveButtonText="@string/bookmarkhistory_button_import"
             android:negativeButtonText="@string/button_cancel"
             android:persistent="false" />
 
     <ListPreference android:key="app.update.autodownload"
                     android:title="@string/pref_update_autodownload"
                     android:entries="@array/pref_update_autodownload_entries"
--- a/mobile/android/base/resources/xml/preferences_customize.xml
+++ b/mobile/android/base/resources/xml/preferences_customize.xml
@@ -36,19 +36,18 @@
                     android:entries="@array/pref_restore_entries"
                     android:entryValues="@array/pref_restore_values"
                     android:persistent="true" />
 
 
     <org.mozilla.gecko.preferences.AndroidImportPreference
                   android:key="android.not_a_preference.import_android"
                   gecko:entries="@array/pref_import_android_entries"
-                  gecko:entryValues="@array/pref_import_android_values"
-                  gecko:initialValues="@array/pref_import_android_defaults"
                   gecko:entryKeys="@array/pref_import_android_keys"
+                  gecko:initialValues="@array/pref_import_android_values"
                   android:title="@string/pref_import_android"
                   android:positiveButtonText="@string/bookmarkhistory_button_import"
                   android:negativeButtonText="@string/button_cancel"
                   android:persistent="false" />
 
 
    <ListPreference android:key="app.update.autodownload"
                    android:title="@string/pref_update_autodownload"
--- a/mobile/android/base/resources/xml/preferences_privacy.xml
+++ b/mobile/android/base/resources/xml/preferences_privacy.xml
@@ -26,38 +26,20 @@
                         android:persistent="false" />
 
     <CheckBoxPreference android:key="privacy.masterpassword.enabled"
                         android:title="@string/pref_use_master_password"
                         android:defaultValue="false"
                         android:persistent="false" />
 
     <!-- keys prefixed with "android.not_a_preference." are not synced with Gecko -->
-    <PreferenceCategory android:title="@string/pref_clear_private_data_category">
-
-        <org.mozilla.gecko.preferences.PrivateDataPreference
-                            android:key="android.not_a_preference.privacy.clear"
-                            android:title="@string/pref_clear_private_data"
-                            android:persistent="true"
-                            android:positiveButtonText="@string/button_clear_data"
-                            gecko:entries="@array/pref_private_data_entries"
-                            gecko:entryValues="@array/pref_private_data_values"
-                            gecko:entryKeys="@array/pref_private_data_keys"
-                            gecko:initialValues="@array/pref_private_data_defaults" />
-
-        <!-- This pref is persisted in both Gecko and Java -->
-        <org.mozilla.gecko.preferences.ListCheckboxPreference
-                            android:key="android.not_a_preference.history.clear_on_exit"
-                            gecko:entries="@array/pref_private_data_entries"
-                            gecko:entryValues="@array/pref_private_data_values"
-                            gecko:initialValues="@array/pref_clear_on_exit_defaults"
-
-                            android:title="@string/pref_clear_on_exit_title"
-                            android:summary="@string/pref_clear_on_exit_summary"
-
-                            android:dialogTitle="@string/pref_clear_on_exit_dialog_title"
-                            android:positiveButtonText="@string/button_set"/>
-
-    </PreferenceCategory>
+    <org.mozilla.gecko.preferences.PrivateDataPreference
+                        android:key="android.not_a_preference.privacy.clear"
+                        android:title="@string/pref_clear_private_data"
+                        android:persistent="true"
+                        android:positiveButtonText="@string/button_clear_data"
+                        gecko:entries="@array/pref_private_data_entries"
+                        gecko:entryKeys="@array/pref_private_data_keys"
+                        gecko:initialValues="@array/pref_private_data_values" />
 
 </PreferenceScreen>
 
 
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -160,21 +160,17 @@
   <string name="pref_donottrack_menu">&pref_donottrack_menu;</string>
   <string name="pref_donottrack_disallow_tracking">&pref_donottrack_disallow_tracking;</string>
   <string name="pref_donottrack_allow_tracking">&pref_donottrack_allow_tracking;</string>
   <string name="pref_donottrack_no_pref">&pref_donottrack_no_pref;</string>
 
   <string name="pref_char_encoding">&pref_char_encoding;</string>
   <string name="pref_char_encoding_on">&pref_char_encoding_on;</string>
   <string name="pref_char_encoding_off">&pref_char_encoding_off;</string>
-  <string name="pref_clear_private_data">&pref_clear_private_data2;</string>
-  <string name="pref_clear_private_data_category">&pref_clear_private_data_category;</string>
-  <string name="pref_clear_on_exit_title">&pref_clear_on_exit_title;</string>
-  <string name="pref_clear_on_exit_summary">&pref_clear_on_exit_summary;</string>
-  <string name="pref_clear_on_exit_dialog_title">&pref_clear_on_exit_dialog_title;</string>
+  <string name="pref_clear_private_data">&pref_clear_private_data;</string>
   <string name="pref_plugins">&pref_plugins;</string>
   <string name="pref_plugins_enabled">&pref_plugins_enabled;</string>
   <string name="pref_plugins_tap_to_play">&pref_plugins_tap_to_play;</string>
   <string name="pref_plugins_disabled">&pref_plugins_disabled;</string>
   <string name="pref_text_size">&pref_text_size;</string>
   <string name="pref_font_size_tiny">&pref_font_size_tiny;</string>
   <string name="pref_font_size_small">&pref_font_size_small;</string>
   <string name="pref_font_size_medium">&pref_font_size_medium;</string>
--- a/mobile/android/base/util/JSONUtils.java
+++ b/mobile/android/base/util/JSONUtils.java
@@ -1,23 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.util;
 
-import org.json.JSONArray;
+import java.util.UUID;
+
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.os.Bundle;
 import android.util.Log;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.UUID;
 
 public final class JSONUtils {
     private static final String LOGTAG = "GeckoJSONUtils";
 
     private JSONUtils() {}
 
     public static UUID getUUID(String name, JSONObject json) {
@@ -45,25 +46,9 @@ public final class JSONUtils {
                 json.put(key, bundle.get(key));
             } catch (JSONException e) {
                 Log.w(LOGTAG, "Error building JSON response.", e);
             }
         }
 
         return json;
     }
-
-    // Handles conversions between a JSONArray and a Set<String>
-    public static Set<String> parseStringSet(JSONArray json) {
-        final Set<String> ret = new HashSet<String>();
-
-        for (int i = 0; i < json.length(); i++) {
-            try {
-                ret.add(json.getString(i));
-            } catch(JSONException ex) {
-                Log.i(LOGTAG, "Error parsing json", ex);
-            }
-        }
-
-        return ret;
-    }
-
 }
deleted file mode 100644
--- a/mobile/android/base/util/PrefUtils.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import android.content.SharedPreferences;
-import android.os.Build;
-import android.util.Log;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-
-
-public class PrefUtils {
-    private static final String LOGTAG = "GeckoPrefUtils";
-
-    // Cross version compatible way to get a string set from a pref
-    public static Set<String> getStringSet(final SharedPreferences prefs,
-                                           final String key,
-                                           final Set<String> defaultVal) {
-        if (!prefs.contains(key)) {
-            return defaultVal;
-        }
-
-        if (Build.VERSION.SDK_INT < 11) {
-            return getFromJSON(prefs, key);
-        }
-
-        // If this is Android version >= 11, try to use a Set<String>.
-        try {
-            return prefs.getStringSet(key, new HashSet<String>());
-        } catch(ClassCastException ex) {
-            // A ClassCastException means we've upgraded from a pre-v11 Android to a new one
-            final Set<String> val = getFromJSON(prefs, key);
-            SharedPreferences.Editor edit = prefs.edit();
-            putStringSet(edit, key, val).commit();
-            return val;
-        }
-    }
-
-    private static Set<String> getFromJSON(SharedPreferences prefs, String key) {
-        try {
-            final String val = prefs.getString(key, "[]");
-            return JSONUtils.parseStringSet(new JSONArray(val));
-        } catch(JSONException ex) {
-            Log.i(LOGTAG, "Unable to parse JSON", ex);
-        }
-
-        return new HashSet<String>();
-    }
-
-    // Cross version compatible way to save a string set to a pref.
-    // NOTE: The editor that is passed in will not commit the transaction for you. It is up to callers to commit
-    //       when they are done with any other changes to the database.
-    public static SharedPreferences.Editor putStringSet(final SharedPreferences.Editor edit,
-                                    final String key,
-                                    final Set<String> vals) {
-        if (Build.VERSION.SDK_INT < 11) {
-            final JSONArray json = new JSONArray(vals);
-            edit.putString(key, json.toString()).commit();
-        } else {
-            edit.putStringSet(key, vals).commit();
-        }
-
-        return edit;
-    }
-}
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1108,17 +1108,17 @@ var BrowserApp = {
   _handleTabSelected: function _handleTabSelected(aTab) {
     this.selectedTab = aTab;
 
     let evt = document.createEvent("UIEvents");
     evt.initUIEvent("TabSelect", true, false, window, null);
     aTab.browser.dispatchEvent(evt);
   },
 
-  quit: function quit(aClear = {}) {
+  quit: function quit() {
     // Figure out if there's at least one other browser window around.
     let lastBrowser = true;
     let e = Services.wm.getEnumerator("navigator:browser");
     while (e.hasMoreElements() && lastBrowser) {
       let win = e.getNext();
       if (!win.closed && win != window)
         lastBrowser = false;
     }
@@ -1128,20 +1128,18 @@ var BrowserApp = {
       let closingCanceled = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
       Services.obs.notifyObservers(closingCanceled, "browser-lastwindow-close-requested", null);
       if (closingCanceled.data)
         return;
 
       Services.obs.notifyObservers(null, "browser-lastwindow-close-granted", null);
     }
 
-    BrowserApp.sanitize(aClear, function() {
-      window.QueryInterface(Ci.nsIDOMChromeWindow).minimize();
-      window.close();
-    });
+    window.QueryInterface(Ci.nsIDOMChromeWindow).minimize();
+    window.close();
   },
 
   saveAsPDF: function saveAsPDF(aBrowser) {
     // Create the final destination file location
     let fileName = ContentAreaUtils.getDefaultFileName(aBrowser.contentTitle, aBrowser.currentURI, null, null);
     fileName = fileName.trim() + ".pdf";
 
     let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
@@ -1385,60 +1383,43 @@ var BrowserApp = {
         let pref = Cc["@mozilla.org/pref-localizedstring;1"].createInstance(Ci.nsIPrefLocalizedString);
         pref.data = json.value;
         Services.prefs.setComplexValue(json.name, Ci.nsISupportsString, pref);
         break;
       }
     }
   },
 
-  sanitize: function (aItems, callback) {
-    if (!aItems) {
-      return;
-    }
-
+  sanitize: function (aItems) {
+    let json = JSON.parse(aItems);
     let success = true;
 
-    for (let key in aItems) {
-      if (!aItems[key])
+    for (let key in json) {
+      if (!json[key])
         continue;
 
-      key = key.replace("private.data.", "");
-
-      var promises = [];
-      switch (key) {
-        case "cookies_sessions":
-          promises.push(Sanitizer.clearItem("cookies"));
-          promises.push(Sanitizer.clearItem("sessions"));
-          break;
-        default:
-          promises.push(Sanitizer.clearItem(key));
-      }
-    }
-
-    Promise.all(promises).then(function() {
-      sendMessageToJava({
-        type: "Sanitize:Finished",
-        success: true
-      });
-
-      if (callback) {
-        callback();
-      }
-    }).catch(function(err) {
-      sendMessageToJava({
-        type: "Sanitize:Finished",
-        error: err,
-        success: false
-      });
-
-      if (callback) {
-        callback();
-      }
-    })
+      try {
+        switch (key) {
+          case "cookies_sessions":
+            Sanitizer.clearItem("cookies");
+            Sanitizer.clearItem("sessions");
+            break;
+          default:
+            Sanitizer.clearItem(key);
+        }
+      } catch (e) {
+        dump("sanitize error: " + e);
+        success = false;
+      }
+    }
+
+    sendMessageToJava({
+      type: "Sanitize:Finished",
+      success: success
+    });
   },
 
   getFocusedInput: function(aBrowser, aOnlyInputElements = false) {
     if (!aBrowser)
       return null;
 
     let doc = aBrowser.contentDocument;
     if (!doc)
@@ -1615,18 +1596,17 @@ var BrowserApp = {
           type: "Search:Keyword",
           identifier: engine.identifier,
           name: engine.name,
           query: aData
         });
         break;
 
       case "Browser:Quit":
-        Services.console.logStringMessage(aData);
-        this.quit(JSON.parse(aData));
+        this.quit();
         break;
 
       case "SaveAs:PDF":
         this.saveAsPDF(browser);
         break;
 
       case "Preferences:Set":
         this.setPreferences(aData);
@@ -1634,17 +1614,17 @@ var BrowserApp = {
 
       case "ScrollTo:FocusedInput":
         // these messages come from a change in the viewable area and not user interaction
         // we allow scrolling to the selected input, but not zooming the page
         this.scrollToFocusedInput(browser, false);
         break;
 
       case "Sanitize:ClearData":
-        this.sanitize(JSON.parse(aData));
+        this.sanitize(aData);
         break;
 
       case "FullScreen:Exit":
         browser.contentDocument.mozCancelFullScreen();
         break;
 
       case "Viewport:Change":
         if (this.isBrowserContentDocumentDisplayed())
--- a/mobile/android/modules/Sanitizer.jsm
+++ b/mobile/android/modules/Sanitizer.jsm
@@ -59,137 +59,115 @@ Sanitizer.prototype = {
       item.clear();
     }
   },
 
   items: {
     cache: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
-          try {
-            cache.clear();
-          } catch(er) {}
+        var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
+        try {
+          cache.clear();
+        } catch(er) {}
 
-          let imageCache = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                                                           .getImgCacheForDocument(null);
-          try {
-            imageCache.clearCache(false); // true=chrome, false=content
-          } catch(er) {}
-
-          resolve();
-        });
+        let imageCache = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
+                                                         .getImgCacheForDocument(null);
+        try {
+          imageCache.clearCache(false); // true=chrome, false=content
+        } catch(er) {}
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     cookies: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          Services.cookies.removeAll();
-          resolve();
-        });
+        Services.cookies.removeAll();
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     siteSettings: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          // Clear site-specific permissions like "Allow this site to open popups"
-          Services.perms.removeAll();
-
-          // Clear site-specific settings like page-zoom level
-          Cc["@mozilla.org/content-pref/service;1"]
-            .getService(Ci.nsIContentPrefService2)
-            .removeAllDomains(null);
+        // Clear site-specific permissions like "Allow this site to open popups"
+        Services.perms.removeAll();
 
-          // Clear "Never remember passwords for this site", which is not handled by
-          // the permission manager
-          var hosts = Services.logins.getAllDisabledHosts({})
-          for (var host of hosts) {
-            Services.logins.setLoginSavingEnabled(host, true);
-          }
+        // Clear site-specific settings like page-zoom level
+        Cc["@mozilla.org/content-pref/service;1"]
+          .getService(Ci.nsIContentPrefService2)
+          .removeAllDomains(null);
 
-          resolve();
-        });
+        // Clear "Never remember passwords for this site", which is not handled by
+        // the permission manager
+        var hosts = Services.logins.getAllDisabledHosts({})
+        for (var host of hosts) {
+          Services.logins.setLoginSavingEnabled(host, true);
+        }
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     offlineApps: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          var cacheService = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
-          var appCacheStorage = cacheService.appCacheStorage(LoadContextInfo.default, null);
-          try {
-            appCacheStorage.asyncEvictStorage(null);
-          } catch(er) {}
-
-          resolve();
-        });
+        var cacheService = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
+        var appCacheStorage = cacheService.appCacheStorage(LoadContextInfo.default, null);
+        try {
+          appCacheStorage.asyncEvictStorage(null);
+        } catch(er) {}
       },
 
       get canClear()
       {
           return true;
       }
     },
 
     history: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          sendMessageToJava({ type: "Sanitize:ClearHistory" }, function() {
-            try {
-              Services.obs.notifyObservers(null, "browser:purge-session-history", "");
-            }
-            catch (e) { }
+        sendMessageToJava({ type: "Sanitize:ClearHistory" });
 
-            try {
-              var predictor = Cc["@mozilla.org/network/predictor;1"].getService(Ci.nsINetworkPredictor);
-              predictor.reset();
-            } catch (e) { }
+        try {
+          Services.obs.notifyObservers(null, "browser:purge-session-history", "");
+        }
+        catch (e) { }
 
-            resolve();
-          });
-        });
+        try {
+          var predictor = Cc["@mozilla.org/network/predictor;1"].getService(Ci.nsINetworkPredictor);
+          predictor.reset();
+        } catch (e) { }
       },
 
       get canClear()
       {
         // bug 347231: Always allow clearing history due to dependencies on
         // the browser:purge-session-history notification. (like error console)
         return true;
       }
     },
 
     formdata: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          FormHistory.update({ op: "remove" });
-          resolve();
-        });
+        FormHistory.update({ op: "remove" });
       },
 
       canClear: function (aCallback)
       {
         let count = 0;
         let countDone = {
           handleResult: function(aResult) { count = aResult; },
           handleError: function(aError) { Cu.reportError(aError); },
@@ -197,66 +175,56 @@ Sanitizer.prototype = {
         };
         FormHistory.count({}, countDone);
       }
     },
 
     downloadFiles: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          downloads.iterate(function (dl) {
-            // Delete the downloaded files themselves
-            let f = dl.targetFile;
-            if (f.exists()) {
-              f.remove(false);
-            }
+        downloads.iterate(function (dl) {
+          // Delete the downloaded files themselves
+          let f = dl.targetFile;
+          if (f.exists()) {
+            f.remove(false);
+          }
 
-            // Also delete downloads from history
-            dl.remove();
-          });
-          resolve();
+          // Also delete downloads from history
+          dl.remove();
         });
       },
 
       get canClear()
       {
         return downloads.canClear;
       }
     },
 
     passwords: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          Services.logins.removeAllLogins();
-          resolve();
-        });
+        Services.logins.removeAllLogins();
       },
 
       get canClear()
       {
         let count = Services.logins.countLogins("", "", ""); // count all logins
         return (count > 0);
       }
     },
 
     sessions: {
       clear: function ()
       {
-        return new Promise(function(resolve, reject) {
-          // clear all auth tokens
-          var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
-          sdr.logoutAndTeardown();
+        // clear all auth tokens
+        var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
+        sdr.logoutAndTeardown();
 
-          // clear FTP and plain HTTP auth sessions
-          Services.obs.notifyObservers(null, "net:clear-active-logins", null);
-
-          resolve();
-        });
+        // clear FTP and plain HTTP auth sessions
+        Services.obs.notifyObservers(null, "net:clear-active-logins", null);
       },
 
       get canClear()
       {
         return true;
       }
     }
   }