Merge "Added widget preview image. NOTE: This image should be replaced by a custom graphic."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 58ce133..0a69fde 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -140,18 +140,6 @@
             <meta-data android:name="android.app.searchable"
                     android:resource="@xml/searchable" />
         </activity>
-
-        <activity android:name="CombinedBookmarkHistoryActivity" android:label="@string/bookmarks"
-                  android:excludeFromRecents="true"
-                  android:launchMode="singleTop" android:configChanges="orientation|keyboardHidden"
-                  android:theme="@style/BookmarkTheme" >
-            <meta-data android:name="android.app.default_searchable"
-                    android:value=".BrowserActivity" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-            </intent-filter>
-        </activity>
-
         <activity android:name="BrowserBookmarksPage" android:label="@string/bookmarks"
                   android:launchMode="singleTop" android:configChanges="orientation|keyboardHidden">
         </activity>
diff --git a/res/layout/autofill_settings_fragment.xml b/res/layout/autofill_settings_fragment.xml
new file mode 100644
index 0000000..35dfbe6
--- /dev/null
+++ b/res/layout/autofill_settings_fragment.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+<TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:textAppearance="?android:attr/textAppearanceLarge"
+    android:text="@string/pref_autofill_profile_editor" />
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:stretchColumns="1"
+    android:paddingLeft="100dip"
+    android:paddingRight="100dip" >
+
+    <TableRow>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:padding="10dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/autofill_profile_editor_name" />
+        <EditText android:id="@+id/autofill_profile_editor_name_edit"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:singleLine="true" />
+    </TableRow>
+    <TableRow>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:padding="10dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/autofill_profile_editor_email_address" />
+        <EditText android:id="@+id/autofill_profile_editor_email_address_edit"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:singleLine="true" />
+    </TableRow>
+</TableLayout>
+
+<Button
+    android:id="@+id/autofill_profile_editor_save_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:text="@string/autofill_profile_editor_save_profile"
+    android:textAppearance="?android:attr/textAppearanceMedium" />
+
+</LinearLayout>
diff --git a/res/layout/bookmarks_history.xml b/res/layout/bookmarks_history.xml
index c7f57fd..c0f4d8d 100644
--- a/res/layout/bookmarks_history.xml
+++ b/res/layout/bookmarks_history.xml
@@ -17,6 +17,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="horizontal"
+    android:background="@color/black"
 >
     <ListView android:id="@android:id/list"
         android:layout_width="0dip"
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
index 0420495..51dea1c 100644
--- a/res/values-xlarge/styles.xml
+++ b/res/values-xlarge/styles.xml
@@ -28,7 +28,6 @@
         <item name="android:actionModeBackground">@drawable/cab_bg</item>
         <item name="android:actionModeCloseDrawable">@drawable/ic_menu_cab_close</item>
         <item name="android:actionButtonStyle">@style/ActionButton</item>
-        <item name="android:popupMenuStyle">@style/ActionDropdown</item>
         <item name="android:actionOverflowButtonStyle">@style/Overflow</item>
     </style>
     <style name="Dialog.Holo" parent="android:Theme.Holo">
@@ -63,9 +62,6 @@
         <item name="android:height">12dip</item>
         <item name="android:background">@drawable/browserbarbutton</item>
     </style>
-    <style name="ActionDropdown" parent="@android:style/Widget.PopupMenu">
-        <item name="android:background">@drawable/menu_dropdown</item>
-    </style>
     <style name="Overflow">
         <item name="android:src">@drawable/ic_menu_overflow</item>
         <item name="android:paddingLeft">16dip</item>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 9aae216..7508e00 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -18,4 +18,6 @@
     <integer name="max_suggest_lines_portrait">12</integer>
     <!--  The maximum number of open tabs -->
     <integer name="max_tabs">16</integer>
+    <!--  The duration of the tab animations in millisecs  -->
+    <integer name="tab_animation_duration">500</integer>
 </resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 54e8f63..29d8703 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -341,6 +341,21 @@
     <!-- Dialog title used when asking the user which Google account they want to use to sync data between Android Browser and Google Chrome [CHAR-LIMIT=20] -->
     <string name="pref_personal_account_dialog_title">Select Google account to share with</string>
 
+    <!-- Checkbox setting for enabling/disabling the form AutoFill feature [CHAR-LIMIT=32] -->
+    <string name="pref_autofill_enabled">Form AutoFill</string>
+    <!-- Settings summary for the form AutoFill feature. [CHAR-LIMIT=none] -->
+    <string name="pref_autofill_enabled_summary">Fill out web forms in a single click</string>
+    <!-- Label for option that when clicked opens the AutoFill settings screen. Also used as the title of that AutoFill Settings screen. [CHAR-LIMIT=32] -->
+    <string name="pref_autofill_profile_editor">AutoFill Settings</string>
+    <!-- Summary for the AutoFill Settings preference [CHAR-LIMIT=none] -->
+    <string name="pref_autofill_profile_editor_summary">Set up &amp; manage data for AutoFilled forms</string>
+    <!-- String for the user's full name in the AutoFill profile editor. [CHAR-LIMIT=32] -->
+    <string name="autofill_profile_editor_name">Full Name:</string>
+    <!-- String for the user's e-mail address in the AutoFill profile editor. [CHAR-LIMIT=32] -->
+    <string name="autofill_profile_editor_email_address">e-mail Address:</string>
+    <!-- Button text to save the AutoFill profile [CHAR-LIMIT=20] -->
+    <string name="autofill_profile_editor_save_profile">Save profile</string>
+
     <!-- Settings screen, section title -->
     <string name="pref_privacy_title">Privacy settings</string>
     <!-- Settings label -->
@@ -393,10 +408,6 @@
     <string name="pref_security_save_form_data">Remember form data</string>
     <!-- Settings summary -->
     <string name="pref_security_save_form_data_summary">Remember data I type in forms for later use</string>
-    <!-- Settings label for enabling/disabling the form AutoFill feature -->
-    <string name="pref_autoFill_enabled">AutoFill forms</string>
-    <!-- Settings summary for the form AutoFill feature. -->
-    <string name="pref_autoFill_enabled_summary">Automatically fill out forms where possible</string>
     <!-- Settings label -->
     <string name="pref_security_show_security_warning">Show security warnings</string>
     <!-- Settings summmary -->
diff --git a/res/xml/browser_preferences.xml b/res/xml/browser_preferences.xml
index cc9b18a..cb4e0b5 100644
--- a/res/xml/browser_preferences.xml
+++ b/res/xml/browser_preferences.xml
@@ -140,10 +140,10 @@
                 android:summary="@string/pref_security_save_form_data_summary" />
 
         <CheckBoxPreference
-                android:key="autoFill_enabled"
+                android:key="autofill_enabled"
                 android:defaultValue="false"
-                android:title="@string/pref_autoFill_enabled"
-                android:summary="@string/pref_autoFill_enabled_summary" />
+                android:title="@string/pref_autofill_enabled"
+                android:summary="@string/pref_autofill_enabled_summary" />
 
         <com.android.browser.BrowserYesNoPreference
                 android:key="privacy_clear_form_data"
diff --git a/res/xml/personal_preferences.xml b/res/xml/personal_preferences.xml
index 14b057c..939d14c 100644
--- a/res/xml/personal_preferences.xml
+++ b/res/xml/personal_preferences.xml
@@ -21,4 +21,15 @@
         android:summary="@string/pref_personal_sync_with_chrome_summary"
     />
 
+    <CheckBoxPreference android:key="autofill_enabled"
+        android:title="@string/pref_autofill_enabled"
+        android:summary="@string/pref_autofill_enabled_summary"
+    />
+
+    <PreferenceScreen
+        android:fragment="com.android.browser.AutoFillSettingsFragment"
+        android:key="autofill_profile"
+        android:title="@string/pref_autofill_profile_editor"
+        android:summary="@string/pref_autofill_profile_editor_summary" />
+
 </PreferenceScreen>
