Merge "Add legacy mimetype support to BP2"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d26aae7..5b844e0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -177,7 +177,7 @@
         <activity android:name="AddBookmarkPage" android:label="Save bookmark"
                   android:theme="@style/Dialog"
                   android:configChanges="orientation|keyboardHidden"
-                  android:windowSoftInputMode="stateHidden">
+                  android:windowSoftInputMode="stateHidden|adjustPan">
             <intent-filter>
                 <action android:name="android.intent.action.INSERT" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/res/drawable-mdpi/list_div_bookmark_widget_holo.9.png b/res/drawable-mdpi/list_div_bookmark_widget_holo.9.png
index fc1946f..2fdb639 100644
--- a/res/drawable-mdpi/list_div_bookmark_widget_holo.9.png
+++ b/res/drawable-mdpi/list_div_bookmark_widget_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/list_div_top_btm_bookmark_widget_holo.9.png b/res/drawable-mdpi/list_div_top_btm_bookmark_widget_holo.9.png
index 309b608..04861ce 100644
--- a/res/drawable-mdpi/list_div_top_btm_bookmark_widget_holo.9.png
+++ b/res/drawable-mdpi/list_div_top_btm_bookmark_widget_holo.9.png
Binary files differ
diff --git a/res/layout/browser_add_bookmark.xml b/res/layout/browser_add_bookmark.xml
index 8b6feab..27b8e85 100644
--- a/res/layout/browser_add_bookmark.xml
+++ b/res/layout/browser_add_bookmark.xml
@@ -22,13 +22,16 @@
     <RelativeLayout android:id="@+id/crumb_holder"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="?android:attr/listPreferredItemHeight"
+        android:gravity="center_vertical"
         android:visibility="gone"
         >
         <com.android.browser.BreadCrumbView android:id="@+id/crumbs"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="?android:attr/listPreferredItemHeight"
             android:layout_alignParentLeft="true"
             android:layout_toLeftOf="@+id/add_divider"
+            android:layout_centerVertical="true"
             />
         <TextView
             android:id="@+id/add_new_folder"
@@ -40,17 +43,20 @@
             android:gravity="center_vertical"
             android:text="@string/new_folder"
             android:visibility="gone"
+            android:layout_centerVertical="true"
             android:textAppearance="?android:attr/textAppearanceMedium" />
         <ImageView android:id="@+id/add_divider"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_toLeftOf="@+id/add_new_folder"
             android:src="@drawable/crumb_divider"
+            android:layout_centerVertical="true"
             />
     </RelativeLayout>
     <TextView android:id="@+id/fake_title"
         android:layout_width="wrap_content"
-        android:layout_height="?android:attr/listPreferredItemHeight"
+        android:layout_height="wrap_content"
+        android:minHeight="?android:attr/listPreferredItemHeight"
         android:drawableLeft="@drawable/ic_list_bookmark"
         android:text="@string/bookmark_this_page"
         android:layout_gravity="left"
@@ -148,7 +154,7 @@
         android:visibility="gone"
         >
 
-        <ListView
+        <view class="com.android.browser.AddBookmarkPage$CustomListView"
             android:id="@+id/list"
             android:layout_marginLeft="16dip"
             android:layout_marginRight="16dip"
@@ -165,14 +171,6 @@
             android:text="@string/no_subfolders"
             android:textStyle="italic"
             android:textAppearance="?android:attr/textAppearanceMedium" />
-        <EditText
-            android:id="@+id/folder_namer"
-            android:layout_marginLeft="16dip"
-            android:layout_marginRight="16dip"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
-            />
     </LinearLayout>
 
     <LinearLayout 
diff --git a/res/layout/folder_list_item.xml b/res/layout/folder_list_item.xml
index 56c597b..5d77fd9 100644
--- a/res/layout/folder_list_item.xml
+++ b/res/layout/folder_list_item.xml
@@ -25,7 +25,7 @@
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
         android:minHeight="?android:attr/listPreferredItemHeight"
-        android:src="@drawable/ic_go_normal_white" />
+        android:src="@drawable/ic_folder_bookmark_widget_holo_dark" />
     <TextView
         android:id="@android:id/text1"
         android:layout_width="match_parent"
diff --git a/res/layout/new_folder_layout.xml b/res/layout/new_folder_layout.xml
new file mode 100644
index 0000000..4ce0ade
--- /dev/null
+++ b/res/layout/new_folder_layout.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+<!-- Keep in sync with folder_list_item.xml -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+    <ImageView
+        android:id="@+id/icon1"
+        style="@style/HoloIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:minHeight="?android:attr/listPreferredItemHeight"
+        android:src="@drawable/ic_folder_bookmark_widget_holo_dark" />
+    <EditText
+        android:id="@+id/folder_namer"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:gravity="center_vertical"
+        android:paddingLeft="6dip"
+        android:minHeight="?android:attr/listPreferredItemHeight" />
+</LinearLayout>
diff --git a/src/com/android/browser/ActiveTabsPage.java b/src/com/android/browser/ActiveTabsPage.java
index fb5ed3b..664fd68 100644
--- a/src/com/android/browser/ActiveTabsPage.java
+++ b/src/com/android/browser/ActiveTabsPage.java
@@ -170,7 +170,6 @@
                             + (tab.getSavedState() == null ? "null" : "non-null")
                             + " saved state ");
                 }
