OSDN Git Service

don't create the fake title bar when getGlobalVisible fails
[android-x86/packages-apps-Browser.git] / src / com / android / browser / BrowserActivity.java
index a9fa8f5..15f986e 100644 (file)
@@ -45,6 +45,7 @@ import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.DrawFilter;
 import android.graphics.Paint;
@@ -56,6 +57,7 @@ import android.graphics.drawable.Drawable;
 import android.hardware.SensorListener;
 import android.hardware.SensorManager;
 import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
 import android.net.Uri;
 import android.net.WebAddress;
 import android.net.http.EventHandler;
@@ -74,14 +76,15 @@ import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.provider.Browser;
-import android.provider.Contacts;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Intents.Insert;
 import android.provider.Downloads;
 import android.provider.MediaStore;
-import android.provider.Contacts.Intents.Insert;
 import android.text.IClipboard;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.text.util.Regex;
+import android.util.AttributeSet;
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.Gravity;
@@ -90,7 +93,6 @@ import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -148,8 +150,7 @@ import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 public class BrowserActivity extends Activity
-    implements KeyTracker.OnKeyTracker,
-        View.OnCreateContextMenuListener,
+    implements View.OnCreateContextMenuListener,
         DownloadListener {
 
     /* Define some aliases to make these debugging flags easier to refer to.
@@ -298,7 +299,6 @@ public class BrowserActivity extends Activity
             Log.v(LOGTAG, this + " onStart");
         }
         super.onCreate(icicle);
-        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
         // test the browser in OpenGL
         // requestWindowFeature(Window.FEATURE_OPENGL);
 
@@ -306,6 +306,13 @@ public class BrowserActivity extends Activity
 
         mResolver = getContentResolver();
 
+        // If this was a web search request, pass it on to the default web
+        // search provider and finish this activity.
+        if (handleWebSearchIntent(getIntent())) {
+            finish();
+            return;
+        }
+
         //
         // start MASF proxy service
         //
@@ -332,7 +339,7 @@ public class BrowserActivity extends Activity
         mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
                 .findViewById(R.id.fullscreen_custom_content);
         frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
-        mTitleBar = new TitleBarSet(this);
+        mTitleBar = new TitleBar(this);
 
         // Create the tab control and our initial tab
         mTabControl = new TabControl(this);
@@ -358,9 +365,11 @@ public class BrowserActivity extends Activity
                 public void onReceive(Context context, Intent intent) {
                     if (intent.getAction().equals(
                             ConnectivityManager.CONNECTIVITY_ACTION)) {
-                        boolean down = intent.getBooleanExtra(
-                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
-                        onNetworkToggle(!down);
+                        NetworkInfo info =
+                                (NetworkInfo) intent.getParcelableExtra(
+                                        ConnectivityManager.EXTRA_NETWORK_INFO);
+                        onNetworkToggle(
+                                (info != null) ? info.isConnected() : false);
                     }
                 }
             };
@@ -411,12 +420,6 @@ public class BrowserActivity extends Activity
         };
         registerReceiver(mPackageInstallationReceiver, filter);
 
-        // If this was a web search request, pass it on to the default web search provider.
-        if (handleWebSearchIntent(getIntent())) {
-            moveTaskToBack(true);
-            return;
-        }
-
         if (!mTabControl.restoreState(icicle)) {
             // clear up the thumbnail directory if we can't restore the state as
             // none of the files in the directory are referenced any more.
@@ -474,15 +477,6 @@ public class BrowserActivity extends Activity
             attachTabToContentView(mTabControl.getCurrentTab());
         }
 
-        mTitleBar.init(this);
-        // Create title bars for all of the tabs that have been created
-        for (int i = 0; i < mTabControl.getTabCount(); i ++) {
-            WebView view = mTabControl.getTab(i).getWebView();
-            mTitleBar.addTab(view, false);
-        }
-
-        mTitleBar.setCurrentTab(mTabControl.getCurrentIndex());
-
         // Read JavaScript flags if it exists.
         String jsFlags = mSettings.getJsFlags();
         if (jsFlags.trim().length() != 0) {
@@ -503,7 +497,6 @@ public class BrowserActivity extends Activity
                 return;
             }
             mTabControl.setCurrentTab(current);
-            mTitleBar.setCurrentTab(mTabControl.getTabIndex(current));
             attachTabToContentView(current);
             resetTitleAndIcon(current.getWebView());
         }
@@ -626,7 +619,8 @@ public class BrowserActivity extends Activity
                 || Intent.ACTION_WEB_SEARCH.equals(action)) {
             url = intent.getStringExtra(SearchManager.QUERY);
         }
-        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA));
+        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
+                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
     }
 
     /**
@@ -634,7 +628,7 @@ public class BrowserActivity extends Activity
      * was identified as plain search terms and not URL/shortcut.
      * @return true if the request was handled and web search activity was launched, false if not.
      */
-    private boolean handleWebSearchRequest(String inUrl, Bundle appData) {
+    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
         if (inUrl == null) return false;
 
         // In general, we shouldn't modify URL from Intent.
@@ -658,6 +652,9 @@ public class BrowserActivity extends Activity
         if (appData != null) {
             intent.putExtra(SearchManager.APP_DATA, appData);
         }
+        if (extraData != null) {
+            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
+        }
         intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
         startActivity(intent);
 
@@ -892,6 +889,19 @@ public class BrowserActivity extends Activity
     private TitleBar mFakeTitleBar;
 
     /**
+     * Holder for the fake title bar.  It will have a foreground shadow, as well
+     * as a white background, so the fake title bar looks like the real one.
+     */
+    private ViewGroup mFakeTitleBarHolder;
+
+    /**
+     * Layout parameters for the fake title bar within mFakeTitleBarHolder
+     */
+    private FrameLayout.LayoutParams mFakeTitleBarParams
+            = new FrameLayout.LayoutParams(
+            ViewGroup.LayoutParams.FILL_PARENT,
+            ViewGroup.LayoutParams.WRAP_CONTENT);
+    /**
      * Keeps track of whether the options menu is open.  This is important in
      * determining whether to show or hide the title bar overlay.
      */
@@ -945,35 +955,54 @@ public class BrowserActivity extends Activity
         return true;
     }
 
+    /**
+     * Special class used exclusively for the shadow drawn underneath the fake
+     * title bar.  The shadow does not need to be drawn if the WebView
+     * underneath is scrolled to the top, because it will draw directly on top
+     * of the embedded shadow.
+     */
+    private static class Shadow extends View {
+        private WebView mWebView;
+
+        public Shadow(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public void setWebView(WebView view) {
+            mWebView = view;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            // In general onDraw is the method to override, but we care about
+            // whether or not the background gets drawn, which happens in draw()
+            if (mWebView == null || mWebView.getScrollY() > getHeight()) {
+                super.draw(canvas);
+            }
+            // Need to invalidate so that if the scroll position changes, we
+            // still draw as appropriate.
+            invalidate();
+        }
+    }
+
     private void showFakeTitleBar() {
-        if (mFakeTitleBar == null || mActiveTabsPage != null) {
+        final View decor = getWindow().peekDecorView();
+        if (mFakeTitleBar == null && mActiveTabsPage == null
+                && !mActivityInPause && decor != null
+                && decor.getWindowToken() != null) {
+            Rect visRect = new Rect();
+            if (!mBrowserFrameLayout.getGlobalVisibleRect(visRect)) {
+                if (LOGD_ENABLED) {
+                    Log.d(LOGTAG, "showFakeTitleBar visRect failed");
+                }
+                return;
+            }
             final WebView webView = getTopWindow();
-            mFakeTitleBar = new TitleBar(this, webView);
+            mFakeTitleBar = new TitleBar(this);
             mFakeTitleBar.setTitleAndUrl(null, webView.getUrl());
             mFakeTitleBar.setProgress(webView.getProgress());
             mFakeTitleBar.setFavicon(webView.getFavicon());
             updateLockIconToLatest();
-            final View title = mFakeTitleBar.findViewById(R.id.title);
-            mFakeTitleBar.setOnTouchListener(new View.OnTouchListener() {
-                    public boolean onTouch(View v, MotionEvent event) {
-                        if (event.getAction() == MotionEvent.ACTION_UP) {
-                            if (event.getX() > title.getRight()) {
-                                if (webView != null
-                                        && webView.getProgress() < 100) {
-                                    if (webView != null) {
-                                        webView.stopLoading();
-                                    }
-                                } else {
-                                    bookmarksOrHistoryPicker(false);
-                                }
-                            } else {
-                                onSearchRequested();
-                            }
-                            closeOptionsMenu();
-                        }
-                        return true;
-                    }
-            });
 
             WindowManager manager
                     = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
@@ -986,19 +1015,27 @@ public class BrowserActivity extends Activity
                     ViewGroup.LayoutParams.WRAP_CONTENT,
                     WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
                     WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
-                    PixelFormat.OPAQUE);
+                    PixelFormat.TRANSLUCENT);
             params.gravity = Gravity.TOP;
             WebView mainView = mTabControl.getCurrentWebView();
-            params.windowAnimations = mainView == null
-                    || mainView.getScrollY() != 0
-                    ? com.android.internal.R.style.Animation_DropDownDown : 0;
+            boolean atTop = mainView != null && mainView.getScrollY() == 0;
+            params.windowAnimations = atTop ? 0
+                    : com.android.internal.R.style.Animation_DropDownDown;
             // XXX : Without providing an offset, the fake title bar will be
             // placed underneath the status bar.  Use the global visible rect
             // of mBrowserFrameLayout to determine the bottom of the status bar
-            Rect rectangle = new Rect();
-            mBrowserFrameLayout.getGlobalVisibleRect(rectangle);
-            params.y = rectangle.top;
-            manager.addView(mFakeTitleBar, params);
+            params.y = visRect.top;
+            // Add a holder for the title bar.  It also holds a shadow to show
+            // below the title bar.
+            if (mFakeTitleBarHolder == null) {
+                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
+                    .inflate(R.layout.title_bar_bg, null);
+            }
+            Shadow shadow = (Shadow) mFakeTitleBarHolder.findViewById(
+                    R.id.shadow);
+            shadow.setWebView(mainView);
+            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
+            manager.addView(mFakeTitleBarHolder, params);
         }
     }
 
@@ -1016,13 +1053,36 @@ public class BrowserActivity extends Activity
     }
     private void hideFakeTitleBar() {
         if (mFakeTitleBar == null) return;
+        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
+                mFakeTitleBarHolder.getLayoutParams();
+        WebView mainView = mTabControl.getCurrentWebView();
+        // Although we decided whether or not to animate based on the current
+        // scroll position, the scroll position may have changed since the
+        // fake title bar was displayed.  Make sure it has the appropriate
+        // animation/lack thereof before removing.
+        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
+                ? 0 : com.android.internal.R.style.Animation_DropDownDown;
         WindowManager manager
                     = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
-        manager.removeView(mFakeTitleBar);
+        manager.updateViewLayout(mFakeTitleBarHolder, params);
+        mFakeTitleBarHolder.removeView(mFakeTitleBar);
+        manager.removeView(mFakeTitleBarHolder);
         mFakeTitleBar = null;
     }
 
     /**
+     * Special method for the fake title bar to call when displaying its context
+     * menu, since it is in its own Window, and its parent does not show a
+     * context menu.
+     */
+    /* package */ void showTitleBarContextMenu() {
+        if (null == mTitleBar.getParent()) {
+            return;
+        }
+        openContextMenu(mTitleBar);
+    }
+
+    /**
      *  onSaveInstanceState(Bundle map)
      *  onSaveInstanceState is called right before onStop(). The map contains
      *  the saved state.
@@ -1087,6 +1147,9 @@ public class BrowserActivity extends Activity
             Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
         }
         super.onDestroy();
+
+        if (mTabControl == null) return;
+
         // Remove the current tab and sub window
         TabControl.Tab t = mTabControl.getCurrentTab();
         if (t != null) {
@@ -1299,15 +1362,20 @@ public class BrowserActivity extends Activity
         // options selector, so set mCanChord to true so we can access them.
         mCanChord = true;
         int id = item.getItemId();
-        final WebView webView = getTopWindow();
-        if (null == webView) {
-            return false;
-        }
-        final HashMap hrefMap = new HashMap();
-        hrefMap.put("webview", webView);
-        final Message msg = mHandler.obtainMessage(
-                FOCUS_NODE_HREF, id, 0, hrefMap);
         switch (id) {
+            // For the context menu from the title bar
+            case R.id.title_bar_share_page_url:
+            case R.id.title_bar_copy_page_url:
+                WebView mainView = mTabControl.getCurrentWebView();
+                if (null == mainView) {
+                    return false;
+                }
+                if (id == R.id.title_bar_share_page_url) {
+                    Browser.sendString(this, mainView.getUrl());
+                } else {
+                    copy(mainView.getUrl());
+                }
+                break;
             // -- Browser context menu
             case R.id.open_context_menu_id:
             case R.id.open_newtab_context_menu_id:
@@ -1315,6 +1383,14 @@ public class BrowserActivity extends Activity
             case R.id.save_link_context_menu_id:
             case R.id.share_link_context_menu_id:
             case R.id.copy_link_context_menu_id:
+                final WebView webView = getTopWindow();
+                if (null == webView) {
+                    return false;
+                }
+                final HashMap hrefMap = new HashMap();
+                hrefMap.put("webview", webView);
+                final Message msg = mHandler.obtainMessage(
+                        FOCUS_NODE_HREF, id, 0, hrefMap);
                 webView.requestFocusNodeHref(msg);
                 break;
 
@@ -1337,6 +1413,7 @@ public class BrowserActivity extends Activity
      */
     @Override
     public boolean onSearchRequested() {
+        if (mOptionsMenuOpen) closeOptionsMenu();
         String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
         startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
                 createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
@@ -1372,11 +1449,10 @@ public class BrowserActivity extends Activity
             // we do not need to remove it
             removeTabFromContentView(currentTab);
         }