diff --git a/res/xml/privacy_preferences.xml b/res/xml/privacy_preferences.xml
index f8a8d91..a6ea16b 100644
--- a/res/xml/privacy_preferences.xml
+++ b/res/xml/privacy_preferences.xml
@@ -21,16 +21,16 @@
             android:key="privacy_clear_cache"
             android:title="@string/pref_privacy_clear_cache"
             android:summary="@string/pref_privacy_clear_cache_summary"
-            android:dialogMessage="@string/pref_privacy_clear_cache_dlg" 
-            android:dialogTitle="@string/clear" 
+            android:dialogMessage="@string/pref_privacy_clear_cache_dlg"
+            android:dialogTitle="@string/clear"
             android:dialogIcon="@android:drawable/ic_dialog_alert" />
-            
+
     <com.android.browser.BrowserYesNoPreference
             android:key="privacy_clear_history"
             android:title="@string/pref_privacy_clear_history"
             android:summary="@string/pref_privacy_clear_history_summary"
-            android:dialogMessage="@string/pref_privacy_clear_history_dlg" 
-            android:dialogTitle="@string/clear" 
+            android:dialogMessage="@string/pref_privacy_clear_history_dlg"
+            android:dialogTitle="@string/clear"
             android:dialogIcon="@android:drawable/ic_dialog_alert"/>
 
     <CheckBoxPreference
@@ -38,13 +38,13 @@
             android:defaultValue="true"
             android:title="@string/pref_security_accept_cookies"
             android:summary="@string/pref_security_accept_cookies_summary" />
-            
+
     <com.android.browser.BrowserYesNoPreference
             android:key="privacy_clear_cookies"
             android:title="@string/pref_privacy_clear_cookies"
             android:summary="@string/pref_privacy_clear_cookies_summary"
-            android:dialogMessage="@string/pref_privacy_clear_cookies_dlg" 
-            android:dialogTitle="@string/clear" 
+            android:dialogMessage="@string/pref_privacy_clear_cookies_dlg"
+            android:dialogTitle="@string/clear"
             android:dialogIcon="@android:drawable/ic_dialog_alert"/>
 
     <CheckBoxPreference
@@ -53,18 +53,12 @@
             android:title="@string/pref_security_save_form_data"
             android:summary="@string/pref_security_save_form_data_summary" />
 
-    <CheckBoxPreference
-            android:key="autoFill_enabled"
-            android:defaultValue="false"
-            android:title="@string/pref_autoFill_enabled"
-            android:summary="@string/pref_autoFill_enabled_summary" />
-
     <com.android.browser.BrowserYesNoPreference
             android:key="privacy_clear_form_data"
             android:title="@string/pref_privacy_clear_form_data"
             android:summary="@string/pref_privacy_clear_form_data_summary"
-            android:dialogMessage="@string/pref_privacy_clear_form_data_dlg" 
-            android:dialogTitle="@string/clear" 
+            android:dialogMessage="@string/pref_privacy_clear_form_data_dlg"
+            android:dialogTitle="@string/clear"
             android:dialogIcon="@android:drawable/ic_dialog_alert"/>
 
     <CheckBoxPreference
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 6c066fb..c8251f9 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -45,6 +45,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.AdapterView;
@@ -329,7 +330,8 @@
         setContentView(R.layout.browser_add_bookmark);
 
         setTitle(R.string.bookmark_this_page);
-        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_list_bookmark);
+        Window window = getWindow();
+        window.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_list_bookmark);
 
         String title = null;
         String url = null;
@@ -340,6 +342,13 @@
                 mMap = b;
                 mEditingExisting = true;
                 setTitle(R.string.edit_bookmark);
+            } else {
+                int gravity = mMap.getInt("gravity", -1);
+                if (gravity != -1) {
+                    WindowManager.LayoutParams l = window.getAttributes();
+                    l.gravity = gravity;
+                    window.setAttributes(l);
+                }
             }
             title = mMap.getString("title");
             url = mOriginalUrl = mMap.getString("url");
@@ -391,7 +400,7 @@
         manager.initLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
 
 
-        if (!getWindow().getDecorView().isInTouchMode()) {
+        if (!window.getDecorView().isInTouchMode()) {
             mButton.requestFocus();
         }
     }
