Merge "Fixes cutoff in url suggestions"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9fea44a..b653461 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -39,7 +39,7 @@
 
     <application   android:name="Browser"
                    android:label="@string/application_name"
-                   android:icon="@drawable/ic_launcher_browser"
+                   android:icon="@mipmap/ic_launcher_browser"
                    android:backupAgent=".BrowserBackupAgent"
                    android:hardwareAccelerated="false"
                    android:taskAffinity="android.task.browser" >
@@ -147,7 +147,7 @@
         <activity android:name="ShortcutActivity"
             android:theme="@style/ShortcutTheme"
             android:label="@string/shortcut_bookmark"
-            android:icon="@drawable/ic_launcher_shortcut_browser_bookmark">
+            android:icon="@mipmap/ic_launcher_shortcut_browser_bookmark">
 
             <intent-filter>
                 <action android:name="android.intent.action.CREATE_SHORTCUT" />
diff --git a/res/drawable/preview.png b/res/drawable/preview.png
index f05710f..b363ab5 100644
--- a/res/drawable/preview.png
+++ b/res/drawable/preview.png
Binary files differ
diff --git a/res/layout/bookmark_list.xml b/res/layout/bookmark_list.xml
new file mode 100644
index 0000000..720685b
--- /dev/null
+++ b/res/layout/bookmark_list.xml
@@ -0,0 +1,41 @@
+<?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:id="@+id/list_item"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minHeight="@dimen/widgetItemMinHeight"
+    android:orientation="horizontal"
+    android:padding="8dip">
+    <ImageView
+        android:id="@+id/favicon"
+        android:layout_height="24dp"
+        android:layout_width="24dp"
+        android:layout_gravity="center_vertical"
+        android:scaleType="fitXY"/>
+    <TextView
+        android:id="@+id/label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:padding="8dip"
+        android:maxLines="1"
+        android:scrollHorizontally="true"
+        android:ellipsize="marquee"/>
+</LinearLayout>
diff --git a/res/layout/bookmarklistwidget.xml b/res/layout/bookmarklistwidget.xml
index 983854c..17aee1d 100644
--- a/res/layout/bookmarklistwidget.xml
+++ b/res/layout/bookmarklistwidget.xml
@@ -33,7 +33,7 @@
             android:id="@+id/logo"
             android:layout_width="32dp"
             android:layout_height="32dp"
-            android:src="@drawable/ic_launcher_browser" />
+            android:src="@mipmap/ic_launcher_browser" />
         <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml
index fa08353..7a0aa23 100644
--- a/res/layout/bookmarks.xml
+++ b/res/layout/bookmarks.xml
@@ -14,29 +14,49 @@
      limitations under the License.
 -->
 
-<FrameLayout
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <GridView
-        android:id="@+id/grid"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <FrameLayout
+        android:id="@+id/header_container"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:horizontalSpacing="16dip"
-        android:verticalSpacing="16dip"
-        android:stretchMode="spacingWidth"
-        android:scrollbarStyle="insideInset"
-        android:listSelector="@android:drawable/gallery_thumb"
-        android:drawSelectorOnTop="true"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
-        android:numColumns="auto_fit" />
-    <TextView
-        android:id="@android:id/empty"
-        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:text="@string/empty_bookmarks_folder"
         android:visibility="gone" />
-</FrameLayout>
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <GridView
+            android:id="@+id/grid"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:horizontalSpacing="16dip"
+            android:verticalSpacing="16dip"
+            android:stretchMode="spacingWidth"
+            android:scrollbarStyle="insideInset"
+            android:listSelector="@android:drawable/gallery_thumb"
+            android:drawSelectorOnTop="true"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:numColumns="auto_fit" />
+        <ListView
+            android:id="@+id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:visibility="gone"/>
+        <TextView
+            android:id="@android:id/empty"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:text="@string/empty_bookmarks_folder"
+            android:visibility="gone" />
+    </FrameLayout>
+
+</LinearLayout>
diff --git a/res/layout/bookmarks_header.xml b/res/layout/bookmarks_header.xml
new file mode 100644
index 0000000..597e629
--- /dev/null
+++ b/res/layout/bookmarks_header.xml
@@ -0,0 +1,49 @@
+<?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="48dip"
+    android:orientation="horizontal">
+
+    <TextView
+        android:id="@+id/root_folder"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:text="@string/defaultBookmarksUpButton"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:gravity="center_vertical"
+        android:visibility="gone"
+        android:paddingLeft="16dip"
+        android:drawableLeft="@drawable/ic_tab_bookmarks_selected"
+        android:drawablePadding="16dip" />
+
+    <com.android.browser.BreadCrumbView
+        android:id="@+id/crumbs"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:paddingLeft="16dip" />
+
+    <TextView
+        android:id="@+id/select_bookmark_view"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:text="@string/switch_to_thumbnails"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:gravity="center_vertical" />
+
+</LinearLayout>
diff --git a/res/layout/bookmarks_history.xml b/res/layout/bookmarks_history.xml
index a89a2b9..a3a5084 100644
--- a/res/layout/bookmarks_history.xml
+++ b/res/layout/bookmarks_history.xml
@@ -22,16 +22,14 @@
     android:paddingRight="16dip"
     android:orientation="vertical"
     android:background="@color/black">
-    <RelativeLayout
-        android:id="@+id/bar"
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="48dip">
+
         <LinearLayout
             android:id="@+id/tabs"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip">
+            android:layout_height="match_parent">
             <TextView
                 android:id="@+id/historytab"
                 android:layout_width="wrap_content"
@@ -58,25 +56,34 @@
                 android:text="@string/bookmarks"
                 android:drawableLeft="@drawable/ic_tab_bookmarks_selected"
                 android:drawablePadding="16dip" />
-            <com.android.browser.BreadCrumbView
-                android:id="@+id/crumbs"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:paddingLeft="16dip"
-                android:paddingRight="16dip" />
         </LinearLayout>
+
+        <FrameLayout
+            android:id="@+id/header_container"
+            android:layout_width="0dip"
+            android:layout_weight="1"
+            android:layout_height="match_parent" />
+
+        <ImageView
+            android:id="@+id/seperate_select_add"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingRight="16dip"
+            android:paddingLeft="16dip"
+            android:src="@drawable/divider_vert" />
+
         <TextView
             android:id="@+id/addbm"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:text="@string/add_new_bookmark"
-            android:layout_alignParentRight="true"
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:gravity="center_vertical"
             android:background="@null"
             android:drawableLeft="@drawable/ic_favorite_off_normal"
             android:drawablePadding="16dip" />
-    </RelativeLayout>
+
+    </LinearLayout>
     <FrameLayout
         android:id="@+id/fragment"
         android:paddingTop="8dip"
diff --git a/res/layout/browser_subwindow.xml b/res/layout/browser_subwindow.xml
index adf3284..a3868cd 100644
--- a/res/layout/browser_subwindow.xml
+++ b/res/layout/browser_subwindow.xml
@@ -28,12 +28,6 @@
             android:layout_height="match_parent"
             android:orientation="vertical"
             android:background="@android:drawable/dialog_frame" >
-            <WebView android:id="@+id/webview"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:fadeScrollbars="true"
-                android:scrollbarStyle="outsideOverlay"
-                android:layout_weight="1" />
         </LinearLayout>
     </FrameLayout>
     <LinearLayout
diff --git a/res/layout/suggestion_two_column.xml b/res/layout/suggestion_two_column.xml
index fc74140..cc4f2e2 100644
--- a/res/layout/suggestion_two_column.xml
+++ b/res/layout/suggestion_two_column.xml
@@ -27,18 +27,21 @@
     android:baselineAligned="false">
     <include
         android:id="@+id/suggest1"
-        layout="@layout/suggestion_item"
+        android:layout_height="56dip"
         android:layout_width="0dip"
         android:layout_weight="1"
+        layout="@layout/suggestion_item"
     />
     <ImageView
+      android:id="@+id/suggestion_divider"
       android:layout_width="wrap_content"
       android:layout_height="56dip"
       android:background="@drawable/list_divider_vert" />
     <include
         android:id="@+id/suggest2"
-        layout="@layout/suggestion_item"
+        android:layout_height="56dip"
         android:layout_width="0dip"
         android:layout_weight="1"
+        layout="@layout/suggestion_item"
     />
 </LinearLayout>
diff --git a/res/menu/bookmark_view.xml b/res/menu/bookmark_view.xml
new file mode 100644
index 0000000..fdfd672
--- /dev/null
+++ b/res/menu/bookmark_view.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/thumbnail_view"
+        android:title="@string/bookmark_thumbnail_view"/>
+    <item android:id="@+id/list_view"
+        android:title="@string/bookmark_list_view"/>
+</menu>
diff --git a/res/menu/browsercontext.xml b/res/menu/browsercontext.xml
index 70cf8d4..f5361d5 100644
--- a/res/menu/browsercontext.xml
+++ b/res/menu/browsercontext.xml
@@ -57,5 +57,9 @@
         <item android:id="@+id/set_wallpaper_context_menu_id"
             android:title="@string/contextmenu_set_wallpaper"/>
     </group>
