Merge "fix reduce log spam on errors"
diff --git a/res/menu/downloadhistory.xml b/res/menu/downloadhistory.xml
deleted file mode 100644
index 195b0db..0000000
--- a/res/menu/downloadhistory.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:id="@+id/download_menu_cancel_all"
-        android:title="@string/download_menu_cancel_all" 
-        android:icon="@android:drawable/ic_menu_close_clear_cancel" />
-
-</menu>
diff --git a/res/menu/downloadhistorycontextfailed.xml b/res/menu/downloadhistorycontextfailed.xml
deleted file mode 100644
index f51b29a..0000000
--- a/res/menu/downloadhistorycontextfailed.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:id="@+id/download_menu_clear"
-        android:title="@string/download_menu_clear" />
-
-</menu>
diff --git a/res/menu/downloadhistorycontextfinished.xml b/res/menu/downloadhistorycontextfinished.xml
deleted file mode 100644
index 8d1fdd0..0000000
--- a/res/menu/downloadhistorycontextfinished.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:id="@+id/download_menu_open"
-        android:title="@string/download_menu_open" />
-    <item android:id="@+id/download_menu_delete"
-        android:title="@string/download_menu_delete" />
-
-</menu>
diff --git a/res/menu/downloadhistorycontextrunning.xml b/res/menu/downloadhistorycontextrunning.xml
deleted file mode 100644
index 552d0fa..0000000
--- a/res/menu/downloadhistorycontextrunning.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:id="@+id/download_menu_cancel"
-        android:title="@string/download_menu_cancel" />
-
-</menu>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bfed543..d62d78b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -171,8 +171,6 @@
     <string name="bookmark_url_not_valid">This URL isn\'t valid.</string>
         <!-- Error that appears in the Bookmark dialog when user selects OK with a URL of a type we cannot bookmark -->
     <string name="bookmark_cannot_save_url">This URL can\'t be bookmarked.</string>
-        <!-- Title of a confirmation dialog when the user deletes a bookmark-->
-    <string name="delete_bookmark">Delete</string>
     <!-- Menu item in the page that displays all bookmarks. It brings up a
             dialog that allows the user to bookmark the page that the browser is
             currently on, but is not visible because the bookmarks page is 
@@ -409,8 +407,6 @@
     <!-- Button text to delete all the AutoFill profile data [CHAR-LIMIT=20] -->
     <string name="autofill_profile_editor_delete_profile">Delete</string>
 
-    <!-- Title on a dialog shown to the user when they are prompted to set up the autofill feature [CHAR-LIMIT=32] -->
-    <string name="autofill_setup_dialog_title">Auto-fill</string>
     <!-- Text on a dialog shown to the user when they are prompted to set up the autofill feature [CHAR-LIMIT=NONE] -->
     <string name="autofill_setup_dialog_message">The browser can automatically complete web forms like this one. Would you like to set up your auto-fill text?</string>
     <!-- Toast message displayed when the user decides to not set up autofill at this time. We want to remind them that they can configure
@@ -548,8 +544,6 @@
     <string name="pref_extras_reset_default_summary">Restore default settings</string>
     <!-- Confirmation dialog message -->
     <string name="pref_extras_reset_default_dlg">Revert settings to default values?</string>
-    <!-- Confirmation dialog title -->
-    <string name="pref_extras_reset_default_dlg_title">Reset to default</string>
     <!-- Title for a group of settings -->
     <string name="pref_development_title">Debug</string>
     <!-- Do not tranlsate.  Development option -->
@@ -712,9 +706,6 @@
     <string name="search_settings_description">Bookmarks and web history</string>
 
     <!-- Pop-up window dialog -->
-    <!-- Title for a dialog informing the user that the site is attempting to
-            display a popup window -->
-    <string name="attention">Attention</string>
     <!-- Message for a dialog informing the user that the site is attempting to
             display a popup window -->
     <string name="popup_window_attempt">Allow this site to open a
@@ -739,31 +730,6 @@
       at a time.</string>
 
     <!-- Download History UI strings -->