diff --git a/src/com/android/browser/AutoFillProfileDatabase.java b/src/com/android/browser/AutoFillProfileDatabase.java
new file mode 100644
index 0000000..e3d6ea2
--- /dev/null
+++ b/src/com/android/browser/AutoFillProfileDatabase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 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.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+public class AutoFillProfileDatabase {
+
+    static final String LOGTAG = "AutoFillProfileDatabase";
+
+    static final String DATABASE_NAME = "autofill.db";
+    static final int DATABASE_VERSION = 1;
+    static final String PROFILES_TABLE_NAME = "profiles";
+    private AutoFillProfileDatabaseHelper mOpenHelper;
+    private static AutoFillProfileDatabase sInstance;
+
+    public static final class Profiles implements BaseColumns {
+        private Profiles() { }
+
+        static final String FULL_NAME = "fullname";
+        static final String EMAIL_ADDRESS = "email";
+    }
+
+    private static class AutoFillProfileDatabaseHelper extends SQLiteOpenHelper {
+        AutoFillProfileDatabaseHelper(Context context) {
+             super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + PROFILES_TABLE_NAME + " ("
+                    + Profiles._ID + " INTEGER PRIMARY KEY,"
+                    + Profiles.FULL_NAME + " TEXT,"
+                    + Profiles.EMAIL_ADDRESS + " TEXT"
+                    + " );");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(LOGTAG, "Upgrading database from version " + oldVersion + " to "
+                    + newVersion + ", which will destroy all old data");
+            db.execSQL("DROP TABLE IF EXISTS " + PROFILES_TABLE_NAME);
+            onCreate(db);
+        }
+    }
+
+    private AutoFillProfileDatabase(Context context) {
+        mOpenHelper = new AutoFillProfileDatabaseHelper(context);
+    }
+
+    public static AutoFillProfileDatabase getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new AutoFillProfileDatabase(context);
+        }
+        return sInstance;
+    }
+
+    private SQLiteDatabase getDatabase(boolean writable) {
+        return writable ? mOpenHelper.getWritableDatabase() : mOpenHelper.getReadableDatabase();
+    }
+
+    public void addOrUpdateProfile(final int id, final String fullName, final String email) {
+        final String SQL = "INSERT OR REPLACE INTO " + PROFILES_TABLE_NAME + " ("
+                + Profiles._ID + ","
+                + Profiles.FULL_NAME + ","
+                + Profiles.EMAIL_ADDRESS
+                + ") VALUES (?,?,?);";
+        final Object[] PARAMS = {id, fullName, email};
+        getDatabase(true).execSQL(SQL, PARAMS);
+    }
+
+    public Cursor getProfile(int id) {
+        final String[] COLS = {Profiles.FULL_NAME, Profiles.EMAIL_ADDRESS };
+        final String[] SEL_ARGS = { Integer.toString(id) };
+        return getDatabase(false).query(PROFILES_TABLE_NAME, COLS, Profiles._ID + "=?", SEL_ARGS,
+                null, null, null, "1");
+    }
+
+    public void close() {
+        mOpenHelper.close();
+    }
+}
diff --git a/src/com/android/browser/AutoFillSettingsFragment.java b/src/com/android/browser/AutoFillSettingsFragment.java
new file mode 100644
index 0000000..b650ede
--- /dev/null
+++ b/src/com/android/browser/AutoFillSettingsFragment.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2010 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.app.Fragment;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.view.LayoutInflater;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+public class AutoFillSettingsFragment extends Fragment {
+
+    private static final String LOGTAG = "AutoFillSettingsFragment";
+
+    // TODO: This will become dynamic once we support more than one profile.
+    private int mProfileId = 1;
+
+    public AutoFillSettingsFragment() {
+
+    }
+
+    @Override
+    public void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.autofill_settings_fragment, container, false);
+
+        Button saveButton = (Button)v.findViewById(R.id.autofill_profile_editor_save_button);
+        saveButton.setOnClickListener(new OnClickListener() {
+            public void onClick(View button) {
+                View v = getView();
+                EditText fullName = (EditText)v.findViewById(
+                        R.id.autofill_profile_editor_name_edit);
+                EditText email = (EditText)v.findViewById(
+                        R.id.autofill_profile_editor_email_address_edit);
+                new SaveProfileToDbTask().execute(fullName.getText().toString(),
+                        email.getText().toString());
+            }
+        });
+
+        // Load the profile and populate the text views in the background
+        new LoadProfileFromDbTask().execute(mProfileId);
+
+        return v;
+    }
+
+    @Override
+    public void onPause() {
+        AutoFillProfileDatabase db =
+                AutoFillProfileDatabase.getInstance(getActivity());
+        db.close();
+        super.onPause();
+    }
+
+    private class SaveProfileToDbTask extends AsyncTask<String, Void, Void> {
+        protected Void doInBackground(String... values) {
+            AutoFillProfileDatabase db =
+                    AutoFillProfileDatabase.getInstance(getActivity());
+            db.addOrUpdateProfile(mProfileId, values[0], values[1]);
+            return null;
+        }
+
+        protected void onPostExecute(Void result) {
+            Toast.makeText(getActivity(), "Saved profile", Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    private static class LoadedProfileData {
+        private String mFullName;
+        private String mEmailAddress;
+
+        public LoadedProfileData(String fullName, String emailAddress) {
+            mFullName = fullName;
+            mEmailAddress = emailAddress;
+        }
+
+        public String getFullName() { return mFullName; }
+        public String getEmailAddress() { return mEmailAddress; }
+    }
+
+    private class LoadProfileFromDbTask extends AsyncTask<Integer, Void, LoadedProfileData> {
+        protected LoadedProfileData doInBackground(Integer... id) {
+            AutoFillProfileDatabase db = AutoFillProfileDatabase.getInstance(getActivity());
+            Cursor c = db.getProfile(id[0]);
+            c.moveToFirst();
+
+            LoadedProfileData profileData = null;
+
+            if (c.getCount() > 0) {
+                String fullName = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.FULL_NAME));
+                String email = c.getString(c.getColumnIndex(
+                        AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
+                profileData =  new LoadedProfileData(fullName, email);
+            }
+           c.close();
+           return profileData;
+        }
+
+        protected void onPostExecute(LoadedProfileData data) {
+            if (data == null) {
+                return;
+            }
+
+            View v = getView();
+            if (v != null) {
+                EditText fullName = (EditText)v.findViewById(
+                        R.id.autofill_profile_editor_name_edit);
+                EditText email = (EditText)v.findViewById(
+                        R.id.autofill_profile_editor_email_address_edit);
+                fullName.setText(data.getFullName());
+                email.setText(data.getEmailAddress());
+            }
+        }
+    }
+}
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index f5d72ac..8b737a7 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -35,7 +35,6 @@
 import android.content.ContentProvider;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
-import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -68,9 +67,8 @@
 import android.os.Process;
 import android.os.SystemClock;
 import android.provider.Browser;
-import android.provider.BrowserContract;
-import android.provider.ContactsContract;
 import android.provider.BrowserContract.Images;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Intents.Insert;
 import android.provider.Downloads;
 import android.provider.MediaStore;
@@ -89,7 +87,6 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -131,8 +128,8 @@
 import java.util.regex.Pattern;
 
 public class BrowserActivity extends Activity
-    implements View.OnCreateContextMenuListener, DownloadListener,
-    PopupMenu.OnMenuItemClickListener {
+        implements View.OnCreateContextMenuListener, DownloadListener,
+        PopupMenu.OnMenuItemClickListener, BookmarksHistoryCallbacks {
 
     /* Define some aliases to make these debugging flags easier to refer to.
      * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
@@ -141,13 +138,6 @@
     private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
     private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
 
-    // These are single-character shortcuts for searching popular sources.
-    private static final int SHORTCUT_INVALID = 0;
-    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
-    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
-    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
-    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
-
     private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
         @Override
         public Void doInBackground(File... files) {
@@ -168,6 +158,8 @@
      */
     private FrameLayout mBrowserFrameLayout;
 
+    private CombinedBookmarkHistoryView mComboView;
+
     private boolean mXLargeScreenSize;
 
     private Boolean mIsProviderPresent = null;
@@ -550,21 +542,6 @@
         }
     }
 
-    private int parseUrlShortcut(String url) {
-        if (url == null) return SHORTCUT_INVALID;
-
-        // FIXME: quick search, need to be customized by setting
-        if (url.length() > 2 && url.charAt(1) == ' ') {
-            switch (url.charAt(0)) {
-            case 'g': return SHORTCUT_GOOGLE_SEARCH;
-            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
-            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
-            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
-            }
-        }
-        return SHORTCUT_INVALID;
-    }
-
     /**
      * Launches the default web search activity with the query parameters if the given intent's data
      * are identified as plain search terms and not URLs/shortcuts.
@@ -603,11 +580,10 @@
         // But currently, we get the user-typed URL from search box as well.
         String url = fixUrl(inUrl).trim();
 
-        // URLs and site specific search shortcuts are handled by the regular flow of control, so
+        // URLs are handled by the regular flow of control, so
         // return early.
         if (Patterns.WEB_URL.matcher(url).matches()
-                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
-                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
+                || ACCEPTED_URI_SCHEMA.matcher(url).matches()) {
             return false;
         }
 
@@ -973,6 +949,7 @@
         if (mActiveTabsPage != null) {
             removeActiveTabPage(true);
         }
+        removeComboView();
 
         cancelStopToast();
 
@@ -1312,6 +1289,8 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
+        // menu remains active, so ensure comboview is dismissed
+        removeComboView();
         // check the action bar button before mCanChord check, as the prepare call
         // doesn't come for action bar buttons
         if (item.getItemId() == R.id.newtab) {
@@ -1348,7 +1327,7 @@
                 break;
 
             case R.id.bookmarks_menu_id:
-                bookmarksOrHistoryPicker(false, false);
+                bookmarksOrHistoryPicker(false);
                 break;
 
             case R.id.active_tabs_menu_id:
@@ -1448,7 +1427,7 @@
                 break;
 
             case R.id.classic_history_menu_id:
-                bookmarksOrHistoryPicker(true, false);
+                bookmarksOrHistoryPicker(true);
                 break;
 
             case R.id.title_bar_share_page_url:
@@ -1527,6 +1506,9 @@
         i.putExtra("touch_icon_url", w.getTouchIconUrl());
         i.putExtra("thumbnail", createScreenshot(w, getDesiredThumbnailWidth(this),
                 getDesiredThumbnailHeight(this)));
+        // Put the dialog at the upper right of the screen, covering the
+        // star on the title bar.
+        i.putExtra("gravity", Gravity.RIGHT | Gravity.TOP);
         startActivity(i);
     }
 
@@ -2223,8 +2205,9 @@
                     event.startTracking();
                     return true;
                 } else if (mCustomView == null && mActiveTabsPage == null
+                        && mComboView == null
                         && event.isLongPress()) {
-                    bookmarksOrHistoryPicker(true, false);
+                    bookmarksOrHistoryPicker(true);
                     return true;
                 }
                 break;
@@ -2247,6 +2230,8 @@
                     } else if (mActiveTabsPage != null) {
                         // if tab page is showing, hide it
                         removeActiveTabPage(true);
+                    } else if (mComboView != null) {
+                        removeComboView();
                     } else {
                         WebView subwindow = mTabControl.getCurrentSubWindow();
                         if (subwindow != null) {
@@ -2328,7 +2313,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case OPEN_BOOKMARKS:
-                    bookmarksOrHistoryPicker(false, false);
+                    bookmarksOrHistoryPicker(false);
                     break;
                 case FOCUS_NODE_HREF:
                 {
@@ -3777,46 +3762,57 @@
         }
     }
 
+    /**
+     * callback from ComboPage when bookmark/history selection
+     */
+    @Override
+    public void onUrlSelected(String url, boolean newTab) {
+        removeComboView();
+        if (!TextUtils.isEmpty(url)) {
+            if (newTab) {
+                openTab(url, false);
+            } else {
+                final Tab currentTab = mTabControl.getCurrentTab();
+                dismissSubWindow(currentTab);
+                loadUrl(getTopWindow(), url);
+            }
+        }
+    }
+
+    /**
+     * callback from ComboPage when dismissed
+     */
+    @Override
+    public void onComboCanceled() {
+        removeComboView();
+    }
+
+    /**
+     * dismiss the ComboPage
+     */
+    /* package */ void removeComboView() {
+        if (mComboView != null) {
+            mContentView.removeView(mComboView);
+            mTitleBar.setVisibility(View.VISIBLE);
+            mMenuState = R.id.MAIN_MENU;
+            attachTabToContentView(mTabControl.getCurrentTab());
+            getTopWindow().requestFocus();
+            mComboView = null;
+        }
+    }
+
+    /**
+     * callback from ComboPage when clear history is requested
+     */
+    public void onRemoveParentChildRelationships() {
+        mTabControl.removeParentChildRelationShips();
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode,
                                     Intent intent) {
         if (getTopWindow() == null) return;
-
         switch (requestCode) {
-            case COMBO_PAGE:
-                if (resultCode == RESULT_OK && intent != null) {
-                    String data = intent.getAction();
-                    Bundle extras = intent.getExtras();
-                    if (extras != null &&
-                            extras.getBoolean(
-                                    CombinedBookmarkHistoryActivity.EXTRA_OPEN_NEW_WINDOW,
-                                    false)) {
-                        openTab(data, false);
-                    } else if ((extras != null) &&
-                            extras.getBoolean(CombinedBookmarkHistoryActivity.NEWTAB_MODE)) {
-                        openTab(data, true);
-                    } else {
-                        final Tab currentTab = mTabControl.getCurrentTab();
-                        dismissSubWindow(currentTab);
-                        if (data != null && data.length() != 0) {
-                            loadUrl(getTopWindow(), data);
-                        }
-                    }
-                } else if (resultCode == RESULT_CANCELED) {
-                    if (intent != null) {
-                        float evtx = intent.getFloatExtra(CombinedBookmarkHistoryActivity.EVT_X, -1);
-                        float evty = intent.getFloatExtra(CombinedBookmarkHistoryActivity.EVT_Y, -1);
-                        long now = System.currentTimeMillis();
-                        MotionEvent evt = MotionEvent.obtain(now, now,
-                                MotionEvent.ACTION_DOWN, evtx, evty, 0);
-                        dispatchTouchEvent(evt);
-                        MotionEvent up = MotionEvent.obtain(evt);
-                        up.setAction(MotionEvent.ACTION_UP);
-                        dispatchTouchEvent(up);
-                    }
-                }
-                // Deliberately fall through to PREFERENCES_PAGE, since the
-                // same extra may be attached to the COMBO_PAGE
             case PREFERENCES_PAGE:
                 if (resultCode == RESULT_OK && intent != null) {
                     String action = intent.getStringExtra(Intent.EXTRA_TEXT);
@@ -3937,13 +3933,11 @@
      * @param startWithHistory If true, open starting on the history tab.
      *                         Otherwise, start with the bookmarks tab.
      */
-    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory, boolean newTabMode) {
+    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
         WebView current = mTabControl.getCurrentWebView();
         if (current == null) {
             return;
         }
-        Intent intent = new Intent(this,
-                CombinedBookmarkHistoryActivity.class);
         String title = current.getTitle();
         String url = current.getUrl();
         Bitmap thumbnail = createScreenshot(current, getDesiredThumbnailWidth(this),
@@ -3962,28 +3956,22 @@
         if (title == null) {
             title = url;
         }
-        intent.putExtra("title", title);
-        intent.putExtra("url", url);
-        intent.putExtra("thumbnail", thumbnail);
+        Bundle extras = new Bundle();
+        extras.putString("title", title);
+        extras.putString("url", url);
+        extras.putParcelable("thumbnail", thumbnail);
         // Disable opening in a new window if we have maxed out the windows
-        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
-        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
-        if (startWithHistory) {
-            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_FRAGMENT,
-                    CombinedBookmarkHistoryActivity.FRAGMENT_ID_HISTORY);
-        }
-        intent.putExtra(CombinedBookmarkHistoryActivity.NEWTAB_MODE, newTabMode);
-        int top = -1;
-        int height = -1;
-        if (mXLargeScreenSize) {
-            showFakeTitleBar();
-            int titleBarHeight = ((TitleBarXLarge)mFakeTitleBar).getHeightWithoutProgress();
-            top = mTabBar.getBottom() + titleBarHeight;
-            height = getTopWindow().getHeight() - titleBarHeight;
-        }
-        intent.putExtra(CombinedBookmarkHistoryActivity.EXTRA_TOP, top);
-        intent.putExtra(CombinedBookmarkHistoryActivity.EXTRA_HEIGHT, height);
-        startActivityForResult(intent, COMBO_PAGE);
+        extras.putBoolean("disable_new_window", !mTabControl.canCreateNewTab());
+        extras.putString("touch_icon_url", current.getTouchIconUrl());
+
+        mComboView = new CombinedBookmarkHistoryView(this,
+                startWithHistory ? CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
+                        : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
+                extras);
+        removeTabFromContentView(mTabControl.getCurrentTab());
+        mTitleBar.setVisibility(View.GONE);
+        hideFakeTitleBar();
+        mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
     }
 
     private void showSaveToHomescreenDialog(String url, String title, Bitmap touchIcon,
@@ -4012,7 +4000,6 @@
         startActivity(intent);
     }
 
-
     // Called when loading from context menu or LOAD_URL message
     private void loadUrlFromContext(WebView view, String url) {
         // In case the user enters nothing.
@@ -4107,31 +4094,15 @@
             }
             return inUrl;
         }
-        if (hasSpace) {
-            // FIXME: Is this the correct place to add to searches?
-            // what if someone else calls this function?
-            int shortcut = parseUrlShortcut(inUrl);
-            if (shortcut != SHORTCUT_INVALID) {
-                Browser.addSearchUrl(mResolver, inUrl);
-                String query = inUrl.substring(2);
-                switch (shortcut) {
-                case SHORTCUT_GOOGLE_SEARCH:
-                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
-                case SHORTCUT_WIKIPEDIA_SEARCH:
-                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
-                case SHORTCUT_DICTIONARY_SEARCH:
-                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
-                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
-                    // FIXME: we need location in this case
-                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
-                }
-            }
-        } else {
+        if (!hasSpace) {
             if (Patterns.WEB_URL.matcher(inUrl).matches()) {
                 return URLUtil.guessUrl(inUrl);
             }
         }
 
+        // FIXME: Is this the correct place to add to searches?
+        // what if someone else calls this function?
+
         Browser.addSearchUrl(mResolver, inUrl);
         return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
     }
@@ -4290,12 +4261,6 @@
                                             Gravity.CENTER);
     // Google search
     final static String QuickSearch_G = "http://www.google.com/m?q=%s";
-    // Wikipedia search
-    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
-    // Dictionary search
-    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
-    // Google Mobile Local search
-    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
 
     final static String QUERY_PLACE_HOLDER = "%s";
 
@@ -4339,7 +4304,6 @@
     private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
 
     // activity requestCode
-    final static int COMBO_PAGE                 = 1;
     final static int PREFERENCES_PAGE           = 3;
     final static int FILE_SELECTED              = 4;
 
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 4630d4e..be6f8f8 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -77,7 +77,7 @@
     static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
 
     static final String ACCOUNT_NAME_UNSYNCED = "Unsynced";
-    
+
     public static final String PREF_ACCOUNT_TYPE = "acct_type";
     public static final String PREF_ACCOUNT_NAME = "acct_name";
 
@@ -95,6 +95,13 @@
     Stack<Pair<String, Uri>> mFolderStack = new Stack<Pair<String, Uri>>();
     Button mUpButton;
 
+    static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb, Bundle args) {
+        BrowserBookmarksPage bbp = new BrowserBookmarksPage();
+        bbp.mCallbacks = cb;
+        bbp.setArguments(args);
+        return bbp;
+    }
+
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         switch (id) {
@@ -107,7 +114,6 @@
                 }
                 return new BookmarksLoader(getActivity(), accountType, accountName);
             }
