Merge "Bookmark widget asset update"
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/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/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/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);