-                tab.populatePickerData();
                 if (tab.getTitle() == null || tab.getTitle().length() == 0) {
                     Log.w(LOGTAG, "Tab " + position + " has no title. "
                             + "Check above in the Logs to see whether it has a "
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 262884b..d3c147c 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -41,6 +41,7 @@
 import android.preference.PreferenceManager;
 import android.provider.BrowserContract;
 import android.text.TextUtils;
+import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
@@ -97,6 +98,8 @@
     private View mDefaultView;
     private View mFolderSelector;
     private EditText mFolderNamer;
+    private boolean mIsFolderNamerShowing;
+    private View mFolderNamerHolder;
     private View mAddNewFolder;
     private View mAddSeparator;
     private long mCurrentFolder = 0;
@@ -104,9 +107,11 @@
     private BreadCrumbView mCrumbs;
     private TextView mFakeTitle;
     private View mCrumbHolder;
-    private ListView mListView;
+    private CustomListView mListView;
     private boolean mSaveToHomeScreen;
     private long mRootFolder;
+    private TextView mTopLevelLabel;
+    private Drawable mHeaderIcon;
 
     private static class Folder {
         String Name;
@@ -151,9 +156,19 @@
                 LOADER_ID_FOLDER_CONTENTS));
         loader.setUri(getUriForFolder(folder));
         loader.forceLoad();
-        if (mFolderNamer.getVisibility() == View.VISIBLE) {
+        if (mIsFolderNamerShowing) {
             completeOrCancelFolderNaming(true);
         }
+        setShowBookmarkIcon(level == 1);
+    }
+
+    /**
+     * Show or hide the icon for bookmarks next to "Bookmarks" in the crumb view.
+     * @param show True if the icon should visible, false otherwise.
+     */
+    private void setShowBookmarkIcon(boolean show) {
+        Drawable drawable = show ? mHeaderIcon: null;
+        mTopLevelLabel.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
     }
 
     @Override
@@ -197,7 +212,7 @@
         if (v == mButton) {
             if (mFolderSelector.getVisibility() == View.VISIBLE) {
                 // We are showing the folder selector.
-                if (mFolderNamer.getVisibility() == View.VISIBLE) {
+                if (mIsFolderNamerShowing) {
                     completeOrCancelFolderNaming(false);
                 } else {
                     // User has selected a folder.  Go back to the opening page
@@ -208,7 +223,7 @@
                 finish();
             }
         } else if (v == mCancelButton) {
-            if (mFolderNamer.getVisibility() == View.VISIBLE) {
+            if (mIsFolderNamerShowing) {
                 completeOrCancelFolderNaming(true);
             } else if (mFolderSelector.getVisibility() == View.VISIBLE) {
                 switchToDefaultView(false);
@@ -225,14 +240,16 @@
             popup.setOnMenuItemClickListener(this);
             popup.show();
         } else if (v == mAddNewFolder) {
-            mFolderNamer.setVisibility(View.VISIBLE);
+            setShowFolderNamer(true);
             mFolderNamer.setText(R.string.new_folder);
             mFolderNamer.requestFocus();
-            updateList();
             mAddNewFolder.setVisibility(View.GONE);
             mAddSeparator.setVisibility(View.GONE);
-            getInputMethodManager().showSoftInput(mFolderNamer,
-                    InputMethodManager.SHOW_IMPLICIT);
+            InputMethodManager imm = getInputMethodManager();
+            // Set the InputMethodManager to focus on the ListView so that it
+            // can transfer the focus to mFolderNamer.
+            imm.focusIn(mListView);
+            imm.showSoftInput(mFolderNamer, InputMethodManager.SHOW_IMPLICIT);
         }
     }
 
@@ -258,27 +275,17 @@
         return true;
     }
 
-    // Refresh the ListView to hide or show the empty view, as necessary.
-    // Should be called after mFolderNamer is shown or hidden.
-    private void updateList() {
-        if (mAdapter.getCount() == 0) {
-            // XXX: Is there a better way to refresh the ListView?
-            mListView.setAdapter(mAdapter);
-        }
-    }
-
     private void completeOrCancelFolderNaming(boolean cancel) {
         if (!cancel && !TextUtils.isEmpty(mFolderNamer.getText())) {
             String name = mFolderNamer.getText().toString();
             long id = addFolderToCurrent(mFolderNamer.getText().toString());
             descendInto(name, id);
         }
-        mFolderNamer.setVisibility(View.GONE);
+        setShowFolderNamer(false);
         mAddNewFolder.setVisibility(View.VISIBLE);
         mAddSeparator.setVisibility(View.VISIBLE);
         getInputMethodManager().hideSoftInputFromWindow(
-                mFolderNamer.getWindowToken(), 0);
-        updateList();
+                mListView.getWindowToken(), 0);
     }
 
     private long addFolderToCurrent(String name) {
@@ -403,7 +410,7 @@
                     Folder thisFolder = folderStack.pop();
                     mCrumbs.pushView(thisFolder.Name, thisFolder);
                 }
-                getLoaderManager().stopLoader(LOADER_ID_ALL_FOLDERS);
+                getLoaderManager().destroyLoader(LOADER_ID_ALL_FOLDERS);
                 break;
             default:
                 break;
@@ -461,6 +468,24 @@
         descendInto(tv.getText().toString(), id);
     }
 
+    private void setShowFolderNamer(boolean show) {
+        if (show != mIsFolderNamerShowing) {
+            mIsFolderNamerShowing = show;
+            if (show) {
+                // Set the selection to the folder namer so it will be in
+                // view.
+                mListView.addFooterView(mFolderNamerHolder);
+            } else {
+                mListView.removeFooterView(mFolderNamerHolder);
+            }
+            // Refresh the list.
+            mListView.setAdapter(mAdapter);
+            if (show) {
+                mListView.setSelection(mListView.getCount() - 1);
+            }
+        }
+    }
+
     /**
      * Shows a list of names of folders.
      */
@@ -488,7 +513,7 @@
         @Override
         public boolean isEmpty() {
             // Do not show the empty view if the user is creating a new folder.
-            return super.isEmpty() && mFolderNamer.getVisibility() == View.GONE;
+            return super.isEmpty() && !mIsFolderNamerShowing;
         }
     }
 
@@ -554,7 +579,8 @@
         mDefaultView = findViewById(R.id.default_view);
         mFolderSelector = findViewById(R.id.folder_selector);
 
-        mFolderNamer = (EditText) findViewById(R.id.folder_namer);
+        mFolderNamerHolder = getLayoutInflater().inflate(R.layout.new_folder_layout, null);
+        mFolderNamer = (EditText) mFolderNamerHolder.findViewById(R.id.folder_namer);
         mFolderNamer.setOnEditorActionListener(this);
 
         mAddNewFolder = findViewById(R.id.add_new_folder);
@@ -565,20 +591,26 @@
         mCrumbs.setUseBackButton(true);
         mCrumbs.setController(this);
         String name = getString(R.string.bookmarks);
-        mCrumbs.pushView(name, false, new Folder(name, mRootFolder));
+        mTopLevelLabel = (TextView) mCrumbs.pushView(name, false, new Folder(name, mRootFolder));
+        // To better match the other folders.
+        mTopLevelLabel.setCompoundDrawablePadding(6);
+        mHeaderIcon = getResources().getDrawable(R.drawable.ic_folder_bookmark_widget_holo_dark);
         mCrumbHolder = findViewById(R.id.crumb_holder);
         mCrumbs.setMaxVisible(MAX_CRUMBS_SHOWN);
 
         mAdapter = new FolderAdapter(this);
-        mListView = (ListView) findViewById(R.id.list);
+        mListView = (CustomListView) findViewById(R.id.list);
         View empty = findViewById(R.id.empty);
         mListView.setEmptyView(empty);
         mListView.setAdapter(mAdapter);
         mListView.setOnItemClickListener(this);
+        mListView.addEditText(mFolderNamer);
         LoaderManager manager = getLoaderManager();
         if (mCurrentFolder != mRootFolder) {
             // Find all the folders
             manager.initLoader(LOADER_ID_ALL_FOLDERS, null, this);
+        } else {
+            setShowBookmarkIcon(true);
         }
         // Find the contents of the current folder
         manager.initLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
@@ -848,4 +880,32 @@
         }
         return true;
     }
+
+    /*
+     * Class used as a proxy for the InputMethodManager to get to mFolderNamer
+     */
+    public static class CustomListView extends ListView {
+        private EditText mEditText;
+
+        public void addEditText(EditText editText) {
+            mEditText = editText;
+        }
+
+        public CustomListView(Context context) {
+            super(context);
+        }
+
+        public CustomListView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public CustomListView(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+        }
+
+        @Override
+        public boolean checkInputConnectionProxy(View view) {
+            return view == mEditText;
+        }
+    }
 }
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 1e9038d..7e0c5da 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -16,6 +16,8 @@
 
 package com.android.browser;
 
+import com.android.browser.Tab.LockIcon;
+
 import android.app.Activity;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -178,15 +180,12 @@
         return false;
     }
 