-
             case LOADER_ACCOUNTS_THEN_BOOKMARKS: {
                 return new CursorLoader(getActivity(), Accounts.CONTENT_URI,
                         new String[] { Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_NAME }, null, null,
@@ -328,7 +334,7 @@
         item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
         Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
         if (bitmap == null) {
-            bitmap = CombinedBookmarkHistoryActivity.getIconListenerSet().getFavicon(url);
+            bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url);
         }
         item.setFavicon(bitmap);
     }
@@ -346,12 +352,6 @@
     }
 
     @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        mCallbacks = (BookmarksHistoryCallbacks) activity;
-    }
-
-    @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         Context context = getActivity();
@@ -395,7 +395,7 @@
         }
 
         // Add our own listener in case there are favicons that have yet to be loaded.
-        CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(this);
+        CombinedBookmarkHistoryView.getIconListenerSet().addListener(this);
 
         return root;
     }
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 2295804..ab622b1 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -17,11 +17,14 @@
 package com.android.browser;
 
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
 import android.app.Fragment;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.CursorLoader;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.Loader;
 import android.content.pm.PackageManager;
@@ -95,6 +98,13 @@
         cm.setText(text);
     }
 
+    static BrowserHistoryPage newInstance(BookmarksHistoryCallbacks cb, Bundle args) {
+        BrowserHistoryPage bhp = new BrowserHistoryPage();
+        bhp.mCallbacks = cb;
+        bhp.setArguments(args);
+        return bhp;
+    }
+
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         switch (id) {
@@ -153,12 +163,6 @@
     }
 
     @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        mCallbacks = (BookmarksHistoryCallbacks) activity;