-    <string name="download_title">Download history</string>
-    <!-- Download history screen string-->
-    <string name="download_unknown_filename">&lt;Unknown&gt;</string>
-    <!-- Context menu item on Download history screen -->
-    <string name="download_menu_open">Open</string>
-    <!-- Context menu item on Download history screen -->
-    <string name="download_menu_clear">Clear from list</string>
-    <!-- Context menu item in Download history screen -->
-    <string name="download_menu_delete">Delete</string>
-    <!-- Context menu item in Download history screen -->
-    <string name="download_menu_cancel">Cancel download</string>
-    <!-- Menu item -->
-    <string name="download_menu_cancel_all">Cancel all downloads</string>
-    <!-- Confirmation dialog title -->
-    <string name="download_cancel_dlg_title">Cancel downloads</string>
-    <!-- Confirmation dialog message -->
-    <string name="download_cancel_dlg_msg">Cancel and clear all <xliff:g id="download_count">%d</xliff:g> downloads from the download history?</string>
-    <!-- Confirmation dialog title -->
-    <string name="download_delete_file">Delete</string>
-    <!-- Dialog title -->
-    <string name="download_file_error_dlg_title">Out of space</string>
-    <!-- Dialog message -->
-    <string name="download_file_error_dlg_msg"><xliff:g id="filename">%s</xliff:g> couldn\'t be downloaded.\nFree up some space and try again.</string>
-    <!-- Title for a dialog informing the user that the download has failed -->
-    <string name="download_failed_generic_dlg_title">Download unsuccessful</string>
     <!-- Dialog title [CHAR LIMIT=25] -->
     <string name="download_no_sdcard_dlg_title" product="nosdcard">USB storage unavailable</string>
     <!-- Dialog title -->
@@ -789,51 +755,10 @@
 
     <!-- Toast for a download which cannot begin because the URL is not http or https -->
     <string name="cannot_download">Can only download \"http\" or \"https\" URLs.</string>
-    <!-- Title for a dialog informing the user that there is no application on
-            the phone that can open the file that was downloaded -->
-    <string name="download_no_application_title">Can\'t open file</string>
-    <!-- Label for a button to re-attempt downloading a file -->
-    <string name="retry">Retry</string>
-    <!-- Appears in Download history screen if there is no history -->
-    <string name="no_downloads">No download history.</string>
-    <!-- the following download_xxxx matches the download manager state, ie Downloads.Status -->
-    <string name="download_error">Couldn\'t download.</string>
-    <!-- Appears in Download history screen after an item has downloaded, included item size -->
-    <string name="download_success"><xliff:g id="file">%s</xliff:g> download complete.</string>
-    <!-- Appears in Download history screen while an item is being downloaded -->
-    <string name="download_running">Downloading\u2026</string>
     <!-- Message in the list of items which have received download requests
             telling their status.  This message states that the download has not
             yet begun -->
     <string name="download_pending">Starting download\u2026</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the download is
-            waiting for a network connection to continue -->
-    <string name="download_pending_network">Waiting for data connection\u2026</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the download has
-            paused to wait for a network connection -->
-    <string name="download_running_paused">Waiting for data connection\u2026</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the download has
-            been canceled -->
-    <string name="download_canceled">Download canceled.</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the download will
-            not happen because the content is not supported by the phone -->
-    <string name="download_not_acceptable">Can\'t download because the content isn\'t supported on this phone.</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the download did not
-            finish because there is not enough storage for the file -->
-    <string name="download_file_error">Can\'t finish download because there isn\'t enough space.</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the item cannot be
-            downloaded because it cannot determine the length of the item -->
-    <string name="download_length_required">Can\'t download because the size of the item can\'t be determined.</string>
-    <!-- Message in the list of items which have received download requests
-            telling their status.  This message states that the download was
-            interrupted and cannot be resumed -->
-    <string name="download_precondition_failed">Download interrupted and can\'t be resumed.</string>
 
     <!-- Do not translate.  Testing only -->
     <string name="dump_nav" translatable="false">Dump navigation cache</string>
@@ -896,7 +821,6 @@
     <string name="webstorage_clear_data_title">Clear stored data</string>
     
     <!-- Confirmation dialog when the user ask to clear all data for an origin -->
