Tab.java revision e969cc59ddcc763ab9d6349a854dd17a6456d1a4
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
198ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport com.android.common.speech.LoggingEvents;
208ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton
218233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity;
2222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.app.AlertDialog;
2358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.app.SearchManager;
2422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentResolver;
2530c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.content.Context;
2622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface;
27fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.DialogInterface.OnCancelListener;
288ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport android.content.Intent;
2922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
3030c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.graphics.BitmapFactory;
3122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
3322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
3422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
354dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
36a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
3722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
3822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
3922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
4022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
4150c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
42c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
43dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
4422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
4522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
4622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
4722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
4822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
4922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebBackForwardList;
500c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
5122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
5222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
5322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
5422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
5522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.LinearLayout;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.TextView;
588029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
5922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
60fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.ArrayList;
61fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.HashMap;
62fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Iterator;
63fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
64fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
65fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
66fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
6722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
6822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
6922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
7022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaclass Tab {
718233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
7322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
74c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
75c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
76c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
77c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
78c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
7930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public enum LockIcon {
8030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_UNSECURE,
8130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_SECURE,
8230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_MIXED,
8330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
848233facddcc51865d612a919d450db6954aa48e3Michael Kolb
858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Activity mActivity;
868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WebViewController mWebViewController;
878233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
8922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
9022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
91a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
9222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
9322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
9522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
9622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
9722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
9822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
9922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
10022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
10122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
10222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
10322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
10422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mParentTab;
10522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
10622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
10722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Vector<Tab> mChildTabs;
10822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab will be removed when back out of the first page.
10922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mCloseOnExit;
11022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
11122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1128233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1148233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
11530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
11630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1174dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1184dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
11922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
12022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
12122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
12222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
12322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
12422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
12522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
126dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
127dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
128dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1290c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1300c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
131e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController mDataController;
13222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
13322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
13422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
13522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
13630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
13730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private static class PageState {
13830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
13930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
14030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LockIcon mLockIcon;
14130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
142e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        Boolean mIsBookmarkedSite = false;
14330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
14430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
14530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (incognito) {
14630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "browser:incognito";
14730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
14830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = BitmapFactory.decodeResource(
14930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        c.getResources(), R.drawable.fav_incognito);
15030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
15130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "";
15230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
15330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = BitmapFactory.decodeResource(
15430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        c.getResources(), R.drawable.app_web_browser_sm);
15530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
15630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
15730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
15830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
15930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
16030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mUrl = url;
16130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mTitle = null;
16230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
16330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_SECURE;
16430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
16530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
16630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
16730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (favicon != null) {
16830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = favicon;
16930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
17030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (incognito) {
17130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    mFavicon = BitmapFactory.decodeResource(
17230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                            c.getResources(), R.drawable.fav_incognito);
17330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                } else {
17430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    mFavicon = BitmapFactory.decodeResource(
17530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                            c.getResources(), R.drawable.app_web_browser_sm);
17630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                }
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";
19822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
19922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
20022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
20158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
20258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
20358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
20458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
20558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
20658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
20795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     * Remove voice search mode from this tab.
20895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     */
20995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    public void revertVoiceSearchMode() {
21095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        if (mVoiceSearchData != null) {
21195d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            mVoiceSearchData = null;
21295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            if (mInForeground) {
2138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.revertVoiceSearchMode(this);
21495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            }
21595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        }
21695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    }
2178233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    /**
21958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
22058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
22158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
22258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
22358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
22458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
225c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Return true if the Tab is in voice search mode and the voice search
226c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Intent came with a String identifying that Google provided the Intent.
2271fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
2281fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
2291fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
2301fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
2311fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
23258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
23358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
23458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
23558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
23658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
23758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
23858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
23958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
24158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
24258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
24358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
24458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
24558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
24658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
24758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
24958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
25058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
25158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
25258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
25382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
25458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
255a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
25658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
25782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
25882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
25982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
26082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
26182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
26282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
26382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
26458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
26558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
26682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
26782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
26858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
26958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
27082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
27182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
27282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
27382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
27482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
27582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
27682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
27782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
27882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
2799df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
2809df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
2819df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
2821fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
2831fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
2842ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
285e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
286e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
287e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
288e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
289e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
290e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
291e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
292e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
293e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
294e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
295e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
296e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
297e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
298e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
299e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
300e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
301e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
302e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                mActivity.sendBroadcast(logIntent);
303e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
304e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
3052ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
3062ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
3072ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
3082ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
3092ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
31058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
31158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
31258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
31382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
31458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
3158233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.activateVoiceSearchMode(mVoiceSearchData.mLastVoiceSearchTitle);
31658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
31782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
31882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
31982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
32082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
32182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
32282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
32382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
32482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
32582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
32682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
32782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
32882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
32982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
33082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
33182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
33282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
33382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
33482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
33582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
33682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
33782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
33882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
33958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
34082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
34182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
3428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter(
34382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
34482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
3459df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
3469df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
3479df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
3489df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
3499df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
3509df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
3519df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
3529df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
3539df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
3549df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
3559df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
3569df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
3579df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
3589df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
3599df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
36058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
36158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
36258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
36382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
36482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
36558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
36658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
36782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
36882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
36958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
37058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
37158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
37258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
37358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
37458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
37558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
37658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
37758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
37858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
37958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
38058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
38182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
38282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
38382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
38482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
38582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
38682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
38782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
38882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
38982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
39082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
39182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
39282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
39358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
39482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
39558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
39658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
39758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
39858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
39958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
40058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
40158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
4021fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4031fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
4041fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
4051fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4061fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
4071fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4089df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
4099df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
4109df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
4119df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
4129df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
4130c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
4140c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
4150c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
4160c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
417e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
4180c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
4191fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
4201fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4211fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
4221fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
42358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
42458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
42522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
42622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
42722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
42822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
42922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
43022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
43122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
43222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
43322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
43422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
4358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
43822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
43922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
44022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
44122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
44222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
44322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
44422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
44522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
44722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
44822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
44922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
45022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
45122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
45222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
45322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
45522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
45622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
45722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
45822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
45922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
46022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
46122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
46222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
46322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
46422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
46522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
47522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
47622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            AlertDialog d = new AlertDialog.Builder(mActivity)
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
4984a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
4994a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
5028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
50330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = 0;
50430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState = new PageState(mActivity,
50530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
5064dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
50758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
50858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
5091fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
5101fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
5111fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
5121fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    mActivity.sendBroadcast(i);
5131fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
51495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III                revertVoiceSearchMode();
51558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
5298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
5358233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onPageStarted(Tab.this, view, url, favicon);
5364cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
537e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
53922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
54122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
5425b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
5435b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
5445b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
5455b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
5468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = false;
54730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            // Sync state (in case of stop/timeout)
54830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mUrl = view.getUrl();
54930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = view.getTitle();
55030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = view.getFavicon();
55130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
55230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // In case we stop when loading an HTTPS page from an HTTP page
55330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // but before a provisional load occurred
55430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
55530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
5568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onPageFinished(Tab.this, url);
55722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
55822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
56022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
56122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
562c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            if (voiceSearchSourceIsGoogle()) {
563c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // This method is called when the user clicks on a link.
564c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // VoiceSearchMode is turned off when the user leaves the
565c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // Google results page, so at this point the user must be on
566c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that page.  If the user clicked a link on that page, assume
567c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that the voice search was effective, and broadcast an Intent
568c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // so a receiver can take note of that fact.
569c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT);
570c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
571c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                        LoggingEvents.VoiceSearch.RESULT_CLICKED);
572c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                mActivity.sendBroadcast(logIntent);
573c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            }
57422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
57518eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
57618eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
57722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
57822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
57922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
58022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
58122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
58222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
58322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Updates the lock icon. This method is called when we discover another
58422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * resource to be loaded for this page (for example, javascript). While
58522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we update the icon type, we do not update the lock icon itself until
58622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we are done loading, it is slightly more secure this way.
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
58822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
58922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
59022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
59122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
59222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // to update the lock:
59330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) {
59422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // If NOT a 'safe' url, change the lock to mixed content!
59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
59730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED;
59822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
59922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
60022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
60122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
60322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
60522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
60722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
60822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
60922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
61022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
61422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
61522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
61622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
61747654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
61847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log URLs when in private browsing mode
619f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (!isPrivateBrowsingEnabled()) {
62047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
62147654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
62247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
62522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
62622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
62722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
62822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
62922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
63022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
63122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
63222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6364a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
6374a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
6384a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
6394a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
6404a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
6414a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
6424a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
6434a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new AlertDialog.Builder(mActivity).setTitle(
64522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
64622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
64722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
64822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
64922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
65022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6514a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
6524a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
6534a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6544a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6554a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6614a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
6624a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
6634a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6644a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6654a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
66622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
66722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
66822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
6694a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
6704a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
6714a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
6724a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
6734a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
67422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
67522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
67722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
67822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
67922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
68022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
68122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
68222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
68322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
68422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
68522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
68622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
6878233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.doUpdateVisitedHistory(Tab.this, url, isReload);
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
69830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (BrowserSettings.getInstance().showSecurityWarnings()) {
70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LayoutInflater factory =
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LayoutInflater.from(mActivity);
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final View warningsView =
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    factory.inflate(R.layout.ssl_warnings, null);
70622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LinearLayout placeholder =
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_UNTRUSTED)) {
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_untrusted);
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
71722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_IDMISMATCH)) {
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_mismatch);
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
72522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_EXPIRED)) {
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_expired);
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_NOTYETVALID)) {
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_not_yet_valid);
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity).setTitle(
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        R.string.security_warning).setIcon(
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        android.R.drawable.ic_dialog_alert).setView(
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        warningsView).setPositiveButton(R.string.ssl_continue,
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNeutralButton(R.string.view_certificate,
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
7548233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mWebViewController.showSslCertificateOnError(view,
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        handler, error);
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
757a49b829e91ea1290d9e1cf326417fdbf669f9d3aBen Murdoch                        }).setNegativeButton(R.string.ssl_go_back,
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
76130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setOnCancelListener(
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
76730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
76830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).show();
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
77422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
77522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
77622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
77722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
77822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
78522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
7878233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
7958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
79822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
80122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8038233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onUnhandledKeyEvent(event);
80422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
80622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
81022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
81222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
81622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
8188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
81922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
82022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
8218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final Tab newTab = mWebViewController.openTabAndShow(
82218eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        Tab.this,
8238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        IntentHandler.EMPTY_URL_DATA, false, null);
82422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (newTab != Tab.this) {
82522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Tab.this.addChildTab(newTab);
82622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
82722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
82822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
82922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
83022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
83122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
83222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
83322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
83422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
83522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
83622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
83722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
83822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
83922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
84022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
84122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
84222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
84322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
84422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
84522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
84622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
8488233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
85122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
85322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
85622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
85722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
85822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.Builder(mActivity)
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(R.string.attention)
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
898eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
899eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
9008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.switchToTab(mWebViewController.getTabControl().getTabIndex(
901eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott                        Tab.this));
902eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
903eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
904eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
905eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mParentTab != null) {
90822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
90922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
9108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.switchToTab(mWebViewController.getTabControl()
91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .getTabIndex(mParentTab));
91222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
9138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
91422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
91522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
91822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
91930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
92030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
92122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
92421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
92530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
9268233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
92822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
92922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
93022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
93130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
9328233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final ContentResolver cr = mActivity.getContentResolver();
939c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
940c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
941c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
942c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
943c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
944c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
945c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
946c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
9478233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
9488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mActivity, cr, view);
949c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
95022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
95322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
95422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
95522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
9568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
9578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    callback);
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
96122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
9628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
96622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
97122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
97222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
97422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
101650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
102122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
102222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
102322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
102422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
102550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
102622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103065acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
103165acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
103265acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1033c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1036c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1040c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
10418233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
10428233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
10438233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1047c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
104847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
1049f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
105047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
1051c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1052c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1053c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1054c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1055c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1056c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1057c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1058c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1059c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1060c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1061c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1062c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1063c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1064c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1065c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1066c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1067c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1068c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1069c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1070c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1071c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1072c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1073c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
108122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
108322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
10848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
108722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
109122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
10978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
110362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.openFileChooser(uploadMsg, acceptType);
110622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
110722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
11168233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
11178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11188029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
11198029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
11208029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
11218029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
11228029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
11238029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
11248029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            builder.setMessage(R.string.autofill_setup_dialog_message)
11258029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
11268029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       @Override
11278029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       public void onClick(DialogInterface dialog, int id) {
11288029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // Take user to the AutoFill profile editor. When they return,
11298029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // we will send the message that we pass here which will trigger
11308029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // the form to get filled out with their new profile.
11318029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           mWebViewController.setupAutoFill(msg);
11328029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       }
11338029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   })
11348029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
11358029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       @Override
11368029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       public void onClick(DialogInterface dialog, int id) {
11378029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // Disable autofill and show a toast with how to turn it on again.
11388029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           BrowserSettings s = BrowserSettings.getInstance();
11398029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           s.addObserver(mMainView.getSettings());
11408029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           s.disableAutoFill(mActivity);
11418029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           s.update();
11428029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           Toast.makeText(mActivity, R.string.autofill_setup_dialog_negative_toast,
11438029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                                   Toast.LENGTH_LONG).show();
11448029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       }
11458029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   }).show();
11468029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
114922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
115022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
115322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
115422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
115522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
115622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
115722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
11588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
115922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11608233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
116122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
11628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1163211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1164211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1165211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1166211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1167211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
116801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
11698233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
117022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
117122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
117222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
117322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
117422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
117522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
117622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
117722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
117822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
117922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
118022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
118122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
118222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
118322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
118422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
118522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
118622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
118722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
118822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
118922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
119022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
119122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
119222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
119322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
119422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
119522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
119622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
119722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
119922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
120022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
120122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
120222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
120322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
120422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
120522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
120622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
120722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
120822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
121122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
121222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
121322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
121422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
121722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
121822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
122622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
12378233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // TODO temporarily use activity here
12448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // remove later
12458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
12478233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Tab(WebViewController wvcontroller, WebView w, boolean closeOnExit, String appId,
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String url) {
12498233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
12508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity = mWebViewController.getActivity();
125122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = closeOnExit;
125222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = appId;
1253e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController = DataController.getInstance(mActivity);
125430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState = new PageState(mActivity, w.isPrivateBrowsingEnabled());
12558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
125622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
125722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1258dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1259dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1260dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1261dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
12628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1263dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1264dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1265dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
12660c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
12670c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
12680c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
12690c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
12700c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
12710c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
12720c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
12730c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
12740c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
12750c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
12760c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
12770c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
12780c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
12790c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
12800c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1281dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
128422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
128522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
128822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setWebView(WebView w) {
129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
129122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
129222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1293a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
129650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
129750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
129850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
129922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1300a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
130122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
130222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
130322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1304dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
130622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
130722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1308dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1309dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1310dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1311dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1312dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
13130c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
131422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
131622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
131822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
132022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
132122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
132222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
132322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
132522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
132922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs != null) {
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            for(Tab t : mChildTabs) {
133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                t.setParentTab(null);
133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mParentTab.mChildTabs.remove(this);
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
13531514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1354211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
13558233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1358dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1359dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1360dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1361dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1362dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1363dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
13648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1365dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1366dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1367dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1368dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
13698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1370dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1371dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1372dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
137522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
137722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
137822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
138022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
13848233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mSubView.getSettings());
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
138922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
139022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
139122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
139222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
139322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
139422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
139522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
139622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
139722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setParentTab(Tab parent) {
139822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mParentTab = parent;
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the parent tab index is already saved. If we are changing that index
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
140222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // parent tab index in the saved Bundle.
140322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
140422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
140522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
140622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
14078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl()
140822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getTabIndex(parent));
140922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
141022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
141122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
141222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
141322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
141422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
141522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
141622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
141722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
141822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
141922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs == null) {
142022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mChildTabs = new Vector<Tab>();
142122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
142222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mChildTabs.add(child);
142322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        child.setParentTab(this);
142422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
142622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Vector<Tab> getChildTabs() {
142722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mChildTabs;
142822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
143022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
143222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
143322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
143422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
143522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
143622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
143722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
143822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
143922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
144022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
144122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
144222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
144322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
144422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
144522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
144622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
144722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
145022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(mActivity);
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
145322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
145522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
145622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
145722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
145822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
14591961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
146022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
146122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
146222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
146322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
146422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
146822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
146922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14718233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
14728233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
14738233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
14748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
147822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
147922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
148122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
148722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
148822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
149122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1497a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1498a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1499a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1500a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
15018233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
15028233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
15038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15048233facddcc51865d612a919d450db6954aa48e3Michael Kolb
150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1506f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1507f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1508f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1509f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
15108233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1511f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        WebView webView = getWebView();
1512f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        if (webView == null) {
1513f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            return false;
1514f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        }
1515f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        return webView.isPrivateBrowsingEnabled();
1516f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1517f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1518f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
151922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
152022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
152122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
152222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
152322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
152422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15261514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
15271514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
15281514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15291514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
15308233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
15318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
15328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15338233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15341514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
15351514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
15361514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15371514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
154022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
154122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
154250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
154350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
154450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
154550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
154650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
154750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.init();
154850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
154922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
155022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
155122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
155222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
155322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
155422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
155522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
155622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
155722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
155822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
155922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
156022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
156522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
156722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
156830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mUrl;
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
157230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
157322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
157530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
157630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mActivity.getString(R.string.title_bar_loading);
157722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
157830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
157922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
158022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
158122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
158230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
158322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
158422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
158530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mFavicon;
158622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
158722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1588e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1589e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1590e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1591f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
159222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole = new ErrorConsoleView(mActivity);
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
160922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * If this Tab was created through another Tab, then this method returns
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * that Tab.
161122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return the Tab parent or null
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public Tab getParentTab() {
161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mParentTab;
161522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
161822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return whether this tab should be closed when it is backing out of the
161922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * first page.
162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if this tab should be closed when exit.
162122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean closeOnExit() {
162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mCloseOnExit;
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
162522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
162630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private void setLockIconType(LockIcon icon) {
162730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState.mLockIcon = icon;
162830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mWebViewController.onUpdatedLockIcon(this);
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return The tab's lock icon type.
163322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
163430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    LockIcon getLockIconType() {
163530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mLockIcon;
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
163930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
164030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
164130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
164230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
164322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
164422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
164522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
164622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
164722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16498233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
16508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
16558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void clearInPageLoad() {
16568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
165722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
166030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the cached saved state bundle.
166130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return cached state bundle
166222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
166322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bundle getSavedState() {
166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSavedState;
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
166822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the saved state.
166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setSavedState(Bundle state) {
167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = state;
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
167522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if succeed in saving the state.
167622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
167722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean saveState() {
167822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSavedState != null;
168222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
168522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.saveState(mSavedState);
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Store some extra info for displaying the tab in the picker.
168822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
169130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
169222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
16988233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mParentTab));
170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
170522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
170622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean restoreState(Bundle b) {
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (b == null) {
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
171022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
171122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
171222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
171322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = null;
171422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = b.getBoolean(CLOSEONEXIT);
171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.restoreState(b);
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (list == null) {
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1723211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
17241961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
1725e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
17261961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
17271961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
1728e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
1729e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
1730e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
1731e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
1732e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
1733e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
1734e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
17351961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
1736e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
1737e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
1739