-        removeTabFromContentView(tab);
         mTabControl.setCurrentTab(tab);
         attachTabToContentView(tab);
-        mTitleBar.setCurrentTab(index);
-        resetTitle();
+        resetTitleIconAndProgress();
+        updateLockIconToLatest();
         return true;
     }
 
@@ -1453,6 +1529,10 @@ public class BrowserActivity extends Activity
                 break;
 
             case R.id.goto_menu_id:
+                onSearchRequested();
+                break;
+
+            case R.id.bookmarks_menu_id:
                 bookmarksOrHistoryPicker(false);
                 break;
 
@@ -1471,6 +1551,8 @@ public class BrowserActivity extends Activity
                 WebView w = getTopWindow();
                 i.putExtra("url", w.getUrl());
                 i.putExtra("title", w.getTitle());
+                i.putExtra("touch_icon_url", w.getTouchIconUrl());
+                i.putExtra("thumbnail", createScreenshot(w));
                 startActivity(i);
                 break;
 
@@ -1534,7 +1616,8 @@ public class BrowserActivity extends Activity
                 break;
 
             case R.id.share_page_menu_id:
-                Browser.sendString(this, getTopWindow().getUrl());
+                Browser.sendString(this, getTopWindow().getUrl(),
+                        getText(R.string.choosertitle_sharevia).toString());
                 break;
 
             case R.id.dump_nav_menu_id:
