Bug 773535 - Use tablet style prefs on tablets. r=bnicholson
authorWes Johnston <wjohnston@mozilla.com>
Mon, 22 Apr 2013 14:39:30 -0700
changeset 140472 43ddb78c171845f54dd623e5d42e8118cf15f169
parent 140471 86959499a5b81ce7aadf8c57c84c538b04b16698
child 140473 d813280d88f31941791d8aa2f9d8fa5d2528243e
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson
bugs773535
milestone23.0a1
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
Bug 773535 - Use tablet style prefs on tablets. r=bnicholson
mobile/android/base/GeckoPreferenceFragment.java
mobile/android/base/GeckoPreferences.java
mobile/android/base/Makefile.in
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/resources/xml/preference_headers.xml
mobile/android/base/resources/xml/preferences.xml
mobile/android/base/resources/xml/preferences_content.xml
mobile/android/base/resources/xml/preferences_general.xml
mobile/android/base/resources/xml/preferences_privacy.xml
mobile/android/base/strings.xml.in
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/GeckoPreferenceFragment.java
@@ -0,0 +1,61 @@
+/* -*- 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;
+
+import java.util.ArrayList;
+
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.os.Bundle;
+import android.util.Log;
+
+/* A simple implementation of PreferenceFragment for large screen devices
+ * This will strip category headers (so that they aren't shown to the user twice)
+ * as well as initializing Gecko prefs when a fragment is shown.
+*/
+public class GeckoPreferenceFragment extends PreferenceFragment {
+
+    private static final String LOGTAG = "GeckoPreferenceFragment";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        String resource = getArguments().getString("resource");
+        int res = getActivity().getResources().getIdentifier(resource,
+                                                             "xml",
+                                                             getActivity().getPackageName());
+        addPreferencesFromResource(res);
+
+        /* This is only hit when we're using the headers (i.e. on large screen devices).
+           Strip the first category it isn't shown twice */
+        PreferenceScreen screen = stripCategories(getPreferenceScreen());
+        setPreferenceScreen(screen);
+        ((GeckoPreferences)getActivity()).setupPreferences(screen);
+    }
+
+    private PreferenceScreen stripCategories(PreferenceScreen preferenceScreen) {
+        PreferenceScreen newScreen = getPreferenceManager().createPreferenceScreen(preferenceScreen.getContext());
+        int order = 0;
+        if (preferenceScreen.getPreferenceCount() > 0 && preferenceScreen.getPreference(0) instanceof PreferenceCategory) {
+            PreferenceCategory cat = (PreferenceCategory) preferenceScreen.getPreference(0);
+            for (int i = 0; i < cat.getPreferenceCount(); i++) {
+                Preference pref = cat.getPreference(i);
+                pref.setOrder(order++);
+                newScreen.addPreference(pref);
+            }
+        }
+
+        for (int i = 1; i < preferenceScreen.getPreferenceCount(); i++) {
+            Preference pref = preferenceScreen.getPreference(i);
+            pref.setOrder(order++);
+            newScreen.addPreference(pref);
+        }
+
+        return newScreen;
+    }
+}
--- a/mobile/android/base/GeckoPreferences.java
+++ b/mobile/android/base/GeckoPreferences.java
@@ -36,73 +36,73 @@ import android.text.TextWatcher;
 import android.util.Log;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.EditText;
 import android.widget.LinearLayout;
 import android.widget.Toast;
 
 import java.util.ArrayList;
+import java.util.List;
 
 public class GeckoPreferences
     extends PreferenceActivity
     implements OnPreferenceChangeListener, GeckoEventListener, GeckoActivityStatus
 {
     private static final String LOGTAG = "GeckoPreferences";
 
     private ArrayList<String> mPreferencesList;
     private PreferenceScreen mPreferenceScreen;
     private static boolean sIsCharEncodingEnabled = false;
     private static final String NON_PREF_PREFIX = "android.not_a_preference.";
+    private boolean mInitialized = false;
 
     // These match keys in resources/xml/preferences.xml.in.
     private static String PREFS_ANNOUNCEMENTS_ENABLED = NON_PREF_PREFIX + "privacy.announcements.enabled";
     private static String PREFS_CATEGORY_GENERAL = "category_general";
     private static String PREFS_CATEGORY_PRIVACY = "category_privacy";
     private static String PREFS_MENU_CHAR_ENCODING = "browser.menu.showCharacterEncoding";
     private static String PREFS_MP_ENABLED = "privacy.masterpassword.enabled";
     private static String PREFS_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
     private static String PREFS_TELEMETRY_ENABLED_PRERELEASE = "toolkit.telemetry.enabledPreRelease";
     private static String PREFS_UPDATER_AUTODOWNLOAD = "app.update.autodownload";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.preferences);
