Tab.java revision 9206677e461328f15854c5fcb1366d0e261534c6
122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/*
222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Copyright (C) 2009 The Android Open Source Project
322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *
422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Licensed under the Apache License, Version 2.0 (the "License");
522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * you may not use this file except in compliance with the License.
622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * You may obtain a copy of the License at
722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *
822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *      http://www.apache.org/licenses/LICENSE-2.0
922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *
1022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Unless required by applicable law or agreed to in writing, software
1122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * distributed under the License is distributed on an "AS IS" BASIS,
1222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * See the License for the specific language governing permissions and
1422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * limitations under the License.
1522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
1622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobapackage com.android.browser;
1822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
19438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport com.android.browser.homepages.HomeProvider;
208ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport com.android.common.speech.LoggingEvents;
218ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton
228233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity;
2322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.app.AlertDialog;
2458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.app.SearchManager;
2522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentResolver;
2630c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.content.Context;
2722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface;
28fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.DialogInterface.OnCancelListener;
298ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport android.content.Intent;
3022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
3130c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.graphics.BitmapFactory;
3222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
3422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
3522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
364dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
37a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
3822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
3922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
4022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
4122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
4250c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
43c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
44dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
4522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
4622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
4722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
4822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
4922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
5022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebBackForwardList;
510c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
5222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
5322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
54438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport android.webkit.WebResourceResponse;
5522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
581d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdochimport android.widget.CheckBox;
5922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.LinearLayout;
6022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.TextView;
618029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
6222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
63fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.ArrayList;
64fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.HashMap;
65fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Iterator;
66fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
67fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
68fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
69fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
7022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
7122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
7222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
7322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaclass Tab {
748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
7622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
77c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
78c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
79c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
80c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
81c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
8230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public enum LockIcon {
8330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_UNSECURE,
8430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_SECURE,
8530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_MIXED,
8630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
878233facddcc51865d612a919d450db6954aa48e3Michael Kolb
888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Activity mActivity;
898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WebViewController mWebViewController;
908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
9222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
9322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
94a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
9522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
9622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
9722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
9822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
9922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
10022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
10122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
10222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
10322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
10422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
10522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
10622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
10722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mParentTab;
10822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
10922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
11022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Vector<Tab> mChildTabs;
11122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab will be removed when back out of the first page.
11222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mCloseOnExit;
11322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
11422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1158233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
11830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
11930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1204dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1214dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
12222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
12322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
12422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
12522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
12622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
12722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
12822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
129dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
130dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
131dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1320c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1330c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
134e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController mDataController;
1359206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // State of the auto-login request.
1369206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private DeviceAccountLogin mDeviceAccountLogin;
13722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
13922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
14022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
14230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private static class PageState {
14330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
14430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
14530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LockIcon mLockIcon;
14630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
147e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        Boolean mIsBookmarkedSite = false;
14830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
14930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
15030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (incognito) {
15130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "browser:incognito";
15230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
15330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
15430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "";
15530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
15630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
157dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho            mFavicon = BitmapFactory.decodeResource(
158dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho                    c.getResources(), R.drawable.app_web_browser_sm);
15930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
16030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
16130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
16230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
16330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mUrl = url;
16430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mTitle = null;
16530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
16630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_SECURE;
16730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
16830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
16930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
17030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (favicon != null) {
17130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = favicon;
17230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
173dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho                mFavicon = BitmapFactory.decodeResource(
174dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho                        c.getResources(), R.drawable.app_web_browser_sm);
17530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
17630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
17722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
17822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
17930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
18030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private PageState mCurrentState;
18130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
18222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
18330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // TODO: Figure out who uses what and where
18430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    //       Some of these aren't use in this class, and some are only used in
18530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    //       restoring state but not saving it - FIX THIS
18622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String WEBVIEW = "webview";
18722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String NUMTABS = "numTabs";
18822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTAB = "currentTab";
18922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
19022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
19122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CLOSEONEXIT = "closeonexit";
19222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
19322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
19422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String ORIGINALURL = "originalUrl";
1953d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
19622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
19722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
19822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
19958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
20058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
20158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
20258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
20358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
20458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
20595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     * Remove voice search mode from this tab.
20695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     */
20795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    public void revertVoiceSearchMode() {
20895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        if (mVoiceSearchData != null) {
20995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            mVoiceSearchData = null;
21095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            if (mInForeground) {
2118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.revertVoiceSearchMode(this);
21295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            }
21395d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        }
21495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    }
2158233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    /**
21758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
21858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
21958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
22058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
22158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
22258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
223c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Return true if the Tab is in voice search mode and the voice search
224c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Intent came with a String identifying that Google provided the Intent.
2251fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
2261fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
2271fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
2281fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
2291fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
23058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
23158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
23258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
23358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
23458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
23558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
23658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
23758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
23858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
23958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
24058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
24158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
24258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
24358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
24458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
24558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
24758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
24858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
24958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
25058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
25182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
25258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
253a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
25458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
25582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
25682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
25782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
25882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
25982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
26082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
26182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
26258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
26358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
26482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
26582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
26658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
26758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
26882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
26982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
27082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
27182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
27282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
27382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
27482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
27582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
27682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
2779df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
2789df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
2799df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
2801fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
2811fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
2822ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
283e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
284e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
285e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
286e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
287e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
288e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
289e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
290e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
291e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
292e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
293e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
294e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
295e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
296e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
297e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
298e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
299e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
300e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                mActivity.sendBroadcast(logIntent);
301e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
302e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
3032ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
3042ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
3052ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
3062ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
3072ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
30858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
30958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
31058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
31182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
31258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
3138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.activateVoiceSearchMode(mVoiceSearchData.mLastVoiceSearchTitle);
31458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
31582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
31682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
31782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
31882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
31982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
32082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
32182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
32282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
32382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
32482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
32582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
32682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
32782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
32882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
32982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
33082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
33182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
33282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
33382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
33482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
33582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
33682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
33758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
33882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
33982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
3408233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter(
34182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
34282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
3439df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
3449df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
3459df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
3469df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
3479df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
3489df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
3499df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
3509df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
3519df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
3529df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
3539df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
3549df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
3559df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
3569df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
3579df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
35858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
35958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
36058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
36182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
36282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
36358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
36458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
36582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
36682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
36758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
36858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
36958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
37058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
37158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
37258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
37358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
37458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
37558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
37658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
37758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
37858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
37982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
38082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
38182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
38282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
38382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
38482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
38582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
38682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
38782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
38882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
38982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
39082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
39158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
39282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
39358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
39458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
39558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
39658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
39758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
39858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
39958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
4001fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4011fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
4021fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
4031fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4041fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
4051fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4069df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
4079df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
4089df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
4099df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
4109df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
4110c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
4120c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
4130c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
4140c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
415e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
4160c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
4171fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
4181fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4191fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
4201fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
42158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
42258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
42322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
42422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
42522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
42622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
42722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
42822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
42922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
43022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
43122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
43222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
4338233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
43422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
43522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
43822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
43922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
44022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
44122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
44222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
44322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
44422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
44522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
44722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
44822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
44922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
45022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
45122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
45222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
45322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
45522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
45622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
45722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
45822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
45922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
46022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
46122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
46222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
46322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
46422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
46522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
47522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
47622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            AlertDialog d = new AlertDialog.Builder(mActivity)
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
4964a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
4974a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
5008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
50130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = 0;
50230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState = new PageState(mActivity,
50330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
5044dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
50558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
50658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
5071fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
5081fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
5091fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
5101fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    mActivity.sendBroadcast(i);
5111fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
51295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III                revertVoiceSearchMode();
51358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
51422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
5278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
5329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            // Cancel the auto-login process.
5339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (mDeviceAccountLogin != null) {
5349206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin.cancel();
5359206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin = null;
5369206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebViewController.hideAutoLogin(Tab.this);
5379206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
5389206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
53922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
540324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageStarted(Tab.this, view, favicon);
5414cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
542e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
54322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
54422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
54522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
54622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
5475b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
5485b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
5495b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
5505b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
5518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = false;
55230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            // Sync state (in case of stop/timeout)
55330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mUrl = view.getUrl();
5546c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck            if (mCurrentState.mUrl == null) {
5556c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck                mCurrentState.mUrl = url != null ? url : "";
5566c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck            }
55730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = view.getTitle();
55830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = view.getFavicon();
55930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
56030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // In case we stop when loading an HTTPS page from an HTTP page
56130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // but before a provisional load occurred
56230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
56330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
564324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageFinished(Tab.this);
56522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
56822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
56922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
570c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            if (voiceSearchSourceIsGoogle()) {
571c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // This method is called when the user clicks on a link.
572c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // VoiceSearchMode is turned off when the user leaves the
573c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // Google results page, so at this point the user must be on
574c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that page.  If the user clicked a link on that page, assume
575c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that the voice search was effective, and broadcast an Intent
576c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // so a receiver can take note of that fact.
577c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT);
578c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
579c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                        LoggingEvents.VoiceSearch.RESULT_CLICKED);
580c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                mActivity.sendBroadcast(logIntent);
581c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            }
58222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
58318eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
58418eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
58522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
58622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
58822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
58922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
59022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
59122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Updates the lock icon. This method is called when we discover another
59222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * resource to be loaded for this page (for example, javascript). While
59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we update the icon type, we do not update the lock icon itself until
59422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we are done loading, it is slightly more secure this way.
59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
59722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
59822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
59922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
60022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // to update the lock:
60130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) {
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // If NOT a 'safe' url, change the lock to mixed content!
60322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
60530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED;
60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
60722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
60822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
60922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
61022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
61422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
61522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
61622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
61722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
61822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
61922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
62022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
62122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
62222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
62547654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
62647654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log URLs when in private browsing mode
627f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (!isPrivateBrowsingEnabled()) {
62847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
62947654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
63047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
63122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
63222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6444a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
6454a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
6464a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
6474a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
6484a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
6494a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
6504a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
6514a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
65222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new AlertDialog.Builder(mActivity).setTitle(
65322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
65422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
65522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6594a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
6604a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
6614a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6624a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6634a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
66422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
66522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
66622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
66722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
66822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6694a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
6704a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
6714a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6724a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6734a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
67422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
67522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
6774a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
6784a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
6794a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
6804a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
6814a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
68222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
68322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
68422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
68522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
68622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
695324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.doUpdateVisitedHistory(Tab.this, isReload);
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
70630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (BrowserSettings.getInstance().showSecurityWarnings()) {
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LayoutInflater factory =
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LayoutInflater.from(mActivity);
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final View warningsView =
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    factory.inflate(R.layout.ssl_warnings, null);
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LinearLayout placeholder =
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
71722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_UNTRUSTED)) {
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_untrusted);
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
72522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_IDMISMATCH)) {
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_mismatch);
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_EXPIRED)) {
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_expired);
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_NOTYETVALID)) {
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_not_yet_valid);
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity).setTitle(
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        R.string.security_warning).setIcon(
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        android.R.drawable.ic_dialog_alert).setView(
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        warningsView).setPositiveButton(R.string.ssl_continue,
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNeutralButton(R.string.view_certificate,
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
7628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mWebViewController.showSslCertificateOnError(view,
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        handler, error);
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
765a49b829e91ea1290d9e1cf326417fdbf669f9d3aBen Murdoch                        }).setNegativeButton(R.string.ssl_go_back,
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
76930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setOnCancelListener(
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
77422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
77530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
77630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
77722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
77822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).show();
77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
78522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
7958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
79822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
799438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        public WebResourceResponse shouldInterceptRequest(WebView view,
800438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                String url) {
801438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
802438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                    mActivity, url);
803438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            return res;
804438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        }
805438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck
806438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        @Override
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
81022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8118233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
81222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8168233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
81822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8198233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onUnhandledKeyEvent(event);
82022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
8219206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
8229206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        @Override
8239206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void onReceivedLoginRequest(WebView view, String realm,
8249206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                String account, String args) {
8259206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            new DeviceAccountLogin(mActivity, view, Tab.this, mWebViewController)
8269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    .handleLogin(realm, account, args);
8279206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
8289206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
82922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
83022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
8319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
8329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // displayed.
8339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    void setDeviceAccountLogin(DeviceAccountLogin login) {
8349206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mDeviceAccountLogin = login;
8359206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
8369206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
8379206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Returns non-null if the title bar should display the auto-login UI.
8389206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    DeviceAccountLogin getDeviceAccountLogin() {
8399206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mDeviceAccountLogin;
8409206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
8419206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
84222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
84322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
84422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
84522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
84622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
85122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
8538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
8568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final Tab newTab = mWebViewController.openTabAndShow(
85718eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        Tab.this,
8588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        IntentHandler.EMPTY_URL_DATA, false, null);
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (newTab != Tab.this) {
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Tab.this.addChildTab(newTab);
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
8838233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
89822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
90022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
90222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
90422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
90922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
91022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
91222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
91322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
91422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
91522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
91822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.Builder(mActivity)
91922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(R.string.attention)
92022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
92122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
92422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
92522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
92622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
92822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
92922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
93022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
93122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
933eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
934eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
9358233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.switchToTab(mWebViewController.getTabControl().getTabIndex(
936eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott                        Tab.this));
937eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
938eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
939eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
940eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
94122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
94222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mParentTab != null) {
94322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
94422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
9458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.switchToTab(mWebViewController.getTabControl()
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .getTabIndex(mParentTab));
94722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
9488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
94922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
95022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
95322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
95430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
95530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
95622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
95921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
96030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
9618233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
96630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
9678233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
97122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
97222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final ContentResolver cr = mActivity.getContentResolver();
974c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
975c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
976c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
977c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
978c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
979c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
980c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
981c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
9828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
9838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mActivity, cr, view);
984c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
9918233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
9928233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    callback);
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
9978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
102222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
102322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
102422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
102522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
102622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
103122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
103322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
103622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
104022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
104122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
104222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
104322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
105150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
105722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
105822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
106050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
106222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
106322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
106565acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
106665acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
106765acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1068c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
106922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1071c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1075c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
10768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
10778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
10788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
108122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1082c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
108347654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
1084f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
108547654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
1086c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1087c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1088c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1089c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1090c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1091c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1092c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1093c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1094c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1095c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1096c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1097c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1098c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1099c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1100c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1101c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1102c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1103c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1104c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1105c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1106c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1107c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1108c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
112822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
112922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
113022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
113322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
113422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
113522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
113622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
113722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
113862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
113922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11408233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.openFileChooser(uploadMsg, acceptType);
114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
114222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
114322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
114522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
114922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
115022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
11518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
11528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11538029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
11548029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
11558029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
11568029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
11578029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
11588029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
11591d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
11601d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    Context.LAYOUT_INFLATER_SERVICE);
11611d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null);
11621d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
11631d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            builder.setView(layout)
11641d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
11651d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    @Override
11661d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    public void onClick(DialogInterface dialog, int id) {
11671d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        CheckBox disableAutoFill = (CheckBox) layout.findViewById(
11681d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                R.id.setup_autofill_dialog_disable_autofill);
11691d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
11701d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        if (disableAutoFill.isChecked()) {
11711d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Disable autofill and show a toast with how to turn it on again.
11721d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            BrowserSettings s = BrowserSettings.getInstance();
11731d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            s.addObserver(mMainView.getSettings());
11741d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            s.disableAutoFill(mActivity);
11751d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            s.update();
11761d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            Toast.makeText(mActivity,
11771d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    R.string.autofill_setup_dialog_negative_toast,
11781d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    Toast.LENGTH_LONG).show();
11791d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        } else {
11801d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Take user to the AutoFill profile editor. When they return,
11811d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // we will send the message that we pass here which will trigger
11821d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // the form to get filled out with their new profile.
11831d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            mWebViewController.setupAutoFill(msg);
11841d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        }
11851d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    }
11861d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                })
11871d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setNegativeButton(R.string.cancel, null)
11881d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .show();
11898029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
119022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
119122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
119222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
119322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
119422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
119522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
119622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
119722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
119922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
120022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
12018233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
120222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
120422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
12058233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1206211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1207211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1208211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1209211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1210211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
121101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
12128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
121322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
121722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
121822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
122622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
124722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
125022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
125122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
125222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
125322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
125422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
125522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
125622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
125722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
125822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
126022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
126122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
126422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
126522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
126822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
126922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
127022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
127122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
127222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
127322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
127422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
127522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
127622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
127722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
127822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
127922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
12808233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
128122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
128422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
128522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // TODO temporarily use activity here
12878233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // remove later
12888233facddcc51865d612a919d450db6954aa48e3Michael Kolb
128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
12908233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Tab(WebViewController wvcontroller, WebView w, boolean closeOnExit, String appId,
129122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String url) {
12928233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
12938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity = mWebViewController.getActivity();
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = closeOnExit;
129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = appId;
1296e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController = DataController.getInstance(mActivity);
129730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState = new PageState(mActivity, w.isPrivateBrowsingEnabled());
12988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
129922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
130022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1301dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1302dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1303dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1304dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
13058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1306dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1307dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1308dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
13090c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
13100c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
13110c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
13120c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
13130c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
13140c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
13150c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
13160c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
13170c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
13180c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
13190c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
13200c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
13210c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
13220c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
13230c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1324dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
132522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
132922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setWebView(WebView w) {
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1336a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
133950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
134050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
134150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1343a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1347dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1351dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1352dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1353dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1354dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1355dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
13560c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
136122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
136222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
136322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
136422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
136522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
137122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
137522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
137722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
137822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs != null) {
138022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            for(Tab t : mChildTabs) {
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                t.setParentTab(null);
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mParentTab.mChildTabs.remove(this);
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
138922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
139022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
139122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
139222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
139322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
139422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
139522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
13961514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1397211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
13988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1401dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1402dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1403dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1404dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1405dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1406dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
14078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1408dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1409dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1410dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1411dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
14128233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1413dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1414dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1415dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
141622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
141722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
141822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
141922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
142022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
142222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
142322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
142422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
142522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
142622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
14278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
142822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(
142922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mSubView.getSettings());
143022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
143222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
143322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
143422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
143522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
143622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
143722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
143822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
143922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
144022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setParentTab(Tab parent) {
144122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mParentTab = parent;
144222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
144322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the parent tab index is already saved. If we are changing that index
144422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
144522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // parent tab index in the saved Bundle.
144622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
144722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
14508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl()
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getTabIndex(parent));
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
145322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
145522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
145622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
145722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
145822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
145922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
146022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
146122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
146222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs == null) {
146322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mChildTabs = new Vector<Tab>();
146422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mChildTabs.add(child);
146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        child.setParentTab(this);
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
146822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
146922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Vector<Tab> getChildTabs() {
147022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mChildTabs;
147122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
147422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
147822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
147922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
148422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
148722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
148822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
149122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(mActivity);
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
15021961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
150322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
150722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
150822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
150922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
151022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
151122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
151222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
151322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15148233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
15158233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
15168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15178233facddcc51865d612a919d450db6954aa48e3Michael Kolb
151822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
151922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
152022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
152122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
152222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
152322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
152422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
152622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
152722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
152822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
152922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
153022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
153122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
153222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
153322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
153422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
153522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
153622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1540a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1541a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1542a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1543a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
15448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
15458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
15468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
154822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1549f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1550f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1551f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1552f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
15538233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1554f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        WebView webView = getWebView();
1555f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        if (webView == null) {
1556f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            return false;
1557f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        }
1558f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        return webView.isPrivateBrowsingEnabled();
1559f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1560f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1561f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
156522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
156722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15691514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
15701514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
15711514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15721514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
15738233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
15748233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
15758233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15768233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15771514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
15781514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
15791514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15801514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
158122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
158222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
158322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
158422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
158550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
158650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
158750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
158850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
158950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
159050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.init();
159150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
159222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
160722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
1611324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        return UrlUtils.filteredUrl(mCurrentState.mUrl);
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161449a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    String getOriginalUrl() {
161549a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        if (mMainView == null) {
161649a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck            return "";
161749a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        }
161849a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        return UrlUtils.filteredUrl(mMainView.getOriginalUrl());
161949a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    }
162049a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck
162122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
162230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
162530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
162630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mActivity.getString(R.string.title_bar_loading);
162722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
162830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
163322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
163422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
163530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mFavicon;
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1638e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1639e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1640e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1641f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
164222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
164322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
164422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
164522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
164622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
164722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole = new ErrorConsoleView(mActivity);
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
165522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
165622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * If this Tab was created through another Tab, then this method returns
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * that Tab.
166122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return the Tab parent or null
166222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
166322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public Tab getParentTab() {
166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mParentTab;
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
166822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return whether this tab should be closed when it is backing out of the
166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * first page.
167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if this tab should be closed when exit.
167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean closeOnExit() {
167322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mCloseOnExit;
167422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private void setLockIconType(LockIcon icon) {
167730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState.mLockIcon = icon;
167830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mWebViewController.onUpdatedLockIcon(this);
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
168230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return The tab's lock icon type.
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
168430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    LockIcon getLockIconType() {
168530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mLockIcon;
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
168930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
169030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
169130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
169230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
169822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16998233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
17008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
17058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void clearInPageLoad() {
17068233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
171030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the cached saved state bundle.
171130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return cached state bundle
171222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
171322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bundle getSavedState() {
171422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSavedState;
171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the saved state.
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setSavedState(Bundle state) {
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = state;
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if succeed in saving the state.
172622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean saveState() {
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSavedState != null;
173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
173322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
173422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.saveState(mSavedState);
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Store some extra info for displaying the tab in the picker.
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
173922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
174130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
174222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
174322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
174422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
174522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
174622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
174722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
17488233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
174922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mParentTab));
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
175122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
175322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
175422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
175522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
175622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
175722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean restoreState(Bundle b) {
175822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (b == null) {
175922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
176022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
176122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
176222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
176322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = null;
176422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = b.getBoolean(CLOSEONEXIT);
176522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
176622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
176722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.restoreState(b);
176822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (list == null) {
176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
177022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
177222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1773211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
17741961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
1775e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
17761961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
17771961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
1778e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
1779e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
1780e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
1781e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
1782e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
1783e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
1784e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
17851961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
1786e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
1787e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
17881acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
178922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
1790