@@ -1701,7 +1784,7 @@ public class BrowserActivity extends Activity
                                 .parse(WebView.SCHEME_TEL + extra)));
                 Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
                 addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
-                addIntent.setType(Contacts.People.CONTENT_ITEM_TYPE);
+                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
                 menu.findItem(R.id.add_contact_context_menu_id).setIntent(
                         addIntent);
                 menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
@@ -1763,10 +1846,11 @@ public class BrowserActivity extends Activity
     }
 
     // Attach the given tab to the content view.
+    // this should only be called for the current tab.
     private void attachTabToContentView(TabControl.Tab t) {
         // Attach the container that contains the main WebView and any other UI
         // associated with the tab.
-        mContentView.addView(t.getContainer(), COVER_SCREEN_PARAMS);
+        t.attachTabToContentView(mContentView);
 
         if (mShouldShowErrorConsole) {
             ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
@@ -1781,29 +1865,30 @@ public class BrowserActivity extends Activity
                                                   ViewGroup.LayoutParams.WRAP_CONTENT));
         }
 
+        setLockIconType(t.getLockIconType());
+        setPrevLockType(t.getPrevLockIconType());
+
+        // this is to match the code in removeTabFromContentView()
+        if (!mPageStarted && t.getTopWindow().getProgress() < 100) {
+            mPageStarted = true;
+        }
+
         WebView view = t.getWebView();
         view.setEmbeddedTitleBar(mTitleBar);