-    }
-
-    @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         View root = inflater.inflate(R.layout.history, container, false);
@@ -174,15 +178,14 @@
         getLoaderManager().initLoader(LOADER_HISTORY, null, this);
 
         // Register to receive icons in case they haven't all been loaded.
-        CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(mIconReceiver);
-
+        CombinedBookmarkHistoryView.getIconListenerSet().addListener(mIconReceiver);
         return root;
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-        CombinedBookmarkHistoryActivity.getIconListenerSet().removeListener(mIconReceiver);
+        CombinedBookmarkHistoryView.getIconListenerSet().removeListener(mIconReceiver);
     }
 
     @Override
@@ -195,20 +198,32 @@
         menu.findItem(R.id.clear_history_menu_id).setVisible(
                 Browser.canClearHistory(getActivity().getContentResolver()));
     }
-    
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.clear_history_menu_id:
-                Browser.clearHistory(getActivity().getContentResolver());
-                // BrowserHistoryPage is always a child of
-                // CombinedBookmarkHistoryActivity
-                mCallbacks.onRemoveParentChildRelationShips();
+                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+                        .setTitle(R.string.clear)
+                        .setMessage(R.string.pref_privacy_clear_history_dlg)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setNegativeButton(R.string.cancel, null)
+                        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+                             @Override
+                             public void onClick(DialogInterface dialog, int which) {
+                                 if (which == DialogInterface.BUTTON_POSITIVE) {
+                                     Browser.clearHistory(getActivity().getContentResolver());
+                                     mCallbacks.onRemoveParentChildRelationships();
+                                 }
+                             }
+                        });
+                final Dialog dialog = builder.create();
+                dialog.show();
                 return true;
-                
+
             default:
                 break;
-        }  
+        }
         return super.onOptionsItemSelected(item);
     }
 
@@ -251,13 +266,13 @@
         send.setType("text/plain");
         ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
         menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
-        
+
         super.onCreateContextMenu(menu, v, menuInfo);
     }