+    <group android:id="@+id/SELECT_TEXT_MENU">
+        <item android:id="@+id/select_text_menu_id"
+            android:title="@string/select_dot"/>
+    </group>
 </menu>
  
diff --git a/res/drawable-hdpi/ic_launcher_browser.png b/res/mipmap-hdpi/ic_launcher_browser.png
similarity index 100%
rename from res/drawable-hdpi/ic_launcher_browser.png
rename to res/mipmap-hdpi/ic_launcher_browser.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png b/res/mipmap-hdpi/ic_launcher_shortcut_browser_bookmark.png
similarity index 100%
rename from res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png
rename to res/mipmap-hdpi/ic_launcher_shortcut_browser_bookmark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_browser.png b/res/mipmap-mdpi/ic_launcher_browser.png
similarity index 100%
rename from res/drawable-mdpi/ic_launcher_browser.png
rename to res/mipmap-mdpi/ic_launcher_browser.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png b/res/mipmap-mdpi/ic_launcher_shortcut_browser_bookmark.png
similarity index 100%
rename from res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png
rename to res/mipmap-mdpi/ic_launcher_shortcut_browser_bookmark.png
Binary files differ
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 4e029b1..2864d47 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -13,7 +13,7 @@
 <resources
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- The number of lines in the suggestions dropdown in landscape -->
-    <integer name="max_suggest_lines_landscape">6</integer>
+    <integer name="max_suggest_lines_landscape">4</integer>
     <!-- The number of lines in the suggestions dropdown in portrait -->
     <integer name="max_suggest_lines_portrait">12</integer>
     <!--  The maximum number of open tabs -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d724085..7d27dec 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -75,6 +75,9 @@
     <!-- Label for a button on an SSL error dialog that lets the user view the
         certificate -->
     <string name="view_certificate">View certificate</string>
+    <!-- Label for a button on an SSL error dialog that lets the user go back to
+         the last page they were on instead of continuing to the new page. [CHAR-LIMIT=20] -->
+    <string name="ssl_go_back">Go back</string>
 
     <!-- Message in an SSL Error dialog -->
     <string name="ssl_untrusted">This certificate is not from a trusted authority.</string>
@@ -181,11 +184,11 @@
             showing. -->
     <string name="bookmark_page">Bookmark last-viewed page</string>
     <!-- Menu item in the page that displays all bookmarks.  Switches to
-            a grid view which shows thumbnails -->
-    <string name="switch_to_thumbnails">Thumbnail view</string>
+            a grid view which shows thumbnails [CHAR LIMIT=50] -->
+    <string name="bookmark_thumbnail_view">Thumbnail view</string>
     <!-- Menu item in the page that displays all bookmarks.  Switches to a
-            list view which shows titles -->
-    <string name="switch_to_list">List view</string>
+            list view which shows titles [CHAR LIMIT=50] -->
+    <string name="bookmark_list_view">List view</string>
     <!-- Summary text under the New Bookmark item on the Bookmarks screen.
             Tells the user that if they select this item, it will bring up a
             dialog to bookmark the page that the browser is currently viewing,
@@ -393,6 +396,12 @@
     <!-- Button text to delete all the AutoFill profile data [CHAR-LIMIT=20] -->
     <string name="autofill_profile_editor_delete_profile">Delete profile data</string>
 
+    <!-- Text on a dialog shown to the user when they are prompted to set up the autofill feature [CHAR-LIMIT=NONE] -->
+    <string name="autofill_setup_dialog_message">Browser can automatically complete web forms like this one. Would you like to set up your profile?</string>
+    <!-- Toast message displayed when the user decides to not set up autofill at this time. We want to remind them that they can configure
+         it through the Browser Settings menu. [CHAR-LIMIT=NONE] -->
+    <string name="autofill_setup_dialog_negative_toast">AutoFill can always be configured through Browser Settings -&gt; Personal Settings.</string>
+
     <!-- Settings screen, section title -->
     <string name="pref_privacy_title">Privacy settings</string>
     <!-- Settings label -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a1ca842..1a4ee2d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,7 +32,7 @@
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowContentOverlay">@null</item>
     </style>
-    <style name="ShortcutTheme" parent="@android:Theme.Black">
+    <style name="ShortcutTheme" parent="@android:Theme.Holo.DialogWhenLarge">
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowContentOverlay">@null</item>
     </style>
diff --git a/res/xml/browser_preferences.xml b/res/xml/browser_preferences.xml
index 623c8e7..a2d91ff 100644
--- a/res/xml/browser_preferences.xml
+++ b/res/xml/browser_preferences.xml
@@ -135,7 +135,7 @@
 
         <CheckBoxPreference
                 android:key="autofill_enabled"
-                android:defaultValue="false"
+                android:defaultValue="true"
                 android:title="@string/pref_autofill_enabled"
                 android:summary="@string/pref_autofill_enabled_summary" />
 
diff --git a/res/xml/personal_preferences.xml b/res/xml/personal_preferences.xml
index 939d14c..30ebae2 100644
--- a/res/xml/personal_preferences.xml
+++ b/res/xml/personal_preferences.xml
@@ -24,6 +24,7 @@
     <CheckBoxPreference android:key="autofill_enabled"
         android:title="@string/pref_autofill_enabled"
         android:summary="@string/pref_autofill_enabled_summary"
+        android:defaultValue="true"
     />
 
     <PreferenceScreen
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 2a23bb1..5f8944f 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -34,12 +34,15 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 import android.webkit.WebChromeClient;
 import android.webkit.WebHistoryItem;
 import android.webkit.WebView;
 import android.widget.FrameLayout;
+import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.Toast;
 
@@ -164,6 +167,16 @@
         return w;
     }
 
+    @Override
+    public WebView createSubWebView(boolean privateBrowsing) {
+        ScrollWebView web = (ScrollWebView) createWebView(privateBrowsing);
+        if (mXLargeScreenSize) {
+            // no scroll listener for subview
+            web.setScrollListener(null);
+        }
+        return web;
+    }
+
     void stopWebViewScrolling() {
         ScrollWebView web = (ScrollWebView) mUiController.getCurrentWebView();
         if (web != null) {
@@ -415,6 +428,33 @@
     }
 
     /**
+     * create a sub window container and webview for the tab
+     * Note: this methods operates through side-effects for now
+     * it sets both the subView and subViewContainer for the given tab
+     * @param tab tab to create the sub window for
+     * @param subView webview to be set as a subwindow for the tab
+     */
+    @Override
+    public void createSubWindow(Tab tab, WebView subView) {
+        View subViewContainer = mActivity.getLayoutInflater().inflate(
+                R.layout.browser_subwindow, null);
+        ViewGroup inner = (ViewGroup) subViewContainer
+                .findViewById(R.id.inner_container);
+        inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT));
+        final ImageButton cancel = (ImageButton) subViewContainer
+                .findViewById(R.id.subwindow_close);
+        final WebView cancelSubView = subView;
+        cancel.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                cancelSubView.getWebChromeClient().onCloseWindow(cancelSubView);
+            }
+        });
+        tab.setSubWebView(subView);
+        tab.setSubViewContainer(subViewContainer);
+    }
+
+    /**
      * Remove the sub window from the content view.
      */
     @Override
@@ -428,6 +468,10 @@
      */
     @Override
     public void attachSubWindow(View container) {
+        if (container.getParent() != null) {
+            // already attached, remove first
+            ((ViewGroup) container.getParent()).removeView(container);
+        }
         mContentView.addView(container, COVER_SCREEN_PARAMS);
     }
 
diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java
index 0fdad15..751c0b3 100644
--- a/src/com/android/browser/BookmarkUtils.java
+++ b/src/com/android/browser/BookmarkUtils.java
@@ -105,12 +105,12 @@
             // Want to create a shortcut icon on the homescreen, so the icon
             // background is the red bookmark.
             return BitmapFactory.decodeResource(context.getResources(),
-                    R.drawable.ic_launcher_shortcut_browser_bookmark);
+                    R.mipmap.ic_launcher_shortcut_browser_bookmark);
         } else if (type == BookmarkIconType.ICON_INSTALLABLE_WEB_APP) {
             // Use the web browser icon as the background for the icon for an installable
             // web app.
             return BitmapFactory.decodeResource(context.getResources(),
-                    R.drawable.ic_launcher_browser);
+                    R.mipmap.ic_launcher_browser);
         }
         return null;
     }
diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java
index a5d51dd..f587f01 100644
--- a/src/com/android/browser/BrowserBookmarksAdapter.java
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -20,42 +20,102 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CursorAdapter;
 import android.widget.ImageView;
-import android.widget.ResourceCursorAdapter;
 import android.widget.TextView;
 