-        // Attach the sub window if necessary
-        attachSubWindow(t);
         // Request focus on the top window.
         t.getTopWindow().requestFocus();
     }
 
     // Attach a sub window to the main WebView of the given tab.
     private void attachSubWindow(TabControl.Tab t) {
-        // If a sub window exists, attach it to the content view.
-        final WebView subView = t.getSubWebView();
-        if (subView != null) {
-            final View container = t.getSubWebViewContainer();
-            mContentView.addView(container, COVER_SCREEN_PARAMS);
-            subView.requestFocus();
-        }
+        t.attachSubWindow(mContentView);
+        getTopWindow().requestFocus();
     }
 
     // Remove the given tab from the content view.
     private void removeTabFromContentView(TabControl.Tab t) {
         // Remove the container that contains the main WebView.
-        mContentView.removeView(t.getContainer());
+        t.removeTabFromContentView(mContentView);
 
         if (mTabControl.getCurrentErrorConsole(false) != null) {
             mErrorConsoleContainer.removeView(mTabControl.getCurrentErrorConsole(false));
@@ -1814,24 +1899,32 @@ public class BrowserActivity extends Activity
             view.setEmbeddedTitleBar(null);
         }
 
-        // Remove the sub window if it exists.
-        if (t.getSubWebView() != null) {
-            mContentView.removeView(t.getSubWebViewContainer());
+        // unlike attachTabToContentView(), removeTabFromContentView() can be
+        // called for the non-current tab. Need to add the check.
+        if (t == mTabControl.getCurrentTab()) {
+            t.setLockIconType(getLockIconType());
+            t.setPrevLockIconType(getPrevLockType());
+
+            // this is not a perfect solution. But currently there is one
+            // WebViewClient for all the WebView. if user switches from an
+            // in-load window to an already loaded window, mPageStarted will not
+            // be set to false. If user leaves the Browser, pauseWebViewTimers()
+            // won't do anything and leaves the timer running even Browser is in
+            // the background.
+            if (mPageStarted) {
+                mPageStarted = false;
+            }
         }
     }
 
     // Remove the sub window if it exists. Also called by TabControl when the
     // user clicks the 'X' to dismiss a sub window.
     /* package */ void dismissSubWindow(TabControl.Tab t) {
-        final WebView mainView = t.getWebView();
-        if (t.getSubWebView() != null) {
-            // Remove the container view and request focus on the main WebView.
-            mContentView.removeView(t.getSubWebViewContainer());
-            mainView.requestFocus();
-            // Tell the TabControl to dismiss the subwindow. This will destroy
-            // the WebView.
-            mTabControl.dismissSubWindow(t);
-        }
+        t.removeSubWindow(mContentView);
+        // Tell the TabControl to dismiss the subwindow. This will destroy
+        // the WebView.
+        mTabControl.dismissSubWindow(t);
+        getTopWindow().requestFocus();
     }
 
     // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
@@ -1852,16 +1945,15 @@ public class BrowserActivity extends Activity
             final TabControl.Tab tab = mTabControl.createNewTab(
                     closeOnExit, appId, urlData.mUrl);
             WebView webview = tab.getWebView();
-            mTitleBar.addTab(webview, true);
             // If the last tab was removed from the active tabs page, currentTab
             // will be null.
             if (currentTab != null) {
                 removeTabFromContentView(currentTab);
             }
-            attachTabToContentView(tab);
             // We must set the new tab as the current tab to reflect the old
             // animation behavior.
             mTabControl.setCurrentTab(tab);
+            attachTabToContentView(tab);
             if (!urlData.isEmpty()) {
                 urlData.loadIn(webview);
             }
@@ -1882,7 +1974,6 @@ public class BrowserActivity extends Activity
             TabControl.Tab t = mTabControl.createNewTab();
             if (t != null) {
                 WebView view = t.getWebView();
-                mTitleBar.addTab(view, false);
                 view.loadUrl(url);
             }
             return t;
@@ -1929,15 +2020,6 @@ public class BrowserActivity extends Activity
     }
 
     /**
-     * Resets the browser title-view to whatever it must be (for example, if we
-     * load a page from history).
-     */
-    private void resetTitle() {
-        resetLockIcon();
-        resetTitleIconAndProgress();
-    }
-
-    /**
      * 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
@@ -1967,10 +2049,10 @@ public class BrowserActivity extends Activity
     private void resetTitleAndIcon(WebView view) {
         WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
         if (item != null) {
-            setUrlTitle(item.getUrl(), item.getTitle(), view);
+            setUrlTitle(item.getUrl(), item.getTitle());
             setFavicon(item.getFavicon());
         } else {
-            setUrlTitle(null, null, view);
+            setUrlTitle(null, null);
             setFavicon(null);
         }
     }
@@ -1980,11 +2062,11 @@ public class BrowserActivity extends Activity
      * @param url The URL of the site being loaded.
      * @param title The title of the site being loaded.
      */
