Tab.java revision 847b532045e3cb117a847ebb956c9919401f332d
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
141eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    private Bitmap mScreenshot;
142eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
14330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
14430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private static class PageState {
14530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
14630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
14730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LockIcon mLockIcon;
14830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
149e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        Boolean mIsBookmarkedSite = false;
15030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
15130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
15230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (incognito) {
15330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "browser:incognito";
15430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
15530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
15630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "";
15730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
15830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
159dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho            mFavicon = BitmapFactory.decodeResource(
160dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho                    c.getResources(), R.drawable.app_web_browser_sm);
16130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
16230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
16330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
16430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
16530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mUrl = url;
16630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mTitle = null;
16730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
16830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_SECURE;
16930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
17030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
17130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
17230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (favicon != null) {
17330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = favicon;
17430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
175dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho                mFavicon = BitmapFactory.decodeResource(
176dc6cbb737dbe70fa2236c3fbf27827ed4453c686Justin Ho                        c.getResources(), R.drawable.app_web_browser_sm);
17730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
17830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
17922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
18022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
18230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private PageState mCurrentState;
18330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
18422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
18530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // TODO: Figure out who uses what and where
18630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    //       Some of these aren't use in this class, and some are only used in
18730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    //       restoring state but not saving it - FIX THIS
18822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String WEBVIEW = "webview";
18922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String NUMTABS = "numTabs";
19022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTAB = "currentTab";
19122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
19222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
19322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CLOSEONEXIT = "closeonexit";
19422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
19522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
19622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String ORIGINALURL = "originalUrl";
1973d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
198eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    static final String SCREENSHOT = "screenshot";
19922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
20022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
20122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
20258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
20358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
20458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
20558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
20658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
20758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
20895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     * Remove voice search mode from this tab.
20995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     */
21095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    public void revertVoiceSearchMode() {
21195d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        if (mVoiceSearchData != null) {
21295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            mVoiceSearchData = null;
21395d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            if (mInForeground) {
2148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.revertVoiceSearchMode(this);
21595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            }
21695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        }
21795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    }
2188233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    /**
22058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
22158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
22258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
22358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
22458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
22558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
226c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Return true if the Tab is in voice search mode and the voice search
227c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Intent came with a String identifying that Google provided the Intent.
2281fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
2291fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
2301fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
2311fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
2321fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
23358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
23458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
23558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
23658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
23758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
23858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
23958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
24058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
24258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
24358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
24458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
24558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
24658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
24758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
24858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
25058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
25158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
25258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
25358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
25482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
25558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
256a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
25758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
25882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
25982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
26082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
26182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
26282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
26382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
26482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
26558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
26658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
26782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
26882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
26958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
27058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
27182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
27282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
27382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
27482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
27582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
27682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
27782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
27882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
27982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
2809df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
2819df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
2829df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
2831fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
2841fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
2852ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
286e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
287e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
288e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
289e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
290e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
291e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
292e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
293e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
294e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
295e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
296e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
297e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
298e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
299e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
300e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
301e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
302e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
303e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                mActivity.sendBroadcast(logIntent);
304e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
305e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
3062ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
3072ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
3082ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
3092ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
3102ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
31158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
31258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
31358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
31482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
31558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
31611d1978d8d16004598347abc93918b54a5ef760bMichael Kolb            mWebViewController.activateVoiceSearchMode(
31711d1978d8d16004598347abc93918b54a5ef760bMichael Kolb                    mVoiceSearchData.mLastVoiceSearchTitle,
31811d1978d8d16004598347abc93918b54a5ef760bMichael Kolb                    mVoiceSearchData.mVoiceSearchResults);
31958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
32082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
32182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
32282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
32382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
32482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
32582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
32682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
32782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
32882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
32982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
33082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
33182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
33282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
33382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
33482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
33582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
33682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
33782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
33882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
33982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
34082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
34182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
34258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
34382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
34482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
3458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter(
34682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
34782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
3489df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
3499df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
3509df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
3519df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
3529df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
3539df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
3549df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
3559df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
3569df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
3579df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
3589df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
3599df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
3609df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
3619df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
3629df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
36358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
36458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
36558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
36682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
36782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
36858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
36958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
37082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
37182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
37258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
37358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
37458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
37558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
37658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
37758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
37858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
37958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
38058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
38158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
38258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
38358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
38482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
38582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
38682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
38782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
38882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
38982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
39082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
39182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
39282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
39382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
39482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
39582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
39658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
39782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
39858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
39958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
40058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
40158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
40258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
40458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
4051fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4061fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
4071fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
4081fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4091fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
4101fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4119df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
4129df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
4139df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
4149df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
4159df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
4160c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
4170c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
4180c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
4190c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
420e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
4210c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
4221fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
4231fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4241fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
4251fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
42658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
42758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
42822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
42922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
43022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
43122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
43222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
43322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
43422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
43522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
4388233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
43922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
44022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
44122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
44222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
44322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
44422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
44522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
44722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
44822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
44922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
45022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
45122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
45222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
45322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
45522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
45622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
45722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
45822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
45922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
46022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
46122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
46222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
46322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
46422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
46522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
47522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
47622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            AlertDialog d = new AlertDialog.Builder(mActivity)
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
5014a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
5024a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
5058233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
50630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = 0;
50730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState = new PageState(mActivity,
50830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
5094dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
51058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
51158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
5121fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
5131fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
5141fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
5151fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    mActivity.sendBroadcast(i);
5161fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
51795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III                revertVoiceSearchMode();
51858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
5328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
53622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
5379206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            // Cancel the auto-login process.
5389206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (mDeviceAccountLogin != null) {
5399206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin.cancel();
5409206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin = null;
5419206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebViewController.hideAutoLogin(Tab.this);
5429206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
5439206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
54422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
545324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageStarted(Tab.this, view, favicon);
5464cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
547e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
54822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
55122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
5525b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
5535b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
5545b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
5555b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
5568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = false;
55730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            // Sync state (in case of stop/timeout)
55830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mUrl = view.getUrl();
5596c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck            if (mCurrentState.mUrl == null) {
5606c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck                mCurrentState.mUrl = url != null ? url : "";
5616c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck            }
56230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = view.getTitle();
56330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = view.getFavicon();
56430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
56530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // In case we stop when loading an HTTPS page from an HTTP page
56630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // but before a provisional load occurred
56730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
56830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
569324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageFinished(Tab.this);
57022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
57122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
57222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
57322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
57422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
575c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            if (voiceSearchSourceIsGoogle()) {
576c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // This method is called when the user clicks on a link.
577c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // VoiceSearchMode is turned off when the user leaves the
578c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // Google results page, so at this point the user must be on
579c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that page.  If the user clicked a link on that page, assume
580c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that the voice search was effective, and broadcast an Intent
581c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // so a receiver can take note of that fact.
582c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT);
583c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
584c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                        LoggingEvents.VoiceSearch.RESULT_CLICKED);
585c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                mActivity.sendBroadcast(logIntent);
586c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            }
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
58818eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
58918eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
59022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
59122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
59222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
59422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Updates the lock icon. This method is called when we discover another
59722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * resource to be loaded for this page (for example, javascript). While
59822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we update the icon type, we do not update the lock icon itself until
59922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we are done loading, it is slightly more secure this way.
60022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
60122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
60322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
60522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // to update the lock:
60630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) {
60722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // If NOT a 'safe' url, change the lock to mixed content!
60822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
60922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
61030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED;
61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
61422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
61522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
61622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
61722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
61822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
61922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
62022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
62122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
62222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
62522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
62622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
62722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
62822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
62922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
63047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
63147654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log URLs when in private browsing mode
632f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (!isPrivateBrowsingEnabled()) {
63347654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
63447654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
63547654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
64522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
64622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
64722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
64822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6494a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
6504a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
6514a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
6524a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
6534a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
6544a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
6554a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
6564a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new AlertDialog.Builder(mActivity).setTitle(
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
66122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
66222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
66322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6644a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
6654a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
6664a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6674a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6684a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
66922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
67022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
67122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
67222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
67322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6744a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
6754a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
6764a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6774a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6784a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
67922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
68022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
68122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
6824a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
6834a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
6844a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
6854a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
6864a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
700324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.doUpdateVisitedHistory(Tab.this, isReload);
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
70622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
71130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (BrowserSettings.getInstance().showSecurityWarnings()) {
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LayoutInflater factory =
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LayoutInflater.from(mActivity);
71722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final View warningsView =
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    factory.inflate(R.layout.ssl_warnings, null);
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LinearLayout placeholder =
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_UNTRUSTED)) {
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
72522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_untrusted);
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_IDMISMATCH)) {
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_mismatch);
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_EXPIRED)) {
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_expired);
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_NOTYETVALID)) {
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_not_yet_valid);
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity).setTitle(
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        R.string.security_warning).setIcon(
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        android.R.drawable.ic_dialog_alert).setView(
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        warningsView).setPositiveButton(R.string.ssl_continue,
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNeutralButton(R.string.view_certificate,
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
7678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mWebViewController.showSslCertificateOnError(view,
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        handler, error);
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
770a49b829e91ea1290d9e1cf326417fdbf669f9d3aBen Murdoch                        }).setNegativeButton(R.string.ssl_go_back,
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
77430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
77522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
77622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setOnCancelListener(
77722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
77822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
78030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
78130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).show();
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
78522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
79522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
79822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
79922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
8008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
80122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
804438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        public WebResourceResponse shouldInterceptRequest(WebView view,
805438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                String url) {
806438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
807438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                    mActivity, url);
808438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            return res;
809438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        }
810438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck
811438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        @Override
81222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8168233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
82022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
82222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
82322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8248233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onUnhandledKeyEvent(event);
82522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
8269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
8279206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        @Override
8289206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void onReceivedLoginRequest(WebView view, String realm,
8299206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                String account, String args) {
8309206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            new DeviceAccountLogin(mActivity, view, Tab.this, mWebViewController)
8319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    .handleLogin(realm, account, args);
8329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
8339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
83422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
83522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
8369206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
8379206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // displayed.
8389206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    void setDeviceAccountLogin(DeviceAccountLogin login) {
8399206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mDeviceAccountLogin = login;
8409206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
8419206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
8429206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Returns non-null if the title bar should display the auto-login UI.
8439206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    DeviceAccountLogin getDeviceAccountLogin() {
8449206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mDeviceAccountLogin;
8459206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
8469206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
85122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
85322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
85622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
85722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
8588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
8618233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final Tab newTab = mWebViewController.openTabAndShow(
86218eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        Tab.this,
8638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        IntentHandler.EMPTY_URL_DATA, false, null);
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (newTab != Tab.this) {
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Tab.this.addChildTab(newTab);
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
8888233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
89922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
90022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
90222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
90822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
90922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
91022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
91222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
91322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
91422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
91522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
91822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
91922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
92022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
92122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.Builder(mActivity)
92422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(R.string.attention)
92522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
92622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
92822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
92922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
93022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
93122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
93522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
938eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
939eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
9408233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.switchToTab(mWebViewController.getTabControl().getTabIndex(
941eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott                        Tab.this));
942eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
943eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
944eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
945eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
94722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mParentTab != null) {
94822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
94922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
9508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.switchToTab(mWebViewController.getTabControl()
95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .getTabIndex(mParentTab));
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
9538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
95422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
95522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
95722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
95930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
96030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
96122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
96421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
96530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
9668233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
97130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
9728233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
97422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final ContentResolver cr = mActivity.getContentResolver();
979c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
980c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
981c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
982c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
983c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
984c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
985c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
986c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
9878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
9888233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mActivity, cr, view);
989c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
9968233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
9978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    callback);
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
10028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
102122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
102222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
102322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
102422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
102522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
103122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
103322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
103622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
104022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
104122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
104222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
104322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
105122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
105650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
105722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
105822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
106022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
106222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
106322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
106550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
106622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
106722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
106822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
106922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
107065acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
107165acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
107265acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1073c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1076c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1080c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
10818233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
10828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
10838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1087c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
108847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
1089f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
109047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
1091c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1092c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1093c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1094c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1095c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1096c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1097c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1098c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1099c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1100c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1101c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1102c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1103c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1104c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1105c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1106c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1107c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1108c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1109c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1110c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1111c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1112c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1113c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
112822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
112922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
113022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
113222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
113322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
113422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
113522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
113622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11378233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
113822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
113922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
114022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
114222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
114362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.openFileChooser(uploadMsg, acceptType);
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
114922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
115022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
115322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
115422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
115522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
11568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
11578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11588029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
11598029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
11608029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
11618029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
11628029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
11638029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
11641d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
11651d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    Context.LAYOUT_INFLATER_SERVICE);
11661d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null);
11671d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
11681d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            builder.setView(layout)
11691d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
11701d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    @Override
11711d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    public void onClick(DialogInterface dialog, int id) {
11721d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        CheckBox disableAutoFill = (CheckBox) layout.findViewById(
11731d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                R.id.setup_autofill_dialog_disable_autofill);
11741d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
11751d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        if (disableAutoFill.isChecked()) {
11761d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Disable autofill and show a toast with how to turn it on again.
11771d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            BrowserSettings s = BrowserSettings.getInstance();
11781d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            s.addObserver(mMainView.getSettings());
11791d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            s.disableAutoFill(mActivity);
11801d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            s.update();
11811d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            Toast.makeText(mActivity,
11821d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    R.string.autofill_setup_dialog_negative_toast,
11831d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    Toast.LENGTH_LONG).show();
11841d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        } else {
11851d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Take user to the AutoFill profile editor. When they return,
11861d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // we will send the message that we pass here which will trigger
11871d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // the form to get filled out with their new profile.
11881d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            mWebViewController.setupAutoFill(msg);
11891d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        }
11901d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    }
11911d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                })
11921d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setNegativeButton(R.string.cancel, null)
11931d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .show();
11948029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
119522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
119622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
119722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
119922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
120022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
120122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
120222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
120322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
120422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
120522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
12068233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
120722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12088233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
12108233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1211211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1212211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1213211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1214211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1215211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
121601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
12178233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
121822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
122622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
124722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
125022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
125122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
125222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
125322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
125422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
125522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
125622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
125722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
125822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
126122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
126522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
126922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
127022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
127122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
127222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
127322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
127422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
127522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
127622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
127722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
127822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
127922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
128022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
128122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
128422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
12858233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
128822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12918233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // TODO temporarily use activity here
12928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // remove later
12938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
12958233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Tab(WebViewController wvcontroller, WebView w, boolean closeOnExit, String appId,
129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String url) {
12978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
12988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity = mWebViewController.getActivity();
129922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = closeOnExit;
130022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = appId;
1301e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController = DataController.getInstance(mActivity);
1302847b532045e3cb117a847ebb956c9919401f332dJohn Reck        mCurrentState = new PageState(mActivity, w != null
1303847b532045e3cb117a847ebb956c9919401f332dJohn Reck                ? w.isPrivateBrowsingEnabled() : false);
13048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
130622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1307dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1308dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1309dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1310dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
13118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1312dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1313dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1314dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
13150c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
13160c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
13170c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
13180c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
13190c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
13200c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
13210c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
13220c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
13230c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
13240c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
13250c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
13260c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
13270c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
13280c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
13290c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1330dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setWebView(WebView w) {
133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1342a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
134550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
134650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
134750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1349a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1353dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1357dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1358dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1359dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1360dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1361dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
13620c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
136322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
136422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
136522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
137122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
137522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
137722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs != null) {
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            for(Tab t : mChildTabs) {
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                t.setParentTab(null);
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
138922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
139022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
139122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
139222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mParentTab.mChildTabs.remove(this);
139322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
139422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
139522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
139622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
139722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
139822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
14021514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1403211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
14048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
140522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
140622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1407dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1408dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1409dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1410dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1411dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1412dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
14138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1414dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1415dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1416dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1417dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
14188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1419dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1420dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1421dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
142222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
142322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
142422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
142522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
142622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
142822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
142922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
143022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
143222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
14338233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
143422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(
143522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mSubView.getSettings());
143622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
143722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
143822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
143922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
144022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
144122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
144222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
144322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
144422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
144522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
144622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setParentTab(Tab parent) {
144722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mParentTab = parent;
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the parent tab index is already saved. If we are changing that index
145022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // parent tab index in the saved Bundle.
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
145322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
145522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
14568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl()
145722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getTabIndex(parent));
145822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
145922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
146022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
146122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
146222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
146322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
146422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
146822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs == null) {
146922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mChildTabs = new Vector<Tab>();
147022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
147122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mChildTabs.add(child);
147222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        child.setParentTab(this);
147322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Vector<Tab> getChildTabs() {
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mChildTabs;
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
148122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
148422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
148822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
149122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(mActivity);
150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
150222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
150322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
150722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
15081961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
150922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
151022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
151122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
151222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
151322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
151422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
151522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
151622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
151722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
151822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
151922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15208233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
15218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
15228233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15238233facddcc51865d612a919d450db6954aa48e3Michael Kolb
152422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
152622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
152722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
152822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
152922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
153022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
153122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
153222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
153322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
153422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
153522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
153622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
154022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
154122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
154222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
154322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
154422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
154522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1546a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1547a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1548a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1549a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
15508233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
15518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
15528233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15538233facddcc51865d612a919d450db6954aa48e3Michael Kolb
155422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1555f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1556f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1557f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1558f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
15598233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1560f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        WebView webView = getWebView();
1561f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        if (webView == null) {
1562f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            return false;
1563f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        }
1564f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        return webView.isPrivateBrowsingEnabled();
1565f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1566f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1567f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
157222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
157322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
157422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15751514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
15761514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
15771514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15781514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
15798233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
15808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
15818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15828233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15831514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
15841514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
15851514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15861514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
158722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
158822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
159022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
159150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
159250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
159350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
159450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
159550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
159650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.init();
159750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
160922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
161122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
1617324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        return UrlUtils.filteredUrl(mCurrentState.mUrl);
161822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
162049a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    String getOriginalUrl() {
162149a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        if (mMainView == null) {
162249a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck            return "";
162349a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        }
162449a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        return UrlUtils.filteredUrl(mMainView.getOriginalUrl());
162549a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    }
162649a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck
162722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
162830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
163130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
163230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mActivity.getString(R.string.title_bar_loading);
163322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
163430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
163522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
163922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
164022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
164130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mFavicon;
164222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
164322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1644e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1645e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1646e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1647f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
165522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
165622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
165722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole = new ErrorConsoleView(mActivity);
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
166122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
166222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * If this Tab was created through another Tab, then this method returns
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * that Tab.
166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return the Tab parent or null
166822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public Tab getParentTab() {
167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mParentTab;
167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
167422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return whether this tab should be closed when it is backing out of the
167522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * first page.
167622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if this tab should be closed when exit.
167722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
167822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean closeOnExit() {
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mCloseOnExit;
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private void setLockIconType(LockIcon icon) {
168330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState.mLockIcon = icon;
168430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mWebViewController.onUpdatedLockIcon(this);
168522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
168830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return The tab's lock icon type.
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
169030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    LockIcon getLockIconType() {
169130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mLockIcon;
169222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
169530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
169630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
169730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
169830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
17058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
17068233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
171022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
17118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void clearInPageLoad() {
17128233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
171322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
171422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
171630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the cached saved state bundle.
171730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return cached state bundle
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bundle getSavedState() {
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSavedState;
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the saved state.
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
172622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setSavedState(Bundle state) {
172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = state;
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if succeed in saving the state.
173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
173322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean saveState() {
173422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSavedState != null;
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
173922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
174122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.saveState(mSavedState);
174222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Store some extra info for displaying the tab in the picker.
174422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
174522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
174730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
174822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
174922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
175122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
175322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
17548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
175522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mParentTab));
175622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1757eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        if (mScreenshot != null) {
1758eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb            mSavedState.putParcelable(SCREENSHOT, mScreenshot);
1759eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        }
176022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
176122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
176222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
176322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
176422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
176522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
176622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean restoreState(Bundle b) {
176722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (b == null) {
176822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
177022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
177222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = null;
177322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = b.getBoolean(CLOSEONEXIT);
177422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
1775eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        mScreenshot = b.getParcelable(SCREENSHOT);
177622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
177722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.restoreState(b);
177822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (list == null) {
177922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
178022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
178122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
178222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1783211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
17841961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
1785e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
17861961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
17871961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
1788e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
1789e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
1790e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
1791e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
1792e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
1793e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
1794e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
17951961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
1796e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
1797e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
17981acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1799eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    public void setScreenshot(Bitmap screenshot) {
1800eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        mScreenshot = screenshot;
1801eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    }
1802eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
1803eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    public Bitmap getScreenshot() {
1804eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        return mScreenshot;
1805eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    }
1806eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
180722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
1808