-class BrowserBookmarksAdapter extends ResourceCursorAdapter {
+class BrowserBookmarksAdapter extends CursorAdapter {
+    LayoutInflater mInflater;
+    int mCurrentView;
+
     /**
      *  Create a new BrowserBookmarksAdapter.
      */
-    public BrowserBookmarksAdapter(Context context) {
+    public BrowserBookmarksAdapter(Context context, int defaultView) {
         // Make sure to tell the CursorAdapter to avoid the observer and auto-requery
         // since the Loader will do that for us.
-        super(context, R.layout.bookmark_thumbnail, null);
+        super(context, null);
+        mInflater = LayoutInflater.from(context);
+        selectView(defaultView);
     }
 
     @Override
     public void bindView(View view, Context context, Cursor cursor) {
+        if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
+            bindListView(view, context, cursor);
+        } else {
+            bindGridView(view, context, cursor);
+        }
+    }
+
+    void bindGridView(View view, Context context, Cursor cursor) {
         ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
         TextView tv = (TextView) view.findViewById(R.id.label);
 
         tv.setText(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
-        Bitmap thumbnail = null;
         if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0) {
             // folder
             thumb.setImageResource(R.drawable.ic_folder);
         } else {
-            byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_THUMBNAIL);
-            if (data != null) {
-                thumbnail = BitmapFactory.decodeByteArray(data, 0, data.length);
+            byte[] thumbData = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_THUMBNAIL);
+            Bitmap thumbBitmap = null;
+            if (thumbData != null) {
+                thumbBitmap = BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length);
             }
 
-            if (thumbnail == null) {
+            if (thumbBitmap == null) {
                 thumb.setImageResource(R.drawable.browser_thumbnail);
             } else {
-                thumb.setImageBitmap(thumbnail);
+                thumb.setImageBitmap(thumbBitmap);
             }
         }
     }
+
+    void bindListView(View view, Context context, Cursor cursor) {
+        ImageView favicon = (ImageView) view.findViewById(R.id.favicon);
+        TextView tv = (TextView) view.findViewById(R.id.label);
+
+        tv.setText(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
+        if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0) {
+            // folder
+            favicon.setImageResource(R.drawable.ic_folder);
+        } else {
+            byte[] faviconData = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
+            Bitmap faviconBitmap = null;
+            if (faviconData != null) {
+                faviconBitmap = BitmapFactory.decodeByteArray(faviconData, 0, faviconData.length);
+            }
+
+            if (faviconBitmap == null) {
+                favicon.setImageResource(R.drawable.app_web_browser_sm);
+            } else {
+                favicon.setImageBitmap(faviconBitmap);
+            }
+        }
+    }
+
+    @Override
+    public View newView(Context context, Cursor cursor, ViewGroup parent) {
+        if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
+            return mInflater.inflate(R.layout.bookmark_list, parent, false);
+        } else {
+            return mInflater.inflate(R.layout.bookmark_thumbnail, parent, false);
+        }
+    }
+
+    public void selectView(int view) {
+        if (view != BrowserBookmarksPage.VIEW_LIST
+                && view != BrowserBookmarksPage.VIEW_THUMBNAILS) {
+            throw new IllegalArgumentException("Unknown view specified: " + view);
+        }
+        mCurrentView = view;
+    }
+
+    @Override
+    public Cursor getItem(int position) {
+        return (Cursor) super.getItem(position);
+    }
 }
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index c7392cc..4370885 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -31,6 +31,7 @@
 import android.content.Intent;
 import android.content.Loader;
 import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -46,6 +47,7 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.webkit.WebIconDatabase.IconListener;
 import android.widget.Adapter;
@@ -53,14 +55,25 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.GridView;
+import android.widget.ListView;
+import android.widget.PopupMenu;
+import android.widget.PopupMenu.OnMenuItemClickListener;
+import android.widget.TextView;
 import android.widget.Toast;
 
+interface BookmarksPageCallbacks {
+    // Return true if handled
+    boolean onBookmarkSelected(Cursor c, boolean isFolder);
+    // Return true if handled
+    boolean onOpenInNewWindow(Cursor c);
+}
+
 /**
  *  View showing the user's bookmarks in the browser.
  */
 public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
         LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener,