-    <string name="webstorage_clear_data_dialog_title">Clear stored data</string>
     <string name="webstorage_clear_data_dialog_message">Delete all data stored by this website?</string>
     <string name="webstorage_clear_data_dialog_ok_button">OK</string>
     <string name="webstorage_clear_data_dialog_cancel_button">Cancel</string>
@@ -919,13 +843,11 @@
     <string name="geolocation_settings_page_summary_allowed">This site can currently access your location</string>
     <string name="geolocation_settings_page_summary_not_allowed">This site can\'t currently access your location</string>
     <!-- Settings page dialog -->
-    <string name="geolocation_settings_page_dialog_title">Clear location access</string>
     <string name="geolocation_settings_page_dialog_message">Clear location access for this website?</string>
     <string name="geolocation_settings_page_dialog_ok_button">OK</string>
     <string name="geolocation_settings_page_dialog_cancel_button">Cancel</string>
     <!-- Label for the menu item in the website settings activity used to clear data stored by all websites -->
     <string name="website_settings_clear_all">Clear all</string>
-    <string name="website_settings_clear_all_dialog_title">Clear all</string>
     <string name="website_settings_clear_all_dialog_message">Delete all website data and location permissions?</string>
     <string name="website_settings_clear_all_dialog_ok_button">OK</string>
     <string name="website_settings_clear_all_dialog_cancel_button">Cancel</string>
diff --git a/res/xml/advanced_preferences.xml b/res/xml/advanced_preferences.xml
index 6e58164..4c5ecdf 100644
--- a/res/xml/advanced_preferences.xml
+++ b/res/xml/advanced_preferences.xml
@@ -92,7 +92,6 @@
                 android:title="@string/pref_extras_reset_default"
                 android:summary="@string/pref_extras_reset_default_summary"
                 android:dialogMessage="@string/pref_extras_reset_default_dlg" 
-                android:dialogTitle="@string/pref_extras_reset_default_dlg_title" 
                 android:dialogIcon="@android:drawable/ic_dialog_alert" />
     </PreferenceCategory>
 
diff --git a/res/xml/privacy_security_preferences.xml b/res/xml/privacy_security_preferences.xml
index 50802ca..2633600 100644
--- a/res/xml/privacy_security_preferences.xml
+++ b/res/xml/privacy_security_preferences.xml
@@ -22,7 +22,6 @@
             android:title="@string/pref_privacy_clear_cache"
             android:summary="@string/pref_privacy_clear_cache_summary"
             android:dialogMessage="@string/pref_privacy_clear_cache_dlg"
-            android:dialogTitle="@string/clear"
             android:dialogIcon="@android:drawable/ic_dialog_alert" />
 
     <com.android.browser.BrowserYesNoPreference
@@ -30,7 +29,6 @@
             android:title="@string/pref_privacy_clear_history"
             android:summary="@string/pref_privacy_clear_history_summary"
             android:dialogMessage="@string/pref_privacy_clear_history_dlg"
-            android:dialogTitle="@string/clear"
             android:dialogIcon="@android:drawable/ic_dialog_alert"/>
 
     <CheckBoxPreference
@@ -51,7 +49,6 @@
                 android:title="@string/pref_privacy_clear_cookies"
                 android:summary="@string/pref_privacy_clear_cookies_summary"
                 android:dialogMessage="@string/pref_privacy_clear_cookies_dlg"
-                android:dialogTitle="@string/clear"
                 android:dialogIcon="@android:drawable/ic_dialog_alert"/>
     </PreferenceCategory>
 
@@ -67,7 +64,6 @@
                 android:title="@string/pref_privacy_clear_form_data"
                 android:summary="@string/pref_privacy_clear_form_data_summary"
                 android:dialogMessage="@string/pref_privacy_clear_form_data_dlg"
-                android:dialogTitle="@string/clear"
                 android:dialogIcon="@android:drawable/ic_dialog_alert"/>
     </PreferenceCategory>
 