-    private void setUrlTitle(String url, String title, WebView view) {
+    private void setUrlTitle(String url, String title) {
         mUrl = url;
         mTitle = title;
 
-        mTitleBar.setTitleAndUrl(title, url, view);
+        mTitleBar.setTitleAndUrl(title, url);
         if (mFakeTitleBar != null) {
             mFakeTitleBar.setTitleAndUrl(title, url);
         }
@@ -2029,7 +2111,7 @@ public class BrowserActivity extends Activity
 
     // Set the favicon in the title bar.
     private void setFavicon(Bitmap icon) {
-        mTitleBar.setFavicon(icon, getTopWindow());
+        mTitleBar.setFavicon(icon);
         if (mFakeTitleBar != null) {
             mFakeTitleBar.setFavicon(icon);
         }
@@ -2067,12 +2149,12 @@ public class BrowserActivity extends Activity
     /* package */ void closeTab(TabControl.Tab t) {
         int currentIndex = mTabControl.getCurrentIndex();
         int removeIndex = mTabControl.getTabIndex(t);
-        mTitleBar.removeTab(removeIndex);
         mTabControl.removeTab(t);
         if (currentIndex >= removeIndex && currentIndex != 0) {
             currentIndex--;
         }
         mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
+        resetTitleIconAndProgress();
     }
 
     private void goBackOnePageOrQuit() {
@@ -2086,6 +2168,7 @@ public class BrowserActivity extends Activity
              * moveTaskToBack().
              */
             moveTaskToBack(true);
+            return;
         }
         WebView w = current.getWebView();
         if (w.canGoBack()) {
@@ -2122,7 +2205,6 @@ public class BrowserActivity extends Activity
                     pauseWebViewTimers();
                     mActivityInPause = savedState;
                     removeTabFromContentView(current);
-                    mTitleBar.removeTab(mTabControl.getTabIndex(current));
                     mTabControl.removeTab(current);
                 }
                 /*
@@ -2137,83 +2219,76 @@ public class BrowserActivity extends Activity
         }
     }
 
-    public KeyTracker.State onKeyTracker(int keyCode,
-                                         KeyEvent event,
-                                         KeyTracker.Stage stage,
-                                         int duration) {
-        // if onKeyTracker() is called after activity onStop()
-        // because of accumulated key events,
-        // we should ignore it as browser is not active any more.
-        WebView topWindow = getTopWindow();
-        if (topWindow == null && mCustomView == null)
-            return KeyTracker.State.NOT_TRACKING;
-
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            // Check if a custom view is currently showing and, if it is, hide it.
-            if (mCustomView != null) {
-                mWebChromeClient.onHideCustomView();
-                return KeyTracker.State.DONE_TRACKING;
-            }
-            if (stage == KeyTracker.Stage.LONG_REPEAT) {
-                bookmarksOrHistoryPicker(true);
-                return KeyTracker.State.DONE_TRACKING;
-            } else if (stage == KeyTracker.Stage.UP) {
-                // FIXME: Currently, we do not have a notion of the
-                // history picker for the subwindow, but maybe we
-                // should?
-                WebView subwindow = mTabControl.getCurrentSubWindow();
-                if (subwindow != null) {
-                    if (subwindow.canGoBack()) {
-                        subwindow.goBack();
-                    } else {
-                        dismissSubWindow(mTabControl.getCurrentTab());
-                    }
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
+        // still down, we don't want to trigger the search. Pretend to consume
+        // the key and do nothing.
+        if (mMenuIsDown) return true;
+
+        switch(keyCode) {
+            case KeyEvent.KEYCODE_MENU:
+                mMenuIsDown = true;
+                break;
+            case KeyEvent.KEYCODE_SPACE:
+                // WebView/WebTextView handle the keys in the KeyDown. As
+                // the Activity's shortcut keys are only handled when WebView
+                // doesn't, have to do it in onKeyDown instead of onKeyUp.
+                if (event.isShiftPressed()) {
+                    getTopWindow().pageUp(false);
                 } else {
-                    goBackOnePageOrQuit();
+                    getTopWindow().pageDown(false);
                 }
-                return KeyTracker.State.DONE_TRACKING;
-            }
-            return KeyTracker.State.KEEP_TRACKING;
+                return true;
+            case KeyEvent.KEYCODE_BACK:
+                if (event.getRepeatCount() == 0) {
+                    event.startTracking();
+                    return true;
+                } else if (mCustomView == null && mActiveTabsPage == null
+                        && event.isLongPress()) {
+                    bookmarksOrHistoryPicker(true);
+                    return true;
+                }
+                break;
         }
-        return KeyTracker.State.NOT_TRACKING;
+        return super.onKeyDown(keyCode, event);
     }
 
-    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_MENU) {
-            mMenuIsDown = true;
-        } else if (mMenuIsDown) {
-            // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
-            // still down, we don't want to trigger the search. Pretend to
-            // consume the key and do nothing.
-            return true;
-        }
-        boolean handled =  mKeyTracker.doKeyDown(keyCode, event);
-        if (!handled) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_SPACE:
-                    if (event.isShiftPressed()) {
-                        getTopWindow().pageUp(false);
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        switch(keyCode) {
+            case KeyEvent.KEYCODE_MENU:
+                mMenuIsDown = false;
+                break;
+            case KeyEvent.KEYCODE_BACK:
+                if (event.isTracking() && !event.isCanceled()) {
+                    if (mCustomView != null) {
+                        // if a custom view is showing, hide it
+                        mWebChromeClient.onHideCustomView();
+                    } else if (mActiveTabsPage != null) {
+                        // if tab page is showing, hide it
+                        removeActiveTabPage(true);
                     } else {
-                        getTopWindow().pageDown(false);
+                        WebView subwindow = mTabControl.getCurrentSubWindow();
+                        if (subwindow != null) {
+                            if (subwindow.canGoBack()) {
+                                subwindow.goBack();
+                            } else {
+                                dismissSubWindow(mTabControl.getCurrentTab());
+                            }
+                        } else {
+                            goBackOnePageOrQuit();
+                        }
                     }
-                    handled = true;
-                    break;
-
-                default:
-                    break;
-            }
-        }
-        return handled || super.onKeyDown(keyCode, event);
-    }
-
-    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_MENU) {
-            mMenuIsDown = false;
+                    return true;
+                }
+                break;
         }
-        return mKeyTracker.doKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
+        return super.onKeyUp(keyCode, event);
     }
 
-    private void stopLoading() {
+    /* package */ void stopLoading() {
+        mDidStopLoad = true;
         resetTitleAndRevertLockIcon();
         WebView w = getTopWindow();
         w.stopLoading();
@@ -2246,12 +2321,15 @@ public class BrowserActivity extends Activity
     private static final int CANCEL_CREDS_REQUEST    = 103;
     private static final int RELEASE_WAKELOCK        = 107;
 
+    private static final int UPDATE_BOOKMARK_THUMBNAIL = 108;
+
     // Private handler for handling javascript and saving passwords
     private Handler mHandler = new Handler() {
 
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case FOCUS_NODE_HREF:
+                {
                     String url = (String) msg.getData().get("url");
                     if (url == null || url.length() == 0) {
                         break;
@@ -2282,7 +2360,8 @@ public class BrowserActivity extends Activity
                             startActivity(intent);
                             break;
                         case R.id.share_link_context_menu_id:
-                            Browser.sendString(BrowserActivity.this, url);
+                            Browser.sendString(BrowserActivity.this, url,
+                                    getText(R.string.choosertitle_sharevia).toString());
                             break;
                         case R.id.copy_link_context_menu_id:
                             copy(url);
@@ -2293,6 +2372,7 @@ public class BrowserActivity extends Activity
                             break;
                     }
                     break;
+                }
 
                 case LOAD_URL:
                     loadURL(getTopWindow(), (String) msg.obj);
@@ -2311,6 +2391,13 @@ public class BrowserActivity extends Activity
                         mWakeLock.release();
                     }
                     break;
+
+                case UPDATE_BOOKMARK_THUMBNAIL:
+                    WebView view = (WebView) msg.obj;
+                    if (view != null) {
+                        updateScreenshot(view);
+                    }
+                    break;
             }
         }
     };
@@ -2321,9 +2408,10 @@ public class BrowserActivity extends Activity
         // FIXME: Would like to make sure there is actually something to
         // draw, but the API for that (WebViewCore.pictureReady()) is not
         // currently accessible here.
+
         ContentResolver cr = getContentResolver();
         final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
-                cr, view.getOriginalUrl(), view.getUrl(), false);
+                cr, view.getOriginalUrl(), view.getUrl(), true);
         if (c != null) {
             boolean succeed = c.moveToFirst();
             ContentValues values = null;
@@ -2331,16 +2419,7 @@ public class BrowserActivity extends Activity
                 if (values == null) {
                     final ByteArrayOutputStream os
                             = new ByteArrayOutputStream();
-                    Picture thumbnail = view.capturePicture();
-                    // Keep width and height in sync with BrowserBookmarksPage
-                    // and bookmark_thumb
-                    Bitmap bm = Bitmap.createBitmap(100, 80,
-                            Bitmap.Config.ARGB_4444);
-                    Canvas canvas = new Canvas(bm);
-                    // May need to tweak these values to determine what is the
-                    // best scale factor
-                    canvas.scale(.5f, .5f);
-                    thumbnail.draw(canvas);
+                    Bitmap bm = createScreenshot(view);
                     bm.compress(Bitmap.CompressFormat.PNG, 100, os);
                     values = new ContentValues();
                     values.put(Browser.BookmarkColumns.THUMBNAIL,
@@ -2354,6 +2433,58 @@ public class BrowserActivity extends Activity
         }
     }
 
+    /**
+     * Values for the size of the thumbnail created when taking a screenshot.
+     * Lazily initialized.  Instead of using these directly, use
+     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
+     */
+    private static int THUMBNAIL_WIDTH = 0;
+    private static int THUMBNAIL_HEIGHT = 0;
+
+    /**
+     * Return the desired width for thumbnail screenshots, which are stored in
+     * the database, and used on the bookmarks screen.
+     * @param context Context for finding out the density of the screen.
+     * @return int desired width for thumbnail screenshot.
+     */
+    /* package */ static int getDesiredThumbnailWidth(Context context) {
+        if (THUMBNAIL_WIDTH == 0) {
+            float density = context.getResources().getDisplayMetrics().density;
+            THUMBNAIL_WIDTH = (int) (90 * density);
+            THUMBNAIL_HEIGHT = (int) (80 * density);
+        }
+        return THUMBNAIL_WIDTH;
+    }
+
+    /**
+     * Return the desired height for thumbnail screenshots, which are stored in
+     * the database, and used on the bookmarks screen.
+     * @param context Context for finding out the density of the screen.
+     * @return int desired height for thumbnail screenshot.
+     */
+    /* package */ static int getDesiredThumbnailHeight(Context context) {
+        // To ensure that they are both initialized.
+        getDesiredThumbnailWidth(context);
+        return THUMBNAIL_HEIGHT;
+    }
+
+    private Bitmap createScreenshot(WebView view) {
+        Picture thumbnail = view.capturePicture();
+        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
+                getDesiredThumbnailHeight(this), Bitmap.Config.ARGB_4444);
+        Canvas canvas = new Canvas(bm);
+        // May need to tweak these values to determine what is the
+        // best scale factor
+        int thumbnailWidth = thumbnail.getWidth();
+        if (thumbnailWidth > 0) {
+            float scaleFactor = (float) getDesiredThumbnailWidth(this) /
+                    (float)thumbnailWidth;
+            canvas.scale(scaleFactor, scaleFactor);
+        }
+        thumbnail.draw(canvas);
+        return bm;
+    }
+
     // -------------------------------------------------------------------------
     // WebViewClient implementation.
     //-------------------------------------------------------------------------