-        OnItemSelectedListener {
+        OnItemSelectedListener, BreadCrumbView.Controller, OnClickListener, OnMenuItemClickListener {
 
     static final int BOOKMARKS_SAVE = 1;
     static final String LOGTAG = "browser";
@@ -68,7 +81,6 @@
     static final int LOADER_BOOKMARKS = 1;
     static final int LOADER_ACCOUNTS_THEN_BOOKMARKS = 2;
 
-    static final String EXTRA_SHORTCUT = "create_shortcut";
     static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
 
     static final String ACCOUNT_NAME_UNSYNCED = "Unsynced";
@@ -77,24 +89,33 @@
     public static final String PREF_ACCOUNT_NAME = "acct_name";
 
     static final String DEFAULT_ACCOUNT = "local";
+    static final int VIEW_THUMBNAILS = 1;
+    static final int VIEW_LIST = 2;
+    static final String PREF_SELECTED_VIEW = "bookmarks_view";
 
-    BookmarksHistoryCallbacks mCallbacks;
+    BookmarksPageCallbacks mCallbacks;
     GridView mGrid;
+    ListView mList;
     BrowserBookmarksAdapter mAdapter;
     boolean mDisableNewWindow;
     BookmarkItem mContextHeader;
     boolean mCanceled = false;
-    boolean mCreateShortcut;
+    boolean mEnableContextMenu = true;
+    boolean mShowRootFolder = false;
     View mEmptyView;
-
+    int mCurrentView;
+    View mHeader;
+    View mRootFolderView;
+    ViewGroup mHeaderContainer;
     BreadCrumbView mCrumbs;
+    TextView mSelectBookmarkView;
 
-    static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb,
-            BreadCrumbView crumbs, Bundle args) {
+    static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb,
+            Bundle args, ViewGroup headerContainer) {
         BrowserBookmarksPage bbp = new BrowserBookmarksPage();
         bbp.mCallbacks = cb;
+        bbp.mHeaderContainer = headerContainer;
         bbp.setArguments(args);
-        bbp.mCrumbs = crumbs;
         return bbp;
     }
 
@@ -134,9 +155,10 @@
                 if (cursor == null || cursor.getCount() == 0) {
                     mEmptyView.setVisibility(View.VISIBLE);
                     mGrid.setVisibility(View.GONE);
+                    mList.setVisibility(View.GONE);
                 } else {
                     mEmptyView.setVisibility(View.GONE);
-                    mGrid.setVisibility(View.VISIBLE);
+                    setupBookmarkView();
                 }
 
                 // Give the new data to the adapter
@@ -209,7 +231,7 @@
     long getFolderId() {
         LoaderManager manager = getLoaderManager();
         BookmarksLoader loader =
-                (BookmarksLoader) ((Loader)(manager.getLoader(LOADER_BOOKMARKS)));
+                (BookmarksLoader) ((Loader<?>)manager.getLoader(LOADER_BOOKMARKS));
 
         Uri uri = loader.getUri();
         if (uri != null) {
@@ -230,7 +252,7 @@
         }
         LoaderManager manager = getLoaderManager();
         BookmarksLoader loader =
-                (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
+                (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS));
         loader.setUri(uri);
         loader.forceLoad();
 
@@ -259,7 +281,8 @@
             editBookmark(i.position);
             break;
         case R.id.shortcut_context_menu_id:
-            activity.sendBroadcast(createShortcutIntent(i.position));
+            Cursor c = mAdapter.getItem(i.position);
+            activity.sendBroadcast(createShortcutIntent(getActivity(), c));
             break;
         case R.id.delete_context_menu_id:
             displayRemoveBookmarkDialog(i.position);
@@ -268,7 +291,7 @@
             openInNewWindow(i.position);
             break;
         case R.id.share_link_context_menu_id: {
-            Cursor cursor = (Cursor) mAdapter.getItem(i.position);
+            Cursor cursor = mAdapter.getItem(i.position);
             Controller.sharePage(activity,
                     cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
                     cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
@@ -286,7 +309,7 @@
         }
         // Only for the Most visited page
         case R.id.save_to_bookmarks_menu_id: {
-            Cursor cursor = (Cursor) mAdapter.getItem(i.position);
+            Cursor cursor = mAdapter.getItem(i.position);
             String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
             String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
             // If the site is bookmarked, the item becomes remove from
@@ -300,7 +323,7 @@
         return true;
     }
 
-    Bitmap getBitmap(Cursor cursor, int columnIndex) {
+    static Bitmap getBitmap(Cursor cursor, int columnIndex) {
         byte[] data = cursor.getBlob(columnIndex);
         if (data == null) {
             return null;
@@ -311,7 +334,7 @@
     @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
         AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
-        Cursor cursor = (Cursor) mAdapter.getItem(info.position);
+        Cursor cursor = mAdapter.getItem(info.position);
         boolean isFolder
                 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
         if (isFolder) return;
@@ -354,7 +377,6 @@
         super.onCreate(icicle);
 
         Bundle args = getArguments();
-        mCreateShortcut = args == null ? false : args.getBoolean(EXTRA_SHORTCUT, false);
         mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
     }
 
@@ -369,16 +391,36 @@
         mGrid = (GridView) root.findViewById(R.id.grid);
         mGrid.setOnItemClickListener(this);
         mGrid.setColumnWidth(Controller.getDesiredThumbnailWidth(getActivity()));
-        if (!mCreateShortcut) {
-            mGrid.setOnCreateContextMenuListener(this);
-        }
+        mList = (ListView) root.findViewById(R.id.list);
+        mList.setOnItemClickListener(this);
+        setEnableContextMenu(mEnableContextMenu);
 
-        mAdapter = new BrowserBookmarksAdapter(getActivity());
-        mGrid.setAdapter(mAdapter);
+        // Prep the header
+        ViewGroup hc = mHeaderContainer;
+        if (hc == null) {
+            hc = (ViewGroup) root.findViewById(R.id.header_container);
+            hc.setVisibility(View.VISIBLE);
+        }
+        mHeader = inflater.inflate(R.layout.bookmarks_header, hc, true);
+        mCrumbs = (BreadCrumbView) mHeader.findViewById(R.id.crumbs);
+        mCrumbs.setController(this);
+        mSelectBookmarkView = (TextView) mHeader.findViewById(R.id.select_bookmark_view);
+        mSelectBookmarkView.setOnClickListener(this);
+        mRootFolderView = mHeader.findViewById(R.id.root_folder);
+        mRootFolderView.setOnClickListener(this);
+        setShowRootFolder(mShowRootFolder);
 
         // Start the loaders
         LoaderManager lm = getLoaderManager();
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        mCurrentView =
+            prefs.getInt(PREF_SELECTED_VIEW, BrowserBookmarksPage.VIEW_THUMBNAILS);
+        if (mCurrentView == BrowserBookmarksPage.VIEW_THUMBNAILS) {
+            mSelectBookmarkView.setText(R.string.bookmark_thumbnail_view);
+        } else {
+            mSelectBookmarkView.setText(R.string.bookmark_list_view);
+        }
+        mAdapter = new BrowserBookmarksAdapter(getActivity(), mCurrentView);
         String accountType = prefs.getString(PREF_ACCOUNT_TYPE, DEFAULT_ACCOUNT);
         String accountName = prefs.getString(PREF_ACCOUNT_NAME, DEFAULT_ACCOUNT);
         if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) {
@@ -401,6 +443,27 @@
         return root;
     }
 
+    public void setShowRootFolder(boolean show) {
+        mShowRootFolder = show;
+        if (mRootFolderView != null) {
+            if (mShowRootFolder) {
+                mRootFolderView.setVisibility(View.VISIBLE);
+            } else {
+                mRootFolderView.setVisibility(View.GONE);
+            }
+        }
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        if (mHeaderContainer != null) {
+            mHeaderContainer.removeView(mHeader);
+        }
+        mCrumbs.setController(null);
+        mCrumbs = null;
+    }
+
     @Override
     public void onReceivedIcon(String url, Bitmap icon) {
         // A new favicon has been loaded, so let anything attached to the adapter know about it
@@ -409,7 +472,7 @@
     }
 
     @Override
-    public void onItemClick(AdapterView parent, View v, int position, long id) {
+    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
         // It is possible that the view has been canceled when we get to
         // this point as back has a higher priority
         if (mCanceled) {
@@ -417,22 +480,18 @@
             return;
         }
 
-        if (mCreateShortcut) {
-            Intent intent = createShortcutIntent(position);
-            // the activity handles the intent in startActivityFromFragment
-            startActivity(intent);
+        Cursor cursor = mAdapter.getItem(position);
+        boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+        if (mCallbacks != null &&
+                mCallbacks.onBookmarkSelected(cursor, isFolder)) {
             return;
         }
 
-        Cursor cursor = (Cursor) mAdapter.getItem(position);
-        boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
-        if (!isFolder) {
-            mCallbacks.onUrlSelected(getUrl(position), false);
-        } else {
+        if (isFolder) {
             String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
             LoaderManager manager = getLoaderManager();
             BookmarksLoader loader =
-                    (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
+                    (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS));
             Uri uri = ContentUris.withAppendedId(
                     BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
             if (mCrumbs != null) {
@@ -474,26 +533,29 @@
         // Do nothing
     }
 
-    private Intent createShortcutIntent(int position) {
-        Cursor cursor = (Cursor) mAdapter.getItem(position);
+    /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
         String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
         String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
         Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
         Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
-        return BookmarkUtils.createAddToHomeIntent(getActivity(), url, title, touchIcon, favicon);
+        return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
     }
 
     private void loadUrl(int position) {
-        mCallbacks.onUrlSelected(getUrl(position), false);
+        if (mCallbacks != null) {
+            mCallbacks.onBookmarkSelected(mAdapter.getItem(position), false);
+        }
     }
 
     private void openInNewWindow(int position) {
-        mCallbacks.onUrlSelected(getUrl(position), true);
+        if (mCallbacks != null) {
+            mCallbacks.onOpenInNewWindow(mAdapter.getItem(position));
+        }
     }
 
     private void editBookmark(int position) {
         Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
-        Cursor cursor = (Cursor) mAdapter.getItem(position);
+        Cursor cursor = mAdapter.getItem(position);
         Bundle item = new Bundle();
         item.putString(BrowserContract.Bookmarks.TITLE,
                 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
@@ -576,7 +638,7 @@
     private void displayRemoveBookmarkDialog(final int position) {
         // Put up a dialog asking if the user really wants to
         // delete the bookmark
-        Cursor cursor = (Cursor) mAdapter.getItem(position);
+        Cursor cursor = mAdapter.getItem(position);
         Context context = getActivity();
         final ContentResolver resolver = context.getContentResolver();
         final Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
@@ -599,8 +661,11 @@
     }
 
     private String getUrl(int position) {
-        Cursor cursor = (Cursor) mAdapter.getItem(position);
-        return cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
+        return getUrl(mAdapter.getItem(position));
+    }
+
+    /* package */ static String getUrl(Cursor c) {
+        return c.getString(BookmarksLoader.COLUMN_INDEX_URL);
     }
 
     private void copy(CharSequence text) {
@@ -609,4 +674,109 @@
         cm.setPrimaryClip(ClipData.newRawUri(null, null, Uri.parse(text.toString())));
     }
 
+    void selectView(int view) {
+        if (view == mCurrentView) {
+            return;
+        }
+        mCurrentView = view;
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+        Editor edit = prefs.edit();
+        edit.putInt(PREF_SELECTED_VIEW, mCurrentView);
+        edit.apply();
+        if (mEmptyView.getVisibility() == View.VISIBLE) {
+            return;
+        }
+        setupBookmarkView();
+    }
+
+    private void setupBookmarkView() {
+        mAdapter.selectView(mCurrentView);
+        switch (mCurrentView) {
+        case VIEW_THUMBNAILS:
+            mList.setAdapter(null);
+            mGrid.setAdapter(mAdapter);
+            mGrid.setVisibility(View.VISIBLE);
+            mList.setVisibility(View.GONE);
+            break;
+        case VIEW_LIST:
+            mGrid.setAdapter(null);
+            mList.setAdapter(mAdapter);
+            mGrid.setVisibility(View.GONE);
+            mList.setVisibility(View.VISIBLE);
+            break;
+        }
+    }
+
+    public BreadCrumbView getBreadCrumb() {
+        return mCrumbs;
+    }
+
+    /**
+     * BreadCrumb controller callback
+     */
+    @Override
+    public void onTop(int level, Object data) {
+        onFolderChange(level, data);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (mSelectBookmarkView == view) {
+            PopupMenu popup = new PopupMenu(getActivity(), mSelectBookmarkView);
+            popup.getMenuInflater().inflate(R.menu.bookmark_view,
+                    popup.getMenu());
+            popup.setOnMenuItemClickListener(this);
+            popup.show();
+        } else if (mRootFolderView == view) {
+            mCrumbs.clear();
+        }
+    }
+
+    @Override
+    public boolean onMenuItemClick(MenuItem item) {
+        switch (item.getItemId()) {
+        case R.id.list_view:
+            mSelectBookmarkView.setText(R.string.bookmark_list_view);
+            selectView(BrowserBookmarksPage.VIEW_LIST);
+            return true;
+        case R.id.thumbnail_view:
+            mSelectBookmarkView.setText(R.string.bookmark_thumbnail_view);
+            selectView(BrowserBookmarksPage.VIEW_THUMBNAILS);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean onBackPressed() {
+        if (mCrumbs != null &&
+                mCrumbs.size() > 0) {
+            mCrumbs.popView();
+            return true;
+        }
+        return false;
+    }
+
+    public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
+        mCallbacks = callbackListener;
+    }
+
+    public void setEnableContextMenu(boolean enable) {
+        mEnableContextMenu = enable;
+        if (mGrid != null) {
+            if (mEnableContextMenu) {
+                registerForContextMenu(mGrid);
+            } else {
+                unregisterForContextMenu(mGrid);
+                mGrid.setLongClickable(false);
+            }
+        }
+        if (mList != null) {
+            if (mEnableContextMenu) {
+                registerForContextMenu(mList);
+            } else {
+                unregisterForContextMenu(mList);
+                mList.setLongClickable(false);
+            }
+        }
+    }
 }
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 069f886..1229e4b 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -567,6 +567,13 @@
         ed.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.
@@ -716,7 +723,7 @@
         showSecurityWarnings = true;
         rememberPasswords = true;
         saveFormData = true;
-        autoFillEnabled = false;
+        autoFillEnabled = true;
         openInBackground = false;
         autoFitPage = true;
         loadsPageInOverviewMode = true;
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
index c078b51..15f31f6 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -22,6 +22,7 @@
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.res.Resources;
+import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -29,6 +30,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.webkit.WebIconDatabase;
 import android.webkit.WebIconDatabase.IconListener;
 import android.widget.LinearLayout;
@@ -44,7 +46,7 @@
 }
 
 public class CombinedBookmarkHistoryView extends LinearLayout
-        implements OnClickListener, BreadCrumbView.Controller {
+        implements OnClickListener {
 
     final static String STARTING_FRAGMENT = "fragment";
 
@@ -59,10 +61,11 @@
     long mCurrentFragment;
 
     View mTabs;
-    BreadCrumbView mCrumbs;
     TextView mTabBookmarks;
     TextView mTabHistory;
     TextView mAddBookmark;
+    View mSeperateSelectAdd;
+    ViewGroup mBookmarksHeader;
 
     BrowserBookmarksPage mBookmarks;
     BrowserHistoryPage mHistory;
@@ -116,12 +119,12 @@
 //        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
 
         mTabs = findViewById(R.id.tabs);
-        mCrumbs = (BreadCrumbView) findViewById(R.id.crumbs);
-        mCrumbs.setController(this);
+        mBookmarksHeader = (ViewGroup) findViewById(R.id.header_container);
 
         mTabBookmarks = (TextView) findViewById(R.id.bmtab);
         mTabHistory = (TextView) findViewById(R.id.historytab);
         mAddBookmark = (TextView) findViewById(R.id.addbm);
+        mSeperateSelectAdd = findViewById(R.id.seperate_select_add);
         mAddBookmark.setOnClickListener(this);
         mTabHistory.setOnClickListener(this);
         mTabBookmarks.setOnClickListener(this);
@@ -146,8 +149,26 @@
 
     }
 
+    private BookmarksPageCallbacks mBookmarkCallbackWrapper = new BookmarksPageCallbacks() {
+        @Override
+        public boolean onOpenInNewWindow(Cursor c) {
+            mUiController.onUrlSelected(BrowserBookmarksPage.getUrl(c), true);
+            return true;
+        }
+
+        @Override
+        public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
+            if (isFolder) {
+                return false;
+            }
+            mUiController.onUrlSelected(BrowserBookmarksPage.getUrl(c), false);
+            return true;
+        }
+    };
+
     private void initFragments(Bundle extras) {
-        mBookmarks =  BrowserBookmarksPage.newInstance(mUiController, mCrumbs, extras);
+        mBookmarks = BrowserBookmarksPage.newInstance(mBookmarkCallbackWrapper,
+                extras, mBookmarksHeader);
         mHistory = BrowserHistoryPage.newInstance(mUiController, extras);
     }
 
@@ -157,14 +178,13 @@
         switch (id) {
             case FRAGMENT_ID_BOOKMARKS:
                 fragment = mBookmarks;
-                mCrumbs.setVisibility(View.VISIBLE);
-                if (notify) {
-                    mCrumbs.notifyController();
-                }
+                mSeperateSelectAdd.setVisibility(View.VISIBLE);
+                mBookmarksHeader.setVisibility(View.VISIBLE);
                 break;
             case FRAGMENT_ID_HISTORY:
                 fragment = mHistory;
-                mCrumbs.setVisibility(View.GONE);
+                mBookmarksHeader.setVisibility(View.INVISIBLE);
+                mSeperateSelectAdd.setVisibility(View.INVISIBLE);
                 break;
             default:
                 throw new IllegalArgumentException();
@@ -178,6 +198,19 @@
     }
 
     @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        FragmentManager fm = mActivity.getFragmentManager();
+        FragmentTransaction transaction = fm.openTransaction();
+        if (mCurrentFragment == FRAGMENT_ID_BOOKMARKS) {
+            transaction.remove(mBookmarks);
+        } else if (mCurrentFragment == FRAGMENT_ID_HISTORY) {
+            transaction.remove(mHistory);
+        }
+        transaction.commit();
+    }
+
+    @Override
     public void onClick(View view) {
         if ((mTabHistory == view) && (mCurrentFragment != FRAGMENT_ID_HISTORY)) {
             loadFragment(FRAGMENT_ID_HISTORY, mExtras, false);
@@ -185,7 +218,10 @@
             if (mCurrentFragment != FRAGMENT_ID_BOOKMARKS) {
                 loadFragment(FRAGMENT_ID_BOOKMARKS, mExtras, true);
             } else {
-                mCrumbs.clear();
+                BreadCrumbView crumbs = mBookmarks.getBreadCrumb();
+                if (crumbs != null) {
+                    crumbs.clear();
+                }
             }
         } else if (mAddBookmark == view) {
             mUiController.bookmarkCurrentPage(mBookmarks.getFolderId());
@@ -193,23 +229,12 @@
     }
 
     /**
-     * BreadCrumb controller callback
-     */
-    @Override
-    public void onTop(int level, Object data) {
-        mBookmarks.onFolderChange(level, data);
-    }
-
-    /**
      * callback for back key presses
      */
     boolean onBackPressed() {
-        if ((mCurrentFragment == FRAGMENT_ID_BOOKMARKS) &&
-                (mCrumbs.size() > 0)) {
-            mCrumbs.popView();
-            return true;
+        if (mCurrentFragment == FRAGMENT_ID_BOOKMARKS) {
+            return mBookmarks.onBackPressed();
         }
         return false;
     }
-
 }
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index aabdb26..41e7356 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -47,6 +47,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
+import android.preference.PreferenceActivity;
 import android.provider.Browser;
 import android.provider.BrowserContract;
 import android.provider.BrowserContract.History;
@@ -114,6 +115,8 @@
     // activity requestCode
     final static int PREFERENCES_PAGE = 3;
     final static int FILE_SELECTED = 4;
+    final static int AUTOFILL_SETUP = 5;
+
     private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
 
     // As the ids are dynamically created, we can't guarantee that they will
@@ -143,6 +146,8 @@
     private PageDialogsHandler mPageDialogsHandler;
     private NetworkStateHandler mNetworkHandler;
 
+    private Message mAutoFillSetupMessage;
+
     private boolean mShouldShowErrorConsole;
 
     private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
@@ -306,11 +311,22 @@
         mFactory = factory;
     }
 
-    WebViewFactory getWebViewFactory() {
+    @Override
+    public WebViewFactory getWebViewFactory() {
         return mFactory;
     }
 
     @Override
+    public void createSubWindow(Tab tab) {
+        endActionMode();
+        WebView mainView = tab.getWebView();
+        WebView subView = mFactory.createWebView((mainView == null)
+                ? false
+                : mainView.isPrivateBrowsingEnabled());
+        mUi.createSubWindow(tab, subView);
+    }
+
+    @Override
     public Activity getActivity() {
         return mActivity;
     }
@@ -394,6 +410,13 @@
                             case R.id.view_image_context_menu_id:
                                 loadUrlFromContext(getCurrentTopWebView(), url);
                                 break;
+                            case R.id.open_newtab_context_menu_id:
+                                final Tab parent = mTabControl.getCurrentTab();
+                                final Tab newTab = openTab(url, false);
+                                if (newTab != null && newTab != parent) {
+                                    parent.addChildTab(newTab);
+                                }
+                                break;
                             case R.id.bookmark_context_menu_id:
                                 Intent intent = new Intent(mActivity,
                                         AddBookmarkPage.class);
@@ -1032,6 +1055,15 @@
                 mUploadHandler.onResult(resultCode, intent);
                 mUploadHandler = null;
                 break;
+            case AUTOFILL_SETUP:
+                // Determine whether a profile was actually set up or not
+                // and if so, send the message back to the WebTextView to
+                // fill the form with the new profile.
+                if (getSettings().getAutoFillProfile() != null) {
+                    mAutoFillSetupMessage.sendToTarget();
+                    mAutoFillSetupMessage = null;
+                }
+                break;
             default:
                 break;
         }
@@ -1156,7 +1188,7 @@
         if (!(v instanceof WebView)) {
             return;
         }
-        WebView webview = (WebView) v;
+        final WebView webview = (WebView) v;
         WebView.HitTestResult result = webview.getHitTestResult();
         if (result == null) {
             return;
@@ -1193,7 +1225,15 @@
         menu.setGroupVisible(R.id.ANCHOR_MENU,
                 type == WebView.HitTestResult.SRC_ANCHOR_TYPE
                 || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
-
+        boolean hitText = type == WebView.HitTestResult.SRC_ANCHOR_TYPE
+                || type == WebView.HitTestResult.PHONE_TYPE
+                || type == WebView.HitTestResult.EMAIL_TYPE
+                || type == WebView.HitTestResult.GEO_TYPE;
+        menu.setGroupVisible(R.id.SELECT_TEXT_MENU, hitText);
+        if (hitText) {
+            menu.findItem(R.id.select_text_menu_id)
+                    .setOnMenuItemClickListener(new SelectText(webview));
+        }
         // Setup custom handling depending on the type
         switch (type) {
             case WebView.HitTestResult.PHONE_TYPE:
@@ -1245,17 +1285,36 @@
                         = menu.findItem(R.id.open_newtab_context_menu_id);
                 newTabItem.setVisible(showNewTab);
                 if (showNewTab) {
-                    newTabItem.setOnMenuItemClickListener(
-                            new MenuItem.OnMenuItemClickListener() {
-                                public boolean onMenuItemClick(MenuItem item) {
-                                    final Tab parent = mTabControl.getCurrentTab();
-                                    final Tab newTab = openTab(extra, false);
-                                    if (newTab != parent) {
-                                        parent.addChildTab(newTab);
+                    if (WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE == type) {
+                        newTabItem.setOnMenuItemClickListener(
+                                new MenuItem.OnMenuItemClickListener() {
+                                    @Override
+                                    public boolean onMenuItemClick(MenuItem item) {
+                                        final HashMap<String, WebView> hrefMap =
+                                                new HashMap<String, WebView>();
+                                        hrefMap.put("webview", webview);
+                                        final Message msg = mHandler.obtainMessage(
+                                                FOCUS_NODE_HREF,
+                                                R.id.open_newtab_context_menu_id,
+                                                0, hrefMap);
+                                        webview.requestFocusNodeHref(msg);
+                                        return true;
                                     }
-                                    return true;
-                                }
-                            });
+                                });
+                    } else {
+                        newTabItem.setOnMenuItemClickListener(
+                                new MenuItem.OnMenuItemClickListener() {
+                                    @Override
+                                    public boolean onMenuItemClick(MenuItem item) {
+                                        final Tab parent = mTabControl.getCurrentTab();
+                                        final Tab newTab = openTab(extra, false);
+                                        if (newTab != parent) {
+                                            parent.addChildTab(newTab);
+                                        }
+                                        return true;
+                                    }
+                                });
+                    }
                 }
                 menu.findItem(R.id.bookmark_context_menu_id).setVisible(
                         Bookmarks.urlHasAcceptableScheme(extra));
@@ -1884,6 +1943,22 @@
         }
     }
 
+    private static class SelectText implements OnMenuItemClickListener {
+        private WebView mWebView;
+
+        public boolean onMenuItemClick(MenuItem item) {
+            if (mWebView != null) {
+                return mWebView.selectText();
+            }
+            return false;
+        }
+
+        public SelectText(WebView webView) {
+            mWebView = webView;
+        }
+
+    }
+
     /********************** TODO: UI stuff *****************************/
 
     // these methods have been copied, they still need to be cleaned up
@@ -2348,4 +2423,14 @@
         return mMenuIsDown;
     }
 
+    public void setupAutoFill(Message message) {
+        // Open the settings activity at the AutoFill profile fragment so that
+        // the user can create a new profile. When they return, we will dispatch
+        // the message so that we can autofill the form using their new profile.
+        Intent intent = new Intent(mActivity, BrowserPreferencesPage.class);
+        intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
+                AutoFillSettingsFragment.class.getName());
+        mAutoFillSetupMessage = message;
+        mActivity.startActivityForResult(intent, AUTOFILL_SETUP);
+    }
 }
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 354d694..57cb4a7 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -17,62 +17,51 @@
 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.Cursor;
 import android.os.Bundle;
 
 public class ShortcutActivity extends Activity
-    implements BookmarksHistoryCallbacks {
+    implements BookmarksPageCallbacks {
+
+    private BrowserBookmarksPage mBookmarks;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        // TODO: Is this needed?
         setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
-        FragmentManager fm = getFragmentManager();
-        FragmentTransaction transaction = fm.openTransaction();
-        Bundle extras = new Bundle();
-        extras.putBoolean(BrowserBookmarksPage.EXTRA_SHORTCUT, true);
-        extras.putBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW, true);
-        Fragment frag = BrowserBookmarksPage.newInstance(this, null, extras);
-        transaction.add(android.R.id.content, frag);
-        transaction.commit();
+        mBookmarks = BrowserBookmarksPage.newInstance(this, null, null);
+        mBookmarks.setEnableContextMenu(false);
+        mBookmarks.setShowRootFolder(true);
+        getFragmentManager()
+                .openTransaction()
+                .add(android.R.id.content, mBookmarks)
+                .commit();
     }
 
+    // BookmarksPageCallbacks
 
-    /**
-     * handle fragment startActivity
-     */
     @Override
-    public void startActivityFromFragment(Fragment f, Intent intent, int requestCode) {
+    public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
+        if (isFolder) {
+            return false;
+        }
+        Intent intent = BrowserBookmarksPage.createShortcutIntent(this, c);
         setResult(RESULT_OK, intent);
         finish();
+        return true;
     }
 
     @Override
-    public void finish() {
-        super.finish();
+    public boolean onOpenInNewWindow(Cursor c) {
+        return false;
     }
 
-    // BookmarksHistoryCallbacks
-
-    /**
-     * not used for shortcuts
-     */
     @Override
-    public void onRemoveParentChildRelationships() {}
-
-    @Override
-    public void onComboCanceled() {
-        setResult(RESULT_CANCELED);
-        finish();
+    public void onBackPressed() {
+        if (!mBookmarks.onBackPressed()) {
+            super.onBackPressed();
+        }
     }
-
-    /**
-     * not used for shortcuts
-     */
-    @Override
-    public void onUrlSelected(String url, boolean newWindow) {}
-
 }
diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
index d3609b2..8c06353 100644
--- a/src/com/android/browser/SuggestionsAdapter.java
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -22,6 +22,8 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
 import android.provider.BrowserContract;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
@@ -32,24 +34,21 @@
 import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.ImageView;
-import android.widget.LinearLayout.LayoutParams;
 import android.widget.TextView;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * adapter to wrap multiple cursors for url/search completions
  */
 public class SuggestionsAdapter extends BaseAdapter implements Filterable, OnClickListener {
 
-    static final int TYPE_SEARCH = 0;
-    static final int TYPE_SUGGEST = 1;
-    static final int TYPE_BOOKMARK = 2;
-    static final int TYPE_SUGGEST_URL = 3;
-    static final int TYPE_HISTORY = 4;
+    static final int TYPE_BOOKMARK = 0;
+    static final int TYPE_SUGGEST_URL = 1;
+    static final int TYPE_HISTORY = 2;
+    static final int TYPE_SEARCH = 3;
+    static final int TYPE_SUGGEST = 4;
 
     private static final String[] COMBINED_PROJECTION =
             {BrowserContract.Combined._ID, BrowserContract.Combined.TITLE,
@@ -62,12 +61,14 @@
 
     Context mContext;
     Filter mFilter;
-    SuggestionResults mResults;
+    SuggestionResults mMixedResults;
+    List<SuggestItem> mSuggestResults, mFilterResults;
     List<CursorSource> mSources;
     boolean mLandscapeMode;
     CompletionListener mListener;
     int mLinesPortrait;
     int mLinesLandscape;
+    Object mResultsLock = new Object();
 
     interface CompletionListener {
 
@@ -87,21 +88,21 @@
         mLinesLandscape = mContext.getResources().
                 getInteger(R.integer.max_suggest_lines_landscape);
         mFilter = new SuggestFilter();
-        addSource(new SuggestCursor());
         addSource(new SearchesCursor());
         addSource(new CombinedCursor());
     }
 
     public void setLandscapeMode(boolean mode) {
         mLandscapeMode = mode;
+        notifyDataSetChanged();
     }
 
     public int getLeftCount() {
-        return mResults.getLeftCount();
+        return mMixedResults.getLeftCount();
     }
 
     public int getRightCount() {
-        return mResults.getRightCount();
+        return mMixedResults.getRightCount();
     }
 
     public void addSource(CursorSource c) {
@@ -131,32 +132,32 @@
 
     @Override
     public int getCount() {
-        return (mResults == null) ? 0 : mResults.getLineCount();
+        return (mMixedResults == null) ? 0 : mMixedResults.getLineCount();
     }
 
     @Override
     public SuggestItem getItem(int position) {
-        if (mResults == null) {
+        if (mMixedResults == null) {
             return null;
         }
         if (mLandscapeMode) {
-            if (position >= mResults.getLineCount()) {
+            if (position >= mMixedResults.getLineCount()) {
                 // right column
-                position = position - mResults.getLineCount();
+                position = position - mMixedResults.getLineCount();
                 // index in column
-                if (position >= mResults.getRightCount()) {
+                if (position >= mMixedResults.getRightCount()) {
                     return null;
                 }
-                return mResults.items.get(position + mResults.getLeftCount());
+                return mMixedResults.items.get(position + mMixedResults.getLeftCount());
             } else {
                 // left column
-                if (position >= mResults.getLeftCount()) {
+                if (position >= mMixedResults.getLeftCount()) {
                     return null;
                 }
-                return mResults.items.get(position);
+                return mMixedResults.items.get(position);
             }
         } else {
-            return mResults.items.get(position);
+            return mMixedResults.items.get(position);
         }
     }
 
@@ -168,34 +169,35 @@
     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         final LayoutInflater inflater = LayoutInflater.from(mContext);
+        View view = convertView;
+        if (view == null) {
+            view = inflater.inflate(R.layout.suggestion_two_column, parent, false);
+        }
+        View s1 = view.findViewById(R.id.suggest1);
+        View s2 = view.findViewById(R.id.suggest2);
+        View div = view.findViewById(R.id.suggestion_divider);
         if (mLandscapeMode) {
-            View view = inflater.inflate(R.layout.suggestion_two_column, parent, false);
             SuggestItem item = getItem(position);
-            View iv = view.findViewById(R.id.suggest1);
-            LayoutParams lp = new LayoutParams(iv.getLayoutParams());
-            lp.weight = 0.5f;
-            iv.setLayoutParams(lp);
+            div.setVisibility(View.VISIBLE);
             if (item != null) {
-                bindView(iv, item);
+                s1.setVisibility(View.VISIBLE);
+                bindView(s1, item);
             } else {
-                iv.setVisibility((mResults.getLeftCount() == 0) ? View.GONE :
-                        View.INVISIBLE);
+                s1.setVisibility(View.INVISIBLE);
             }
-            item = getItem(position + mResults.getLineCount());
-            iv = view.findViewById(R.id.suggest2);
-            lp = new LayoutParams(iv.getLayoutParams());
-            lp.weight = 0.5f;
-            iv.setLayoutParams(lp);
+            item = getItem(position + mMixedResults.getLineCount());
             if (item != null) {
-                bindView(iv, item);
+                s2.setVisibility(View.VISIBLE);
+                bindView(s2, item);
             } else {
-                iv.setVisibility((mResults.getRightCount() == 0) ? View.GONE :
-                        View.INVISIBLE);
+                s2.setVisibility(View.INVISIBLE);
             }
             return view;
         } else {
-            View view = inflater.inflate(R.layout.suggestion_item, parent, false);
-            bindView(view, getItem(position));
+            s1.setVisibility(View.VISIBLE);
+            div.setVisibility(View.GONE);
+            s2.setVisibility(View.GONE);
+            bindView(s1, getItem(position));
             return view;
         }
     }
@@ -241,9 +243,52 @@
         ic2.setOnClickListener(this);
     }
 
-    class SuggestFilter extends Filter {
+    class SlowFilterTask extends AsyncTask<CharSequence, Void, List<SuggestItem>> {
 
-        SuggestionResults results;
+        @Override
+        protected List<SuggestItem> doInBackground(CharSequence... params) {
+            SuggestCursor cursor = new SuggestCursor();
+            cursor.runQuery(params[0]);
+            List<SuggestItem> results = new ArrayList<SuggestItem>();
+            int count = cursor.getCount();
+            for (int i = 0; i < count; i++) {
+                results.add(cursor.getItem());
+                cursor.moveToNext();
+            }
+            cursor.close();
+            return results;
+        }
+
+        @Override
+        protected void onPostExecute(List<SuggestItem> items) {
+            mSuggestResults = items;
+            mMixedResults = buildSuggestionResults();
+            notifyDataSetChanged();
+            mListener.onFilterComplete(mMixedResults.getLineCount());
+        }
+    }
+
+    SuggestionResults buildSuggestionResults() {
+        SuggestionResults mixed = new SuggestionResults();
+        List<SuggestItem> filter, suggest;
+        synchronized (mResultsLock) {
+            filter = mFilterResults;
+            suggest = mSuggestResults;
+        }
+        if (filter != null) {
+            for (SuggestItem item : filter) {
+                mixed.addResult(item);
+            }
+        }
+        if (suggest != null) {
+            for (SuggestItem item : suggest) {
+                mixed.addResult(item);
+            }
+        }
+        return mixed;
+    }
+
+    class SuggestFilter extends Filter {
 
         @Override
         public CharSequence convertResultToString(Object item) {
@@ -258,6 +303,10 @@
             }
         }
 
+        void startSuggestionsAsync(final CharSequence constraint) {
+            new SlowFilterTask().execute(constraint);
+        }
+
         @Override
         protected FilterResults performFiltering(CharSequence constraint) {
             FilterResults res = new FilterResults();
@@ -266,47 +315,40 @@
                 res.values = null;
                 return res;
             }
-            results = new SuggestionResults();
+            startSuggestionsAsync(constraint);
+            List<SuggestItem> filterResults = new ArrayList<SuggestItem>();
             if (constraint != null) {
                 for (CursorSource sc : mSources) {
                     sc.runQuery(constraint);
                 }
-                mixResults();
+                mixResults(filterResults);
             }
-            res.count = results.getLineCount();
-            res.values = results;
+            synchronized (mResultsLock) {
+                mFilterResults = filterResults;
+            }
+            SuggestionResults mixed = buildSuggestionResults();
+            res.count = mixed.getLineCount();
+            res.values = mixed;
             return res;
         }
 
-        void mixResults() {
+        void mixResults(List<SuggestItem> results) {
+            int maxLines = mLandscapeMode ? mLinesLandscape : (mLinesPortrait / 2);
             for (int i = 0; i < mSources.size(); i++) {
                 CursorSource s = mSources.get(i);
-                int n = Math.min(s.getCount(), (mLandscapeMode ? mLinesLandscape
-                        : mLinesPortrait));
+                int n = Math.min(s.getCount(), maxLines);
+                maxLines -= n;
                 boolean more = false;
                 for (int j = 0; j < n; j++) {
-                    results.addResult(s.getItem());
+                    results.add(s.getItem());
                     more = s.moveToNext();
                 }
-                if (s instanceof SuggestCursor) {
-                    int k = n;
-                    while (more && (k < mLinesPortrait)) {
-                        SuggestItem item  = s.getItem();
-                        if (item.type == TYPE_SUGGEST_URL) {
-                            results.addResult(item);
-                            break;
-                        }
-                        more = s.moveToNext();
-                        k++;
-
-                    }
-                }
             }
         }
 
         @Override
         protected void publishResults(CharSequence constraint, FilterResults fresults) {
-            mResults = (SuggestionResults) fresults.values;
+            mMixedResults = (SuggestionResults) fresults.values;
             mListener.onFilterComplete(fresults.count);
             notifyDataSetChanged();
         }
@@ -343,20 +385,22 @@
 
         int getLineCount() {
             if (mLandscapeMode) {
-                return Math.max(getLeftCount(), getRightCount());
+                return Math.min(mLinesLandscape,
+                        Math.max(getLeftCount(), getRightCount()));
             } else {
-                return getLeftCount() + getRightCount();
+                return Math.min(mLinesPortrait, getLeftCount() + getRightCount());
             }
         }
 
         int getLeftCount() {
-            return counts[TYPE_SEARCH] + counts[TYPE_SUGGEST];
-        }
-
-        int getRightCount() {
             return counts[TYPE_BOOKMARK] + counts[TYPE_HISTORY] + counts[TYPE_SUGGEST_URL];
         }
 
+        int getRightCount() {
+            return counts[TYPE_SEARCH] + counts[TYPE_SUGGEST];
+        }
+
+        @Override
         public String toString() {
             if (items == null) return null;
             if (items.size() == 0) return "[]";
@@ -513,7 +557,7 @@
                 mCursor.close();
             }
             String like = constraint + "%";
-            String[] args = new String[] {constraint.toString()};
+            String[] args = new String[] {like};
             String selection = BrowserContract.Searches.SEARCH + " LIKE ?";
             Uri.Builder ub = BrowserContract.Searches.CONTENT_URI.buildUpon();
             ub.appendQueryParameter(BrowserContract.PARAM_LIMIT,
@@ -571,4 +615,9 @@
 
     }
 
+    public void clearCache() {
+        mFilterResults = null;
+        mSuggestResults = null;
+    }
+
 }
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index ec42584..a048c2d 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -36,7 +36,6 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewStub;
 import android.webkit.ConsoleMessage;
 import android.webkit.DownloadListener;
@@ -53,9 +52,9 @@
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.FrameLayout;
-import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -706,7 +705,7 @@
                                 mWebViewController.showSslCertificateOnError(view,
                                         handler, error);
                             }
-                        }).setNegativeButton(R.string.cancel,
+                        }).setNegativeButton(R.string.ssl_go_back,
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog,
                                     int whichButton) {
@@ -1063,6 +1062,35 @@
         public void getVisitedHistory(final ValueCallback<String[]> callback) {
             mWebViewController.getVisitedHistory(callback);
         }
+
+        @Override
+        public void setupAutoFill(Message message) {
+            // Prompt the user to set up their profile.
+            final Message msg = message;
+            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
+            builder.setMessage(R.string.autofill_setup_dialog_message)
+                   .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+                       @Override
+                       public void onClick(DialogInterface dialog, int id) {
+                           // Take user to the AutoFill profile editor. When they return,
+                           // we will send the message that we pass here which will trigger
+                           // the form to get filled out with their new profile.
+                           mWebViewController.setupAutoFill(msg);
+                       }
+                   })
+                   .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                       @Override
+                       public void onClick(DialogInterface dialog, int id) {
+                           // 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();
+                           Toast.makeText(mActivity, R.string.autofill_setup_dialog_negative_toast,
+                                   Toast.LENGTH_LONG).show();
+                       }
+                   }).show();
+        }
     };
 
     // -------------------------------------------------------------------------
@@ -1278,15 +1306,7 @@
      */
     boolean createSubWindow() {
         if (mSubView == null) {
-            mWebViewController.endActionMode();
-            mSubViewContainer = mInflateService.inflate(
-                    R.layout.browser_subwindow, null);
-            mSubView = (WebView) mSubViewContainer.findViewById(R.id.webview);
-            mSubView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
-            // use trackball directly
-            mSubView.setMapTrackballToArrowKeys(false);
-            // Enable the built-in zoom
-            mSubView.getSettings().setBuiltInZoomControls(true);
+            mWebViewController.createSubWindow(this);
             mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
                     mWebViewController));
             mSubView.setWebChromeClient(new SubWindowChromeClient(
@@ -1307,15 +1327,6 @@
                 }
             });
             mSubView.setOnCreateContextMenuListener(mActivity);
-            final BrowserSettings s = BrowserSettings.getInstance();
-            s.addObserver(mSubView.getSettings()).update(s, null);
-            final ImageButton cancel = (ImageButton) mSubViewContainer
-                    .findViewById(R.id.subwindow_close);
-            cancel.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    mSubView.getWebChromeClient().onCloseWindow(mSubView);
-                }
-            });
             return true;
         }
         return false;
@@ -1463,10 +1474,18 @@
         return mSubView;
     }
 