@@ -84,7 +80,6 @@
                 android:title="@string/pref_privacy_clear_geolocation_access"
                 android:summary="@string/pref_privacy_clear_geolocation_access_summary"
                 android:dialogMessage="@string/pref_privacy_clear_geolocation_access_dlg"
-                android:dialogTitle="@string/clear"
                 android:dialogIcon="@android:drawable/ic_dialog_alert"/>
     </PreferenceCategory>
 
@@ -100,7 +95,6 @@
                 android:title="@string/pref_privacy_clear_passwords"
                 android:summary="@string/pref_privacy_clear_passwords_summary"
                 android:dialogMessage="@string/pref_privacy_clear_passwords_dlg" 
-                android:dialogTitle="@string/clear" 
                 android:dialogIcon="@android:drawable/ic_dialog_alert"/>
     </PreferenceCategory>
 
diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java
index ca0cfbc..4834c39 100644
--- a/src/com/android/browser/BookmarkUtils.java
+++ b/src/com/android/browser/BookmarkUtils.java
@@ -234,7 +234,6 @@
             final Context context, final Message msg) {
 
         new AlertDialog.Builder(context)
-                .setTitle(R.string.delete_bookmark)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setMessage(context.getString(R.string.delete_bookmark_warning,
                         title))
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 8461d77..69febc5 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -292,7 +292,6 @@
         final ContentResolver resolver = getActivity().getContentResolver();
         final ClearHistoryTask clear = new ClearHistoryTask(resolver);
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.clear)
                 .setMessage(R.string.pref_privacy_clear_history_dlg)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setNegativeButton(R.string.cancel, null)
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 81ba941..686cfcd 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -262,13 +262,13 @@
     void start(final Bundle icicle, final Intent intent) {
         boolean noCrashRecovery = intent.getBooleanExtra(NO_CRASH_RECOVERY, false);
         if (icicle != null || noCrashRecovery) {
-            doStart(icicle, intent);
+            doStart(icicle, intent, false);
         } else {
             mCrashRecoveryHandler.startRecovery(intent);
         }
     }
 
-    void doStart(final Bundle icicle, final Intent intent) {
+    void doStart(final Bundle icicle, final Intent intent, final boolean fromCrash) {
         // Unless the last browser usage was within 24 hours, destroy any
         // remaining incognito tabs.
 
@@ -296,13 +296,14 @@
         GoogleAccountLogin.startLoginIfNeeded(mActivity,
                 new Runnable() {
                     @Override public void run() {
-                        onPreloginFinished(icicle, intent, currentTabId, restoreIncognitoTabs);
+                        onPreloginFinished(icicle, intent, currentTabId, restoreIncognitoTabs,
+                                fromCrash);
                     }
                 });
     }
 
     private void onPreloginFinished(Bundle icicle, Intent intent, long currentTabId,
-            boolean restoreIncognitoTabs) {
+            boolean restoreIncognitoTabs, boolean fromCrash) {
         if (currentTabId == -1) {
             BackgroundHandler.execute(new PruneThumbnails(mActivity, null));
             final Bundle extra = intent.getExtras();
@@ -346,7 +347,7 @@
             setActiveTab(mTabControl.getCurrentTab());
             // Handle the intent if needed. If icicle != null, we are restoring
             // and the intent will be stale - ignore it.
-            if (icicle == null) {
+            if (icicle == null || fromCrash) {
                 mIntentHandler.onNewIntent(intent);
             }
         }
diff --git a/src/com/android/browser/CrashRecoveryHandler.java b/src/com/android/browser/CrashRecoveryHandler.java
index c2fbbd2..396985a 100644
--- a/src/com/android/browser/CrashRecoveryHandler.java
+++ b/src/com/android/browser/CrashRecoveryHandler.java
@@ -233,7 +233,7 @@
         }
         updateLastRecovered(mRecoveryState != null
                 ? System.currentTimeMillis() : 0);
-        mController.doStart(mRecoveryState, intent);
+        mController.doStart(mRecoveryState, intent, true);
         mRecoveryState = null;
     }
 
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index 45b1dcc..14b1e84 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -110,7 +110,8 @@
     }
 
     public void refreshAdapter() {
-        mAdapter.notifyDataSetChanged();
+        mScroller.handleDataChanged(
+                mUiController.getTabControl().getTabPosition(mUi.getActiveTab()));
     }
 
     private void init() {
diff --git a/src/com/android/browser/NavTabScroller.java b/src/com/android/browser/NavTabScroller.java
index 8251928..1dfddff 100644
--- a/src/com/android/browser/NavTabScroller.java
+++ b/src/com/android/browser/NavTabScroller.java
@@ -213,7 +213,7 @@
         handleDataChanged(INVALID_POSITION);
     }
 