-    
+
     @Override
     public boolean onContextItemSelected(MenuItem item) {
-        ExpandableListContextMenuInfo i = 
+        ExpandableListContextMenuInfo i =
             (ExpandableListContextMenuInfo) item.getMenuInfo();
         HistoryItem historyItem = (HistoryItem) i.targetView;
         String url = historyItem.getUrl();
@@ -342,7 +357,7 @@
                 item.setFavicon(BitmapFactory.decodeByteArray(data, 0,
                         data.length));
             } else {
-                item.setFavicon(CombinedBookmarkHistoryActivity
+                item.setFavicon(CombinedBookmarkHistoryView
                         .getIconListenerSet().getFavicon(url));
             }
             return item;
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 8cd001e..4c798a0 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -147,6 +147,8 @@
             "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";
 
     private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (Macintosh; " +
             "U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.16 (KHTML, " +
@@ -260,7 +262,7 @@
     /**
      * Load settings from the browser app's database.
      * NOTE: Strings used for the preferences must match those specified
-     * in the browser_preferences.xml
+     * 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
@@ -298,10 +300,8 @@
             pageCacheCapacity = 1;
         }
 
-    // Load the defaults from the xml
-        // This call is TOO SLOW, need to manually keep the defaults
-        // in sync
-        //PreferenceManager.setDefaultValues(ctx, R.xml.browser_preferences);
+        // PreferenceManager.setDefaultValues is TOO SLOW, need to manually keep
+        // the defaults in sync
         syncSharedPreferences(ctx, p);
     }
 
@@ -342,7 +342,7 @@
                 rememberPasswords);
         saveFormData = p.getBoolean("save_formdata",
                 saveFormData);
-        autoFillEnabled = p.getBoolean("autoFill_enabled", autoFillEnabled);
+        autoFillEnabled = p.getBoolean("autofill_enabled", autoFillEnabled);
         boolean accept_cookies = p.getBoolean("accept_cookies",
                 CookieManager.getInstance().acceptCookie());
         CookieManager.getInstance().setAcceptCookie(accept_cookies);
diff --git a/src/com/android/browser/CombinedBookmarkHistoryActivity.java b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
deleted file mode 100644
index a98408c..0000000
--- a/src/com/android/browser/CombinedBookmarkHistoryActivity.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2009 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.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.Browser;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.webkit.WebIconDatabase;
-import android.webkit.WebIconDatabase.IconListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListView;
-import android.widget.SimpleCursorAdapter;
-
-import java.util.HashMap;
-import java.util.Vector;
-
-interface BookmarksHistoryCallbacks {
-    public void onUrlSelected(String url, boolean newWindow);
-    public void onRemoveParentChildRelationShips();
-}
-
-public class CombinedBookmarkHistoryActivity extends Activity
-        implements BookmarksHistoryCallbacks, OnItemClickListener {
-    final static String NEWTAB_MODE = "newtab_mode";
-    final static String EXTRA_OPEN_NEW_WINDOW = "new_window";
-    final static String STARTING_FRAGMENT = "fragment";
-    final static String EVT_X = "evt_x";
-    final static String EVT_Y = "evt_y";
-    final static String EXTRA_TOP = "top";
-    final static String EXTRA_HEIGHT = "height";
-
-
-    final static int FRAGMENT_ID_BOOKMARKS = 1;
-    final static int FRAGMENT_ID_HISTORY = 2;
-
-    /**
-     * Used to inform BrowserActivity to remove the parent/child relationships
-     * from all the tabs.
-     */
-    private String mExtraData;
-    /**
-     * Intent to be passed to calling Activity when finished.  Keep a pointer to
-     * it locally so mExtraData can be added.
-     */
-    private Intent mResultData;
-    /**
-     * Result code to pass back to calling Activity when finished.
-     */
-    private int mResultCode;
-
-    /**
-     * Flag to inform the browser to force the result to open in a new tab.
-     */
-    private boolean mNewTabMode;
-
-    private int mRequestedTop;
-    private int mRequestedHeight;
-
-    long mCurrentFragment;
-
-    static class IconListenerSet implements IconListener {
-        // Used to store favicons as we get them from the database
-        // FIXME: We use a different method to get the Favicons in
-        // BrowserBookmarksAdapter. They should probably be unified.
-        private HashMap<String, Bitmap> mUrlsToIcons;
-        private Vector<IconListener> mListeners;
-
-        public IconListenerSet() {
-            mUrlsToIcons = new HashMap<String, Bitmap>();
-            mListeners = new Vector<IconListener>();
-        }
-        @Override
-        public void onReceivedIcon(String url, Bitmap icon) {
-            mUrlsToIcons.put(url, icon);
-            for (IconListener listener : mListeners) {
-                listener.onReceivedIcon(url, icon);
-            }
-        }
-        public void addListener(IconListener listener) {
-            mListeners.add(listener);
-        }
-        public void removeListener(IconListener listener) {
-            mListeners.remove(listener);
-        }
-        public Bitmap getFavicon(String url) {
-            return mUrlsToIcons.get(url);
-        }
-    }
-
-    private static IconListenerSet sIconListenerSet;
-    static IconListenerSet getIconListenerSet() {
-        if (null == sIconListenerSet) {
-            sIconListenerSet = new IconListenerSet();
-        }
-        return sIconListenerSet;
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.bookmarks_history);
-
-        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
-
-        ListView list = (ListView) findViewById(android.R.id.list);
-        list.setOnItemClickListener(this);
-        MatrixCursor cursor = new MatrixCursor(new String[] { "name", "_id" });
-        cursor.newRow().add(getString(R.string.bookmarks)).add(FRAGMENT_ID_BOOKMARKS);
-        cursor.newRow().add(getString(R.string.history)).add(FRAGMENT_ID_HISTORY);
-        list.setAdapter(new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor,
-                new String[] { "name" }, new int[] { android.R.id.text1 }));
-
-        int startingFragment = FRAGMENT_ID_BOOKMARKS;
-        Bundle extras = getIntent().getExtras();
-        if (extras != null) {
-            mNewTabMode = extras.getBoolean(NEWTAB_MODE);
-            mRequestedTop = extras.getInt(EXTRA_TOP, -1);
-            mRequestedHeight = extras.getInt(EXTRA_HEIGHT, -1);
-            startingFragment = extras.getInt(STARTING_FRAGMENT, FRAGMENT_ID_BOOKMARKS);
-        }
-
-        // Start up the default fragment
-        loadFragment(startingFragment);
-
-        // XXX: Must do this before launching the AsyncTask to avoid a
-        // potential crash if the icon database has not been created.
-        WebIconDatabase.getInstance();
-
-        // Do this every time we launch the activity in case a new favicon was
-        // added to the webkit db.
-        (new AsyncTask<Void, Void, Void>() {
-            @Override
-            public Void doInBackground(Void... v) {
-                Browser.requestAllIcons(getContentResolver(),
-                        Browser.BookmarkColumns.FAVICON + " is NULL", getIconListenerSet());
-                return null;
-            }
-        }).execute();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        if (mRequestedTop > -1) {
-            WindowManager.LayoutParams lp = getWindow().getAttributes();
-            lp.x = 0;
-            lp.y = mRequestedTop;
-            lp.height = mRequestedHeight;
-            lp.gravity = Gravity.TOP | Gravity.LEFT;
-            getWindow().setAttributes(lp);
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent evt) {
-        if (((evt.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) && (evt.getY() < 0)) {
-            Intent result = new Intent();
-            result.putExtra(EVT_X, evt.getRawX());
-            result.putExtra(EVT_Y, evt.getRawY());
-            setResultFromChild(Activity.RESULT_CANCELED, result);
-            finish();
-            return true;
-        }
-        return super.onTouchEvent(evt);
-    }
-
-    private void loadFragment(int id) {
-        String fragmentClassName;
-        switch (id) {
-            case FRAGMENT_ID_BOOKMARKS:
-                fragmentClassName = BrowserBookmarksPage.class.getName();
-                break;
-            case FRAGMENT_ID_HISTORY:
-                fragmentClassName = BrowserHistoryPage.class.getName();
-                break;
-            default:
-                throw new IllegalArgumentException();
-        }
-        mCurrentFragment = id;
-
-        FragmentManager fm = getFragmentManager();
-        FragmentTransaction transaction = fm.openTransaction();
-        Fragment frag = Fragment.instantiate(this, fragmentClassName, getIntent().getExtras());
-        transaction.replace(R.id.fragment, frag);
-        transaction.commit();
-    }
-
-    @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        if (id == mCurrentFragment) return;
-        loadFragment((int) id);
-    }
-
-    /**
-     * Store extra data in the Intent to return to the calling Activity to tell
-     * it to clear the parent/child relationships from all tabs.
-     */
-    @Override
-    public void onRemoveParentChildRelationShips() {
-        mExtraData = BrowserSettings.PREF_CLEAR_HISTORY;
-    }
-
-    /**
-     * Custom setResult() method so that the Intent can have extra data attached
-     * if necessary.
-     * @param resultCode Uses same codes as Activity.setResult
-     * @param data Intent returned to onActivityResult.
-     */
-    private void setResultFromChild(int resultCode, Intent data) {
-        mResultCode = resultCode;
-        mResultData = data;
-    }
-
-    @Override
-    public void finish() {
-        if (mExtraData != null) {
-            mResultCode = RESULT_OK;
-            if (mResultData == null) mResultData = new Intent();
-            mResultData.putExtra(Intent.EXTRA_TEXT, mExtraData);
-        }
-        if (mNewTabMode) {
-            if (mResultData == null) mResultData = new Intent();
-            mResultData.putExtra(NEWTAB_MODE, true);
-        }
-        setResult(mResultCode, mResultData);
-        super.finish();
-    }
-
-    /**
-     * Report back to the calling activity to load a site.
-     * @param url   Site to load.
-     * @param newWindow True if the URL should be loaded in a new window
-     */
-    @Override
-    public void onUrlSelected(String url, boolean newWindow) {
-        Intent intent = new Intent().setAction(url);
-        if (newWindow) {
-            intent.putExtra(EXTRA_OPEN_NEW_WINDOW, true);
-        }
-        setResultFromChild(RESULT_OK, intent);
-        finish();
-    }
-}
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
new file mode 100644
index 0000000..b480209
--- /dev/null
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2009 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.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.webkit.WebIconDatabase;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+interface BookmarksHistoryCallbacks {
+    public void onUrlSelected(String url, boolean newWindow);
+    public void onRemoveParentChildRelationships();
+    public void onComboCanceled();
+}
+
+public class CombinedBookmarkHistoryView extends LinearLayout
+        implements OnItemClickListener {
+
+    final static String STARTING_FRAGMENT = "fragment";
+
+    final static int FRAGMENT_ID_BOOKMARKS = 1;
+    final static int FRAGMENT_ID_HISTORY = 2;
+
+    private BrowserActivity mBrowserActivity;
+
+    private Bundle mExtras;
+
+    long mCurrentFragment;
+
+    static class IconListenerSet implements IconListener {
+        // Used to store favicons as we get them from the database
+        // FIXME: We use a different method to get the Favicons in
+        // BrowserBookmarksAdapter. They should probably be unified.
+        private HashMap<String, Bitmap> mUrlsToIcons;
+        private Vector<IconListener> mListeners;
+
+        public IconListenerSet() {
+            mUrlsToIcons = new HashMap<String, Bitmap>();
+            mListeners = new Vector<IconListener>();
+        }
+        @Override
+        public void onReceivedIcon(String url, Bitmap icon) {
+            mUrlsToIcons.put(url, icon);
+            for (IconListener listener : mListeners) {
+                listener.onReceivedIcon(url, icon);
+            }
+        }
+        public void addListener(IconListener listener) {
+            mListeners.add(listener);
+        }
+        public void removeListener(IconListener listener) {
+            mListeners.remove(listener);
+        }
+        public Bitmap getFavicon(String url) {
+            return mUrlsToIcons.get(url);
+        }
+    }
+
+    private static IconListenerSet sIconListenerSet;
+    static IconListenerSet getIconListenerSet() {
+        if (null == sIconListenerSet) {
+            sIconListenerSet = new IconListenerSet();
+        }
+        return sIconListenerSet;
+    }
+
+    public CombinedBookmarkHistoryView(Context context, int startingFragment, Bundle extras) {
+        super(context);
+        mBrowserActivity = (BrowserActivity) context;
+        mExtras = extras;
+        View v = LayoutInflater.from(context).inflate(R.layout.bookmarks_history, this);
+        Resources res = context.getResources();
+
+//        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
+
+        ListView list = (ListView) findViewById(android.R.id.list);
+        list.setOnItemClickListener(this);
+        MatrixCursor cursor = new MatrixCursor(new String[] { "name", "_id" });
+        cursor.newRow().add(res.getString(R.string.bookmarks)).add(FRAGMENT_ID_BOOKMARKS);
+        cursor.newRow().add(res.getString(R.string.history)).add(FRAGMENT_ID_HISTORY);
+        list.setAdapter(new SimpleCursorAdapter(context,
+                android.R.layout.simple_list_item_1, cursor,
+                new String[] { "name" }, new int[] { android.R.id.text1 }));
+
+        // Start up the default fragment
+        loadFragment(startingFragment, mExtras);
+
+        // XXX: Must do this before launching the AsyncTask to avoid a
+        // potential crash if the icon database has not been created.
+        WebIconDatabase.getInstance();
+
+        // Do this every time the view is created in case a new favicon was
+        // added to the webkit db.
+        (new AsyncTask<Void, Void, Void>() {
+            @Override
+            public Void doInBackground(Void... v) {
+                Browser.requestAllIcons(mBrowserActivity.getContentResolver(),
+                        Browser.BookmarkColumns.FAVICON + " is NULL", getIconListenerSet());
+                return null;
+            }
+        }).execute();
+
+    }
+
+    private void loadFragment(int id, Bundle extras) {
+        String fragmentClassName;
+        Fragment fragment = null;
+        switch (id) {
+            case FRAGMENT_ID_BOOKMARKS:
+                fragment = BrowserBookmarksPage.newInstance(mBrowserActivity, extras);
+                break;
+            case FRAGMENT_ID_HISTORY:
+                fragment = BrowserHistoryPage.newInstance(mBrowserActivity, extras);
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        mCurrentFragment = id;
+
+        FragmentManager fm = mBrowserActivity.getFragmentManager();
+        FragmentTransaction transaction = fm.openTransaction();
+        transaction.replace(R.id.fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        if (id == mCurrentFragment) return;
+        loadFragment((int) id, mExtras);
+    }
+
+}
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 7994d0a..1d970ea 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -35,16 +35,11 @@
         Bundle extras = new Bundle();
         extras.putBoolean(BrowserBookmarksPage.EXTRA_SHORTCUT, true);
         extras.putBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW, true);
-        Fragment frag = Fragment.instantiate(this, BrowserBookmarksPage.class.getName(), extras);
+        Fragment frag = BrowserBookmarksPage.newInstance(this, extras);
         transaction.add(android.R.id.content, frag);
         transaction.commit();
     }
 