+
+        // If this is a smaller screen
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB || !onIsMultiPane()) {
+            addPreferencesFromResource(R.xml.preferences_general);
+            addPreferencesFromResource(R.xml.preferences_content);
+            addPreferencesFromResource(R.xml.preferences_privacy);
+        }
+
         registerEventListener("Sanitize:Finished");
 
         if (Build.VERSION.SDK_INT >= 14)
             getActionBar().setHomeButtonEnabled(true);
-
-        mPreferenceScreen = getPreferenceScreen();
-        if (!AppConstants.MOZ_UPDATER) {
-            ((PreferenceGroup) mPreferenceScreen.findPreference(PREFS_CATEGORY_GENERAL))
-                    .removePreference(findPreference(PREFS_UPDATER_AUTODOWNLOAD));
-        }
+    }
 
-        Preference telemetryPref = findPreference(PREFS_TELEMETRY_ENABLED);
-        if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-            if (AppConstants.MOZ_TELEMETRY_ON_BY_DEFAULT) {
-                telemetryPref.setKey(PREFS_TELEMETRY_ENABLED_PRERELEASE);
-            }
-        } else {
-            ((PreferenceGroup) mPreferenceScreen.findPreference(PREFS_CATEGORY_PRIVACY))
-                    .removePreference(telemetryPref);
-        }
-
+    @Override
+    public void onBuildHeaders(List<Header> target) {
+        if (onIsMultiPane())
+            loadHeadersFromResource(R.xml.preference_headers, target);
     }
 
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
-        if (!hasFocus)
+        if (!hasFocus || mInitialized)
             return;
 
-        mPreferencesList = new ArrayList<String>();
-        initGroups(mPreferenceScreen);
-        initValues();
+        mInitialized = true;
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB || !onIsMultiPane()) {
+            PreferenceScreen screen = getPreferenceScreen();
+            setupPreferences(screen);
+        }
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
         unregisterEventListener("Sanitize:Finished");
     }
 