-    protected void handleDataChanged(int newscroll) {
+    void handleDataChanged(int newscroll) {
         int scroll = getScrollValue();
         if (mGapAnimator != null) {
             mGapAnimator.cancel();
diff --git a/src/com/android/browser/PageDialogsHandler.java b/src/com/android/browser/PageDialogsHandler.java
index 89c2745..013eaf1 100644
--- a/src/com/android/browser/PageDialogsHandler.java
+++ b/src/com/android/browser/PageDialogsHandler.java
@@ -244,9 +244,7 @@
         }
 
         mSSLCertificateView = tab;
-        // TODO: We should pass the certificate error for the page's main
-        // resource, if present. See http://b/5248376.
-        mSSLCertificateDialog = createSslCertificateDialog(cert, null)
+        mSSLCertificateDialog = createSslCertificateDialog(cert, tab.getSslCertificateError())
                 .setPositiveButton(R.string.ok,
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog,
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index ddb4e0e..d39909e 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -324,8 +324,7 @@
             mAnimScreen = new AnimScreen(mActivity);
         }
         mAnimScreen.set(getTitleBar(), getWebView());
-        final View animView = mAnimScreen.mMain;
-        mCustomViewContainer.addView(animView, COVER_SCREEN_PARAMS);
+        mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
         mCustomViewContainer.setVisibility(View.VISIBLE);
         mCustomViewContainer.bringToFront();
         int fromLeft = 0;
@@ -356,7 +355,8 @@
                 1f, 0f);
         ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
                 1f, scaleFactor);
-        ObjectAnimator blend1 = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 1, 0);
+        ObjectAnimator blend1 = ObjectAnimator.ofFloat(mAnimScreen.mMain,
+                "alpha", 1f, 0f);
         blend1.setDuration(100);
 
         inanim.playTogether(tx, ty, tr, tb, sx, title);
@@ -364,7 +364,7 @@
         set1.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator anim) {
-                mCustomViewContainer.removeView(animView);
+                mCustomViewContainer.removeView(mAnimScreen.mMain);
                 finishAnimationIn();
                 mUiController.setBlockEvents(false);
             }