+    void setSubWebView(WebView subView) {
+        mSubView = subView;
+    }
+
     View getSubViewContainer() {
         return mSubViewContainer;
     }
 
+    void setSubViewContainer(View subViewContainer) {
+        mSubViewContainer = subViewContainer;
+    }
+
     /**
      * @return The geolocation permissions prompt for this tab.
      */
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index 08cf33a..3a8a5cd 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -25,6 +25,7 @@
 import android.view.Menu;
 import android.view.View;
 import android.webkit.WebChromeClient.CustomViewCallback;
+import android.webkit.WebView;
 
 import java.util.List;
 
@@ -57,6 +58,8 @@
 
     public void attachTab(Tab tab);
 
+    public void createSubWindow(Tab tab, WebView subWebView);
+
     public void attachSubWindow(View subContainer);
 
     public void removeSubWindow(View subContainer);
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index e7fc233..2e29f26 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -18,7 +18,6 @@
 
 import com.android.browser.SuggestionsAdapter.CompletionListener;
 
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
@@ -68,6 +67,7 @@
         setAdapter(mAdapter);
         setSelectAllOnFocus(false);
         onConfigurationChanged(ctx.getResources().getConfiguration());
+        setThreshold(1);
     }
 
     void setContainer(View container) {
@@ -76,29 +76,35 @@
 
     @Override
     protected void onConfigurationChanged(Configuration config) {
+        super.onConfigurationChanged(config);
         mLandscape = (config.orientation &
                 Configuration.ORIENTATION_LANDSCAPE) > 0;
+        mAdapter.setLandscapeMode(mLandscape);
         if (isPopupShowing() && (getVisibility() == View.VISIBLE)) {
-            dismissDropDown();
-            getFilter().filter(getText());
+            setupDropDown();
         }
     }
 
     @Override
     public void showDropDown() {
+        setupDropDown();
+        super.showDropDown();
+    }
+
+    @Override
+    public void dismissDropDown() {
+        super.dismissDropDown();
+        mAdapter.clearCache();
+    }
+
+    private void setupDropDown() {
         int width = mContainer.getWidth();
-        if (mLandscape && ((mAdapter.getLeftCount() == 0) ||
-                (mAdapter.getRightCount() == 0))) {
-            width = width / 2;
-        }
         if (width != getDropDownWidth()) {
             setDropDownWidth(width);
         }
         if (getLeft() != -getDropDownHorizontalOffset()) {
             setDropDownHorizontalOffset(-getLeft());
         }
-        mAdapter.setLandscapeMode(mLandscape);
-        super.showDropDown();
     }
 
     @Override
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index fdd8ab1..eeeee18 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -22,6 +22,7 @@
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.net.http.SslError;
+import android.os.Message;
 import android.view.KeyEvent;
 import android.view.View;
 import android.webkit.HttpAuthHandler;
@@ -39,6 +40,10 @@
 
     TabControl getTabControl();
 
+    WebViewFactory getWebViewFactory();
+
+    void createSubWindow(Tab tab);
+
     void onPageStarted(Tab tab, WebView view, String url, Bitmap favicon);
 
     void onPageFinished(Tab tab, String url);
@@ -98,4 +103,6 @@
 
     void closeTab(Tab tab);
 
+    void setupAutoFill(Message message);
+
 }
