Browser settings refactor

Change-Id: I6fc1b21f7ea692fbe37a17bf900e9b7408a9c077
diff --git a/src/com/android/browser/AutoFillSettingsFragment.java b/src/com/android/browser/AutoFillSettingsFragment.java
index 3a7ae12..e87645e 100644
--- a/src/com/android/browser/AutoFillSettingsFragment.java
+++ b/src/com/android/browser/AutoFillSettingsFragment.java
@@ -53,6 +53,7 @@
 
     // Used to display toast after DB interactions complete.
     private Handler mHandler;
+    private BrowserSettings mSettings;
 
     private final static int PROFILE_SAVED_MSG = 100;
     private final static int PROFILE_DELETED_MSG = 101;
@@ -130,6 +131,7 @@
     @Override
     public void onCreate(Bundle savedState) {
         super.onCreate(savedState);
+        mSettings = BrowserSettings.getInstance();
     }
 
     @Override
@@ -177,7 +179,7 @@
                         mCountryEdit.getText().toString(),
                         mPhoneEdit.getText().toString());
 
-                BrowserSettings.getInstance().setAutoFillProfile(getActivity(), newProfile,
+                mSettings.setAutoFillProfile(newProfile,
                         mHandler.obtainMessage(PROFILE_SAVED_MSG));
                 closeEditor();
             }
@@ -200,7 +202,7 @@
 
                 // Update browser settings and native with a null profile. This will
                 // trigger the current profile to get deleted from the DB.
-                BrowserSettings.getInstance().setAutoFillProfile(getActivity(), null,
+                mSettings.setAutoFillProfile(null,
                         mHandler.obtainMessage(PROFILE_DELETED_MSG));
 
                 updateButtonState();
@@ -215,7 +217,7 @@
         });
 
         // Populate the text boxes with any pre existing AutoFill data.
-        AutoFillProfile activeProfile = BrowserSettings.getInstance().getAutoFillProfile();
+        AutoFillProfile activeProfile = mSettings.getAutoFillProfile();
         if (activeProfile != null) {
             mFullNameEdit.setText(activeProfile.getFullName());
             mEmailEdit.setText(activeProfile.getEmailAddress());
diff --git a/src/com/android/browser/AutofillHandler.java b/src/com/android/browser/AutofillHandler.java
new file mode 100644
index 0000000..b0d5dac
--- /dev/null
+++ b/src/com/android/browser/AutofillHandler.java
@@ -0,0 +1,207 @@
+
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package com.android.browser;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.webkit.WebSettings.AutoFillProfile;
+
+public class AutofillHandler {
+
+    private AutoFillProfile mAutoFillProfile;
+    // Default to zero. In the case no profile is set up, the initial
+    // value will come from the AutoFillSettingsFragment when the user
+    // creates a profile. Otherwise, we'll read the ID of the last used
+    // profile from the prefs db.
+    private int mAutoFillActiveProfileId;
+    private static final int NO_AUTOFILL_PROFILE_SET = 0;
+
+    private boolean mLoadFromDbComplete;
+    private Context mContext;
+
+    public AutofillHandler(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Load settings from the browser app's database. It is performed in
+     * an AsyncTask as it involves plenty of slow disk IO.
+     * NOTE: Strings used for the preferences must match those specified
+     * in the various preference XML files.
+     */
+    public void asyncLoadFromDb() {
+        synchronized (this) {
+            mLoadFromDbComplete = false;
+        }
+        // Run the initial settings load in an AsyncTask as it hits the
+        // disk multiple times through SharedPreferences and SQLite. We
+        // need to be certain though that this has completed before we start
+        // to load pages though, so in the worst case we will block waiting
+        // for it to finish in BrowserActivity.onCreate().
+         new LoadFromDbTask().execute();
+    }
+
+    public void waitForLoad() {
+        synchronized (this) {
+            while (!mLoadFromDbComplete) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {}
+            }
+        }
+    }
+
+    private class LoadFromDbTask extends AsyncTask<Void, Void, Void> {
+
+        @Override
+        protected Void doInBackground(Void... unused) {
+            SharedPreferences p =
+                    PreferenceManager.getDefaultSharedPreferences(mContext);
+
+            // Read the last active AutoFill profile id.
+            mAutoFillActiveProfileId = p.getInt(
+                    PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID,
+                    mAutoFillActiveProfileId);
+
+            // Load the autofill profile data from the database. We use a database separate
+            // to the browser preference DB to make it easier to support multiple profiles
+            // and switching between them.
+            AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext);
+            Cursor c = autoFillDb.getProfile(mAutoFillActiveProfileId);
+
+            if (c.getCount() > 0) {
+                c.moveToFirst();
+
+                String fullName = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.FULL_NAME));
+                String email = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
+                String company = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.COMPANY_NAME));
+                String addressLine1 = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1));
+                String addressLine2 = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2));
+                String city = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.CITY));
+                String state = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.STATE));
+                String zip = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.ZIP_CODE));
+                String country = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.COUNTRY));
+                String phone = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.PHONE_NUMBER));
+                mAutoFillProfile = new AutoFillProfile(mAutoFillActiveProfileId,
+                        fullName, email, company, addressLine1, addressLine2, city,
+                        state, zip, country, phone);
+            }
+            c.close();
+            autoFillDb.close();
+
+            synchronized (this) {
+                mLoadFromDbComplete = true;
+                notifyAll();
+            }
+            return null;
+        }
+    }
+
+    public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
+        if (profile != null) {
+            setActiveAutoFillProfileId(profile.getUniqueId());
+            // Update the AutoFill DB with the new profile.
+            new SaveProfileToDbTask(msg).execute(profile);
+        } else {
+            // Delete the current profile.
+            if (mAutoFillProfile != null) {
+                new DeleteProfileFromDbTask(msg).execute(mAutoFillProfile.getUniqueId());
+                setActiveAutoFillProfileId(NO_AUTOFILL_PROFILE_SET);
+            }
+        }
+        mAutoFillProfile = profile;
+    }
+
+    public AutoFillProfile getAutoFillProfile() {
+        return mAutoFillProfile;
+    }
+
+    private void setActiveAutoFillProfileId(int activeProfileId) {
+        mAutoFillActiveProfileId = activeProfileId;
+        Editor ed = PreferenceManager.
+            getDefaultSharedPreferences(mContext).edit();
+        ed.putInt(PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId);
+        ed.apply();
+    }
+
+    private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> {
+        AutoFillProfileDatabase mAutoFillProfileDb;
+        Message mCompleteMessage;
+
+        public AutoFillProfileDbTask(Message msg) {
+            mCompleteMessage = msg;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            if (mCompleteMessage != null) {
+                mCompleteMessage.sendToTarget();
+            }
+            mAutoFillProfileDb.close();
+        }
+
+        @Override
+        abstract protected Void doInBackground(T... values);
+    }
+
+
+    private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
+        public SaveProfileToDbTask(Message msg) {
+            super(msg);
+        }
+
+        @Override
+        protected Void doInBackground(AutoFillProfile... values) {
+            mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
+            assert mAutoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET;
+            AutoFillProfile newProfile = values[0];
+            mAutoFillProfileDb.addOrUpdateProfile(mAutoFillActiveProfileId, newProfile);
+            return null;
+        }
+    }
+
+    private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> {
+        public DeleteProfileFromDbTask(Message msg) {
+            super(msg);
+        }
+
+        @Override
+        protected Void doInBackground(Integer... values) {
+            mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
+            int id = values[0];
+            assert  id > 0;
+            mAutoFillProfileDb.dropProfile(id);
+            return null;
+        }
+    }
+}
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 1e0e183..5bb4c1f 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -150,7 +150,7 @@
         // Add this WebView to the settings observer list and update the
         // settings
         final BrowserSettings s = BrowserSettings.getInstance();