@@ -512,15 +512,19 @@
         }
 
         public void set(TitleBar tbar, WebView web) {
-            if (mTitleBarBitmap == null
-                    || mTitleBarBitmap.getWidth() != tbar.getWidth()
-                    || mTitleBarBitmap.getHeight() != tbar.getEmbeddedHeight()) {
-                mTitleBarBitmap = Bitmap.createBitmap(tbar.getWidth(),
-                        tbar.getEmbeddedHeight(), Bitmap.Config.RGB_565);
+            if (tbar.getWidth() > 0 && tbar.getEmbeddedHeight() > 0) {
+                if (mTitleBarBitmap == null
+                        || mTitleBarBitmap.getWidth() != tbar.getWidth()
+                        || mTitleBarBitmap.getHeight() != tbar.getEmbeddedHeight()) {
+                    mTitleBarBitmap = Bitmap.createBitmap(tbar.getWidth(),
+                            tbar.getEmbeddedHeight(), Bitmap.Config.RGB_565);
+                }
+                Canvas c = new Canvas(mTitleBarBitmap);
+                tbar.draw(c);
+                c.setBitmap(null);
+            } else {
+                mTitleBarBitmap = null;
             }
-            Canvas c = new Canvas(mTitleBarBitmap);
-            tbar.draw(c);
-            c.setBitmap(null);
             mTitle.setImageBitmap(mTitleBarBitmap);
             mTitle.setVisibility(View.VISIBLE);
             int h = web.getHeight() - tbar.getEmbeddedHeight();
@@ -530,7 +534,7 @@
                 mContentBitmap = Bitmap.createBitmap(web.getWidth(), h,
                         Bitmap.Config.RGB_565);
             }
-            c.setBitmap(mContentBitmap);
+            Canvas c = new Canvas(mContentBitmap);
             int tx = web.getScrollX();
             int ty = web.getScrollY();
             c.translate(-tx, -ty - tbar.getEmbeddedHeight());
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 3d90ab6..8a3febe 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -210,9 +210,11 @@
         String mOriginalUrl;
         String mTitle;
         SecurityState mSecurityState;
+        // This is non-null only when mSecurityState is SECURITY_STATE_BAD_CERTIFICATE.
+        SslError mSslCertificateError;
         Bitmap mFavicon;
-        boolean mIsBookmarkedSite = false;
-        boolean mIncognito = false;
+        boolean mIsBookmarkedSite;
+        boolean mIncognito;
 
         PageState(Context c, boolean incognito) {
             mIncognito = incognito;
@@ -223,14 +225,12 @@
                 mOriginalUrl = mUrl = "";
                 mTitle = c.getString(R.string.new_tab);
             }
-            mFavicon = null;
             mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
         }
 
         PageState(Context c, boolean incognito, String url, Bitmap favicon) {
             mIncognito = incognito;
             mOriginalUrl = mUrl = url;
-            mTitle = null;
             if (URLUtil.isHttpsUrl(url)) {
                 mSecurityState = SecurityState.SECURITY_STATE_SECURE;
             } else {
@@ -925,6 +925,7 @@
             // In case we stop when loading an HTTPS page from an HTTP page
             // but before a provisional load occurred
             mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
+            mCurrentState.mSslCertificateError = null;
         }
         mCurrentState.mIncognito = view.isPrivateBrowsingEnabled();
     }
@@ -1013,7 +1014,6 @@
             // Build a confirmation dialog to display to the user.
             final AlertDialog d =
                     new AlertDialog.Builder(mContext)
-                    .setTitle(R.string.attention)
                     .setIcon(android.R.drawable.ic_dialog_alert)
                     .setMessage(R.string.popup_window_attempt)
                     .setPositiveButton(R.string.allow, allowListener)
@@ -1265,7 +1265,6 @@
             final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null);
 
             builder.setView(layout)
-                .setTitle(R.string.autofill_setup_dialog_title)
                 .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int id) {
@@ -1905,8 +1904,13 @@
         return mErrorConsole;
     }
 
+    /**
+     * Sets the security state, clears the SSL certificate error and informs
+     * the controller.
+     */
     private void setSecurityState(SecurityState securityState) {
         mCurrentState.mSecurityState = securityState;
+        mCurrentState.mSslCertificateError = null;
         mWebViewController.onUpdatedSecurityState(this);
     }
 
@@ -1917,6 +1921,15 @@
         return mCurrentState.mSecurityState;
     }
 