@@ -2371,7 +2502,15 @@ public class BrowserActivity extends Activity
     private void updateIcon(WebView view, Bitmap icon) {
         if (icon != null) {
             BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
-                    view, icon);
+                    view.getOriginalUrl(), view.getUrl(), icon);
+        }
+        setFavicon(icon);
+    }
+
+    private void updateIcon(String url, Bitmap icon) {
+        if (icon != null) {
+            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
+                    null, url, icon);
         }
         setFavicon(icon);
     }
@@ -2380,7 +2519,21 @@ public class BrowserActivity extends Activity
         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             resetLockIcon(url);
-            setUrlTitle(url, null, view);
+            setUrlTitle(url, null);
+
+            // We've started to load a new page. If there was a pending message
+            // to save a screenshot then we will now take the new page and
+            // save an incorrect screenshot. Therefore, remove any pending
+            // thumbnail messages from the queue.
+            mHandler.removeMessages(UPDATE_BOOKMARK_THUMBNAIL);
+
+            // If we start a touch icon load and then load a new page, we don't
+            // want to cancel the current touch icon loader. But, we do want to
+            // create a new one when the touch icon url is known.
+            if (mTouchIconLoader != null) {
+                mTouchIconLoader.mActivity = null;
+                mTouchIconLoader = null;
+            }
 
             ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(false);
             if (errorConsole != null) {
@@ -2392,7 +2545,7 @@ public class BrowserActivity extends Activity
 
             // Call updateIcon instead of setFavicon so the bookmark
             // database can be updated.
-            updateIcon(view, favicon);
+            updateIcon(url, favicon);
 
             if (mSettings.isTracing()) {
                 String host;
@@ -2434,20 +2587,11 @@ public class BrowserActivity extends Activity
             CookieSyncManager.getInstance().resetSync();
 
             mInLoad = true;
-            WebView currentWebView = mTabControl.getCurrentWebView();
-            if (currentWebView == null || currentWebView.getScrollY() != 0) {
-                // This page has begun to load, so show the title bar
-                showFakeTitleBar();
-            }
+            mDidStopLoad = false;
+            showFakeTitleBar();
             updateInLoadMenuItems();
             if (!mIsNetworkUp) {
-                if ( mAlertDialog == null) {
-                    mAlertDialog = new AlertDialog.Builder(BrowserActivity.this)
-                        .setTitle(R.string.loadSuspendedTitle)
-                        .setMessage(R.string.loadSuspended)
-                        .setPositiveButton(R.string.ok, null)
-                        .show();
-                }
+                createAndShowNetworkDialog();
                 if (view != null) {
                     view.setNetworkAvailable(false);
                 }
@@ -2460,9 +2604,15 @@ public class BrowserActivity extends Activity
             // load.
             resetTitleAndIcon(view);
 
+            if (!mDidStopLoad) {
+                // Only update the bookmark screenshot if the user did not
+                // cancel the load early.
+                Message updateScreenshot = Message.obtain(mHandler, UPDATE_BOOKMARK_THUMBNAIL, view);
+                mHandler.sendMessageDelayed(updateScreenshot, 500);
+            }
+
             // Update the lock icon image only once we are done loading
             updateLockIconToLatest();
-            updateScreenshot(view);
 
             // Performance probe
             if (false) {
@@ -3080,15 +3230,22 @@ public class BrowserActivity extends Activity
 
         @Override
         public void onProgressChanged(WebView view, int newProgress) {
-            mTitleBar.setProgress(newProgress, view);
+            mTitleBar.setProgress(newProgress);
             if (mFakeTitleBar != null) {
                 mFakeTitleBar.setProgress(newProgress);
             }
 
             if (newProgress == 100) {
-                // onProgressChanged() is called for sub-frame too while
-                // onPageFinished() is only called for the main frame. sync
-                // cookie and cache promptly here.
+                // onProgressChanged() may continue to be called after the main
+                // frame has finished loading, as any remaining sub frames
+                // continue to load. We'll only get called once though with
+                // newProgress as 100 when everything is loaded.
+                // (onPageFinished is called once when the main frame completes
+                // loading regardless of the state of any sub frames so calls
+                // to onProgressChanges may continue after onPageFinished has
+                // executed)
+
+                // sync cookies and cache promptly here.
                 CookieSyncManager.getInstance().sync();
                 if (mInLoad) {
                     mInLoad = false;
@@ -3104,9 +3261,7 @@ public class BrowserActivity extends Activity
                 // and update the menu items.
                 mInLoad = true;
                 updateInLoadMenuItems();
-                WebView currentWebView = mTabControl.getCurrentWebView();
-                if ((currentWebView == null || currentWebView.getScrollY() != 0)
-                        && (!mOptionsMenuOpen || mIconView)) {
+                if (!mOptionsMenuOpen || mIconView) {
                     // This page has begun to load, so show the title bar
                     showFakeTitleBar();
                 }
@@ -3118,7 +3273,7 @@ public class BrowserActivity extends Activity
             String url = view.getUrl();
 
             // here, if url is null, we want to reset the title
-            setUrlTitle(url, title, view);
+            setUrlTitle(url, title);
 
             if (url == null ||
                 url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
@@ -3161,14 +3316,26 @@ public class BrowserActivity extends Activity
         }
 
         @Override
-        public void onReceivedTouchIconUrl(WebView view, String url) {
+        public void onReceivedTouchIconUrl(WebView view, String url,
+                boolean precomposed) {
             final ContentResolver cr = getContentResolver();
             final Cursor c =
                     BrowserBookmarksAdapter.queryBookmarksForUrl(cr,
                             view.getOriginalUrl(), view.getUrl(), true);
             if (c != null) {
                 if (c.getCount() > 0) {
-                    new DownloadTouchIcon(cr, c, view).execute(url);
+                    // Let precomposed icons take precedence over non-composed
+                    // icons.
+                    if (precomposed && mTouchIconLoader != null) {
+                        mTouchIconLoader.cancel(false);
+                        mTouchIconLoader = null;
+                    }
+                    // Have only one async task at a time.
+                    if (mTouchIconLoader == null) {
+                        mTouchIconLoader = new DownloadTouchIcon(
+                                BrowserActivity.this, cr, c, view);
+                        mTouchIconLoader.execute(url);
+                    }
                 } else {
                     c.close();
                 }
@@ -3288,6 +3455,38 @@ public class BrowserActivity extends Activity
                 }
             Log.w(LOGTAG, "Console: " + message + " " + sourceID + ":" + lineNumber);
         }
+
+        /**
+         * Ask the browser for an icon to represent a <video> element.
+         * This icon will be used if the Web page did not specify a poster attribute.
+         *
+         * @return Bitmap The icon or null if no such icon is available.
+         * @hide pending API Council approval
+         */
+        @Override
+        public Bitmap getDefaultVideoPoster() {
+            if (mDefaultVideoPoster == null) {
+                mDefaultVideoPoster = BitmapFactory.decodeResource(
+                        getResources(), R.drawable.default_video_poster);
+            }
+            return mDefaultVideoPoster;
+        }
+
+        /**
+         * Ask the host application for a custom progress view to show while
+         * a <video> is loading.
+         *
+         * @return View The progress view.
+         * @hide pending API Council approval
+         */
+        @Override
+        public View getVideoLoadingProgressView() {
+            if (mVideoProgressView == null) {
+                LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
+                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
+            }
+            return mVideoProgressView;
+        }
     };
 
     /**
@@ -3462,23 +3661,20 @@ public class BrowserActivity extends Activity
         updateLockIconImage(LOCK_ICON_UNSECURE);
     }
 
-    /**
-     * Resets the lock icon.  This method is called when the icon needs to be
-     * reset but we do not know whether we are loading a secure or not secure
-     * page.
-     */
-    private void resetLockIcon() {
-        // Save the lock-icon state (we revert to it if the load gets cancelled)
-        saveLockIcon();
+    /* package */ void setLockIconType(int type) {
+        mLockIconType = type;
+    }
 
-        mLockIconType = LOCK_ICON_UNSECURE;
+    /* package */ int getLockIconType() {
+        return mLockIconType;
+    }
 
-        if (LOGV_ENABLED) {
-          Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
-                " reset lock icon to " + mLockIconType);
-        }
+    /* package */ void setPrevLockType(int type) {
+        mPrevLockType = type;
+    }
 
-        updateLockIconImage(LOCK_ICON_UNSECURE);
+    /* package */ int getPrevLockType() {
+        return mPrevLockType;
     }
 
     /**
@@ -3498,7 +3694,7 @@ public class BrowserActivity extends Activity
         } else if (lockIconType == LOCK_ICON_MIXED) {
             d = mMixLockIcon;
         }
-        mTitleBar.setLock(d, getTopWindow());
+        mTitleBar.setLock(d);
         if (mFakeTitleBar != null) {
             mFakeTitleBar.setLock(d);
         }
@@ -3970,13 +4166,9 @@ public class BrowserActivity extends Activity
             }
         } else {
             mIsNetworkUp = false;
-            if (mInLoad && mAlertDialog == null) {
-                mAlertDialog = new AlertDialog.Builder(this)
-                        .setTitle(R.string.loadSuspendedTitle)
-                        .setMessage(R.string.loadSuspended)
-                        .setPositiveButton(R.string.ok, null)
-                        .show();
-            }
+            if (mInLoad) {
+                createAndShowNetworkDialog();
+           }
         }
         WebView w = mTabControl.getCurrentWebView();
         if (w != null) {
@@ -3984,6 +4176,18 @@ public class BrowserActivity extends Activity
         }
     }
 
+    // This method shows the network dialog alerting the user that the net is
+    // down. It will only show the dialog if mAlertDialog is null.
+    private void createAndShowNetworkDialog() {
+        if (mAlertDialog == null) {
+            mAlertDialog = new AlertDialog.Builder(this)
+                    .setTitle(R.string.loadSuspendedTitle)
+                    .setMessage(R.string.loadSuspended)
+                    .setPositiveButton(R.string.ok, null)
+                    .show();
+        }
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode,
                                     Intent intent) {
@@ -3993,14 +4197,7 @@ public class BrowserActivity extends Activity
                     String data = intent.getAction();
                     Bundle extras = intent.getExtras();
                     if (extras != null && extras.getBoolean("new_window", false)) {
-                        final TabControl.Tab newTab = openTab(data);
-                        if (mSettings.openInBackground() &&
-                                newTab != null) {
-                            mTabControl.populatePickerData(newTab);
-                            mTabControl.setCurrentTab(newTab);
-                            int newIndex = mTabControl.getCurrentIndex();
-                            mTitleBar.setCurrentTab(newIndex);
-                        }
+                        openTab(data);
                     } else {
                         final TabControl.Tab currentTab =
                                 mTabControl.getCurrentTab();
@@ -4044,6 +4241,8 @@ public class BrowserActivity extends Activity
                 CombinedBookmarkHistoryActivity.class);
         String title = current.getTitle();
         String url = current.getUrl();
+        Bitmap thumbnail = createScreenshot(current);
+
         // Just in case the user opens bookmarks before a page finishes loading
         // so the current history item, and therefore the page, is null.
         if (null == url) {
@@ -4059,6 +4258,7 @@ public class BrowserActivity extends Activity
         }
         intent.putExtra("title", title);
         intent.putExtra("url", url);
+        intent.putExtra("thumbnail", thumbnail);
         // Disable opening in a new window if we have maxed out the windows
         intent.putExtra("disable_new_window", mTabControl.getTabCount()
                 >= TabControl.MAX_TABS);
@@ -4191,9 +4391,9 @@ public class BrowserActivity extends Activity
 
     }
 
-    private final static int LOCK_ICON_UNSECURE = 0;
-    private final static int LOCK_ICON_SECURE   = 1;
-    private final static int LOCK_ICON_MIXED    = 2;
+    final static int LOCK_ICON_UNSECURE = 0;
+    final static int LOCK_ICON_SECURE   = 1;
+    final static int LOCK_ICON_MIXED    = 2;
 
     private int mLockIconType = LOCK_ICON_UNSECURE;
     private int mPrevLockType = LOCK_ICON_UNSECURE;
@@ -4221,17 +4421,13 @@ public class BrowserActivity extends Activity
 
     private boolean mInLoad;
     private boolean mIsNetworkUp;
+    private boolean mDidStopLoad;
 
     private boolean mPageStarted;
     private boolean mActivityInPause = true;
 
     private boolean mMenuIsDown;
 
-    private final KeyTracker mKeyTracker = new KeyTracker(this);
-
-    // As trackball doesn't send repeat down, we have to track it ourselves
-    private boolean mTrackTrackball;
-
     private static boolean mInTrace;
 
     // Performance probe
@@ -4336,7 +4532,7 @@ public class BrowserActivity extends Activity
 
     private Toast mStopToast;
 
-    private TitleBarSet mTitleBar;
+    private TitleBar mTitleBar;
 
     private LinearLayout mErrorConsoleContainer = null;
     private boolean mShouldShowErrorConsole = false;
@@ -4354,11 +4550,19 @@ public class BrowserActivity extends Activity
 
     private BroadcastReceiver mPackageInstallationReceiver;
 
+    // AsyncTask for downloading touch icons
+    /* package */ DownloadTouchIcon mTouchIconLoader;
+
     // activity requestCode
     final static int COMBO_PAGE                 = 1;
     final static int DOWNLOAD_PAGE              = 2;
     final static int PREFERENCES_PAGE           = 3;
 
+    // the default <video> poster
+    private Bitmap mDefaultVideoPoster;
+    // the video progress view
+    private View mVideoProgressView;
+
     /**
      * A UrlData class to abstract how the content will be set to WebView.
      * This base class uses loadUrl to show the content.