-    // WebView callbacks
-
+    // Tab callbacks
     @Override
-    public void onPageStarted(Tab tab, String url, Bitmap favicon) {
-        if (tab.inForeground()) {
-            resetLockIcon(tab, url);
-            setUrlTitle(tab, url, null);
-            setFavicon(tab, favicon);
-        }
+    public void onTabDataChanged(Tab tab) {
+        setUrlTitle(tab);
+        setFavicon(tab);
+        updateLockIconToLatest(tab);
     }
 
     @Override
@@ -195,16 +194,6 @@
     }
 
     @Override
-    public void onPageFinished(Tab tab, String url) {
-        if (tab.inForeground()) {
-            // Reset the title and icon in case we stopped a provisional load.
-            resetTitleAndIcon(tab);
-            // Update the lock icon image only once we are done loading
-            updateLockIconToLatest(tab);
-        }
-    }
-
-    @Override
     public void onPageStopped(Tab tab) {
         cancelStopToast();
         if (tab.inForeground()) {
@@ -231,6 +220,8 @@
         mActiveTab = tab;
         attachTabToContentView(tab);
         setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole());
+        onTabDataChanged(tab);
+        onProgressChanged(tab);
     }
 
     Tab getActiveTab() {
@@ -424,7 +415,7 @@
     @Override
     public void revertVoiceTitleBar(Tab tab) {
         getEmbeddedTitleBar().setInVoiceMode(false);
-        String url = tab.getCurrentUrl();
+        String url = tab.getUrl();
         getEmbeddedTitleBar().setDisplayTitle(url);
         getFakeTitleBar().setInVoiceMode(false);
         getFakeTitleBar().setDisplayTitle(url);
@@ -524,81 +515,32 @@
 
     // -------------------------------------------------------------------------
 
-    @Override
-    public void resetTitleAndRevertLockIcon(Tab tab) {
-        tab.revertLockIcon();
-        updateLockIconToLatest(tab);
-        resetTitleIconAndProgress(tab);
-    }
-
-    /**
-     * Resets the lock icon. This method is called when we start a new load and
-     * know the url to be loaded.
-     */
-    private void resetLockIcon(Tab tab, String url) {
-        // Save the lock-icon state (we revert to it if the load gets cancelled)
-        tab.resetLockIcon(url);
-        updateLockIconImage(Tab.LOCK_ICON_UNSECURE);
-    }
-
     /**
      * Update the lock icon to correspond to our latest state.
      */
     protected void updateLockIconToLatest(Tab t) {
-        if (t != null) {
+        if (t != null && t.inForeground()) {
             updateLockIconImage(t.getLockIconType());
         }
     }
 
     /**
-     * Reset the title, favicon, and progress.
-     */
-    protected void resetTitleIconAndProgress(Tab tab) {
-        WebView current = tab.getWebView();
-        if (current == null) {
-            return;
-        }
-        resetTitleAndIcon(tab, current);
-        int progress = current.getProgress();
-        current.getWebChromeClient().onProgressChanged(current, progress);
-    }
-
-    @Override
-    public void resetTitleAndIcon(Tab tab) {
-        WebView current = tab.getWebView();
-        if (current != null) {
-            resetTitleAndIcon(tab, current);
-        }
-    }
-
-    // Reset the title and the icon based on the given item.
-    private void resetTitleAndIcon(Tab tab, WebView view) {
-        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
-        if (item != null) {
-            setUrlTitle(tab, item.getUrl(), item.getTitle());
-            setFavicon(tab, item.getFavicon());
-        } else {
-            setUrlTitle(tab, null, mActivity.getString(R.string.new_tab));
-            setFavicon(tab, null);
-        }
-    }
-
-    /**
      * Updates the lock-icon image in the title-bar.
      */
-    private void updateLockIconImage(int lockIconType) {
+    private void updateLockIconImage(LockIcon lockIconType) {
         Drawable d = null;
-        if (lockIconType == Tab.LOCK_ICON_SECURE) {
+        if (lockIconType == LockIcon.LOCK_ICON_SECURE) {
             d = mSecLockIcon;
-        } else if (lockIconType == Tab.LOCK_ICON_MIXED) {
+        } else if (lockIconType == LockIcon.LOCK_ICON_MIXED) {
             d = mMixLockIcon;
         }
         getEmbeddedTitleBar().setLock(d);
         getFakeTitleBar().setLock(d);
     }
 
-    @Override
-    public void setUrlTitle(Tab tab, String url, String title) {
+    protected void setUrlTitle(Tab tab) {
+        String url = tab.getUrl();
+        String title = tab.getTitle();
         if (TextUtils.isEmpty(title)) {
             title = url;
         }
@@ -610,10 +552,12 @@
     }
 
     // Set the favicon in the title bar.
-    @Override
-    public void setFavicon(Tab tab, Bitmap icon) {
-        getEmbeddedTitleBar().setFavicon(icon);
-        getFakeTitleBar().setFavicon(icon);
+    protected void setFavicon(Tab tab) {
+        if (tab.inForeground()) {
+            Bitmap icon = tab.getFavicon();
+            getEmbeddedTitleBar().setFavicon(icon);
+            getFakeTitleBar().setFavicon(icon);
+        }
     }
 
     @Override
diff --git a/src/com/android/browser/BreadCrumbView.java b/src/com/android/browser/BreadCrumbView.java
index 643bfc7..113d55b 100644
--- a/src/com/android/browser/BreadCrumbView.java
+++ b/src/com/android/browser/BreadCrumbView.java
@@ -135,13 +135,14 @@
         }
     }
 
-    public void pushView(String name, Object data) {
-        pushView(name, true, data);
+    public View pushView(String name, Object data) {
+        return pushView(name, true, data);
     }
 
-    public void pushView(String name, boolean canGoBack, Object data) {
+    public View pushView(String name, boolean canGoBack, Object data) {
         Crumb crumb = new Crumb(name, canGoBack, data);
         pushCrumb(crumb);
+        return crumb.crumbView;
     }
 
     public void pushView(View view, Object data) {
@@ -160,7 +161,7 @@
         mBackButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                 LayoutParams.MATCH_PARENT));
         mBackButton.setOnClickListener(this);
-        mBackButton.setVisibility(View.INVISIBLE);
+        mBackButton.setVisibility(View.GONE);
         addView(mBackButton, 0);
     }
 
@@ -196,7 +197,7 @@
                 if (top != null && top.canGoBack) {
                     mBackButton.setVisibility(View.VISIBLE);
                 } else {
-                    mBackButton.setVisibility(View.INVISIBLE);
+                    mBackButton.setVisibility(View.GONE);
                 }
             }
             updateVisible();
@@ -241,7 +242,7 @@
         }
         if (mUseBackButton) {
             boolean canGoBack = getTopCrumb() != null ? getTopCrumb().canGoBack : false;
-            mBackButton.setVisibility(canGoBack ? View.VISIBLE : View.INVISIBLE);
+            mBackButton.setVisibility(canGoBack ? View.VISIBLE : View.GONE);
         } else {
             mBackButton.setVisibility(View.GONE);
         }
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 3fc270e..825da33 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -482,7 +482,7 @@
         }
         mCrumbs.setController(null);
         mCrumbs = null;
-        getLoaderManager().stopLoader(LOADER_BOOKMARKS);
+        getLoaderManager().destroyLoader(LOADER_BOOKMARKS);
     }
 
     @Override
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 01e3c21..d8e8177 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -224,8 +224,8 @@
     public void onDestroy() {
         super.onDestroy();
         CombinedBookmarkHistoryView.getIconListenerSet().removeListener(mIconReceiver);
-        getLoaderManager().stopLoader(LOADER_HISTORY);
-        getLoaderManager().stopLoader(LOADER_MOST_VISITED);
+        getLoaderManager().destroyLoader(LOADER_HISTORY);
+        getLoaderManager().destroyLoader(LOADER_MOST_VISITED);
     }
 
     @Override
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
index cc56489..426b34d 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -197,6 +197,7 @@
                 fragment = mBookmarks;
                 mSeperateSelectAdd.setVisibility(View.VISIBLE);
                 mBookmarksHeader.setVisibility(View.VISIBLE);
+                mAddBookmark.setVisibility(View.VISIBLE);
                 mTabBookmarks.setActivated(true);
                 mTabHistory.setActivated(false);
                 break;
@@ -204,6 +205,7 @@
                 fragment = mHistory;
                 mBookmarksHeader.setVisibility(View.INVISIBLE);
                 mSeperateSelectAdd.setVisibility(View.INVISIBLE);
+                mAddBookmark.setVisibility(View.INVISIBLE);
                 mTabBookmarks.setActivated(false);
                 mTabHistory.setActivated(true);
                 break;
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 487c69c..ab6578a 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -522,7 +522,6 @@
 
     private void shareCurrentPage(Tab tab) {
         if (tab != null) {
-            tab.populatePickerData();
             sharePage(mActivity, tab.getTitle(),
                     tab.getUrl(), tab.getFavicon(),
                     createScreenshot(tab.getWebView(),
@@ -722,15 +721,8 @@
     public void stopLoading() {
         mLoadStopped = true;
         Tab tab = mTabControl.getCurrentTab();
-        resetTitleAndRevertLockIcon(tab);
         WebView w = getCurrentTopWebView();
         w.stopLoading();
-        // FIXME: before refactor, it is using mWebViewClient. So I keep the
-        // same logic here. But for subwindow case, should we call into the main
-        // WebView's onPageFinished as we never call its onPageStarted and if
-        // the page finishes itself, we don't call onPageFinished.
-        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
-                w.getUrl());
         mUi.onPageStopped(tab);
     }
 
@@ -770,7 +762,7 @@
         }
         endActionMode();
 
-        mUi.onPageStarted(tab, url, favicon);
+        mUi.onTabDataChanged(tab);
 
         // update the bookmark database for favicon
         maybeUpdateFavicon(tab, null, url, favicon);
@@ -786,7 +778,7 @@
 
     @Override
     public void onPageFinished(Tab tab, String url) {
-        mUi.onPageFinished(tab, url);
+        mUi.onTabDataChanged(tab);
         if (!tab.isPrivateBrowsingEnabled()) {
             if (tab.inForeground() && !didUserStopLoading()
                     || !tab.inForeground()) {
@@ -814,7 +806,8 @@
     }
 
     @Override
-    public void onProgressChanged(Tab tab, int newProgress) {
+    public void onProgressChanged(Tab tab) {
+        int newProgress = tab.getLoadProgress();
 
         if (newProgress == 100) {
             CookieSyncManager.getInstance().sync();
@@ -838,13 +831,18 @@
                 updateInLoadMenuItems(mCachedMenu);
             }
         }
-        mUi.onProgressChanged(tab, newProgress);
+        mUi.onProgressChanged(tab);
+    }
+
+    @Override
+    public void onUpdatedLockIcon(Tab tab) {
+        mUi.onTabDataChanged(tab);
     }
 
     @Override
     public void onReceivedTitle(Tab tab, final String title) {
-        final String pageUrl = tab.getWebView().getUrl();
-        setUrlTitle(tab, pageUrl, title);
+        mUi.onTabDataChanged(tab);
+        final String pageUrl = tab.getUrl();
         if (pageUrl == null || pageUrl.length()
                 >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
             return;
@@ -857,7 +855,7 @@
 
     @Override
     public void onFavicon(Tab tab, WebView view, Bitmap icon) {
-        mUi.setFavicon(tab, icon);
+        mUi.onTabDataChanged(tab);
         maybeUpdateFavicon(tab, view.getOriginalUrl(), view.getUrl(), icon);
     }
 
@@ -2016,24 +2014,17 @@
         // content view first.
         mUi.detachTab(appTab);
         // Recreate the main WebView after destroying the old one.
-        // If the WebView has the same original url and is on that
-        // page, it can be reused.
-        boolean needsLoad =
-                mTabControl.recreateWebView(appTab, urlData);
+        mTabControl.recreateWebView(appTab);
         // TODO: analyze why the remove and add are necessary
         mUi.attachTab(appTab);
         if (mTabControl.getCurrentTab() != appTab) {
             switchToTab(mTabControl.getTabIndex(appTab));
-            if (needsLoad) {
-                loadUrlDataIn(appTab, urlData);
-            }
+            loadUrlDataIn(appTab, urlData);
         } else {
             // If the tab was the current tab, we have to attach
             // it to the view system again.
             setActiveTab(appTab);
-            if (needsLoad) {
-                loadUrlDataIn(appTab, urlData);
-            }
+            loadUrlDataIn(appTab, urlData);
         }
     }
 
@@ -2233,33 +2224,15 @@
         data.loadIn(t);
     }
 
-    /**
-     * Resets the browser title-view to whatever it must be
-     * (for example, if we had a loading error)
-     * When we have a new page, we call resetTitle, when we
-     * have to reset the titlebar to whatever it used to be
-     * (for example, if the user chose to stop loading), we
-     * call resetTitleAndRevertLockIcon.
-     */
-    public void resetTitleAndRevertLockIcon(Tab tab) {
-        mUi.resetTitleAndRevertLockIcon(tab);
-    }
-
-    void resetTitleAndIcon(Tab tab) {
-        mUi.resetTitleAndIcon(tab);
-    }
-
-    /**
-     * Sets a title composed of the URL and the title string.
-     * @param url The URL of the site being loaded.
-     * @param title The title of the site being loaded.
-     */
-    void setUrlTitle(Tab tab, String url, String title) {
-        tab.setCurrentUrl(url);
-        tab.setCurrentTitle(title);
-        // If we are in voice search mode, the title has already been set.
-        if (tab.isInVoiceSearchMode()) return;
-        mUi.setUrlTitle(tab, url, title);
+    @Override
+    public void onUserCanceledSsl(Tab tab) {
+        WebView web = tab.getWebView();
+        // TODO: Figure out the "right" behavior
+        if (web.canGoBack()) {
+            web.goBack();
+        } else {
+            web.loadUrl(mSettings.getHomePage());
+        }
     }
 
     void goBackOnePageOrQuit() {
diff --git a/src/com/android/browser/DownloadHandler.java b/src/com/android/browser/DownloadHandler.java
index cbf26f4..40278f4 100644
--- a/src/com/android/browser/DownloadHandler.java
+++ b/src/com/android/browser/DownloadHandler.java
@@ -183,7 +183,9 @@
         Uri uri = Uri.parse(addressString);
         final DownloadManager.Request request = new DownloadManager.Request(uri);
         request.setMimeType(mimetype);
-        request.setDestinationInExternalFilesDir(activity, null, filename);
+        // set downloaded file destination to /sdcard/Download.
+        // or, should it be set to one of several Environment.DIRECTORY* dirs depending on mimetype?
+        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
         // let this downloaded file be scanned by MediaScanner - so that it can 
         // show up in Gallery app, for example.
         request.allowScanningByMediaScanner();
diff --git a/src/com/android/browser/FetchUrlMimeType.java b/src/com/android/browser/FetchUrlMimeType.java
index 2538d90..85c588e 100644
--- a/src/com/android/browser/FetchUrlMimeType.java
+++ b/src/com/android/browser/FetchUrlMimeType.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.net.Proxy;
 import android.net.http.AndroidHttpClient;
+import android.os.Environment;
 import android.webkit.MimeTypeMap;
 import android.webkit.URLUtil;
 
@@ -116,7 +117,7 @@
            }
            String filename = URLUtil.guessFileName(mUri, contentDisposition,
                 mimeType);
-           mRequest.setDestinationInExternalFilesDir(mActivity, null, filename);
+           mRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
        }
 
        // Start the download
diff --git a/src/com/android/browser/IntentHandler.java b/src/com/android/browser/IntentHandler.java
index bd5595f..e5abb11 100644
--- a/src/com/android/browser/IntentHandler.java
+++ b/src/com/android/browser/IntentHandler.java
@@ -75,7 +75,6 @@
                 return;
             }
             mController.setActiveTab(current);
-            mController.resetTitleAndIcon(current);
         }
         final String action = intent.getAction();
         final int flags = intent.getFlags();
diff --git a/src/com/android/browser/PageDialogsHandler.java b/src/com/android/browser/PageDialogsHandler.java
index 6843a10..2dbddf3 100644
--- a/src/com/android/browser/PageDialogsHandler.java
+++ b/src/com/android/browser/PageDialogsHandler.java
@@ -97,7 +97,7 @@
         mHttpAuthenticationDialog.setCancelListener(new HttpAuthenticationDialog.CancelListener() {
             public void onCancel() {
                 handler.cancel();
-                mController.resetTitleAndRevertLockIcon(tab);
+                mController.onUpdatedLockIcon(tab);
                 mHttpAuthenticationDialog = null;
             }
         });
@@ -138,20 +138,8 @@
 
         final WebView view = tab.getWebView();
 
-        String url = null;
-        String title = null;
-
-        if (view == null) {
-            url = tab.getUrl();
-            title = tab.getTitle();
-        } else if (view == mController.getCurrentWebView()) {
-             // Use the cached title and url if this is the current WebView
-            url = tab.getCurrentUrl();
-            title = tab.getCurrentTitle();
-        } else {
-            url = view.getUrl();
-            title = view.getTitle();
-        }
+        String url = tab.getUrl();
+        String title = tab.getTitle();
 
         if (url == null) {
             url = "";
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index e35e624..99fc4a0 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -103,8 +103,9 @@
     }
 
     @Override
-    public void onProgressChanged(Tab tab, int progress) {
+    public void onProgressChanged(Tab tab) {
         if (tab.inForeground()) {
+            int progress = tab.getLoadProgress();
             mFakeTitleBar.setProgress(progress);
             if (progress == 100) {
                 if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
@@ -134,8 +135,6 @@
         } else {
             revertVoiceTitleBar(tab);
         }
-        resetTitleIconAndProgress(tab);
-        updateLockIconToLatest(tab);
         tab.getTopWindow().requestFocus();
     }
 
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 0ba59f4..491c260 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -22,12 +22,14 @@
 import android.app.AlertDialog;
 import android.app.SearchManager;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnCancelListener;
 import android.content.Intent;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteException;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.net.http.SslError;
 import android.os.AsyncTask;
@@ -55,7 +57,6 @@
 import android.webkit.WebStorage;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -79,9 +80,11 @@
     // of the browser.
     private static final String CONSOLE_LOGTAG = "browser";
 
-    final static int LOCK_ICON_UNSECURE = 0;
-    final static int LOCK_ICON_SECURE   = 1;
-    final static int LOCK_ICON_MIXED    = 2;
+    public enum LockIcon {
+        LOCK_ICON_UNSECURE,
+        LOCK_ICON_SECURE,
+        LOCK_ICON_MIXED,
+    }
 
     Activity mActivity;
     private WebViewController mWebViewController;
@@ -100,8 +103,6 @@
     // information needed to restore the WebView if the user goes back to the
     // tab.
     private Bundle mSavedState;
-    // Data used when displaying the tab in the picker.
-    private PickerData mPickerData;
     // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
     // created by the UI
     private Tab mParentTab;
@@ -115,6 +116,8 @@
     // If true, the tab is in page loading state (after onPageStarted,
     // before onPageFinsihed)
     private boolean mInPageLoad;
+    // The last reported progress of the current page
+    private int mPageLoadProgress;
     // The time the load started, used to find load page time
     private long mLoadStartTime;
     // Application identifier used to find tabs that another application wants
@@ -122,16 +125,8 @@
     private String mAppId;
     // Keep the original url around to avoid killing the old WebView if the url
     // has not changed.
-    private String mOriginalUrl;
-    // Hold on to the currently loaded url
-    private String mCurrentUrl;
-    //The currently loaded title
-    private String mCurrentTitle;
     // Error console for the tab
     private ErrorConsoleView mErrorConsole;
-    // the lock icon type and previous lock icon type for the tab
-    private int mLockIconType;
-    private int mPrevLockIconType;
     // The listener that gets invoked when a download is started from the
     // mMainView
     private final DownloadListener mDownloadListener;
@@ -141,13 +136,53 @@
     // AsyncTask for downloading touch icons
     DownloadTouchIcon mTouchIconLoader;
 
-    // Extra saved information for displaying the tab in the picker.
-    private static class PickerData {
-        String  mUrl;
-        String  mTitle;
-        Bitmap  mFavicon;
+    // All the state needed for a page
+    private static class PageState {
+        String mUrl;
+        String mTitle;
+        LockIcon mLockIcon;
+        Bitmap mFavicon;
+
+        PageState(Context c, boolean incognito) {
+            if (incognito) {
+                mUrl = "browser:incognito";
+                mTitle = c.getString(R.string.new_incognito_tab);
+                mFavicon = BitmapFactory.decodeResource(
+                        c.getResources(), R.drawable.fav_incognito);
+            } else {
+                mUrl = "";
+                mTitle = c.getString(R.string.new_tab);
+                mFavicon = BitmapFactory.decodeResource(
+                        c.getResources(), R.drawable.app_web_browser_sm);
+            }
+            mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
+        }
+
+        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
+            mUrl = url;
+            mTitle = null;
+            if (URLUtil.isHttpsUrl(url)) {
+                mLockIcon = LockIcon.LOCK_ICON_SECURE;
+            } else {
+                mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
+            }
+            if (favicon != null) {
+                mFavicon = favicon;
+            } else {
+                if (incognito) {
+                    mFavicon = BitmapFactory.decodeResource(
+                            c.getResources(), R.drawable.fav_incognito);
+                } else {
+                    mFavicon = BitmapFactory.decodeResource(
+                            c.getResources(), R.drawable.app_web_browser_sm);
+                }
+            }
+        }
     }
 
+    // The current/loading page's state
+    private PageState mCurrentState;
+
     // Whether or not the currently shown page is a bookmarked site.  Will be
     // out of date when loading a new page until the mBookmarkAsyncTask returns.
     private boolean mIsBookmarkedSite;
@@ -157,6 +192,9 @@
     public boolean isBookmarkedSite() { return mIsBookmarkedSite; }
 
     // Used for saving and restoring each Tab
+    // TODO: Figure out who uses what and where
+    //       Some of these aren't use in this class, and some are only used in
+    //       restoring state but not saving it - FIX THIS
     static final String WEBVIEW = "webview";
     static final String NUMTABS = "numTabs";
     static final String CURRTAB = "currentTab";
@@ -472,6 +510,9 @@
         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             mInPageLoad = true;
+            mPageLoadProgress = 0;
+            mCurrentState = new PageState(mActivity,
+                    view.isPrivateBrowsingEnabled(), url, favicon);
             mLoadStartTime = SystemClock.uptimeMillis();
             if (mVoiceSearchData != null
                     && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
@@ -513,7 +554,15 @@
                         url, SystemClock.uptimeMillis() - mLoadStartTime);
             }
             mInPageLoad = false;
-
+            // Sync state (in case of stop/timeout)
+            mCurrentState.mUrl = view.getUrl();
+            mCurrentState.mTitle = view.getTitle();
+            mCurrentState.mFavicon = view.getFavicon();
+            if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
+                // In case we stop when loading an HTTPS page from an HTTP page
+                // but before a provisional load occurred
+                mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
+            }
             mWebViewController.onPageFinished(Tab.this, url);
         }
 
@@ -551,11 +600,11 @@
             if (url != null && url.length() > 0) {
                 // It is only if the page claims to be secure that we may have
                 // to update the lock:
-                if (mLockIconType == LOCK_ICON_SECURE) {
+                if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) {
                     // If NOT a 'safe' url, change the lock to mixed content!
                     if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
                             || URLUtil.isAboutUrl(url))) {
-                        mLockIconType = LOCK_ICON_MIXED;
+                        mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED;
                     }
                 }
             }