diff --git a/src/com/android/browser/WebViewFactory.java b/src/com/android/browser/WebViewFactory.java
index 6047d1c..1186e65 100644
--- a/src/com/android/browser/WebViewFactory.java
+++ b/src/com/android/browser/WebViewFactory.java
@@ -25,4 +25,6 @@
 
     public WebView createWebView(boolean privateBrowsing);
 
+    public WebView createSubWebView(boolean privateBrowsing);
+
 }
diff --git a/src/com/android/browser/preferences/PersonalPreferencesFragment.java b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
index 656d47a..a0c8ea0 100644
--- a/src/com/android/browser/preferences/PersonalPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
@@ -34,6 +34,7 @@
 import android.content.OperationApplicationException;
 import android.content.SharedPreferences;
 import android.database.Cursor;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.preference.Preference;
@@ -80,32 +81,47 @@
         refreshUi(context);
     }
 
-    void refreshUi(Context context) {
-        AccountManager am = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
-        Account[] accounts = am.getAccountsByType("com.google");
-        if (accounts == null || accounts.length == 0) {
-            // No Google accounts setup, don't offer Chrome sync
-            if (mChromeSync != null) {
-                getPreferenceScreen().removePreference(mChromeSync);
-            }
-        } else {
-            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-            Bundle args = mChromeSync.getExtras();
-            args.putParcelableArray("accounts", accounts);
-            mEnabled = BrowserContract.Settings.isSyncEnabled(context);
-            if (!mEnabled) {
-                // Google accounts are present, but Chrome sync isn't enabled yet.
-                // Setup a link to the enable wizard
-                mChromeSync.setSummary(R.string.pref_personal_sync_with_chrome_summary);
-            } else {
-                // Chrome sync is enabled, setup a link to account switcher
-                String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
-                mChromeSync.setSummary(accountName);
-                args.putString("curAccount", accountName);
-            }
-            mChromeSync.setOnPreferenceClickListener(this);
+    private class GetAccountsTask extends AsyncTask<Void, Void, Void> {
+        private Context mContext;
+
+        GetAccountsTask(Context ctx) {
+            mContext = ctx;
         }
 
+        protected Void doInBackground(Void... unused) {
+            AccountManager am = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
+            Account[] accounts = am.getAccountsByType("com.google");
+            if (accounts == null || accounts.length == 0) {
+                // No Google accounts setup, don't offer Chrome sync
+                if (mChromeSync != null) {
+                    getPreferenceScreen().removePreference(mChromeSync);
+                }
+            } else {
+                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+                Bundle args = mChromeSync.getExtras();
+                args.putParcelableArray("accounts", accounts);
+                mEnabled = BrowserContract.Settings.isSyncEnabled(mContext);
+                if (!mEnabled) {
+                    // Google accounts are present, but Chrome sync isn't enabled yet.
+                    // Setup a link to the enable wizard
+                    mChromeSync.setSummary(R.string.pref_personal_sync_with_chrome_summary);
+                } else {
+                    // Chrome sync is enabled, setup a link to account switcher
+                    String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME,
+                            null);
+                    mChromeSync.setSummary(accountName);
+                    args.putString("curAccount", accountName);
+                }
+                mChromeSync.setOnPreferenceClickListener(PersonalPreferencesFragment.this);
+            }
+
+            return null;
+        }
+    }
+
+    void refreshUi(Context context) {
+        new GetAccountsTask(context).execute();
+
         PreferenceScreen autoFillSettings =
                 (PreferenceScreen)findPreference(BrowserSettings.PREF_AUTOFILL_PROFILE);
         autoFillSettings.setDependency(BrowserSettings.PREF_AUTOFILL_ENABLED);