@@ -138,34 +138,56 @@ public class GeckoPreferences
                     }
                 });
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
-    private void initGroups(PreferenceGroup preferences) {
-        final int count = preferences.getPreferenceCount();
-        for (int i = 0; i < count; i++) {
+    public void setupPreferences(PreferenceGroup prefs) {
+        ArrayList<String> list = new ArrayList<String>();
+        setupPreferences(prefs, list);
+        getGeckoPreferences(prefs, list);
+    }
+
+    private void setupPreferences(PreferenceGroup preferences, ArrayList<String> prefs) {
+        for (int i = 0; i < preferences.getPreferenceCount(); i++) {
             Preference pref = preferences.getPreference(i);
-            if (pref instanceof PreferenceGroup)
-                initGroups((PreferenceGroup)pref);
-            else {
+            if (pref instanceof PreferenceGroup) {
+                setupPreferences((PreferenceGroup)pref, prefs);
+            } else {
+                String key = pref.getKey();
+
                 pref.setOnPreferenceChangeListener(this);
+                if (PREFS_UPDATER_AUTODOWNLOAD.equals(key) && !AppConstants.MOZ_UPDATER) {
+                    preferences.removePreference(pref);
+                    i--;
+                    continue;
+                } else if (PREFS_TELEMETRY_ENABLED.equals(key)) {
+                    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
+                        if (AppConstants.MOZ_TELEMETRY_ON_BY_DEFAULT) {
+                            pref.setKey(PREFS_TELEMETRY_ENABLED_PRERELEASE);
+                            key = PREFS_TELEMETRY_ENABLED_PRERELEASE;
+                        }
+                    } else {
+                        preferences.removePreference(pref);
+                        i--;
+                        continue;
+                    }
+                }
 
                 // 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.
-                String key = pref.getKey();
                 if (key != null && !key.startsWith(NON_PREF_PREFIX)) {
-                    mPreferencesList.add(pref.getKey());
+                    prefs.add(key);
                 }
             }
         }
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
@@ -241,26 +263,26 @@ public class GeckoPreferences
     public static boolean getBooleanPref(final Context context, final String name, boolean def) {
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         return prefs.getBoolean(name, def);
     }
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         String prefName = preference.getKey();
-        if (prefName != null && prefName.equals(PREFS_MP_ENABLED)) {
+        if (PREFS_MP_ENABLED.equals(prefName)) {
             showDialog((Boolean) newValue ? DIALOG_CREATE_MASTER_PASSWORD : DIALOG_REMOVE_MASTER_PASSWORD);
             return false;
-        } else if (prefName != null && prefName.equals(PREFS_MENU_CHAR_ENCODING)) {
+        } else if (PREFS_MENU_CHAR_ENCODING.equals(prefName)) {
             setCharEncodingState(((String) newValue).equals("true"));
-        } else if (prefName != null && prefName.equals(PREFS_ANNOUNCEMENTS_ENABLED)) {
+        } else if (PREFS_ANNOUNCEMENTS_ENABLED.equals(prefName)) {
             // Send a broadcast intent to the product announcements service, either to start or
             // to stop the repeated background checks.
             broadcastAnnouncementsPref(GeckoApp.mAppContext, ((Boolean) newValue).booleanValue());
-        } else if (prefName != null && prefName.equals(PREFS_UPDATER_AUTODOWNLOAD)) {
+        } else if (PREFS_UPDATER_AUTODOWNLOAD.equals(prefName)) {
             org.mozilla.gecko.updater.UpdateServiceHelper.registerForUpdates(GeckoApp.mAppContext, (String)newValue);
         }
 
         if (!TextUtils.isEmpty(prefName)) {
             PrefsHelper.setPref(prefName, newValue);
         }
         if (preference instanceof ListPreference) {
             // We need to find the entry for the new value
@@ -429,37 +451,40 @@ public class GeckoPreferences
             default:
                 return null;
         }
 
         return dialog;
     }
 
     // Initialize preferences by requesting the preference values from Gecko
-    private void initValues() {
-        JSONArray jsonPrefs = new JSONArray(mPreferencesList);
+    private void getGeckoPreferences(final PreferenceGroup screen, ArrayList<String> prefs) {
+        JSONArray jsonPrefs = new JSONArray(prefs);
+
         PrefsHelper.getPrefs(jsonPrefs, new PrefsHelper.PrefHandlerBase() {
             private Preference getField(String prefName) {
-                return (mPreferenceScreen == null ? null : mPreferenceScreen.findPreference(prefName));
+                return screen.findPreference(prefName);
             }
 
-            @Override public void prefValue(String prefName, final boolean value) {
+            @Override
+            public void prefValue(String prefName, final boolean value) {
                 final Preference pref = getField(prefName);
                 if (pref instanceof CheckBoxPreference) {
                     ThreadUtils.postToUiThread(new Runnable() {
                         @Override
                         public void run() {
                             if (((CheckBoxPreference)pref).isChecked() != value)
                                 ((CheckBoxPreference)pref).setChecked(value);
                         }
                     });
                 }
             }
 
-            @Override public void prefValue(String prefName, final String value) {
+            @Override
+            public void prefValue(String prefName, final String value) {
                 final Preference pref = getField(prefName);
                 if (pref instanceof EditTextPreference) {
                     ThreadUtils.postToUiThread(new Runnable() {
                         @Override
                         public void run() {
                             ((EditTextPreference)pref).setText(value);
                         }
                     });
@@ -481,22 +506,23 @@ public class GeckoPreferences
                         @Override
                         public void run() {
                             fontSizePref.setSummary(fontSizeName); // Ex: "Small".
                         }
                     });
                 }
             }
 
-            @Override public void finish() {
+            @Override
+            public void finish() {
                 // enable all preferences once we have them from gecko
                 ThreadUtils.postToUiThread(new Runnable() {
                     @Override
                     public void run() {
-                        mPreferenceScreen.setEnabled(true);
+                        screen.setEnabled(true);
                     }
                 });
             }
         });
     }
 
     private void registerEventListener(String event) {
         GeckoAppShell.getEventDispatcher().registerEventListener(event, this);
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -97,16 +97,17 @@ FENNEC_JAVA_FILES = \
   GeckoHalDefines.java \
   GeckoInputConnection.java \
   GeckoMenu.java \
   GeckoMenuInflater.java \
   GeckoMenuItem.java \
   GeckoMessageReceiver.java \
   GeckoSubMenu.java \
   GeckoPreferences.java \
+  GeckoPreferenceFragment.java \
   GeckoProfile.java \
   GeckoPopupMenu.java \
   GeckoSmsManager.java \
   GeckoThread.java \
   GlobalHistory.java \
   GeckoViewsFactory.java \
   HeightChangeAnimation.java \
   InputMethods.java \
@@ -518,17 +519,20 @@ RES_VALUES_LAND_V14 = \
   res/values-land-v14/dimens.xml \
   $(NULL)
 
 RES_VALUES_V14 = \
   res/values-v14/styles.xml \
   $(NULL)
 
 RES_XML = \
-  res/xml/preferences.xml \
+  res/xml/preference_headers.xml \
+  res/xml/preferences_general.xml \
+  res/xml/preferences_privacy.xml \
+  res/xml/preferences_content.xml \
   $(SYNC_RES_XML) \
   $(NULL)
 
 RES_ANIM = \
   res/anim/awesomebar_fade_in.xml \
   res/anim/awesomebar_fade_out.xml \
   res/anim/awesomebar_hold_still.xml \
   res/anim/grow_fade_in.xml \
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -60,22 +60,26 @@
 <!ENTITY num_tabs2 "&formatD; tabs">
 <!ENTITY new_tab_opened "New tab opened">
 
 <!ENTITY settings "Settings">
 <!ENTITY settings_title "Settings">
 <!ENTITY pref_category_general "General">
 <!ENTITY pref_category_privacy "Privacy &amp; Security">
 <!ENTITY pref_category_content "Content">
-<!ENTITY pref_category_importexport "Import &amp; Export">
 <!ENTITY pref_about_firefox "About &brandShortName;">
 <!ENTITY pref_do_not_track "Tell sites not to track me">
 <!ENTITY pref_telemetry "Send performance data">
 <!ENTITY pref_remember_signons "Remember passwords">
 
+<!-- Localization note: These are shown in the left sidebar on tablets -->
+<!ENTITY pref_header_general "General">
+<!ENTITY pref_header_privacy "Privacy &amp; Security">
+<!ENTITY pref_header_content "Content">
+
 <!ENTITY pref_cookies_menu "Cookies">
 <!ENTITY pref_cookies_accept_all "Enabled">
 <!ENTITY pref_cookies_not_accept_foreign "Enabled, excluding 3rd party">
 <!ENTITY pref_cookies_disabled "Disabled">
 
 <!ENTITY pref_char_encoding "Character encoding">
 <!ENTITY pref_char_encoding_on "Show menu">
 <!ENTITY pref_char_encoding_off "Don\'t show menu">
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/xml/preference_headers.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <header android:fragment="org.mozilla.gecko.GeckoPreferenceFragment"
+            android:title="@string/pref_header_general">
+        <extra android:name="resource"
+               android:value="preferences_general"/>
+    </header>
+
+    <header android:fragment="org.mozilla.gecko.GeckoPreferenceFragment"
+            android:title="@string/pref_header_content">
+        <extra android:name="resource"
+               android:value="preferences_content"/>
+    </header>
+
+    <header android:fragment="org.mozilla.gecko.GeckoPreferenceFragment"
+            android:title="@string/pref_header_privacy">
+        <extra android:name="resource"
+               android:value="preferences_privacy"/>
+    </header>
+
+</preference-headers>
deleted file mode 100644
--- a/mobile/android/base/resources/xml/preferences.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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/. -->
-
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-                  xmlns:gecko="http://schemas.android.com/apk/res-auto"
-                  android:enabled="false">
-
-    <PreferenceCategory android:title="@string/pref_category_general"
-                        android:key="category_general">
-        <org.mozilla.gecko.LinkPreference android:title="@string/pref_about_firefox"
-                                          url="about:" />
-
-        <org.mozilla.gecko.SyncPreference android:title="@string/pref_sync"
-                                          android:persistent="false" />
-
-        <ListPreference android:key="app.update.autodownload"
-                        android:title="@string/pref_update_autodownload"
-                        android:entries="@array/pref_update_autodownload_entries"
-                        android:entryValues="@array/pref_update_autodownload_values"
-                        android:persistent="false" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory android:title="@string/pref_category_content">
-
-        <ListPreference android:key="browser.menu.showCharacterEncoding"
-                        android:title="@string/pref_char_encoding"
-                        android:entries="@array/pref_char_encoding_entries"
-                        android:entryValues="@array/pref_char_encoding_values"
-                        android:persistent="false" />
-
-        <ListPreference android:key="plugin.enable"
-                        android:title="@string/pref_plugins"
-                        android:entries="@array/pref_plugins_entries"
-                        android:entryValues="@array/pref_plugins_values"
-                        android:persistent="false" />
-
-        <org.mozilla.gecko.FontSizePreference
-                        android:key="font.size.inflation.minTwips"
-                        android:title="@string/pref_text_size"
-                        android:positiveButtonText="@string/pref_font_size_set"
-                        android:negativeButtonText="@string/button_cancel"
-                        android:persistent="false" />
-
-        <CheckBoxPreference
-                        android:key="browser.zoom.reflowOnZoom"
-                        android:title="@string/pref_reflow_on_zoom"
-                        android:defaultValue="false"
-                        android:persistent="false" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory android:title="@string/pref_category_privacy"
-                        android:key="category_privacy">
-
-        <ListPreference android:key="network.cookie.cookieBehavior"
-                        android:title="@string/pref_cookies_menu"
-                        android:entries="@array/pref_cookies_entries"
-                        android:entryValues="@array/pref_cookies_values"
-                        android:persistent="false" />
-
-        <!-- keys prefixed with "android.not_a_preference." are not synced with Gecko -->
-        <org.mozilla.gecko.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" />
-
-        <CheckBoxPreference android:key="privacy.donottrackheader.enabled"
-                            android:title="@string/pref_do_not_track"
-                            android:defaultValue="false"
-                            android:persistent="false" />
-
-        <CheckBoxPreference android:key="signon.rememberSignons"
-                            android:title="@string/pref_remember_signons"
-                            android:defaultValue="true"
-                            android:persistent="false" />
-
-        <CheckBoxPreference android:key="privacy.masterpassword.enabled"
-                            android:title="@string/pref_use_master_password"
-                            android:defaultValue="false"
-                            android:persistent="false" />
-
-        <CheckBoxPreference android:key="browser.search.suggest.enabled"
-                            android:title="@string/pref_search_suggestions"
-                            android:defaultValue="true"
-                            android:persistent="false" />
-
-        <CheckBoxPreference android:key="toolkit.telemetry.enabled"
-                            android:title="@string/pref_telemetry"
-                            android:persistent="false" />
-
-        <CheckBoxPreference android:key="android.not_a_preference.privacy.announcements.enabled"
-                            android:title="@string/pref_show_product_announcements"
-                            android:defaultValue="true"
-                            android:persistent="true" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory android:title="@string/pref_category_importexport">
-
-      <org.mozilla.gecko.AndroidImportPreference
-          android:key="android.not_a_preference.import_android"
-          gecko:entries="@array/pref_import_android_entries"
-          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" />
-
-    </PreferenceCategory>
-</PreferenceScreen>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/xml/preferences_content.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+   
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:enabled="false">
+
+    <PreferenceCategory android:title="@string/pref_category_content">
+
+        <ListPreference android:key="browser.menu.showCharacterEncoding"
+                        android:title="@string/pref_char_encoding"
+                        android:entries="@array/pref_char_encoding_entries"
+                        android:entryValues="@array/pref_char_encoding_values"
+                        android:persistent="false" />
+
+        <ListPreference android:key="plugin.enable"
+                        android:title="@string/pref_plugins"
+                        android:entries="@array/pref_plugins_entries"
+                        android:entryValues="@array/pref_plugins_values"
+                        android:persistent="false" />
+
+        <org.mozilla.gecko.FontSizePreference
+                        android:key="font.size.inflation.minTwips"
+                        android:title="@string/pref_text_size"
+                        android:positiveButtonText="@string/pref_font_size_set"
+                        android:negativeButtonText="@string/button_cancel"
+                        android:persistent="false" />
+
+        <CheckBoxPreference
+                        android:key="browser.zoom.reflowOnZoom"
+                        android:title="@string/pref_reflow_on_zoom"
+                        android:defaultValue="false"
+                        android:persistent="false" />
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/xml/preferences_general.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  xmlns:gecko="http://schemas.android.com/apk/res-auto"
+                  android:enabled="false">
+
+    <PreferenceCategory android:title="@string/pref_category_general">
+
+        <org.mozilla.gecko.LinkPreference android:title="@string/pref_about_firefox"
+                                          url="about:" />
+
+        <org.mozilla.gecko.SyncPreference android:title="@string/pref_sync"
+                                          android:persistent="false" />
+
+        <ListPreference android:key="app.update.autodownload"
+                        android:title="@string/pref_update_autodownload"
+                        android:entries="@array/pref_update_autodownload_entries"
+                        android:entryValues="@array/pref_update_autodownload_values"
+                        android:persistent="false" />
+
+        <org.mozilla.gecko.AndroidImportPreference
+           android:key="android.not_a_preference.import_android"
+           gecko:entries="@array/pref_import_android_entries"
+           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" />
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
+
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/xml/preferences_privacy.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  xmlns:gecko="http://schemas.android.com/apk/res-auto"
+                  android:enabled="false">
+
+    <PreferenceCategory android:title="@string/pref_category_privacy">
+
+        <ListPreference android:key="network.cookie.cookieBehavior"
+                        android:title="@string/pref_cookies_menu"
+                        android:entries="@array/pref_cookies_entries"
+                        android:entryValues="@array/pref_cookies_values"
+                        android:persistent="false" />
+
+        <!-- keys prefixed with "android.not_a_preference." are not synced with Gecko -->
+        <org.mozilla.gecko.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" />
+
+        <CheckBoxPreference android:key="privacy.donottrackheader.enabled"
+                            android:title="@string/pref_do_not_track"
+                            android:defaultValue="false"
+                            android:persistent="false" />
+
+        <CheckBoxPreference android:key="signon.rememberSignons"
+                            android:title="@string/pref_remember_signons"
+                            android:defaultValue="true"
+                            android:persistent="false" />
+
+        <CheckBoxPreference android:key="privacy.masterpassword.enabled"
+                            android:title="@string/pref_use_master_password"
+                            android:defaultValue="false"
+                            android:persistent="false" />
+
+        <CheckBoxPreference android:key="browser.search.suggest.enabled"
+                            android:title="@string/pref_search_suggestions"
+                            android:defaultValue="true"
+                            android:persistent="false" />
+
+        <CheckBoxPreference android:key="toolkit.telemetry.enabled"
+                            android:title="@string/pref_telemetry"
+                            android:persistent="false" />
+
+        <CheckBoxPreference android:key="android.not_a_preference.privacy.announcements.enabled"
+                            android:title="@string/pref_show_product_announcements"
+                            android:defaultValue="true"
+                            android:persistent="true" />
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -72,17 +72,19 @@
   <string name="find_next">&find_next;</string>
   <string name="find_close">&find_close;</string>
 
   <string name="settings">&settings;</string>
   <string name="settings_title">&settings_title;</string>
   <string name="pref_category_general">&pref_category_general;</string>
   <string name="pref_category_privacy">&pref_category_privacy;</string>
   <string name="pref_category_content">&pref_category_content;</string>
-  <string name="pref_category_importexport">&pref_category_importexport;</string>
+  <string name="pref_header_general">&pref_header_general;</string>
+  <string name="pref_header_privacy">&pref_header_privacy;</string>
+  <string name="pref_header_content">&pref_header_content;</string>
   <string name="pref_about_firefox">&pref_about_firefox;</string>
   <string name="pref_do_not_track">&pref_do_not_track;</string>
   <string name="pref_telemetry">&pref_telemetry;</string>
   <string name="pref_remember_signons">&pref_remember_signons;</string>
 
   <string name="pref_cookies_menu">&pref_cookies_menu;</string>
   <string name="pref_cookies_accept_all">&pref_cookies_accept_all;</string>
   <string name="pref_cookies_not_accept_foreign">&pref_cookies_not_accept_foreign;</string>