@@ -581,11 +630,6 @@
                 Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
                         + " " + description);
             }
-
-            // We need to reset the title after an error if it is in foreground.
-            if (mInForeground) {
-                mWebViewController.resetTitleAndRevertLockIcon(Tab.this);
-            }
         }
 
         /**
@@ -661,6 +705,7 @@
                 final SslErrorHandler handler, final SslError error) {
             if (!mInForeground) {
                 handler.cancel();
+                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
                 return;
             }
             if (BrowserSettings.getInstance().showSecurityWarnings()) {
@@ -723,14 +768,14 @@
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog,
                                     int whichButton) {
-                                handler.cancel();
-                                mWebViewController.resetTitleAndRevertLockIcon(Tab.this);
+                                dialog.cancel();
                             }
                         }).setOnCancelListener(
                         new DialogInterface.OnCancelListener() {
                             public void onCancel(DialogInterface dialog) {
                                 handler.cancel();
-                                mWebViewController.resetTitleAndRevertLockIcon(Tab.this);
+                                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
+                                mWebViewController.onUserCanceledSsl(Tab.this);
                             }
                         }).show();
             } else {
@@ -881,16 +926,19 @@
 
         @Override
         public void onProgressChanged(WebView view, int newProgress) {
-            mWebViewController.onProgressChanged(Tab.this, newProgress);
+            mPageLoadProgress = newProgress;
+            mWebViewController.onProgressChanged(Tab.this);
         }
 
         @Override
         public void onReceivedTitle(WebView view, final String title) {
+            mCurrentState.mTitle = title;
             mWebViewController.onReceivedTitle(Tab.this, title);
         }
 
         @Override
         public void onReceivedIcon(WebView view, Bitmap icon) {
+            mCurrentState.mFavicon = icon;
             mWebViewController.onFavicon(Tab.this, view, icon);
         }
 
@@ -1212,9 +1260,7 @@
         mActivity = mWebViewController.getActivity();
         mCloseOnExit = closeOnExit;
         mAppId = appId;
-        mOriginalUrl = url;
-        mLockIconType = LOCK_ICON_UNSECURE;
-        mPrevLockIconType = LOCK_ICON_UNSECURE;
+        mCurrentState = new PageState(mActivity, w.isPrivateBrowsingEnabled());
         mInPageLoad = false;
         mInForeground = false;
 
@@ -1528,77 +1574,25 @@
         mAppId = id;
     }
 
-    /**
-     * @return The original url associated with this Tab
-     */
-    String getOriginalUrl() {
-        return mOriginalUrl;
-    }
-
-    /**
-     * Set the original url associated with this tab
-     */
-    void setOriginalUrl(String url) {
-        mOriginalUrl = url;
-    }
-
-    /**
-     * set the title for the tab
-     */
-    void setCurrentTitle(String title) {
-        mCurrentTitle = title;
-    }
-
-    /**
-     * set url for this tab
-     * @param url
-     */
-    void setCurrentUrl(String url) {
-        mCurrentUrl = url;
-    }
-
-    String getCurrentTitle() {
-        return mCurrentTitle;
-    }
-
-    String getCurrentUrl() {
-        return mCurrentUrl;
-    }
-    /**
-     * Get the url of this tab. Valid after calling populatePickerData, but
-     * before calling wipePickerData, or if the webview has been destroyed.
-     * @return The WebView's url or null.
-     */
     String getUrl() {
-        if (mPickerData != null) {
-            return mPickerData.mUrl;
-        }
-        return null;
+        return mCurrentState.mUrl;
     }
 
     /**
-     * Get the title of this tab. Valid after calling populatePickerData, but
-     * before calling wipePickerData, or if the webview has been destroyed. If
-     * the url has no title, use the url instead.
-     * @return The WebView's title (or url) or null.
+     * Get the title of this tab.
      */
     String getTitle() {
-        if (mPickerData != null) {
-            return mPickerData.mTitle;
+        if (mCurrentState.mTitle == null && mInPageLoad) {
+            return mActivity.getString(R.string.title_bar_loading);
         }
-        return null;
+        return mCurrentState.mTitle;
     }
 
     /**
-     * Get the favicon of this tab. Valid after calling populatePickerData, but
-     * before calling wipePickerData, or if the webview has been destroyed.
-     * @return The WebView's favicon or null.
+     * Get the favicon of this tab.
      */
     Bitmap getFavicon() {
-        if (mPickerData != null) {
-            return mPickerData.mFavicon;
-        }
-        return null;
+        return mCurrentState.mFavicon;
     }
 
 
@@ -1636,31 +1630,23 @@
         return mCloseOnExit;
     }
 