+    /**
+     * Gets the SSL certificate error, if any, for the page's main resource.
+     * This is only non-null when the security state is
+     * SECURITY_STATE_BAD_CERTIFICATE.
+     */
+    SslError getSslCertificateError() {
+        return mCurrentState.mSslCertificateError;
+    }
+
     int getLoadProgress() {
         if (mInPageLoad) {
             return mPageLoadProgress;
@@ -2278,7 +2291,10 @@
         if (error.getUrl().equals(mCurrentState.mUrl)) {
             // The security state should currently be SECURITY_STATE_SECURE.
             setSecurityState(SecurityState.SECURITY_STATE_BAD_CERTIFICATE);
+            mCurrentState.mSslCertificateError = error;
         } else if (getSecurityState() == SecurityState.SECURITY_STATE_SECURE) {
+            // The page's main resource is secure and this error is for a
+            // sub-resource.
             setSecurityState(SecurityState.SECURITY_STATE_MIXED);
         }
     }
diff --git a/src/com/android/browser/preferences/WebsiteSettingsFragment.java b/src/com/android/browser/preferences/WebsiteSettingsFragment.java
index 91c66a0..92cc62f 100644
--- a/src/com/android/browser/preferences/WebsiteSettingsFragment.java
+++ b/src/com/android/browser/preferences/WebsiteSettingsFragment.java
@@ -581,7 +581,6 @@
                 switch (mCurrentSite.getFeatureByIndex(position)) {
                     case Site.FEATURE_WEB_STORAGE:
                         new AlertDialog.Builder(getContext())
-                            .setTitle(R.string.webstorage_clear_data_dialog_title)
                             .setMessage(R.string.webstorage_clear_data_dialog_message)
                             .setPositiveButton(R.string.webstorage_clear_data_dialog_ok_button,
                                                new AlertDialog.OnClickListener() {
@@ -602,7 +601,6 @@
                         break;
                     case Site.FEATURE_GEOLOCATION:
                         new AlertDialog.Builder(getContext())
-                            .setTitle(R.string.geolocation_settings_page_dialog_title)
                             .setMessage(R.string.geolocation_settings_page_dialog_message)
                             .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button,
                                                new AlertDialog.OnClickListener() {
@@ -686,7 +684,6 @@
         case R.id.clear_all_button:
          // Show the prompt to clear all origins of their data and geolocation permissions.
             new AlertDialog.Builder(getActivity())
-                    .setTitle(R.string.website_settings_clear_all_dialog_title)
                     .setMessage(R.string.website_settings_clear_all_dialog_message)
                     .setPositiveButton(R.string.website_settings_clear_all_dialog_ok_button,
                             new AlertDialog.OnClickListener() {
diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java
index 8181efb..9aa2502 100644
--- a/src/com/android/browser/provider/BrowserProvider2.java
+++ b/src/com/android/browser/provider/BrowserProvider2.java
@@ -119,27 +119,27 @@
             Accounts.ACCOUNT_NAME + " IS NOT NULL DESC, "
             + Accounts.ACCOUNT_NAME + " ASC";
 
+    private static final String TABLE_BOOKMARKS_JOIN_HISTORY =
+        "history LEFT OUTER JOIN bookmarks ON history.url = bookmarks.url";
+
     private static final String[] SUGGEST_PROJECTION = new String[] {
-            Bookmarks._ID,
-            Bookmarks.URL,
-            Bookmarks.TITLE,
-            "0"};
+            qualifyColumn(TABLE_HISTORY, History._ID),
+            qualifyColumn(TABLE_HISTORY, History.URL),
+            bookmarkOrHistoryColumn(Combined.TITLE),
+            bookmarkOrHistoryLiteral(Combined.URL,
+                    Integer.toString(R.drawable.ic_bookmark_off_holo_dark),
+                    Integer.toString(R.drawable.ic_history_holo_dark)),
+            qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED)};
 
     private static final String SUGGEST_SELECTION =
-            "url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?"
-            + " OR title LIKE ?";
+            "history.url LIKE ? OR history.url LIKE ? OR history.url LIKE ? OR history.url LIKE ?"
+            + " OR history.title LIKE ? OR bookmarks.title LIKE ?";
 
-    private static final String[] HISTORY_SUGGEST_PROJECTION = new String[] {
-            History._ID,
-            History.URL,
-            History.TITLE,
-            History.DATE_LAST_VISITED};
+    private static final String ZERO_QUERY_SUGGEST_SELECTION =
+            TABLE_HISTORY + "." + History.DATE_LAST_VISITED + " != 0";
 
-    private static final String HISTORY_SUGGEST_SELECTION =
-            History.DATE_LAST_VISITED + " != 0";
-
-    private static final String HISTORY_SUGGEST_ORDER_BY =
-            History.DATE_LAST_VISITED + " DESC";
+    private static final String SUGGEST_ORDER_BY =
+            TABLE_HISTORY + "." + History.DATE_LAST_VISITED + " DESC";
 
     private static final String IMAGE_PRUNE =
             "url_key NOT IN (SELECT url FROM bookmarks " +
@@ -364,6 +364,12 @@
                 "bookmarks." + column + " ELSE history." + column + " END AS " + column;
     }
 
+    static final String bookmarkOrHistoryLiteral(String column, String bookmarkValue,
+            String historyValue) {
+        return "CASE WHEN bookmarks." + column + " IS NOT NULL THEN \"" + bookmarkValue +
+                "\" ELSE \"" + historyValue + "\" END";
+    }
+
     static final String qualifyColumn(String table, String column) {
         return table + "." + column + " AS " + column;
     }
@@ -1106,38 +1112,34 @@
     }
 
     private Cursor doSuggestQuery(String selection, String[] selectionArgs, String limit) {
-        Cursor c;
-        int iconId;
         if (TextUtils.isEmpty(selectionArgs[0])) {
-            c = mOpenHelper.getReadableDatabase().query(TABLE_HISTORY,
-                    HISTORY_SUGGEST_PROJECTION, HISTORY_SUGGEST_SELECTION, null, null, null,
-                    HISTORY_SUGGEST_ORDER_BY, null);
-            iconId = R.drawable.ic_history_holo_dark;
+            selection = ZERO_QUERY_SUGGEST_SELECTION;
+            selectionArgs = null;
         } else {
             String like = selectionArgs[0] + "%";
             if (selectionArgs[0].startsWith("http")
                     || selectionArgs[0].startsWith("file")) {
                 selectionArgs[0] = like;
             } else {
-                selectionArgs = new String[5];
+                selectionArgs = new String[6];
                 selectionArgs[0] = "http://" + like;
                 selectionArgs[1] = "http://www." + like;
                 selectionArgs[2] = "https://" + like;
                 selectionArgs[3] = "https://www." + like;
                 // To match against titles.
                 selectionArgs[4] = like;
+                selectionArgs[5] = like;
                 selection = SUGGEST_SELECTION;
             }
             selection = DatabaseUtils.concatenateWhere(selection,
                     Bookmarks.IS_DELETED + "=0 AND " + Bookmarks.IS_FOLDER + "=0");
 
-            c = mOpenHelper.getReadableDatabase().query(TABLE_BOOKMARKS,
-                    SUGGEST_PROJECTION, selection, selectionArgs, null, null,
-                    DEFAULT_BOOKMARKS_SORT_ORDER, null);
-            iconId = R.drawable.ic_bookmark_off_holo_dark;
         }
+        Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_BOOKMARKS_JOIN_HISTORY,
+                SUGGEST_PROJECTION, selection, selectionArgs, null, null,
+                SUGGEST_ORDER_BY, null);
 
-        return new SuggestionsCursor(c, iconId);
+        return new SuggestionsCursor(c);
     }
 
     private String[] createCombinedQuery(
@@ -2035,7 +2037,8 @@
         private static final int ID_INDEX = 0;
         private static final int URL_INDEX = 1;
         private static final int TITLE_INDEX = 2;
-        private static final int LAST_ACCESS_TIME_INDEX = 3;
+        private static final int ICON_INDEX = 3;
+        private static final int LAST_ACCESS_TIME_INDEX = 4;
         // shared suggestion array index, make sure to match COLUMNS
         private static final int SUGGEST_COLUMN_INTENT_ACTION_ID = 1;
         private static final int SUGGEST_COLUMN_INTENT_DATA_ID = 2;
@@ -2057,11 +2060,9 @@
                 SearchManager.SUGGEST_COLUMN_LAST_ACCESS_HINT};
 
         private final Cursor mSource;
-        private final String mIconId;
 
-        public SuggestionsCursor(Cursor cursor, int iconId) {
+        public SuggestionsCursor(Cursor cursor) {
             mSource = cursor;
-            mIconId = Integer.toString(iconId);
         }
 
         @Override
@@ -2084,7 +2085,7 @@
             case SUGGEST_COLUMN_TEXT_1_ID:
                 return mSource.getString(TITLE_INDEX);
             case SUGGEST_COLUMN_ICON_1_ID:
-                return mIconId;
+                return mSource.getString(ICON_INDEX);
             case SUGGEST_COLUMN_LAST_ACCESS_HINT_ID:
                 return mSource.getString(LAST_ACCESS_TIME_INDEX);
             }