-    /**
-     * not used for shortcuts
-     */
-    @Override
-    public void onRemoveParentChildRelationShips() {}
 
     /**
      * handle fragment startActivity
@@ -60,6 +55,20 @@
         super.finish();
     }
 
+    // BookmarksHistoryCallbacks
+
+    /**
+     * not used for shortcuts
+     */
+    @Override
+    public void onRemoveParentChildRelationships() {}
+
+    @Override
+    public void onComboCanceled() {
+        setResult(RESULT_CANCELED);
+        finish();
+    }
+
     /**
      * not used for shortcuts
      */
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index dc42428..5e02f2d 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -496,10 +496,7 @@
             }
 
             // update the bookmark database for favicon
-            if (favicon != null) {
-                Bookmarks.updateFavicon(mActivity
-                        .getContentResolver(), null, url, favicon);
-            }
+            maybeUpdateFavicon(null, url, favicon);
 
             // reset sync timer to avoid sync starts during loading a page
             CookieSyncManager.getInstance().resetSync();
@@ -523,13 +520,15 @@
                     url, SystemClock.uptimeMillis() - mLoadStartTime);
             mInLoad = false;
 
-            if (mInForeground && !mActivity.didUserStopLoading()
-                    || !mInForeground) {
-                // Only update the bookmark screenshot if the user did not
-                // cancel the load early.
-                mActivity.postMessage(
-                        BrowserActivity.UPDATE_BOOKMARK_THUMBNAIL, 0, 0, view,
-                        500);
+            if (!isPrivateBrowsingEnabled()) {
+                if (mInForeground && !mActivity.didUserStopLoading()
+                        || !mInForeground) {
+                    // Only update the bookmark screenshot if the user did not
+                    // cancel the load early.
+                    mActivity.postMessage(
+                            BrowserActivity.UPDATE_BOOKMARK_THUMBNAIL, 0, 0, view,
+                            500);
+                }
             }
 
             // finally update the UI in the activity if it is in the foreground
@@ -600,7 +599,7 @@
             }
 
             // Don't log URLs when in private browsing mode
-            if (!getWebView().isPrivateBrowsingEnabled()) {
+            if (!isPrivateBrowsingEnabled()) {
                 Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
                         + " " + description);
             }