-    /**
-     * Saves the current lock-icon state before resetting the lock icon. If we
-     * have an error, we may need to roll back to the previous state.
-     */
-    void resetLockIcon(String url) {
-        mPrevLockIconType = mLockIconType;
-        mLockIconType = LOCK_ICON_UNSECURE;
-        if (URLUtil.isHttpsUrl(url)) {
-            mLockIconType = LOCK_ICON_SECURE;
-        }
-    }
-
-    /**
-     * Reverts the lock-icon state to the last saved state, for example, if we
-     * had an error, and need to cancel the load.
-     */
-    void revertLockIcon() {
-        mLockIconType = mPrevLockIconType;
+    private void setLockIconType(LockIcon icon) {
+        mCurrentState.mLockIcon = icon;
+        mWebViewController.onUpdatedLockIcon(this);
     }
 
     /**
      * @return The tab's lock icon type.
      */
-    int getLockIconType() {
-        return mLockIconType;
+    LockIcon getLockIconType() {
+        return mCurrentState.mLockIcon;
+    }
+
+    int getLoadProgress() {
+        if (mInPageLoad) {
+            return mPageLoadProgress;
+        }
+        return 100;
     }
 
     /**
@@ -1677,55 +1663,9 @@
         mInPageLoad = false;
     }
 
-    void populatePickerData() {
-        if (mMainView == null) {
-            populatePickerDataFromSavedState();
-            return;
-        }
-
-        // FIXME: The only place we cared about subwindow was for
-        // bookmarking (i.e. not when saving state). Was this deliberate?
-        final WebBackForwardList list = mMainView.copyBackForwardList();
-        if (list == null) {
-            Log.w(LOGTAG, "populatePickerData called and WebBackForwardList is null");
-        }
-        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
-        populatePickerData(item);
-    }
-
-    // Populate the picker data using the given history item and the current top
-    // WebView.
-    private void populatePickerData(WebHistoryItem item) {
-        mPickerData = new PickerData();
-        if (item == null) {
-            Log.w(LOGTAG, "populatePickerData called with a null WebHistoryItem");
-        } else {
-            mPickerData.mUrl = item.getUrl();
-            mPickerData.mTitle = item.getTitle();
-            mPickerData.mFavicon = item.getFavicon();
-            if (mPickerData.mTitle == null) {
-                mPickerData.mTitle = mPickerData.mUrl;
-            }
-        }
-    }
-
-    // Create the PickerData and populate it using the saved state of the tab.
-    void populatePickerDataFromSavedState() {
-        if (mSavedState == null) {
-            return;
-        }
-        mPickerData = new PickerData();
-        mPickerData.mUrl = mSavedState.getString(CURRURL);
-        mPickerData.mTitle = mSavedState.getString(CURRTITLE);
-    }
-
-    void clearPickerData() {
-        mPickerData = null;
-    }
-
     /**
-     * Get the saved state bundle.
-     * @return
+     * Get the cached saved state bundle.
+     * @return cached state bundle
      */
     Bundle getSavedState() {
         return mSavedState;
@@ -1753,21 +1693,13 @@
 
         // Store some extra info for displaying the tab in the picker.
         final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
-        populatePickerData(item);
 
-        if (mPickerData.mUrl != null) {
-            mSavedState.putString(CURRURL, mPickerData.mUrl);
-        }
-        if (mPickerData.mTitle != null) {
-            mSavedState.putString(CURRTITLE, mPickerData.mTitle);
-        }
+        mSavedState.putString(CURRURL, mCurrentState.mUrl);
+        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
         mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
         if (mAppId != null) {
             mSavedState.putString(APPID, mAppId);
         }
-        if (mOriginalUrl != null) {
-            mSavedState.putString(ORIGINALURL, mOriginalUrl);
-        }
         // Remember the parent tab so the relationship can be restored.
         if (mParentTab != null) {
             mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
@@ -1786,10 +1718,8 @@
         // Restore the internal state even if the WebView fails to restore.
         // This will maintain the app id, original url and close-on-exit values.
         mSavedState = null;
-        mPickerData = null;
         mCloseOnExit = b.getBoolean(CLOSEONEXIT);
         mAppId = b.getString(APPID);
-        mOriginalUrl = b.getString(ORIGINALURL);
 
         final WebBackForwardList list = mMainView.restoreState(b);
         if (list == null) {
@@ -1848,5 +1778,4 @@
         };
         mBookmarkAsyncTask.execute();
     }
-
 }
diff --git a/src/com/android/browser/TabBar.java b/src/com/android/browser/TabBar.java
index ea734a6..88209fe 100644
--- a/src/com/android/browser/TabBar.java
+++ b/src/com/android/browser/TabBar.java
@@ -73,10 +73,8 @@
 
     private boolean mUserRequestedUrlbar;
     private int mVisibleTitleHeight;
-    private boolean mHasReceivedTitle;
 
     private Drawable mGenericFavicon;
-    private String mLoadingText;
 
     private Drawable mActiveDrawable;
     private Drawable mInactiveDrawable;
@@ -111,7 +109,6 @@
         mNewTab = (ImageButton) findViewById(R.id.newtab);
         mNewTab.setOnClickListener(this);
         mGenericFavicon = res.getDrawable(R.drawable.app_web_browser_sm);
-        mLoadingText = res.getString(R.string.title_bar_loading);
         setChildrenDrawingOrderEnabled(true);
 
         // TODO: Change enabled states based on whether you can go
@@ -346,19 +343,16 @@
 
         private void updateFromData() {
             mTabData.mTabView = this;
-            if (mTabData.mUrl != null) {
-                setDisplayTitle(mTabData.mUrl);
+            Tab tab = mTabData.mTab;
+            String displayTitle = tab.getTitle();
+            if (displayTitle == null) {
+                displayTitle = tab.getUrl();
             }
-            if (mTabData.mTitle != null) {
-                setDisplayTitle(mTabData.mTitle);
-            }
+            setDisplayTitle(displayTitle);
             setProgress(mTabData.mProgress);
             if (mTabData.mIcon != null) {
                 setFavicon(mTabData.mIcon);
             }
-            if (mTabData.mLock != null) {
-                setLock(mTabData.mLock);
-            }
             if (mTabData.mTab != null) {
                 mIncognito.setVisibility(
                         mTabData.mTab.isPrivateBrowsingEnabled() ?
@@ -463,21 +457,13 @@
         TabView mTabView;
         int mProgress;
         Drawable mIcon;
-        Drawable mLock;
-        String mTitle;
-        String mUrl;
 
         TabViewData(Tab tab) {
             mTab = tab;
-            WebView web = tab.getWebView();
-            if (web != null) {
-                setUrlAndTitle(web.getUrl(), web.getTitle());
-            }
+            setUrlAndTitle(mTab.getUrl(), mTab.getTitle());
         }
 
         void setUrlAndTitle(String url, String title) {
-            mUrl = url;
-            mTitle = title;
             if (mTabView != null) {
                 if (title != null) {
                     mTabView.setDisplayTitle(title);
@@ -562,31 +548,12 @@
     }
 
     public void onUrlAndTitle(Tab tab, String url, String title) {
-        mHasReceivedTitle = true;
         TabViewData tvd = mTabMap.get(tab);
         if (tvd != null) {
             tvd.setUrlAndTitle(url, title);
         }
     }
 
-    public void onPageFinished(Tab tab) {
-        if (!mHasReceivedTitle) {
-            TabViewData tvd = mTabMap.get(tab);
-            if (tvd != null) {
-                tvd.setUrlAndTitle(tvd.mUrl, null);
-            }
-        }
-    }
-
-    public void onPageStarted(Tab tab, String url, Bitmap favicon) {
-        mHasReceivedTitle = false;
-        TabViewData tvd = mTabMap.get(tab);
-        if (tvd != null) {
-            tvd.setFavicon(favicon);
-            tvd.setUrlAndTitle(url, mLoadingText);
-        }
-    }
-
     private boolean isLoading() {
         TabViewData tvd = mTabMap.get(mTabControl.getCurrentTab());
         if ((tvd != null) && (tvd.mTabView != null)) {
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index 9e669ce..050ad94 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -350,11 +350,9 @@
                     Tab t = new Tab(mController, null, false, null, null);
                     if (state != null) {
                         t.setSavedState(state);
-                        t.populatePickerDataFromSavedState();
                         // Need to maintain the app id and original url so we
                         // can possibly reuse this tab.
                         t.setAppId(state.getString(Tab.APPID));
-                        t.setOriginalUrl(state.getString(Tab.ORIGINALURL));
                     }
                     mTabs.add(t);
                     // added the tab to the front as they are not current
@@ -537,28 +535,11 @@
     }
 
     /**
-     * Recreate the main WebView of the given tab. Returns true if the WebView
-     * requires a load, whether it was due to the fact that it was deleted, or
-     * it is because it was a voice search.
+     * Recreate the main WebView of the given tab.
      */
-    boolean recreateWebView(Tab t, UrlData urlData) {
-        final String url = urlData.mUrl;
+    void recreateWebView(Tab t) {
         final WebView w = t.getWebView();
         if (w != null) {
-            if (url != null && url.equals(t.getOriginalUrl())
-                    // Treat a voice intent as though it is a different URL,
-                    // since it most likely is.
-                    && urlData.mVoiceIntent == null) {
-                // The original url matches the current url. Just go back to the
-                // first history item so we can load it faster than if we
-                // rebuilt the WebView.
-                final WebBackForwardList list = w.copyBackForwardList();
-                if (list != null) {
-                    w.goBackOrForward(-list.getCurrentIndex());
-                    w.clearHistory(); // maintains the current page.
-                    return false;
-                }
-            }
             t.destroy();
         }
         // Create a new WebView. If this tab is the current tab, we need to put
@@ -569,10 +550,6 @@
         }
         // Clear the saved state and picker data
         t.setSavedState(null);
-        t.clearPickerData();
-        // Save the new url in order to avoid deleting the WebView.
-        t.setOriginalUrl(url);
-        return true;
     }
 
     /**
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index 9f03344..e2f76f1 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -64,23 +64,11 @@
 
     public void removeSubWindow(View subContainer);
 
-    // TODO: consolidate
-    public void setUrlTitle(Tab tab, String url, String title);
-
-    // TODO: consolidate
-    public void setFavicon(Tab tab, Bitmap icon);
-
-    public void resetTitleAndRevertLockIcon(Tab tab);
-
-    public void resetTitleAndIcon(Tab tab);
-
-    public void onPageStarted(Tab tab, String url, Bitmap favicon);
-
-    public void onPageFinished(Tab tab, String url);
+    public void onTabDataChanged(Tab tab);
 
     public void onPageStopped(Tab tab);
 
-    public void onProgressChanged(Tab tab, int progress);
+    public void onProgressChanged(Tab tab);
 
     public void showActiveTabsPage();
 
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index 64e97de..a187af0 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -50,7 +50,7 @@
 
     void onPageFinished(Tab tab, String url);
 
-    void onProgressChanged(Tab tab, int newProgress);
+    void onProgressChanged(Tab tab);
 
     void onReceivedTitle(Tab tab, final String title);
 
@@ -83,13 +83,15 @@
     void showSslCertificateOnError(WebView view, SslErrorHandler handler,
             SslError error);
 
+    void onUserCanceledSsl(Tab tab);
+
     void activateVoiceSearchMode(String title);
 
     void revertVoiceSearchMode(Tab tab);
 
     boolean shouldShowErrorConsole();
 
-    void resetTitleAndRevertLockIcon(Tab tab);
+    void onUpdatedLockIcon(Tab tab);
 
     void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType);
 
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 11642af..dcba39b 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -145,12 +145,6 @@
     // WebView callbacks
 
     @Override
-    public void onPageStarted(Tab tab, String url, Bitmap favicon) {
-        super.onPageStarted(tab, url, favicon);
-        mTabBar.onPageStarted(tab, url, favicon);
-    }
-
-    @Override
     public void bookmarkedStatusHasChanged(Tab tab) {
         if (tab.inForeground()) {
             boolean isBookmark = tab.isBookmarkedSite();
@@ -160,16 +154,8 @@
     }
 
     @Override
-    public void onPageFinished(Tab tab, String url) {
-        mTabBar.onPageFinished(tab);
-        super.onPageFinished(tab, url);
-        if (mUseQuickControls) {
-            mFakeTitleBar.setShowProgressOnly(false);
-        }
-    }
-
-    @Override
-    public void onProgressChanged(Tab tab, int progress) {
+    public void onProgressChanged(Tab tab) {
+        int progress = tab.getLoadProgress();
         mTabBar.onProgress(tab, progress);
         if (tab.inForeground()) {
             mFakeTitleBar.setProgress(progress);
@@ -229,7 +215,6 @@
         } else {
             revertVoiceTitleBar(tab);
         }
-        resetTitleIconAndProgress(tab);
         updateLockIconToLatest(tab);
         tab.getTopWindow().requestFocus();
     }
@@ -331,16 +316,16 @@
     }
 
     @Override
-    public void setUrlTitle(Tab tab, String url, String title) {
-        super.setUrlTitle(tab, url, title);
-        mTabBar.onUrlAndTitle(tab, url, title);
+    public void setUrlTitle(Tab tab) {
+        super.setUrlTitle(tab);
+        mTabBar.onUrlAndTitle(tab, tab.getUrl(), tab.getTitle());
     }
 
     // Set the favicon in the title bar.
     @Override
-    public void setFavicon(Tab tab, Bitmap icon) {
-        super.setFavicon(tab, icon);
-        mTabBar.onFavicon(tab, icon);
+    public void setFavicon(Tab tab) {
+        super.setFavicon(tab);
+        mTabBar.onFavicon(tab, tab.getFavicon());
     }
 
     @Override
@@ -358,7 +343,7 @@
     @Override
     public void revertVoiceTitleBar(Tab tab) {
         mTitleBar.setInVoiceMode(false, null);
-        String url = tab.getCurrentUrl();
+        String url = tab.getUrl();
         mTitleBar.setDisplayTitle(url);
         mFakeTitleBar.setInVoiceMode(false, null);
         mFakeTitleBar.setDisplayTitle(url);