-        s.addObserver(w.getSettings()).update(s, null);
+        s.startManagingSettings(w.getSettings());
     }
 
     private void cancelStopToast() {
diff --git a/src/com/android/browser/BookmarkItem.java b/src/com/android/browser/BookmarkItem.java
index 8247c91..e7f37a5 100644
--- a/src/com/android/browser/BookmarkItem.java
+++ b/src/com/android/browser/BookmarkItem.java
@@ -30,6 +30,8 @@
  */
 class BookmarkItem extends LinearLayout {
 
+    final static int MAX_TEXTVIEW_LEN = 80;
+
     protected TextView    mTextView;
     protected TextView    mUrlText;
     protected ImageView   mImageView;
@@ -121,8 +123,8 @@
 
         mTitle = name;
 
-        if (name.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
-            name = name.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+        if (name.length() > MAX_TEXTVIEW_LEN) {
+            name = name.substring(0, MAX_TEXTVIEW_LEN);
         }
 
         mTextView.setText(name);
@@ -139,8 +141,8 @@
 
         mUrl = url;
 
-        if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
-            url = url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+        if (url.length() > MAX_TEXTVIEW_LEN) {
+            url = url.substring(0, MAX_TEXTVIEW_LEN);
         }
 
         mUrlText.setText(url);
diff --git a/src/com/android/browser/Browser.java b/src/com/android/browser/Browser.java
index f49da5d..65eb0ce 100644
--- a/src/com/android/browser/Browser.java
+++ b/src/com/android/browser/Browser.java
@@ -16,12 +16,9 @@
 
 package com.android.browser;
 
-import android.os.FileUtils;
-import android.util.Log;
-
 import android.app.Application;
 import android.content.Intent;
-import android.webkit.CookieManager;
+import android.util.Log;
 import android.webkit.CookieSyncManager;
 
 import dalvik.system.VMRuntime;
@@ -52,9 +49,6 @@
     public void onCreate() {
         super.onCreate();
 
-        // Set the umask so that native code creates files with the correct
-        // permissions (0660)
-        FileUtils.setUMask(FileUtils.S_IRWXO);
         if (LOGV_ENABLED)
             Log.v(LOGTAG, "Browser.onCreate: this=" + this);
 
@@ -63,7 +57,7 @@
                 TARGET_HEAP_UTILIZATION);
         // create CookieSyncManager with current Context
         CookieSyncManager.createInstance(this);
-        BrowserSettings.getInstance().asyncLoadFromDb(this);
+        BrowserSettings.initialize(getApplicationContext());
     }
 
     static Intent createBrowserViewIntent() {
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 3c025d2..c26d850 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -62,11 +62,6 @@
 
         BrowserSettings settings = BrowserSettings.getInstance();
 
-        // We load the first set of BrowserSettings from the db asynchronously
-        // but if it has not completed at this point, we have no choice but
-        // to block waiting for them to finish loading. :(
-        settings.waitForLoadFromDbToComplete();
-
         // render the browser in OpenGL
         if (settings.isHardwareAccelerated()) {
             // Set the flag in the activity's window
@@ -77,12 +72,6 @@
             this.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
         }
 
-        // enable this to test the browser in 32bit
-        if (false) {
-            getWindow().setFormat(PixelFormat.RGBX_8888);
-            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
-        }
-
         // If this was a web search request, pass it on to the default web
         // search provider and finish this activity.
         if (IntentHandler.handleWebSearchIntent(this, null, getIntent())) {
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 88b8979..1dc2612 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -223,7 +223,7 @@
             copy(getUrl(i.position));
             break;
         case R.id.homepage_context_menu_id: {
-            BrowserSettings.getInstance().setHomePage(activity, getUrl(i.position));
+            BrowserSettings.getInstance().setHomePage(getUrl(i.position));
             Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
             break;
         }
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 264c465..e728254 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -455,7 +455,7 @@
                 Browser.deleteFromHistory(activity.getContentResolver(), url);
                 return true;
             case R.id.homepage_context_menu_id:
-                BrowserSettings.getInstance().setHomePage(activity, url);
+                BrowserSettings.getInstance().setHomePage(url);
                 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
                 return true;
             default:
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
index dae838f..8031005 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -48,7 +48,8 @@
     public void onBuildHeaders(List<Header> target) {
         loadHeadersFromResource(R.xml.preference_headers, target);
 
-        if (BrowserSettings.DEV_BUILD || BrowserSettings.getInstance().showDebugSettings()) {
+        if (BrowserSettings.DEV_BUILD
+                || BrowserSettings.getInstance().isDebugEnabled()) {
             Header debug = new Header();
             debug.title = getText(R.string.pref_development_title);
             debug.fragment = DebugPreferencesFragment.class.getName();
@@ -57,16 +58,6 @@
     }
 
     @Override
-    protected void onPause() {
-        super.onPause();
-
-        // sync the shared preferences back to BrowserSettings
-        BrowserSettings.getInstance().syncSharedPreferences(
-                getApplicationContext(),
-                PreferenceManager.getDefaultSharedPreferences(this));
-    }
-
-    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case android.R.id.home:
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
index f69665c..6ebc2c2 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -40,7 +40,6 @@
 import android.preference.PreferenceManager;
 import android.provider.Browser;
 import android.provider.Browser.BookmarkColumns;
-import android.provider.Settings;
 import android.speech.RecognizerResultsIntent;
 import android.text.TextUtils;
 import android.util.Log;
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index b791531..9456561 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -25,398 +24,257 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Message;
 import android.preference.PreferenceManager;
 import android.provider.Browser;
-import android.util.Log;
 import android.webkit.CookieManager;
 import android.webkit.GeolocationPermissions;
 import android.webkit.WebIconDatabase;
 import android.webkit.WebSettings;
 import android.webkit.WebSettings.AutoFillProfile;
+import android.webkit.WebSettings.LayoutAlgorithm;
+import android.webkit.WebSettings.PluginState;
+import android.webkit.WebSettings.TextSize;
+import android.webkit.WebSettings.ZoomDensity;
 import android.webkit.WebStorage;
 import android.webkit.WebView;
 import android.webkit.WebViewDatabase;
 
-import java.util.HashMap;
-import java.util.Observable;
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.LinkedList;
 
-/*
- * Package level class for storing various WebView and Browser settings. To use
- * this class:
- * BrowserSettings s = BrowserSettings.getInstance();
- * s.addObserver(webView.getSettings());
- * s.loadFromDb(context); // Only needed on app startup
- * s.javaScriptEnabled = true;
- * ... // set any other settings
- * s.update(); // this will update all the observers
- *
- * To remove an observer:
- * s.deleteObserver(webView.getSettings());
+/**
+ * Class for managing settings
  */
-// TODO: Really need to refactor this :/
-public class BrowserSettings extends Observable implements OnSharedPreferenceChangeListener {
-    // Private variables for settings
-    // NOTE: these defaults need to be kept in sync with the XML
-    // until the performance of PreferenceManager.setDefaultValues()
-    // is improved.
-    // Note: boolean variables are set inside reset function.
-    private boolean loadsImagesAutomatically;
-    private boolean javaScriptEnabled;
-    private WebSettings.PluginState pluginState;
-    private boolean javaScriptCanOpenWindowsAutomatically;
-    private boolean showSecurityWarnings;
-    private boolean rememberPasswords;
-    private boolean saveFormData;
-    private boolean autoFillEnabled;
-    private boolean openInBackground;
-    private String defaultTextEncodingName;
-    private String homeUrl = "";
-    private SearchEngine searchEngine;
-    private boolean autoFitPage;
-    private boolean loadsPageInOverviewMode;
-    private boolean showDebugSettings;
-    // HTML5 API flags
-    private boolean appCacheEnabled;
-    private boolean databaseEnabled;
-    private boolean domStorageEnabled;
-    private boolean geolocationEnabled;
-    private boolean workersEnabled;  // only affects V8. JSC does not have a similar setting
-    // HTML5 API configuration params
-    private long appCacheMaxSize = Long.MAX_VALUE;
-    private String appCachePath;  // default value set in loadFromDb().
-    private String databasePath; // default value set in loadFromDb()
-    private String geolocationDatabasePath; // default value set in loadFromDb()
-    private WebStorageSizeManager webStorageSizeManager;
-    // Accessibility settings
-    private int minimumFontSize = 1;
-    private WebSettings.TextSize textSize = WebSettings.TextSize.NORMAL;
+public class BrowserSettings implements OnSharedPreferenceChangeListener,
+        PreferenceKeys {
 
-    private String jsFlags = "";
-
-    private final static String TAG = "BrowserSettings";
-
-    // Development settings
-    public WebSettings.LayoutAlgorithm layoutAlgorithm =
-        WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
-    private boolean useWideViewPort = true;
-    private int userAgent = 0;
-    private boolean tracing = false;
-    private boolean lightTouch = false;
-    private boolean navDump = false;
-    private boolean hardwareAccelerated = true;
-    private boolean showVisualIndicator = false;
-    // Lab settings
-    private boolean quickControls = false;
-    private boolean useMostVisitedHomepage = false;
-    private boolean useInstant = false;
-
-    // By default the error console is shown once the user navigates to about:debug.
-    // The setting can be then toggled from the settings menu.
-    private boolean showConsole = true;
-
-    // Private preconfigured values
-    private static int minimumLogicalFontSize = 1;
-    private static int defaultFontSize = 16;
-    private static int defaultFixedFontSize = 13;
-    private static WebSettings.ZoomDensity zoomDensity =
-        WebSettings.ZoomDensity.MEDIUM;
-    private static int pageCacheCapacity;
-
-
-    private AutoFillProfile autoFillProfile;
-    // Default to zero. In the case no profile is set up, the initial
-    // value will come from the AutoFillSettingsFragment when the user
-    // creates a profile. Otherwise, we'll read the ID of the last used
-    // profile from the prefs db.
-    private int autoFillActiveProfileId;
-    private static final int NO_AUTOFILL_PROFILE_SET = 0;
-
-    // Preference keys that are used outside this class
-    public final static String PREF_CLEAR_CACHE = "privacy_clear_cache";
-    public final static String PREF_CLEAR_COOKIES = "privacy_clear_cookies";
-    public final static String PREF_CLEAR_HISTORY = "privacy_clear_history";
-    public final static String PREF_HOMEPAGE = "homepage";
-    public final static String PREF_SEARCH_ENGINE = "search_engine";
-    public final static String PREF_CLEAR_FORM_DATA =
-            "privacy_clear_form_data";
-    public final static String PREF_CLEAR_PASSWORDS =
-            "privacy_clear_passwords";
-    public final static String PREF_EXTRAS_RESET_DEFAULTS =
-            "reset_default_preferences";
-    public final static String PREF_DEBUG_SETTINGS = "debug_menu";
-    public final static String PREF_WEBSITE_SETTINGS = "website_settings";
-    public final static String PREF_TEXT_SIZE = "text_size";
-    public final static String PREF_DEFAULT_ZOOM = "default_zoom";
-    public final static String PREF_DEFAULT_TEXT_ENCODING =
-            "default_text_encoding";
-    public final static String PREF_CLEAR_GEOLOCATION_ACCESS =
-            "privacy_clear_geolocation_access";
-    public final static String PREF_AUTOFILL_ENABLED = "autofill_enabled";
-    public final static String PREF_AUTOFILL_PROFILE = "autofill_profile";
-    public final static String PREF_AUTOFILL_ACTIVE_PROFILE_ID = "autofill_active_profile_id";
-    public final static String PREF_HARDWARE_ACCEL = "enable_hardware_accel";
-    public final static String PREF_VISUAL_INDICATOR = "enable_visual_indicator";
-    public final static String PREF_USER_AGENT = "user_agent";
-
-    public final static String PREF_QUICK_CONTROLS = "enable_quick_controls";
-    public final static String PREF_MOST_VISITED_HOMEPAGE = "use_most_visited_homepage";
-    public final static String PREF_PLUGIN_STATE = "plugin_state";
-    public final static String PREF_USE_INSTANT = "use_instant_search";
-    public final static String PREF_MIN_FONT_SIZE = "min_font_size";
-
+    // TODO: Do something with this UserAgent stuff
     private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (Macintosh; " +
-            "U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.16 (KHTML, " +
-            "like Gecko) Version/5.0 Safari/533.16";
+    "U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.16 (KHTML, " +
+    "like Gecko) Version/5.0 Safari/533.16";
 
     private static final String IPHONE_USERAGENT = "Mozilla/5.0 (iPhone; U; " +
-            "CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 " +
-            "(KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7";
+        "CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 " +
+        "(KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7";
 
     private static final String IPAD_USERAGENT = "Mozilla/5.0 (iPad; U; " +
-            "CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 " +
-            "(KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10";
+        "CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 " +
+        "(KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10";
 
     private static final String FROYO_USERAGENT = "Mozilla/5.0 (Linux; U; " +
-            "Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 " +
-            "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
+        "Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 " +
+        "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
 
-    // Value to truncate strings when adding them to a TextView within
-    // a ListView
-    public final static int MAX_TEXTVIEW_LEN = 80;
+    private static final String USER_AGENTS[] = { null,
+            DESKTOP_USERAGENT,
+            IPHONE_USERAGENT,
+            IPAD_USERAGENT,
+            FROYO_USERAGENT
+    };
 
-    public static final String RLZ_PROVIDER = "com.google.android.partnersetup.rlzappprovider";
+    public static boolean DEV_BUILD = true;
 
-    public static final Uri RLZ_PROVIDER_URI = Uri.parse("content://" + RLZ_PROVIDER + "/");
+    private static BrowserSettings sInstance;
 
-    // Set to true to enable some of the about:debug options
-    public static final boolean DEV_BUILD = true;
-
+    private Context mContext;
+    private SharedPreferences mPrefs;
+    private LinkedList<WeakReference<WebSettings>> mManagedSettings;
     private Controller mController;
+    private WebStorageSizeManager mWebStorageSizeManager;
+    private AutofillHandler mAutofillHandler;
 
-    // Single instance of the BrowserSettings for use in the Browser app.
-    private static BrowserSettings sSingleton;
+    // Cached settings
+    private SearchEngine mSearchEngine;
 
-    // Private map of WebSettings to Observer objects used when deleting an
-    // observer.
-    private HashMap<WebSettings,Observer> mWebSettingsToObservers =
-        new HashMap<WebSettings,Observer>();
+    public static void initialize(final Context context) {
+        sInstance = new BrowserSettings(context);
+    }
 
-    private boolean mLoadFromDbComplete;
+    public static BrowserSettings getInstance() {
+        return sInstance;
+    }
 
-    public void waitForLoadFromDbToComplete() {
-        synchronized (sSingleton) {
-            while (!mLoadFromDbComplete) {
-                try {
-                    sSingleton.wait();
-                } catch (InterruptedException e) { }
-            }
+    private BrowserSettings(Context context) {
+        mContext = context;
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+        mAutofillHandler = new AutofillHandler(mContext);
+        mManagedSettings = new LinkedList<WeakReference<WebSettings>>();
+        mWebStorageSizeManager = new WebStorageSizeManager(mContext,
+                new WebStorageSizeManager.StatFsDiskInfo(getAppCachePath()),
+                new WebStorageSizeManager.WebKitAppCacheInfo(getAppCachePath()));
+        mPrefs.registerOnSharedPreferenceChangeListener(this);
+        mAutofillHandler.asyncLoadFromDb();
+    }
+
+    public void setController(Controller controller) {
+        mController = controller;
+        syncSharedSettings();
+
+        if (mController != null && (mSearchEngine instanceof InstantSearchEngine)) {
+             ((InstantSearchEngine) mSearchEngine).setController(mController);
         }
     }
 
-    /*
-     * An observer wrapper for updating a WebSettings object with the new
-     * settings after a call to BrowserSettings.update().
-     */
-    public static class Observer implements java.util.Observer {
-        // Private WebSettings object that will be updated.
-        private WebSettings mSettings;
-
-        Observer(WebSettings w) {
-            mSettings = w;
-        }
-
-        public void update(Observable o, Object arg) {
-            BrowserSettings b = (BrowserSettings)o;
-            WebSettings s = mSettings;
-
-            s.setLayoutAlgorithm(b.layoutAlgorithm);
-            if (b.userAgent == 0) {
-                // use the default ua string
-                s.setUserAgentString(null);
-            } else if (b.userAgent == 1) {
-                s.setUserAgentString(DESKTOP_USERAGENT);
-            } else if (b.userAgent == 2) {
-                s.setUserAgentString(IPHONE_USERAGENT);
-            } else if (b.userAgent == 3) {
-                s.setUserAgentString(IPAD_USERAGENT);
-            } else if (b.userAgent == 4) {
-                s.setUserAgentString(FROYO_USERAGENT);
-            }
-            s.setUseWideViewPort(b.useWideViewPort);
-            s.setLoadsImagesAutomatically(b.loadsImagesAutomatically);
-            s.setJavaScriptEnabled(b.javaScriptEnabled);
-            s.setShowVisualIndicator(b.showVisualIndicator);
-            s.setPluginState(b.pluginState);
-            s.setJavaScriptCanOpenWindowsAutomatically(
-                    b.javaScriptCanOpenWindowsAutomatically);
-            s.setDefaultTextEncodingName(b.defaultTextEncodingName);
-            s.setMinimumFontSize(b.minimumFontSize);
-            s.setMinimumLogicalFontSize(b.minimumLogicalFontSize);
-            s.setDefaultFontSize(b.defaultFontSize);
-            s.setDefaultFixedFontSize(b.defaultFixedFontSize);
-            s.setNavDump(b.navDump);
-            s.setTextSize(b.textSize);
-            s.setDefaultZoom(b.zoomDensity);
-            s.setLightTouchEnabled(b.lightTouch);
-            s.setSaveFormData(b.saveFormData);
-            s.setAutoFillEnabled(b.autoFillEnabled);
-            s.setSavePassword(b.rememberPasswords);
-            s.setLoadWithOverviewMode(b.loadsPageInOverviewMode);
-            s.setPageCacheCapacity(pageCacheCapacity);
-
-            // WebView inside Browser doesn't want initial focus to be set.
-            s.setNeedInitialFocus(false);
-            // Browser supports multiple windows
-            s.setSupportMultipleWindows(true);
-            // enable smooth transition for better performance during panning or
-            // zooming
-            s.setEnableSmoothTransition(true);
-            // disable content url access
-            s.setAllowContentAccess(false);
-
-            // HTML5 API flags
-            s.setAppCacheEnabled(b.appCacheEnabled);
-            s.setDatabaseEnabled(b.databaseEnabled);
-            s.setDomStorageEnabled(b.domStorageEnabled);
-            s.setWorkersEnabled(b.workersEnabled);  // This only affects V8.
-            s.setGeolocationEnabled(b.geolocationEnabled);
-
-            // HTML5 configuration parameters.
-            s.setAppCacheMaxSize(b.appCacheMaxSize);
-            s.setAppCachePath(b.appCachePath);
-            s.setDatabasePath(b.databasePath);
-            s.setGeolocationDatabasePath(b.geolocationDatabasePath);
-
-            // Active AutoFill profile data.
-            s.setAutoFillProfile(b.autoFillProfile);
-
-            b.updateTabControlSettings();
+    public void startManagingSettings(WebSettings settings) {
+        synchronized (mManagedSettings) {
+            syncStaticSettings(settings);
+            syncSetting(settings);
+            mManagedSettings.add(new WeakReference<WebSettings>(settings));
         }
     }
 
     /**
-     * Load settings from the browser app's database. It is performed in
-     * an AsyncTask as it involves plenty of slow disk IO.
-     * NOTE: Strings used for the preferences must match those specified
-     * in the various preference XML files.
-     * @param ctx A Context object used to query the browser's settings
-     *            database. If the database exists, the saved settings will be
-     *            stored in this BrowserSettings object. This will update all
-     *            observers of this object.
+     * Syncs all the settings that have a Preference UI
      */
-    public void asyncLoadFromDb(final Context ctx) {
-        mLoadFromDbComplete = false;
-        // Run the initial settings load in an AsyncTask as it hits the
-        // disk multiple times through SharedPreferences and SQLite. We
-        // need to be certain though that this has completed before we start
-        // to load pages though, so in the worst case we will block waiting
-        // for it to finish in BrowserActivity.onCreate().
-         new LoadFromDbTask(ctx).execute();
+    private void syncSetting(WebSettings settings) {
+        settings.setGeolocationEnabled(enableGeolocation());
+        settings.setJavaScriptEnabled(enableJavascript());
+        settings.setLightTouchEnabled(enableLightTouch());
+        settings.setNavDump(enableNavDump());
+        settings.setShowVisualIndicator(enableVisualIndicator());
+        settings.setDefaultTextEncodingName(getDefaultTextEncoding());
+        settings.setDefaultZoom(getDefaultZoom());
+        settings.setMinimumFontSize(getMinimumFontSize());
+        settings.setMinimumLogicalFontSize(getMinimumFontSize());
+        settings.setPluginState(getPluginState());
+        settings.setTextSize(getTextSize());
+        settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
+        settings.setAutoFillEnabled(isAutofillEnabled());
+        settings.setLayoutAlgorithm(getLayoutAlgorithm());
+        settings.setJavaScriptCanOpenWindowsAutomatically(blockPopupWindows());
+        settings.setLoadsImagesAutomatically(loadImages());
+        settings.setLoadWithOverviewMode(loadPageInOverviewMode());
+        settings.setSavePassword(rememberPasswords());
+        settings.setSaveFormData(saveFormdata());
+        settings.setUseWideViewPort(isWideViewport());
+        settings.setAutoFillProfile(getAutoFillProfile());
     }
 
-    private class LoadFromDbTask extends AsyncTask<Void, Void, Void> {
-        private Context mContext;
+    /**
+     * Syncs all the settings that have no UI
+     * These cannot change, so we only need to set them once per WebSettings
+     */
+    private void syncStaticSettings(WebSettings settings) {
+        settings.setDefaultFontSize(16);
+        settings.setDefaultFixedFontSize(13);
+        settings.setPageCacheCapacity(getPageCacheCapacity());
 
-        public LoadFromDbTask(Context context) {
-            mContext = context;
+        // WebView inside Browser doesn't want initial focus to be set.
+        settings.setNeedInitialFocus(false);
+        // Browser supports multiple windows
+        settings.setSupportMultipleWindows(true);
+        // enable smooth transition for better performance during panning or
+        // zooming
+        settings.setEnableSmoothTransition(true);
+        // disable content url access
+        settings.setAllowContentAccess(false);
+
+        // HTML5 API flags
+        settings.setAppCacheEnabled(true);
+        settings.setDatabaseEnabled(true);
+        settings.setDomStorageEnabled(true);
+        settings.setWorkersEnabled(true);  // This only affects V8.
+
+        // HTML5 configuration parametersettings.
+        settings.setAppCacheMaxSize(mWebStorageSizeManager.getAppCacheMaxSize());
+        settings.setAppCachePath(getAppCachePath());
+        settings.setDatabasePath(mContext.getDir("databases", 0).getPath());
+        settings.setGeolocationDatabasePath(mContext.getDir("geolocation", 0).getPath());
+    }
+
+    private void syncSharedSettings() {
+        CookieManager.getInstance().setAcceptCookie(acceptCookies());
+        if (mController != null) {
+            mController.setShouldShowErrorConsole(enableJavascriptConsole());
         }
+    }
 
-        protected Void doInBackground(Void... unused) {
-            SharedPreferences p =
-                    PreferenceManager.getDefaultSharedPreferences(mContext);
-            // Set the default value for the Application Caches path.
-            appCachePath = mContext.getDir("appcache", 0).getPath();
-            // Determine the maximum size of the application cache.
-            webStorageSizeManager = new WebStorageSizeManager(
-                    mContext,
-                    new WebStorageSizeManager.StatFsDiskInfo(appCachePath),
-                    new WebStorageSizeManager.WebKitAppCacheInfo(appCachePath));
-            appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
-            // Set the default value for the Database path.
-            databasePath = mContext.getDir("databases", 0).getPath();
-            // Set the default value for the Geolocation database path.
-            geolocationDatabasePath = mContext.getDir("geolocation", 0).getPath();
-
-            if (p.getString(PREF_HOMEPAGE, null) == null) {
-                // No home page preferences is set, set it to default.
-                setHomePage(mContext, getFactoryResetHomeUrl(mContext));
+    private void syncManagedSettings() {
+        syncSharedSettings();
+        synchronized (mManagedSettings) {
+            Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
+            while (iter.hasNext()) {
+                WeakReference<WebSettings> ref = iter.next();
+                WebSettings settings = ref.get();
+                if (settings == null) {
+                    iter.remove();
+                    continue;
+                }
+                syncSetting(settings);
             }
+        }
+    }
 
-            // the cost of one cached page is ~3M (measured using nytimes.com). For
-            // low end devices, we only cache one page. For high end devices, we try
-            // to cache more pages, currently choose 5.
-            ActivityManager am = (ActivityManager) mContext
-                    .getSystemService(Context.ACTIVITY_SERVICE);
-            if (am.getMemoryClass() > 16) {
-                pageCacheCapacity = 5;
+    @Override
+    public void onSharedPreferenceChanged(
+            SharedPreferences sharedPreferences, String key) {
+        syncManagedSettings();
+        if (PREF_SEARCH_ENGINE.equals(key)) {
+            updateSearchEngine(false);
+        }
+        if (PREF_USE_INSTANT_SEARCH.equals(key)) {
+            updateSearchEngine(true);
+        }
+    }
+
+    static String getFactoryResetHomeUrl(Context context) {
+        String url = context.getResources().getString(R.string.homepage_base);
+        if (url.indexOf("{CID}") != -1) {
+            url = url.replace("{CID}",
+                    BrowserProvider.getClientId(context.getContentResolver()));
+        }
+        return url;
+    }
+
+    public LayoutAlgorithm getLayoutAlgorithm() {
+        LayoutAlgorithm layoutAlgorithm = LayoutAlgorithm.NORMAL;
+        if (autofitPages()) {
+            layoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
+        }
+        if (isDebugEnabled()) {
+            if (isSmallScreen()) {
+                layoutAlgorithm = LayoutAlgorithm.SINGLE_COLUMN;
             } else {
-                pageCacheCapacity = 1;
+                if (isNormalLayout()) {
+                    layoutAlgorithm = LayoutAlgorithm.NORMAL;
+                } else {
+                    layoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
+                }
             }
+        }
+        return layoutAlgorithm;
+    }
 
-            // Read the last active AutoFill profile id.
-            autoFillActiveProfileId = p.getInt(
-                    PREF_AUTOFILL_ACTIVE_PROFILE_ID, autoFillActiveProfileId);
-
-            // Load the autofill profile data from the database. We use a database separate
-            // to the browser preference DB to make it easier to support multiple profiles
-            // and switching between them.
-            AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext);
-            Cursor c = autoFillDb.getProfile(autoFillActiveProfileId);
-
-            if (c.getCount() > 0) {
-                c.moveToFirst();
-
-                String fullName = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.FULL_NAME));
-                String email = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
-                String company = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.COMPANY_NAME));
-                String addressLine1 = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1));
-                String addressLine2 = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2));
-                String city = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.CITY));
-                String state = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.STATE));
-                String zip = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.ZIP_CODE));
-                String country = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.COUNTRY));
-                String phone = c.getString(c.getColumnIndex(
-                        AutoFillProfileDatabase.Profiles.PHONE_NUMBER));
-                autoFillProfile = new AutoFillProfile(autoFillActiveProfileId,
-                        fullName, email, company, addressLine1, addressLine2, city,
-                        state, zip, country, phone);
-            }
-            c.close();
-            autoFillDb.close();
-
-            // PreferenceManager.setDefaultValues is TOO SLOW, need to manually keep
-            // the defaults in sync
-            p.registerOnSharedPreferenceChangeListener(BrowserSettings.this);
-            syncSharedPreferences(mContext, p);
-
-            synchronized (sSingleton) {
-                mLoadFromDbComplete = true;
-                sSingleton.notify();
-            }
-            return null;
+    // TODO: Cache
+    public int getPageCacheCapacity() {
+        // the cost of one cached page is ~3M (measured using nytimes.com). For
+        // low end devices, we only cache one page. For high end devices, we try
+        // to cache more pages, currently choose 5.
+        if (ActivityManager.staticGetMemoryClass() > 16) {
+            return 5;
+        } else {
+            return 1;
         }
     }
 
-    private void updateSearchEngine(Context ctx, String searchEngineName, boolean force) {
-        if (force || searchEngine == null ||
-                !searchEngine.getName().equals(searchEngineName)) {
-            if (searchEngine != null) {
-                if (searchEngine.supportsVoiceSearch()) {
+    public WebStorageSizeManager getWebStorageSizeManager() {
+        return mWebStorageSizeManager;
+    }
+
+    // TODO: Cache
+    private String getAppCachePath() {
+        return mContext.getDir("appcache", 0).getPath();
+    }
+
+    private void updateSearchEngine(boolean force) {
+        String searchEngineName = getSearchEngineName();
+        if (force || mSearchEngine == null ||
+                !mSearchEngine.getName().equals(searchEngineName)) {
+            if (mSearchEngine != null) {
+                if (mSearchEngine.supportsVoiceSearch()) {
                      // One or more tabs could have been in voice search mode.
                      // Clear it, since the new SearchEngine may not support
                      // it, or may handle it differently.
@@ -424,307 +282,32 @@
                          mController.getTabControl().getTab(i).revertVoiceSearchMode();
                      }
                  }
-                 searchEngine.close();
+                mSearchEngine.close();
              }
-             searchEngine = SearchEngines.get(ctx, searchEngineName);
+            mSearchEngine = SearchEngines.get(mContext, searchEngineName);
 
-             if (mController != null && (searchEngine instanceof InstantSearchEngine)) {
-                 ((InstantSearchEngine) searchEngine).setController(mController);
+             if (mController != null && (mSearchEngine instanceof InstantSearchEngine)) {
+                 ((InstantSearchEngine) mSearchEngine).setController(mController);
              }
          }
     }
 
-    public void syncSharedPreferences(Context ctx, SharedPreferences p) {
-
-        homeUrl =
-            p.getString(PREF_HOMEPAGE, homeUrl);
-
-        useInstant = p.getBoolean(PREF_USE_INSTANT, useInstant);
-        String searchEngineName = p.getString(PREF_SEARCH_ENGINE,
-               SearchEngine.GOOGLE);
-        updateSearchEngine(ctx, searchEngineName, false);
-
-        loadsImagesAutomatically = p.getBoolean("load_images",
-                loadsImagesAutomatically);
-        javaScriptEnabled = p.getBoolean("enable_javascript",
-                javaScriptEnabled);
-        pluginState = WebSettings.PluginState.valueOf(
-                p.getString(PREF_PLUGIN_STATE, pluginState.name()));
-        javaScriptCanOpenWindowsAutomatically = !p.getBoolean(
-            "block_popup_windows",
-            !javaScriptCanOpenWindowsAutomatically);
-        showSecurityWarnings = p.getBoolean("show_security_warnings",
-                showSecurityWarnings);
-        rememberPasswords = p.getBoolean("remember_passwords",
-                rememberPasswords);
-        saveFormData = p.getBoolean("save_formdata",
-                saveFormData);
-        autoFillEnabled = p.getBoolean("autofill_enabled", autoFillEnabled);
-        boolean accept_cookies = p.getBoolean("accept_cookies",
-                CookieManager.getInstance().acceptCookie());
-        CookieManager.getInstance().setAcceptCookie(accept_cookies);
-        openInBackground = p.getBoolean("open_in_background", openInBackground);
-        textSize = WebSettings.TextSize.valueOf(
-                p.getString(PREF_TEXT_SIZE, textSize.name()));
-        minimumFontSize = p.getInt(PREF_MIN_FONT_SIZE, 1);
-        zoomDensity = WebSettings.ZoomDensity.valueOf(
-                p.getString(PREF_DEFAULT_ZOOM, zoomDensity.name()));
-        autoFitPage = p.getBoolean("autofit_pages", autoFitPage);
-        loadsPageInOverviewMode = p.getBoolean("load_page",
-                loadsPageInOverviewMode);
-        useWideViewPort = true; // use wide view port for either setting
-        if (autoFitPage) {
-            layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
-        } else {
-            layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
-        }
-        defaultTextEncodingName =
-                p.getString(PREF_DEFAULT_TEXT_ENCODING,
-                        defaultTextEncodingName);
-
-        showDebugSettings =
-                p.getBoolean(PREF_DEBUG_SETTINGS, showDebugSettings);
-        // Debug menu items have precidence if the menu is visible
-        if (showDebugSettings) {
-            boolean small_screen = p.getBoolean("small_screen",
-                    layoutAlgorithm ==
-                    WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
-            if (small_screen) {
-                layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN;
-            } else {
-                boolean normal_layout = p.getBoolean("normal_layout",
-                        layoutAlgorithm == WebSettings.LayoutAlgorithm.NORMAL);
-                if (normal_layout) {
-                    layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
-                } else {
-                    layoutAlgorithm =
-                            WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
-                }
-            }
-            useWideViewPort = p.getBoolean("wide_viewport", useWideViewPort);
-            tracing = p.getBoolean("enable_tracing", tracing);
-            lightTouch = p.getBoolean("enable_light_touch", lightTouch);
-            navDump = p.getBoolean("enable_nav_dump", navDump);
-            showVisualIndicator = p.getBoolean(PREF_VISUAL_INDICATOR, showVisualIndicator);
-        }
-
-        quickControls = p.getBoolean(PREF_QUICK_CONTROLS, quickControls);
-        useMostVisitedHomepage = p.getBoolean(PREF_MOST_VISITED_HOMEPAGE, useMostVisitedHomepage);
-
-        // Only set these if this is a dev build or debug is enabled
-        if (DEV_BUILD || showDebugSettings()) {
-            userAgent = Integer.parseInt(p.getString(PREF_USER_AGENT, "0"));
-            hardwareAccelerated = p.getBoolean(PREF_HARDWARE_ACCEL, hardwareAccelerated);
-        }
-
-        // JS flags is loaded from DB even if showDebugSettings is false,
-        // so that it can be set once and be effective all the time.
-        jsFlags = p.getString("js_engine_flags", "");
-
-        // Read the setting for showing/hiding the JS Console always so that should the
-        // user enable debug settings, we already know if we should show the console.
-        // The user will never see the console unless they navigate to about:debug,
-        // regardless of the setting we read here. This setting is only used after debug
-        // is enabled.
-        showConsole = p.getBoolean("javascript_console", showConsole);
-
-        // HTML5 API flags
-        appCacheEnabled = p.getBoolean("enable_appcache", appCacheEnabled);
-        databaseEnabled = p.getBoolean("enable_database", databaseEnabled);
-        domStorageEnabled = p.getBoolean("enable_domstorage", domStorageEnabled);
-        geolocationEnabled = p.getBoolean("enable_geolocation", geolocationEnabled);
-        workersEnabled = p.getBoolean("enable_workers", workersEnabled);
-
-        update();
-    }
-
-    public String getHomePage() {
-        if (useMostVisitedHomepage) {
-            return HomeProvider.MOST_VISITED;
-        }
-        return homeUrl;
-    }
-
     public SearchEngine getSearchEngine() {
-        return searchEngine;
-    }
-
-    public String getJsFlags() {
-        return jsFlags;
-    }
-
-    public WebStorageSizeManager getWebStorageSizeManager() {
-        return webStorageSizeManager;
-    }
-
-    public void setHomePage(Context context, String url) {
-        Editor ed = PreferenceManager.
-                getDefaultSharedPreferences(context).edit();
-        ed.putString(PREF_HOMEPAGE, url);
-        ed.apply();
-        homeUrl = url;
-    }
-
-    public WebSettings.TextSize getTextSize() {
-        return textSize;
-    }
-
-    public int getMinimumFontSize() {
-        return minimumFontSize;
-    }
-
-    public WebSettings.ZoomDensity getDefaultZoom() {
-        return zoomDensity;
-    }
-
-    public boolean openInBackground() {
-        return openInBackground;
-    }
-
-    public boolean showSecurityWarnings() {
-        return showSecurityWarnings;
-    }
-
-    public boolean isTracing() {
-        return tracing;
-    }
-
-    public boolean isLightTouch() {
-        return lightTouch;
-    }
-
-    public boolean isNavDump() {
-        return navDump;
-    }
-
-    public boolean isHardwareAccelerated() {
-        return hardwareAccelerated;
-    }
-
-    public boolean showVisualIndicator() {
-        return showVisualIndicator;
-    }
-
-    public boolean useQuickControls() {
-        return quickControls;
-    }
-
-    public boolean useMostVisitedHomepage() {
-        return useMostVisitedHomepage;
-    }
-
-    public boolean useInstant() {
-        return useInstant;
-    }
-
-    public boolean showDebugSettings() {
-        return showDebugSettings;
-    }
-
-    public void toggleDebugSettings(Context context) {
-        showDebugSettings = !showDebugSettings;
-        navDump = showDebugSettings;
-        syncSharedPreferences(context,
-                PreferenceManager.getDefaultSharedPreferences(context));
-        update();
-    }
-
-    public void setAutoFillProfile(Context ctx, AutoFillProfile profile, Message msg) {
-        if (profile != null) {
-            setActiveAutoFillProfileId(ctx, profile.getUniqueId());
-            // Update the AutoFill DB with the new profile.
-            new SaveProfileToDbTask(ctx, msg).execute(profile);
-        } else {
-            // Delete the current profile.
-            if (autoFillProfile != null) {
-                new DeleteProfileFromDbTask(ctx, msg).execute(autoFillProfile.getUniqueId());
-                setActiveAutoFillProfileId(ctx, NO_AUTOFILL_PROFILE_SET);
-            }
+        if (mSearchEngine == null) {
+            updateSearchEngine(false);
         }
-        autoFillProfile = profile;
+        return mSearchEngine;
     }
 
-    public AutoFillProfile getAutoFillProfile() {
-        return autoFillProfile;
+    public boolean isDebugEnabled() {
+        return mPrefs.getBoolean(PREF_DEBUG_MENU, false);
     }
 
-    private void setActiveAutoFillProfileId(Context context, int activeProfileId) {
-        autoFillActiveProfileId = activeProfileId;
-        Editor ed = PreferenceManager.
-            getDefaultSharedPreferences(context).edit();
-        ed.putInt(PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId);
-        ed.apply();
+    public void setDebugEnabled(boolean value) {
+        mPrefs.edit().putBoolean(PREF_DEBUG_MENU, value).apply();
     }
 
-    /* package */ void disableAutoFill(Context ctx) {
-        autoFillEnabled = false;
-        Editor ed = PreferenceManager.getDefaultSharedPreferences(ctx).edit();
-        ed.putBoolean(PREF_AUTOFILL_ENABLED, false);
-        ed.apply();
-    }
-
-    /**
-     * Add a WebSettings object to the list of observers that will be updated
-     * when update() is called.
-     *
-     * @param s A WebSettings object that is strictly tied to the life of a
-     *            WebView.
-     */
-    public Observer addObserver(WebSettings s) {
-        Observer old = mWebSettingsToObservers.get(s);
-        if (old != null) {
-            super.deleteObserver(old);
-        }
-        Observer o = new Observer(s);
-        mWebSettingsToObservers.put(s, o);
-        super.addObserver(o);
-        return o;
-    }
-
-    /**
-     * Delete the given WebSettings observer from the list of observers.
-     * @param s The WebSettings object to be deleted.
-     */
-    public void deleteObserver(WebSettings s) {
-        Observer o = mWebSettingsToObservers.get(s);
-        if (o != null) {
-            mWebSettingsToObservers.remove(s);
-            super.deleteObserver(o);
-        }
-    }
-
-    /*
-     * Application level method for obtaining a single app instance of the
-     * BrowserSettings.
-     */
-    public static BrowserSettings getInstance() {
-        if (sSingleton == null ) {
-            sSingleton = new BrowserSettings();
-        }
-        return sSingleton;
-    }
-
-    /*
-     * Package level method for associating the BrowserSettings with TabControl
-     */
-    /* package */void setController(Controller ctrl) {
-        mController = ctrl;
-        updateTabControlSettings();
-
-        if (mController != null && (searchEngine instanceof InstantSearchEngine)) {
-             ((InstantSearchEngine) searchEngine).setController(mController);
-        }
-    }
-
-    /*
-     * Update all the observers of the object.
-     */
-    /*package*/ void update() {
-        setChanged();
-        notifyObservers();
-    }
-
-    /*package*/ void clearCache(Context context) {
+    public void clearCache() {
         WebIconDatabase.getInstance().removeAllIcons();
         if (mController != null) {
             WebView current = mController.getCurrentWebView();
@@ -734,18 +317,18 @@
         }
     }
 
-    /*package*/ void clearCookies(Context context) {
+    public void clearCookies() {
         CookieManager.getInstance().removeAllCookie();
     }
 
-    /* package */void clearHistory(Context context) {
-        ContentResolver resolver = context.getContentResolver();
+    public void clearHistory() {
+        ContentResolver resolver = mContext.getContentResolver();
         Browser.clearHistory(resolver);
         Browser.clearSearches(resolver);
     }
 
-    /* package */ void clearFormData(Context context) {
-        WebViewDatabase.getInstance(context).clearFormData();
+    public void clearFormData() {
+        WebViewDatabase.getInstance(mContext).clearFormData();
         if (mController!= null) {
             WebView currentTopView = mController.getCurrentTopWebView();
             if (currentTopView != null) {
@@ -754,149 +337,247 @@
         }
     }
 
-    /*package*/ void clearPasswords(Context context) {
-        WebViewDatabase db = WebViewDatabase.getInstance(context);
+    public void clearPasswords() {
+        WebViewDatabase db = WebViewDatabase.getInstance(mContext);
         db.clearUsernamePassword();
         db.clearHttpAuthUsernamePassword();
     }
 
-    private void updateTabControlSettings() {
-        // Enable/disable the error console.
-        mController.setShouldShowErrorConsole(
-            showDebugSettings && showConsole);
-    }
-
-    /*package*/ void clearDatabases(Context context) {
+    public void clearDatabases() {
         WebStorage.getInstance().deleteAllData();
     }
 
-    /*package*/ void clearLocationAccess(Context context) {
+    public void clearLocationAccess() {
         GeolocationPermissions.getInstance().clearAll();
     }
 
-    /*package*/ void resetDefaultPreferences(Context ctx) {
-        reset();
-        SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(ctx);
-        p.edit().clear().apply();
-        PreferenceManager.setDefaultValues(ctx, R.xml.general_preferences, true);
-        PreferenceManager.setDefaultValues(ctx, R.xml.privacy_security_preferences, true);
-        PreferenceManager.setDefaultValues(ctx, R.xml.advanced_preferences, true);
-        // reset homeUrl
-        setHomePage(ctx, getFactoryResetHomeUrl(ctx));
-        // reset appcache max size
-        appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
-        setActiveAutoFillProfileId(ctx, NO_AUTOFILL_PROFILE_SET);
+    public void resetDefaultPreferences() {
+        mPrefs.edit().clear().apply();
+        syncManagedSettings();
     }
 
-    /*package*/ static String getFactoryResetHomeUrl(Context context) {
-        String url = context.getResources().getString(R.string.homepage_base);
-        if (url.indexOf("{CID}") != -1) {
-            url = url.replace("{CID}",
-                    BrowserProvider.getClientId(context.getContentResolver()));
-        }
-        return url;
+    public AutoFillProfile getAutoFillProfile() {
+        mAutofillHandler.waitForLoad();
+        return mAutofillHandler.getAutoFillProfile();
     }
 
-    // Private constructor that does nothing.
-    private BrowserSettings() {
-        reset();
+    public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
+        mAutofillHandler.waitForLoad();
+        mAutofillHandler.setAutoFillProfile(profile, msg);
     }
 
-    private void reset() {
-        // Private variables for settings
-        // NOTE: these defaults need to be kept in sync with the XML
-        // until the performance of PreferenceManager.setDefaultValues()
-        // is improved.
-        loadsImagesAutomatically = true;
-        javaScriptEnabled = true;
-        pluginState = WebSettings.PluginState.ON;
-        javaScriptCanOpenWindowsAutomatically = false;
-        showSecurityWarnings = true;
-        rememberPasswords = true;
-        saveFormData = true;
-        autoFillEnabled = true;
-        openInBackground = false;
-        autoFitPage = true;
-        loadsPageInOverviewMode = true;
-        showDebugSettings = false;
-        // HTML5 API flags
-        appCacheEnabled = true;
-        databaseEnabled = true;
-        domStorageEnabled = true;
-        geolocationEnabled = true;
-        workersEnabled = true;  // only affects V8. JSC does not have a similar setting
+    public void toggleDebugSettings() {
+        setDebugEnabled(!isDebugEnabled());
     }
 
-    private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> {
-        Context mContext;
-        AutoFillProfileDatabase mAutoFillProfileDb;
-        Message mCompleteMessage;
+    // -----------------------------
+    // getter/setters for accessibility_preferences.xml
+    // -----------------------------
 
-        public AutoFillProfileDbTask(Context ctx, Message msg) {
-            mContext = ctx;
-            mCompleteMessage = msg;
-        }
-
-        protected void onPostExecute(Void result) {
-            if (mCompleteMessage != null) {
-                mCompleteMessage.sendToTarget();
-            }
-            mAutoFillProfileDb.close();
-        }
-
-        abstract protected Void doInBackground(T... values);
+    // TODO: Cache
+    public TextSize getTextSize() {
+        String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
+        return TextSize.valueOf(textSize);
     }
 
-
-    private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
-        public SaveProfileToDbTask(Context ctx, Message msg) {
-            super(ctx, msg);
-        }
-
-        protected Void doInBackground(AutoFillProfile... values) {
-            mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
-            assert autoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET;
-            AutoFillProfile newProfile = values[0];
-            mAutoFillProfileDb.addOrUpdateProfile(autoFillActiveProfileId, newProfile);
-            return null;
-        }
+    public int getMinimumFontSize() {
+        return mPrefs.getInt(PREF_MIN_FONT_SIZE, 1);
     }
 
-    private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> {
-        public DeleteProfileFromDbTask(Context ctx, Message msg) {
-            super(ctx, msg);
-        }
+    // -----------------------------
+    // getter/setters for advanced_preferences.xml
+    // -----------------------------
 
-        protected Void doInBackground(Integer... values) {
-            mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
-            int id = values[0];
-            assert  id > 0;
-            mAutoFillProfileDb.dropProfile(id);
-            return null;
-        }
+    public String getSearchEngineName() {
+        return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
     }
 
-    @Override
-    public void onSharedPreferenceChanged(
-            SharedPreferences p, String key) {
-        if (PREF_HARDWARE_ACCEL.equals(key)) {
-            hardwareAccelerated = p.getBoolean(PREF_HARDWARE_ACCEL, hardwareAccelerated);
-        } else if (PREF_VISUAL_INDICATOR.equals(key)) {
-            showVisualIndicator = p.getBoolean(PREF_VISUAL_INDICATOR, showVisualIndicator);
-        } else if (PREF_USER_AGENT.equals(key)) {
-            userAgent = Integer.parseInt(p.getString(PREF_USER_AGENT, "0"));
-            update();
-        } else if (PREF_QUICK_CONTROLS.equals(key)) {
-            quickControls = p.getBoolean(PREF_QUICK_CONTROLS, quickControls);
-        } else if (PREF_MOST_VISITED_HOMEPAGE.equals(key)) {
-            useMostVisitedHomepage = p.getBoolean(PREF_MOST_VISITED_HOMEPAGE, useMostVisitedHomepage);
-        } else if (PREF_USE_INSTANT.equals(key)) {
-            useInstant = p.getBoolean(PREF_USE_INSTANT, useInstant);
-            updateSearchEngine(mController.getActivity(), SearchEngine.GOOGLE, true);
-        } else if (PREF_SEARCH_ENGINE.equals(key)) {
-            final String searchEngineName = p.getString(PREF_SEARCH_ENGINE,
-                    SearchEngine.GOOGLE);
-            updateSearchEngine(mController.getActivity(), searchEngineName, false);
-        }
+    public boolean openInBackground() {
+        return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
     }
+
+    public boolean enableJavascript() {
+        return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
+    }
+
+    // TODO: Cache
+    public PluginState getPluginState() {
+        String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
+        return PluginState.valueOf(state);
+    }
+
+    // TODO: Cache
+    public ZoomDensity getDefaultZoom() {
+        String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
+        return ZoomDensity.valueOf(zoom);
+    }
+
+    public boolean loadPageInOverviewMode() {
+        return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
+    }
+
+    public boolean autofitPages() {
+        return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
+    }
+
+    public boolean blockPopupWindows() {
+        return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
+    }
+
+    public boolean loadImages() {
+        return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
+    }
+
+    public String getDefaultTextEncoding() {
+        return mPrefs.getString(PREF_DEFAULT_TEXT_ENCODING, null);
+    }
+
+    // -----------------------------
+    // getter/setters for general_preferences.xml
+    // -----------------------------
+
+    public String getHomePage() {
+        if (useMostVisitedHomepage()) {
+            return HomeProvider.MOST_VISITED;
+        }
+        return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
+    }
+
+    public void setHomePage(String value) {
+        mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
+    }
+
+    public boolean isAutofillEnabled() {
+        return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
+    }
+
+    public void setAutofillEnabled(boolean value) {
+        mPrefs.edit().putBoolean(PREF_AUTOFILL_ENABLED, value).apply();
+    }
+
+    // -----------------------------
+    // getter/setters for debug_preferences.xml
+    // -----------------------------
+
+    public boolean isHardwareAccelerated() {
+        if (!isDebugEnabled() && !DEV_BUILD) {
+            return true;
+        }
+        return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
+    }
+
+    public int getUserAgent() {
+        if (!isDebugEnabled() && !DEV_BUILD) {
+            return 0;
+        }
+        return Integer.parseInt(mPrefs.getString(PREF_USER_AGENT, "0"));
+    }
+
+    // -----------------------------
+    // getter/setters for hidden_debug_preferences.xml
+    // -----------------------------
+
+    public boolean enableVisualIndicator() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
+    }
+
+    public boolean enableJavascriptConsole() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
+    }
+
+    public boolean isSmallScreen() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_SMALL_SCREEN, false);
+    }
+
+    public boolean isWideViewport() {
+        if (!isDebugEnabled()) {
+            return true;
+        }
+        return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
+    }
+
+    public boolean isNormalLayout() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
+    }
+
+    public boolean isTracing() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
+    }
+
+    public boolean enableLightTouch() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
+    }
+
+    public boolean enableNavDump() {
+        if (!isDebugEnabled()) {
+            return false;
+        }
+        return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
+    }
+
+    public String getJsEngineFlags() {
+        if (!isDebugEnabled()) {
+            return "";
+        }
+        return mPrefs.getString(PREF_JS_ENGINE_FLAGS, "");
+    }
+
+    // -----------------------------
+    // getter/setters for lab_preferences.xml
+    // -----------------------------
+
+    public boolean useQuickControls() {
+        return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
+    }
+
+    public boolean useMostVisitedHomepage() {
+        return mPrefs.getBoolean(PREF_USE_MOST_VISITED_HOMEPAGE, false);
+    }
+
+    public boolean useInstantSearch() {
+        return mPrefs.getBoolean(PREF_USE_INSTANT_SEARCH, false);
+    }
+
+    // -----------------------------
+    // getter/setters for privacy_security_preferences.xml
+    // -----------------------------
+
+    public boolean showSecurityWarnings() {
+        return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
+    }
+
+    public boolean acceptCookies() {
+        return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
+    }
+
+    public boolean saveFormdata() {
+        return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
+    }
+
+    public boolean enableGeolocation() {
+        return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
+    }
+
+    public boolean rememberPasswords() {
+        return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
+    }
+
 }
diff --git a/src/com/android/browser/BrowserYesNoPreference.java b/src/com/android/browser/BrowserYesNoPreference.java
index caea092..d5d5205 100644
--- a/src/com/android/browser/BrowserYesNoPreference.java
+++ b/src/com/android/browser/BrowserYesNoPreference.java
@@ -35,25 +35,25 @@
         if (positiveResult) {
             setEnabled(false);
 
-            Context context = getContext();
-            if (BrowserSettings.PREF_CLEAR_CACHE.equals(getKey())) {
-                BrowserSettings.getInstance().clearCache(context);
-                BrowserSettings.getInstance().clearDatabases(context);
-            } else if (BrowserSettings.PREF_CLEAR_COOKIES.equals(getKey())) {
-                BrowserSettings.getInstance().clearCookies(context);
-            } else if (BrowserSettings.PREF_CLEAR_HISTORY.equals(getKey())) {
-                BrowserSettings.getInstance().clearHistory(context);
-            } else if (BrowserSettings.PREF_CLEAR_FORM_DATA.equals(getKey())) {
-                BrowserSettings.getInstance().clearFormData(context);
-            } else if (BrowserSettings.PREF_CLEAR_PASSWORDS.equals(getKey())) {
-                BrowserSettings.getInstance().clearPasswords(context);
-            } else if (BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS.equals(
+            BrowserSettings settings = BrowserSettings.getInstance();
+            if (PreferenceKeys.PREF_PRIVACY_CLEAR_CACHE.equals(getKey())) {
+                settings.clearCache();
+                settings.clearDatabases();
+            } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_COOKIES.equals(getKey())) {
+                settings.clearCookies();
+            } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY.equals(getKey())) {
+                settings.clearHistory();
+            } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_FORM_DATA.equals(getKey())) {
+                settings.clearFormData();
+            } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_PASSWORDS.equals(getKey())) {
+                settings.clearPasswords();
+            } else if (PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES.equals(
                     getKey())) {
-                BrowserSettings.getInstance().resetDefaultPreferences(context);
+                settings.resetDefaultPreferences();
                 setEnabled(true);
-            } else if (BrowserSettings.PREF_CLEAR_GEOLOCATION_ACCESS.equals(
+            } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_GEOLOCATION_ACCESS.equals(
                     getKey())) {
-                BrowserSettings.getInstance().clearLocationAccess(context);
+                settings.clearLocationAccess();
             }
         }
     }
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index f920702..0f33380 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -47,7 +47,6 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.preference.PreferenceActivity;
@@ -84,7 +83,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.net.URLEncoder;
 import java.util.Calendar;
 import java.util.HashMap;
@@ -347,7 +345,7 @@
         new ClearThumbnails().execute(mTabControl.getThumbnailDir()
                 .listFiles());
         // Read JavaScript flags if it exists.
-        String jsFlags = getSettings().getJsFlags();
+        String jsFlags = getSettings().getJsEngineFlags();
         if (jsFlags.trim().length() != 0) {
             getCurrentWebView().setJsFlags(jsFlags);
         }
@@ -1085,8 +1083,7 @@
     }
 
     public boolean supportsVoiceSearch() {
-        SearchEngine searchEngine = BrowserSettings.getInstance()
-                .getSearchEngine();
+        SearchEngine searchEngine = getSettings().getSearchEngine();
         return (searchEngine != null && searchEngine.supportsVoiceSearch());
     }
 
@@ -1124,7 +1121,7 @@
             case PREFERENCES_PAGE:
                 if (resultCode == Activity.RESULT_OK && intent != null) {
                     String action = intent.getStringExtra(Intent.EXTRA_TEXT);
-                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
+                    if (PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY.equals(action)) {
                         mTabControl.removeParentChildRelationShips();
                     }
                 }
@@ -1361,8 +1358,7 @@
                 boolean showNewTab = mTabControl.canCreateNewTab();
                 MenuItem newTabItem
                         = menu.findItem(R.id.open_newtab_context_menu_id);
-                newTabItem.setTitle(
-                        BrowserSettings.getInstance().openInBackground()
+                newTabItem.setTitle(getSettings().openInBackground()
                         ? R.string.contextmenu_openlink_newwindow_background
                         : R.string.contextmenu_openlink_newwindow);
                 newTabItem.setVisible(showNewTab);
@@ -1491,12 +1487,12 @@
                         PackageManager.MATCH_DEFAULT_ONLY);
                 menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
 
-                boolean isNavDump = mSettings.isNavDump();
+                boolean isNavDump = mSettings.enableNavDump();
                 final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
                 nav.setVisible(isNavDump);
                 nav.setEnabled(isNavDump);
 
-                boolean showDebugSettings = mSettings.showDebugSettings();
+                boolean showDebugSettings = mSettings.isDebugEnabled();
                 final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
                 counter.setVisible(showDebugSettings);
                 counter.setEnabled(showDebugSettings);
diff --git a/src/com/android/browser/IntentHandler.java b/src/com/android/browser/IntentHandler.java
index fa8bfbc..1322d96 100644
--- a/src/com/android/browser/IntentHandler.java
+++ b/src/com/android/browser/IntentHandler.java
@@ -187,7 +187,7 @@
                     } else if ("about:debug.nav".equals(urlData.mUrl)) {
                         current.getWebView().debugDump();
                     } else {
-                        mSettings.toggleDebugSettings(mActivity);
+                        mSettings.toggleDebugSettings();
                     }
                     return;
                 }
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
new file mode 100644
index 0000000..929339f
--- /dev/null
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package com.android.browser;
+
+public interface PreferenceKeys {
+
+    static final String PREF_AUTOFILL_ACTIVE_PROFILE_ID = "autofill_active_profile_id";
+    static final String PREF_DEBUG_MENU = "debug_menu";
+
+    // ----------------------
+    // Keys for accessibility_preferences.xml
+    // ----------------------
+    static final String PREF_MIN_FONT_SIZE = "min_font_size";
+    static final String PREF_TEXT_SIZE = "text_size";
+
+    // ----------------------
+    // Keys for advanced_preferences.xml
+    // ----------------------
+    static final String PREF_AUTOFIT_PAGES = "autofit_pages";
+    static final String PREF_BLOCK_POPUP_WINDOWS = "block_popup_windows";
+    static final String PREF_DEFAULT_TEXT_ENCODING = "default_text_encoding";
+    static final String PREF_DEFAULT_ZOOM = "default_zoom";
+    static final String PREF_ENABLE_JAVASCRIPT = "enable_javascript";
+    static final String PREF_LOAD_IMAGES = "load_images";
+    static final String PREF_LOAD_PAGE = "load_page";
+    static final String PREF_OPEN_IN_BACKGROUND = "open_in_background";
+    static final String PREF_PLUGIN_STATE = "plugin_state";
+    static final String PREF_RESET_DEFAULT_PREFERENCES = "reset_default_preferences";
+    static final String PREF_SEARCH_ENGINE = "search_engine";
+    static final String PREF_WEBSITE_SETTINGS = "website_settings";
+
+    // ----------------------
+    // Keys for debug_preferences.xml
+    // ----------------------
+    static final String PREF_ENABLE_HARDWARE_ACCEL = "enable_hardware_accel";
+    static final String PREF_USER_AGENT = "user_agent";
+
+    // ----------------------
+    // Keys for general_preferences.xml
+    // ----------------------
+    static final String PREF_AUTOFILL_ENABLED = "autofill_enabled";
+    static final String PREF_AUTOFILL_PROFILE = "autofill_profile";
+    static final String PREF_HOMEPAGE = "homepage";
+    static final String PREF_SYNC_WITH_CHROME = "sync_with_chrome";
+
+    // ----------------------
+    // Keys for hidden_debug_preferences.xml
+    // ----------------------
+    static final String PREF_ENABLE_LIGHT_TOUCH = "enable_light_touch";
+    static final String PREF_ENABLE_NAV_DUMP = "enable_nav_dump";
+    static final String PREF_ENABLE_TRACING = "enable_tracing";
+    static final String PREF_ENABLE_VISUAL_INDICATOR = "enable_visual_indicator";
+    static final String PREF_JAVASCRIPT_CONSOLE = "javascript_console";
+    static final String PREF_JS_ENGINE_FLAGS = "js_engine_flags";
+    static final String PREF_NORMAL_LAYOUT = "normal_layout";
+    static final String PREF_SMALL_SCREEN = "small_screen";
+    static final String PREF_WIDE_VIEWPORT = "wide_viewport";
+
+    // ----------------------
+    // Keys for lab_preferences.xml
+    // ----------------------
+    static final String PREF_ENABLE_QUICK_CONTROLS = "enable_quick_controls";
+    static final String PREF_USE_MOST_VISITED_HOMEPAGE = "use_most_visited_homepage";
+    static final String PREF_USE_INSTANT_SEARCH = "use_instant_search";
+
+    // ----------------------
+    // Keys for privacy_security_preferences.xml
+    // ----------------------
+    static final String PREF_ACCEPT_COOKIES = "accept_cookies";
+    static final String PREF_ENABLE_GEOLOCATION = "enable_geolocation";
+    static final String PREF_PRIVACY_CLEAR_CACHE = "privacy_clear_cache";
+    static final String PREF_PRIVACY_CLEAR_COOKIES = "privacy_clear_cookies";
+    static final String PREF_PRIVACY_CLEAR_FORM_DATA = "privacy_clear_form_data";
+    static final String PREF_PRIVACY_CLEAR_GEOLOCATION_ACCESS = "privacy_clear_geolocation_access";
+    static final String PREF_PRIVACY_CLEAR_HISTORY = "privacy_clear_history";
+    static final String PREF_PRIVACY_CLEAR_PASSWORDS = "privacy_clear_passwords";
+    static final String PREF_REMEMBER_PASSWORDS = "remember_passwords";
+    static final String PREF_SAVE_FORMDATA = "save_formdata";
+    static final String PREF_SHOW_SECURITY_WARNINGS = "show_security_warnings";
+
+}
diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
index ecdaa15..91ee501 100644
--- a/src/com/android/browser/SuggestionsAdapter.java
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -71,6 +71,7 @@
     final Object mResultsLock = new Object();
     List<String> mVoiceResults;
     boolean mIncognitoMode;
+    BrowserSettings mSettings;
 
     interface CompletionListener {
 
@@ -82,6 +83,7 @@
 
     public SuggestionsAdapter(Context ctx, CompletionListener listener) {
         mContext = ctx;
+        mSettings = BrowserSettings.getInstance();
         mListener = listener;
         mLinesPortrait = mContext.getResources().
                 getInteger(R.integer.max_suggest_lines_portrait);
@@ -276,7 +278,7 @@
         }
 
         private boolean shouldProcessEmptyQuery() {
-            final SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
+            final SearchEngine searchEngine = mSettings.getSearchEngine();
             return searchEngine.wantsEmptyQuery();
         }
 
@@ -541,7 +543,7 @@
             if (mCursor != null) {
                 mCursor.close();
             }
-            SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
+            SearchEngine searchEngine = mSettings.getSearchEngine();
             if (!TextUtils.isEmpty(constraint)) {
                 if (searchEngine != null && searchEngine.supportsSuggestions()) {
                     mCursor = searchEngine.getSuggestions(mContext, constraint.toString());
@@ -560,7 +562,7 @@
     }
 
     private boolean useInstant() {
-        return BrowserSettings.getInstance().useInstant();
+        return mSettings.useInstantSearch();
     }
 
     public void clearCache() {
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 8368c33..3508005 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -139,6 +139,7 @@
     DownloadTouchIcon mTouchIconLoader;
 
     private Bitmap mScreenshot;
+    private BrowserSettings mSettings;
 
     // All the state needed for a page
     private static class PageState {
@@ -711,7 +712,7 @@
                 setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
                 return;
             }
-            if (BrowserSettings.getInstance().showSecurityWarnings()) {
+            if (mSettings.showSecurityWarnings()) {
                 final LayoutInflater factory =
                     LayoutInflater.from(mActivity);
                 final View warningsView =
@@ -1017,7 +1018,7 @@
         public void onExceededDatabaseQuota(String url,
             String databaseIdentifier, long currentQuota, long estimatedSize,
             long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
-            BrowserSettings.getInstance().getWebStorageSizeManager()
+            mSettings.getWebStorageSizeManager()
                     .onExceededDatabaseQuota(url, databaseIdentifier,
                             currentQuota, estimatedSize, totalUsedQuota,
                             quotaUpdater);
@@ -1036,7 +1037,7 @@
         @Override
         public void onReachedMaxAppCacheSize(long spaceNeeded,
                 long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
-            BrowserSettings.getInstance().getWebStorageSizeManager()
+            mSettings.getWebStorageSizeManager()
                     .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
                             quotaUpdater);
         }
@@ -1174,10 +1175,7 @@
 
                         if (disableAutoFill.isChecked()) {
                             // Disable autofill and show a toast with how to turn it on again.
-                            BrowserSettings s = BrowserSettings.getInstance();
-                            s.addObserver(mMainView.getSettings());
-                            s.disableAutoFill(mActivity);
-                            s.update();
+                            mSettings.setAutofillEnabled(false);
                             Toast.makeText(mActivity,
                                     R.string.autofill_setup_dialog_negative_toast,
                                     Toast.LENGTH_LONG).show();
@@ -1296,6 +1294,7 @@
             String url) {
         mWebViewController = wvcontroller;
         mActivity = mWebViewController.getActivity();
+        mSettings = BrowserSettings.getInstance();
         mCloseOnExit = closeOnExit;
         mAppId = appId;
         mDataController = DataController.getInstance(mActivity);
@@ -1369,7 +1368,6 @@
     void destroy() {
         if (mMainView != null) {
             dismissSubWindow();
-            BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
             // save the WebView to call destroy() after detach it from the tab
             WebView webView = mMainView;
             setWebView(null);
@@ -1431,8 +1429,6 @@
     void dismissSubWindow() {
         if (mSubView != null) {
             mWebViewController.endActionMode();
-            BrowserSettings.getInstance().deleteObserver(
-                    mSubView.getSettings());
             mSubView.destroy();
             mSubView = null;
             mSubViewContainer = null;
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index af9928a..07c9fa5 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -16,11 +16,8 @@
 
 package com.android.browser;
 
-import com.android.browser.IntentHandler.UrlData;
-
 import android.os.Bundle;
 import android.util.Log;
-import android.webkit.WebBackForwardList;
 import android.webkit.WebView;
 
 import java.io.File;
diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java
index 03bab9b..fbbc3cf 100644
--- a/src/com/android/browser/UrlHandler.java
+++ b/src/com/android/browser/UrlHandler.java
@@ -37,6 +37,9 @@
  */
 public class UrlHandler {
 
+    static final String RLZ_PROVIDER = "com.google.android.partnersetup.rlzappprovider";
+    static final Uri RLZ_PROVIDER_URI = Uri.parse("content://" + RLZ_PROVIDER + "/");
+
     // Use in overrideUrlLoading
     /* package */ final static String SCHEME_WTAI = "wtai://wp/";
     /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
@@ -268,8 +271,7 @@
     private boolean rlzProviderPresent() {
         if (mIsProviderPresent == null) {
             PackageManager pm = mActivity.getPackageManager();
-            mIsProviderPresent = pm.resolveContentProvider(
-                    BrowserSettings.RLZ_PROVIDER, 0) != null;
+            mIsProviderPresent = pm.resolveContentProvider(RLZ_PROVIDER, 0) != null;
         }
         return mIsProviderPresent;
     }
@@ -280,7 +282,7 @@
         if (mRlzUri == null) {
             String ap = mActivity.getResources()
                     .getString(R.string.rlz_access_point);
-            mRlzUri = Uri.withAppendedPath(BrowserSettings.RLZ_PROVIDER_URI, ap);
+            mRlzUri = Uri.withAppendedPath(RLZ_PROVIDER_URI, ap);
         }
         return mRlzUri;
     }
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 350d772..18d0215 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -175,7 +175,7 @@
 
     @Override
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-        if (BrowserSettings.getInstance().useInstant() &&
+        if (BrowserSettings.getInstance().useInstantSearch() &&
                 (actionId == EditorInfo.IME_ACTION_NEXT)) {
             // When instant is turned on AND the user chooses to complete
             // using the tab key, then use the completion rather than the
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index c135fbc..4bfd3cf 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -126,7 +126,7 @@
     @Override
     public void onResume() {
         super.onResume();
-        if (!BrowserSettings.getInstance().useInstant()) {
+        if (!BrowserSettings.getInstance().useInstantSearch()) {
             mTitleBar.clearCompletions();
         }
     }
diff --git a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
index e51a629..50ba758 100644
--- a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
+++ b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
@@ -752,7 +752,7 @@
     }
 
     private void updateText(SuggestionsAdapter adapter) {
-        if (!BrowserSettings.getInstance().useInstant()) {
+        if (!BrowserSettings.getInstance().useInstantSearch()) {
             return;
         }
 
diff --git a/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java b/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
index 1f88e48..99bd687 100644
--- a/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
@@ -16,14 +16,13 @@
 
 package com.android.browser.preferences;
 
-import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
 import com.android.browser.R;
 
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
-import android.util.Log;
 import android.view.View;
 
 public class AccessibilityPreferencesFragment extends PreferenceFragment
@@ -34,11 +33,11 @@
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.accessibility_preferences);
 
-        Preference e = findPreference(BrowserSettings.PREF_TEXT_SIZE);
+        Preference e = findPreference(PreferenceKeys.PREF_TEXT_SIZE);
         e.setOnPreferenceChangeListener(this);
         e.setSummary(getVisualTextSizeName(
                 getPreferenceScreen().getSharedPreferences()
-                .getString(BrowserSettings.PREF_TEXT_SIZE, null)) );
+                .getString(PreferenceKeys.PREF_TEXT_SIZE, null)) );
     }
 
     @Override
@@ -55,7 +54,7 @@
             return false;
         }
 
-        if (pref.getKey().equals(BrowserSettings.PREF_TEXT_SIZE)) {
+        if (pref.getKey().equals(PreferenceKeys.PREF_TEXT_SIZE)) {
             pref.setSummary(getVisualTextSizeName((String) objValue));
             return true;
         }
diff --git a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
index 80db879..2cc504e 100644
--- a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
@@ -17,7 +17,7 @@
 package com.android.browser.preferences;
 
 import com.android.browser.BrowserActivity;
-import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
 import com.android.browser.R;
 
 import android.content.Intent;
@@ -46,22 +46,22 @@
         addPreferencesFromResource(R.xml.advanced_preferences);
 
         PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(
-                BrowserSettings.PREF_WEBSITE_SETTINGS);
+                PreferenceKeys.PREF_WEBSITE_SETTINGS);
         websiteSettings.setFragment(WebsiteSettingsFragment.class.getName());
 
-        Preference e = findPreference(BrowserSettings.PREF_DEFAULT_ZOOM);
+        Preference e = findPreference(PreferenceKeys.PREF_DEFAULT_ZOOM);
         e.setOnPreferenceChangeListener(this);
         e.setSummary(getVisualDefaultZoomName(
                 getPreferenceScreen().getSharedPreferences()
-                .getString(BrowserSettings.PREF_DEFAULT_ZOOM, null)) );
+                .getString(PreferenceKeys.PREF_DEFAULT_ZOOM, null)) );
 
-        e = findPreference(BrowserSettings.PREF_DEFAULT_TEXT_ENCODING);
+        e = findPreference(PreferenceKeys.PREF_DEFAULT_TEXT_ENCODING);
         e.setOnPreferenceChangeListener(this);
 
-        e = findPreference(BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS);
+        e = findPreference(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES);
         e.setOnPreferenceChangeListener(this);
 
-        e = findPreference(BrowserSettings.PREF_PLUGIN_STATE);
+        e = findPreference(PreferenceKeys.PREF_PLUGIN_STATE);
         e.setOnPreferenceChangeListener(this);
         updatePluginSummary((ListPreference) e);
     }
@@ -79,7 +79,7 @@
     public void onResume() {
         super.onResume();
         final PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(
-                BrowserSettings.PREF_WEBSITE_SETTINGS);
+                PreferenceKeys.PREF_WEBSITE_SETTINGS);
         websiteSettings.setEnabled(false);
         WebStorage.getInstance().getOrigins(new ValueCallback<Map>() {
             @Override
@@ -108,20 +108,20 @@
             return false;
         }
 
-        if (pref.getKey().equals(BrowserSettings.PREF_DEFAULT_ZOOM)) {
+        if (pref.getKey().equals(PreferenceKeys.PREF_DEFAULT_ZOOM)) {
             pref.setSummary(getVisualDefaultZoomName((String) objValue));
             return true;
-        } else if (pref.getKey().equals(BrowserSettings.PREF_DEFAULT_TEXT_ENCODING)) {
+        } else if (pref.getKey().equals(PreferenceKeys.PREF_DEFAULT_TEXT_ENCODING)) {
             pref.setSummary((String) objValue);
             return true;
-        } else if (pref.getKey().equals(BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS)) {
+        } else if (pref.getKey().equals(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES)) {
             Boolean value = (Boolean) objValue;
             if (value.booleanValue() == true) {
                 startActivity(new Intent(BrowserActivity.ACTION_RESTART, null,
                         getActivity(), BrowserActivity.class));
                 return true;
             }
-        } else if (pref.getKey().equals(BrowserSettings.PREF_PLUGIN_STATE)) {
+        } else if (pref.getKey().equals(PreferenceKeys.PREF_PLUGIN_STATE)) {
             ListPreference lp = (ListPreference) pref;
             lp.setValue((String) objValue);
             updatePluginSummary(lp);
diff --git a/src/com/android/browser/preferences/DebugPreferencesFragment.java b/src/com/android/browser/preferences/DebugPreferencesFragment.java
index 0a82371..42b18cc 100644
--- a/src/com/android/browser/preferences/DebugPreferencesFragment.java
+++ b/src/com/android/browser/preferences/DebugPreferencesFragment.java
@@ -18,21 +18,14 @@
 
 import com.android.browser.BrowserActivity;
 import com.android.browser.BrowserSettings;
-import com.android.browser.Controller;
+import com.android.browser.PreferenceKeys;
 import com.android.browser.R;
 
-import android.content.Context;
 import android.content.Intent;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.PreferenceActivity.Header;
 import android.preference.PreferenceFragment;
-import android.preference.PreferenceManager.OnActivityResultListener;
-
-import java.io.IOException;
-import java.io.Serializable;
 
 public class DebugPreferencesFragment extends PreferenceFragment
         implements OnPreferenceChangeListener {
@@ -43,11 +36,11 @@
         // Load the XML preferences file
         addPreferencesFromResource(R.xml.debug_preferences);
 
-        if (BrowserSettings.getInstance().showDebugSettings()) {
+        if (BrowserSettings.getInstance().isDebugEnabled()) {
             addPreferencesFromResource(R.xml.hidden_debug_preferences);
         }
 
-        Preference e = findPreference(BrowserSettings.PREF_HARDWARE_ACCEL);
+        Preference e = findPreference(PreferenceKeys.PREF_ENABLE_HARDWARE_ACCEL);
         e.setOnPreferenceChangeListener(this);
     }
 
diff --git a/src/com/android/browser/preferences/GeneralPreferencesFragment.java b/src/com/android/browser/preferences/GeneralPreferencesFragment.java
index 0c63ab5..879b95d 100644
--- a/src/com/android/browser/preferences/GeneralPreferencesFragment.java
+++ b/src/com/android/browser/preferences/GeneralPreferencesFragment.java
@@ -19,7 +19,7 @@
 import com.android.browser.BrowserBookmarksPage;
 import com.android.browser.BrowserHomepagePreference;
 import com.android.browser.BrowserPreferencesPage;
-import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
 import com.android.browser.R;
 import com.android.browser.widget.BookmarkThumbnailWidgetProvider;
 
@@ -62,10 +62,10 @@
         // Load the XML preferences file
         addPreferencesFromResource(R.xml.general_preferences);
 
-        Preference e = findPreference(BrowserSettings.PREF_HOMEPAGE);
+        Preference e = findPreference(PreferenceKeys.PREF_HOMEPAGE);
         e.setOnPreferenceChangeListener(this);
         e.setSummary(getPreferenceScreen().getSharedPreferences()
-                .getString(BrowserSettings.PREF_HOMEPAGE, null));
+                .getString(PreferenceKeys.PREF_HOMEPAGE, null));
         ((BrowserHomepagePreference) e).setCurrentPage(
                 getActivity().getIntent().getStringExtra(BrowserPreferencesPage.CURRENT_PAGE));
         mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
@@ -81,7 +81,7 @@
             return false;
         }
 
-        if (pref.getKey().equals(BrowserSettings.PREF_HOMEPAGE)) {
+        if (pref.getKey().equals(PreferenceKeys.PREF_HOMEPAGE)) {
             pref.setSummary((String) objValue);
             return true;
         }
@@ -202,8 +202,8 @@
         new GetAccountsTask(getActivity()).execute();
 
         PreferenceScreen autoFillSettings =
-                (PreferenceScreen)findPreference(BrowserSettings.PREF_AUTOFILL_PROFILE);
-        autoFillSettings.setDependency(BrowserSettings.PREF_AUTOFILL_ENABLED);
+                (PreferenceScreen)findPreference(PreferenceKeys.PREF_AUTOFILL_PROFILE);
+        autoFillSettings.setDependency(PreferenceKeys.PREF_AUTOFILL_ENABLED);
     }
 
     @Override
diff --git a/src/com/android/browser/preferences/LabPreferencesFragment.java b/src/com/android/browser/preferences/LabPreferencesFragment.java
index 88a9690..f99b96d 100644
--- a/src/com/android/browser/preferences/LabPreferencesFragment.java
+++ b/src/com/android/browser/preferences/LabPreferencesFragment.java
@@ -18,6 +18,7 @@
 
 import com.android.browser.BrowserActivity;
 import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
 import com.android.browser.R;
 import com.android.browser.search.SearchEngine;
 
@@ -41,11 +42,11 @@
         // Load the XML preferences file
         addPreferencesFromResource(R.xml.lab_preferences);
 
-        Preference e = findPreference(BrowserSettings.PREF_QUICK_CONTROLS);
+        Preference e = findPreference(PreferenceKeys.PREF_ENABLE_QUICK_CONTROLS);
         if (e != null) {
             e.setOnPreferenceChangeListener(this);
         }
-        useInstantPref = findPreference(BrowserSettings.PREF_USE_INSTANT);
+        useInstantPref = findPreference(PreferenceKeys.PREF_USE_INSTANT_SEARCH);
     }
 
     @Override
diff --git a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
index 2266608..35e6e43 100644
--- a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
@@ -16,7 +16,7 @@
 
 package com.android.browser.preferences;
 
-import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
 import com.android.browser.R;
 
 import android.app.Activity;
@@ -28,18 +28,14 @@
 public class PrivacySecurityPreferencesFragment extends PreferenceFragment
         implements Preference.OnPreferenceChangeListener {
 
-    private BrowserSettings mSettings;
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mSettings = BrowserSettings.getInstance();
-
         // Load the preferences from an XML resource
         addPreferencesFromResource(R.xml.privacy_security_preferences);
 
-        Preference e = findPreference(BrowserSettings.PREF_CLEAR_HISTORY);
+        Preference e = findPreference(PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY);
         e.setOnPreferenceChangeListener(this);
     }
 
@@ -50,7 +46,7 @@
 
     @Override
     public boolean onPreferenceChange(Preference pref, Object objValue) {
-        if (pref.getKey().equals(BrowserSettings.PREF_CLEAR_HISTORY)
+        if (pref.getKey().equals(PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY)
                 && ((Boolean) objValue).booleanValue() == true) {
             // Need to tell the browser to remove the parent/child relationship
             // between tabs
diff --git a/src/com/android/browser/preferences/WebViewPreview.java b/src/com/android/browser/preferences/WebViewPreview.java
index 15dc83a..94598bc 100644
--- a/src/com/android/browser/preferences/WebViewPreview.java
+++ b/src/com/android/browser/preferences/WebViewPreview.java
@@ -66,8 +66,6 @@
     void updatePreview() {
         if (mWebView == null) return;
 
-        BrowserSettings.getInstance().syncSharedPreferences(getContext(),
-                PreferenceManager.getDefaultSharedPreferences(getContext()));
         WebSettings ws = mWebView.getSettings();
         BrowserSettings bs = BrowserSettings.getInstance();
         ws.setMinimumFontSize(bs.getMinimumFontSize());
diff --git a/src/com/android/browser/search/SearchEngines.java b/src/com/android/browser/search/SearchEngines.java
index a159f17..fd967f9 100644
--- a/src/com/android/browser/search/SearchEngines.java
+++ b/src/com/android/browser/search/SearchEngines.java
@@ -32,7 +32,7 @@
     private static final String TAG = "SearchEngines";
 
     public static SearchEngine getDefaultSearchEngine(Context context) {
-        if (BrowserSettings.getInstance().useInstant()) {
+        if (BrowserSettings.getInstance().useInstantSearch()) {
             return new InstantSearchEngine(context, DefaultSearchEngine.create(context));
         }