@@ -674,7 +673,7 @@
         public void doUpdateVisitedHistory(WebView view, String url,
                 boolean isReload) {
             // Don't save anything in private browsing mode
-            if (getWebView().isPrivateBrowsingEnabled()) return;
+            if (isPrivateBrowsingEnabled()) return;
 
             if (url.regionMatches(true, 0, "about:", 0, 6)) {
                 return;
@@ -994,7 +993,7 @@
             }
 
             // Update the title in the history database if not in private browsing mode
-            if (!getWebView().isPrivateBrowsingEnabled()) {
+            if (!isPrivateBrowsingEnabled()) {
                 new AsyncTask<Void, Void, Void>() {
                     @Override
                     protected Void doInBackground(Void... unused) {
@@ -1034,11 +1033,8 @@
 
         @Override
         public void onReceivedIcon(WebView view, Bitmap icon) {
-            if (icon != null) {
-                Bookmarks.updateFavicon(mActivity
-                        .getContentResolver(), view.getOriginalUrl(), view
-                        .getUrl(), icon);
-            }
+            maybeUpdateFavicon(view.getOriginalUrl(), view.getUrl(), icon);
+
             if (mInForeground) {
                 mActivity.setFavicon(icon);
             }
@@ -1158,7 +1154,7 @@
             }
 
             // Don't log console messages in private browsing mode
-            if (getWebView().isPrivateBrowsingEnabled()) return true;
+            if (isPrivateBrowsingEnabled()) return true;
 
             String message = "Console: " + consoleMessage.message() + " "
                     + consoleMessage.sourceId() +  ":"
@@ -1696,6 +1692,19 @@
     }
 
     /**
+     * Return whether private browsing is enabled for the main window of
+     * this tab.
+     * @return True if private browsing is enabled.
+     */
+    private boolean isPrivateBrowsingEnabled() {
+        WebView webView = getWebView();
+        if (webView == null) {
+            return false;
+        }
+        return webView.isPrivateBrowsingEnabled();
+    }
+
+    /**
      * Return the subwindow of this tab or null if there is no subwindow.
      * @return The subwindow of this tab or null.
      */
@@ -1783,6 +1792,20 @@
         return null;
     }
 
+    /*
+     * Update the favorites icon if the private browsing isn't enabled and the
+     * icon is valid.
+     */
+    void maybeUpdateFavicon(final String originalUrl, final String url, Bitmap favicon) {
+        if (favicon == null) {
+            return;
+        }
+        if (!isPrivateBrowsingEnabled()) {
+            Bookmarks.updateFavicon(mActivity
+                    .getContentResolver(), originalUrl, url, favicon);
+        }
+    }
+
     /**
      * Return the tab's error console. Creates the console if createIfNEcessary
      * is true and we haven't already created the console.
diff --git a/src/com/android/browser/TabBar.java b/src/com/android/browser/TabBar.java
index 9217ef2..696301e 100644
--- a/src/com/android/browser/TabBar.java
+++ b/src/com/android/browser/TabBar.java
@@ -121,6 +121,7 @@
     }
 
     public void onClick(View view) {
+        mBrowserActivity.removeComboView();
         if (mNewTab == view) {
             mBrowserActivity.openTabToHomePage();
         } else if (mTabs.getSelectedTab() == view) {
diff --git a/src/com/android/browser/TabScrollView.java b/src/com/android/browser/TabScrollView.java
index dc21cb6..0d85920 100644
--- a/src/com/android/browser/TabScrollView.java
+++ b/src/com/android/browser/TabScrollView.java
@@ -1,26 +1,31 @@
 /*
  * Copyright (C) 2010 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
+ * 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
+ * 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.
+ * 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.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.animation.AccelerateInterpolator;
 import android.widget.HorizontalScrollView;
 import android.widget.LinearLayout;
 
@@ -34,6 +39,7 @@
     private int mSelected;
     private Drawable mArrowLeft;
     private Drawable mArrowRight;
+    private int mAnimationDuration;
 
     /**
      * @param context
@@ -63,16 +69,20 @@
     }
 
     private void init(Context ctx) {
-        mBrowserActivity = (BrowserActivity)ctx;
+        mBrowserActivity = (BrowserActivity) ctx;
+        mAnimationDuration = ctx.getResources().getInteger(
+                R.integer.tab_animation_duration);
         setHorizontalScrollBarEnabled(false);
         mContentView = new LinearLayout(mBrowserActivity);
         mContentView.setOrientation(LinearLayout.HORIZONTAL);
-        mContentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
-                LayoutParams.MATCH_PARENT));
+        mContentView.setLayoutParams(
+                new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
         addView(mContentView);
         mSelected = -1;
         mArrowLeft = ctx.getResources().getDrawable(R.drawable.ic_arrow_left);
         mArrowRight = ctx.getResources().getDrawable(R.drawable.ic_arrow_right);
+        // prevent ProGuard from removing the property methods
+        setScroll(getScroll());
     }
 
     @Override
@@ -112,6 +122,7 @@
 
     void addTab(View tab) {
         mContentView.addView(tab);
+        animateIn(tab);
         tab.setActivated(false);
     }
 
@@ -122,10 +133,10 @@
         } else if (ix < mSelected) {
             mSelected--;
         }
-        mContentView.removeView(tab);
+        animateOut(tab);
     }
 
-    void ensureChildVisible(View child) {
+    private void ensureChildVisible(View child) {
         if (child != null) {
             int childl = child.getLeft();
             int childr = childl + child.getWidth();
@@ -133,10 +144,10 @@
             int viewr = viewl + getWidth();
             if (childl < viewl) {
                 // need scrolling to left
-                scrollTo(childl, 0);
+                animateScroll(childl);
             } else if (childr > viewr) {
                 // need scrolling to right
-                scrollTo(childr - viewr + viewl, 0);
+                animateScroll(childr - viewr + viewl);
             }
         }
     }
@@ -159,4 +170,60 @@
         }
     }
 
+    private void animateIn(View tab) {
+        ObjectAnimator animator = new ObjectAnimator<PropertyValuesHolder>(
+                mAnimationDuration, tab,
+                new PropertyValuesHolder<Integer>("TranslationX", 500, 0));
+        animator.start();
+    }
+
+    private void animateOut(final View tab) {
+        ObjectAnimator animator = new ObjectAnimator<PropertyValuesHolder>(
+                mAnimationDuration, tab,
+                new PropertyValuesHolder<Integer>("TranslationX", 0,
+                        getScrollX() - tab.getRight()));
+        animator.addListener(new AnimatorListener() {
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mContentView.removeView(tab);
+            }
+
+            @Override
+            public void onAnimationRepeat(Animator animation) {
+            }
+
+            @Override
+            public void onAnimationStart(Animator animation) {
+            }
+        });
+        animator.setInterpolator(new AccelerateInterpolator());
+        animator.start();
+    }
+
+    private void animateScroll(int newscroll) {
+        ObjectAnimator animator = new ObjectAnimator<PropertyValuesHolder>(
+                mAnimationDuration, this,
+                new PropertyValuesHolder<Integer>("scroll", getScrollX(), newscroll));
+        animator.start();
+    }
+
+    /**
+     * required for animation
+     */
+    public void setScroll(int newscroll) {
+        scrollTo(newscroll, getScrollY());
+    }
+
+    /**
+     * required for animation
+     */
+    public int getScroll() {
+        return getScrollX();
+    }
+
 }
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index b652e15..57098a9 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -126,7 +126,7 @@
         } else if (mStar == v) {
             mBrowserActivity.promptAddOrInstallBookmark(mStar);
         } else if (mAllButton == v) {
-            mBrowserActivity.bookmarksOrHistoryPicker(false, false);
+            mBrowserActivity.bookmarksOrHistoryPicker(false);
         } else if (mSearchButton == v) {
             search();
         } else if (mStopButton == v) {
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 8662f55..daf879f 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -88,11 +88,16 @@
     @Override
     public void showDropDown() {
         int width = mContainer.getWidth();
-        if ((mAdapter.getLeftCount() == 0) || (mAdapter.getRightCount() == 0)) {
+        if (mLandscape && ((mAdapter.getLeftCount() == 0) ||
+                (mAdapter.getRightCount() == 0))) {
             width = width / 2;
         }
-        setDropDownWidth(width);
-        setDropDownHorizontalOffset(-getLeft());
+        if (width != getDropDownWidth()) {
+            setDropDownWidth(width);
+        }
+        if (getLeft() != -getDropDownHorizontalOffset()) {
+            setDropDownHorizontalOffset(-getLeft());
+        }
         mAdapter.setLandscapeMode(mLandscape);
         super.showDropDown();
     }
diff --git a/src/com/android/browser/preferences/PersonalPreferencesFragment.java b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
index 12751c5..656d47a 100644
--- a/src/com/android/browser/preferences/PersonalPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
@@ -17,6 +17,7 @@
 package com.android.browser.preferences;
 
 import com.android.browser.BrowserBookmarksPage;
+import com.android.browser.BrowserSettings;
 import com.android.browser.R;
 
 import android.accounts.Account;
@@ -39,6 +40,7 @@
 import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
 import android.provider.BrowserContract;
 import android.provider.BrowserContract.Bookmarks;
 import android.provider.BrowserContract.ChromeSyncColumns;
@@ -83,7 +85,9 @@
         Account[] accounts = am.getAccountsByType("com.google");
         if (accounts == null || accounts.length == 0) {
             // No Google accounts setup, don't offer Chrome sync
-            getPreferenceScreen().removePreference(mChromeSync);
+            if (mChromeSync != null) {
+                getPreferenceScreen().removePreference(mChromeSync);
+            }
         } else {
             SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
             Bundle args = mChromeSync.getExtras();
@@ -101,6 +105,10 @@
             }
             mChromeSync.setOnPreferenceClickListener(this);
         }
+
+        PreferenceScreen autoFillSettings =
+                (PreferenceScreen)findPreference(BrowserSettings.PREF_AUTOFILL_PROFILE);
+        autoFillSettings.setDependency(BrowserSettings.PREF_AUTOFILL_ENABLED);
     }
 
     @Override
diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java
index b73927a..a7545d4 100644
--- a/src/com/android/browser/provider/BrowserProvider2.java
+++ b/src/com/android/browser/provider/BrowserProvider2.java
@@ -618,7 +618,12 @@
                             };
                 }
 
-                return db.rawQuery(query, args);
+                Cursor cursor = db.rawQuery(query, args);
+                if (cursor != null) {
+                    cursor.setNotificationUri(getContext().getContentResolver(),
+                            BrowserContract.AUTHORITY_URI);
+                }
+                return cursor;
             }
 
             case HISTORY_ID: {