Tab.java revision 30c714c853a4239e72ab1e238ce2a92472d06ab0
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;
294cd97793901e8f5681cf642d0b2684697964a37aLeon Scrogginsimport android.database.Cursor;
304cd97793901e8f5681cf642d0b2684697964a37aLeon Scrogginsimport android.database.sqlite.SQLiteException;
3122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
3230c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.graphics.BitmapFactory;
3322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
354cd97793901e8f5681cf642d0b2684697964a37aLeon Scrogginsimport android.os.AsyncTask;
3622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
3722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
384dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
394cd97793901e8f5681cf642d0b2684697964a37aLeon Scrogginsimport android.provider.BrowserContract;
40a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
4122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
4222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
4322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
4422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
4550c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
46c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
47dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
4822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
4922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
5022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
5122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
5222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
5322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebBackForwardList;
540c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
5522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
5822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
5922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
6022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.LinearLayout;
6122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.TextView;
628029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
6322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
64fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.ArrayList;
65fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.HashMap;
66fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Iterator;
67fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
68fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
69fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
70fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
7122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
7222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
7322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
7422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaclass Tab {
758233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
7722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
78c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
79c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
80c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
81c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
82c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
8330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public enum LockIcon {
8430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_UNSECURE,
8530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_SECURE,
8630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_MIXED,
8730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
888233facddcc51865d612a919d450db6954aa48e3Michael Kolb
898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Activity mActivity;
908233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WebViewController mWebViewController;
918233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
9322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
95a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
9622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
9722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
9822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
9922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
10022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
10122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
10222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
10322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
10422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
10522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
10622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
10722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
10822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mParentTab;
10922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
11022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
11122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Vector<Tab> mChildTabs;
11222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab will be removed when back out of the first page.
11322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mCloseOnExit;
11422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
11522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1188233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
11930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
12030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1214dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1224dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
12322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
12422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
12522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
12622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
12722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
12822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
12922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
130dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
131dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
132dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1330c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1340c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
13522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
13622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
13722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
13930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
14030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private static class PageState {
14130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
14230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
14330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LockIcon mLockIcon;
14430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
14530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
14630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
14730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (incognito) {
14830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "browser:incognito";
14930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
15030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = BitmapFactory.decodeResource(
15130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        c.getResources(), R.drawable.fav_incognito);
15230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
15330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mUrl = "";
15430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
15530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = BitmapFactory.decodeResource(
15630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        c.getResources(), R.drawable.app_web_browser_sm);
15730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
15830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
15930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
16030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
16130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
16230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mUrl = url;
16330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mTitle = null;
16430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
16530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_SECURE;
16630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
16730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
16830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
16930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (favicon != null) {
17030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mFavicon = favicon;
17130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
17230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (incognito) {
17330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    mFavicon = BitmapFactory.decodeResource(
17430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                            c.getResources(), R.drawable.fav_incognito);
17530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                } else {
17630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    mFavicon = BitmapFactory.decodeResource(
17730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                            c.getResources(), R.drawable.app_web_browser_sm);
17830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                }
17930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
18030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
18122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
18222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
18430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private PageState mCurrentState;
18530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
1864cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    // Whether or not the currently shown page is a bookmarked site.  Will be
1874cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    // out of date when loading a new page until the mBookmarkAsyncTask returns.
1884cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    private boolean mIsBookmarkedSite;
1894cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    // Used to determine whether the current site is bookmarked.
1904cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    private AsyncTask<Void, Void, Boolean> mBookmarkAsyncTask;
1914cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
1924cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    public boolean isBookmarkedSite() { return mIsBookmarkedSite; }
1934cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
19422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
19530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // TODO: Figure out who uses what and where
19630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    //       Some of these aren't use in this class, and some are only used in
19730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    //       restoring state but not saving it - FIX THIS
19822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String WEBVIEW = "webview";
19922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String NUMTABS = "numTabs";
20022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTAB = "currentTab";
20122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
20222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
20322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CLOSEONEXIT = "closeonexit";
20422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
20522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
20622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String ORIGINALURL = "originalUrl";
2073d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
20822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
20922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
21022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
21258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
21358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
21458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
21558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
21658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
21795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     * Remove voice search mode from this tab.
21895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     */
21995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    public void revertVoiceSearchMode() {
22095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        if (mVoiceSearchData != null) {
22195d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            mVoiceSearchData = null;
22295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            if (mInForeground) {
2238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.revertVoiceSearchMode(this);
22495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            }
22595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        }
22695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    }
2278233facddcc51865d612a919d450db6954aa48e3Michael Kolb
22895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    /**
22958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
23058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
23158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
23258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
23358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
23458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
235c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Return true if the Tab is in voice search mode and the voice search
236c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Intent came with a String identifying that Google provided the Intent.
2371fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
2381fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
2391fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
2401fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
2411fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
24258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
24358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
24458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
24558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
24658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
24758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
24858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
24958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
25058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
25158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
25258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
25358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
25458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
25558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
25658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
25758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
25858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
25958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
26058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
26158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
26258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
26382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
26458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
265a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
26658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
26782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
26882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
26982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
27082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
27182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
27282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
27382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
27458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
27558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
27682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
27782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
27858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
27958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
28082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
28182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
28282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
28382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
28482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
28582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
28682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
28782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
28882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
2899df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
2909df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
2919df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
2921fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
2931fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
2942ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
295e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
296e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
297e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
298e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
299e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
300e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
301e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
302e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
303e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
304e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
305e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
306e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
307e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
308e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
309e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
310e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
311e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
312e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                mActivity.sendBroadcast(logIntent);
313e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
314e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
3152ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
3162ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
3172ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
3182ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
3192ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
32058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
32158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
32258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
32382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
32458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
3258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.activateVoiceSearchMode(mVoiceSearchData.mLastVoiceSearchTitle);
32658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
32782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
32882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
32982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
33082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
33182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
33282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
33382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
33482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
33582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
33682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
33782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
33882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
33982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
34082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
34182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
34282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
34382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
34482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
34582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
34682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
34782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
34882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
34958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
35082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
35182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
3528233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter(
35382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
35482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
3559df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
3569df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
3579df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
3589df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
3599df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
3609df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
3619df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
3629df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
3639df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
3649df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
3659df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
3669df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
3679df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
3689df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
3699df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
37058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
37158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
37258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
37382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
37482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
37558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
37658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
37782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
37882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
37958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
38058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
38158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
38258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
38358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
38458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
38558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
38658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
38758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
38858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
38958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
39058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
39182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
39282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
39382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
39482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
39582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
39682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
39782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
39882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
39982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
40082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
40182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
40282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
40482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
40558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
40658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
40758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
40858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
40958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
41058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
41158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
4121fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4131fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
4141fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
4151fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4161fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
4171fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4189df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
4199df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
4209df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
4219df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
4229df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
4230c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
4240c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
4250c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
4260c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
427e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
4280c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
4291fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
4301fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4311fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
4321fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
43358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
43458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
43522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
43822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
43922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
44022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
44122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
44222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
44322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
44422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
4458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
44722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
44822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
44922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
45022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
45122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
45222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
45322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
45522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
45622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
45722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
45822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
45922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
46022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
46122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
46222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
46322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
46422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
46522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
47522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
47622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            AlertDialog d = new AlertDialog.Builder(mActivity)
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
5084a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
5094a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
51022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
51122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
5128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
51330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = 0;
51430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState = new PageState(mActivity,
51530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
5164dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
51758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
51858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
5191fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
5201fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
5211fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
5221fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    mActivity.sendBroadcast(i);
5231fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
52495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III                revertVoiceSearchMode();
52558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
53722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
5398233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
54122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
54222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
54322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
54422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
5458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onPageStarted(Tab.this, view, url, favicon);
5464cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
5471961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            updateBookmarkedStatusForUrl(url);
54822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
55122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
5525b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
5535b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
5545b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
5555b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
5568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = false;
55730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            // Sync state (in case of stop/timeout)
55830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mUrl = view.getUrl();
55930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = view.getTitle();
56030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = view.getFavicon();
56130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
56230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // In case we stop when loading an HTTPS page from an HTTP page
56330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                // but before a provisional load occurred
56430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
56530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
5668233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onPageFinished(Tab.this, url);
56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
56822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
56922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
57022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
57122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
572c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            if (voiceSearchSourceIsGoogle()) {
573c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // This method is called when the user clicks on a link.
574c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // VoiceSearchMode is turned off when the user leaves the
575c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // Google results page, so at this point the user must be on
576c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that page.  If the user clicked a link on that page, assume
577c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that the voice search was effective, and broadcast an Intent
578c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // so a receiver can take note of that fact.
579c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT);
580c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
581c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                        LoggingEvents.VoiceSearch.RESULT_CLICKED);
582c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                mActivity.sendBroadcast(logIntent);
583c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            }
58422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
58518eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
58618eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
58822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
58922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
59022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
59122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
59222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Updates the lock icon. This method is called when we discover another
59422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * resource to be loaded for this page (for example, javascript). While
59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we update the icon type, we do not update the lock icon itself until
59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we are done loading, it is slightly more secure this way.
59722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
59822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
59922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
60022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
60122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // to update the lock:
60330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) {
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // If NOT a 'safe' url, change the lock to mixed content!
60522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
60730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED;
60822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
60922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
61022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
61422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
61522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
61622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
61722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
61822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
61922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
62022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
62122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
62222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
62522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
62622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
62747654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
62847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log URLs when in private browsing mode
629f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (!isPrivateBrowsingEnabled()) {
63047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
63147654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
63247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
64522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6464a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
6474a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
6484a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
6494a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
6504a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
6514a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
6524a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
6534a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
65422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new AlertDialog.Builder(mActivity).setTitle(
65522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6614a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
6624a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
6634a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6644a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6654a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
66622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
66722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
66822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
66922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
67022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6714a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
6724a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
6734a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6744a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6754a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
67722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
67822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
6794a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
6804a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
6814a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
6824a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
6834a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
68422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
68522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
68622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
6978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.doUpdateVisitedHistory(Tab.this, url, isReload);
69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
70622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
70830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (BrowserSettings.getInstance().showSecurityWarnings()) {
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LayoutInflater factory =
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LayoutInflater.from(mActivity);
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final View warningsView =
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    factory.inflate(R.layout.ssl_warnings, null);
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LinearLayout placeholder =
71722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_UNTRUSTED)) {
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_untrusted);
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
72522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_IDMISMATCH)) {
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_mismatch);
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_EXPIRED)) {
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_expired);
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_NOTYETVALID)) {
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_not_yet_valid);
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity).setTitle(
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        R.string.security_warning).setIcon(
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        android.R.drawable.ic_dialog_alert).setView(
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        warningsView).setPositiveButton(R.string.ssl_continue,
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNeutralButton(R.string.view_certificate,
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
7648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mWebViewController.showSslCertificateOnError(view,
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        handler, error);
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
767a49b829e91ea1290d9e1cf326417fdbf669f9d3aBen Murdoch                        }).setNegativeButton(R.string.ssl_go_back,
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
77130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setOnCancelListener(
77422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
77522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
77622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
77730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
77830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).show();
78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
78522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
79522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
7978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
79822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
79922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
80122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
80322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
80422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8058233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
80622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8108233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
81122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
81222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onUnhandledKeyEvent(event);
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
81622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
81822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
81922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
82022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
82122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
82222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
82322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
82422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
82522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
82622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
82722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
8288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
82922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
83022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
8318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final Tab newTab = mWebViewController.openTabAndShow(
83218eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        Tab.this,
8338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        IntentHandler.EMPTY_URL_DATA, false, null);
83422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (newTab != Tab.this) {
83522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Tab.this.addChildTab(newTab);
83622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
83722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
83822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
83922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
84022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
84122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
84222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
84322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
84422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
84522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
84622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
85122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
85322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
85622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
85722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
8588233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.Builder(mActivity)
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(R.string.attention)
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
89822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
89922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
90022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
90422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
908eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
909eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
9108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.switchToTab(mWebViewController.getTabControl().getTabIndex(
911eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott                        Tab.this));
912eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
913eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
914eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
915eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mParentTab != null) {
91822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
91922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
9208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.switchToTab(mWebViewController.getTabControl()
92122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .getTabIndex(mParentTab));
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
9238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
92422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
92522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
92622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
92822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
92930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
93030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
93122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
93222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
93421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
93530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
9368233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
94130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
9428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
94322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
94422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
94522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
94722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
94822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final ContentResolver cr = mActivity.getContentResolver();
949c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
950c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
951c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
952c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
953c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
954c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
955c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
956c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
9578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
9588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mActivity, cr, view);
959c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
96022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
96122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
9668233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
9678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    callback);
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
97122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
9728233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
97422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
102122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
102222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
102322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
102422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
102522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
102650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
103122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
103322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
103550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
103622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104065acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
104165acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
104265acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1043c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1046c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1050c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
10518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
10528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
10538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1057c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
105847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
1059f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
106047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
1061c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1062c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1063c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1064c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1065c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1066c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1067c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1068c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1069c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1070c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1071c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1072c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1073c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1074c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1075c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1076c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1077c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1078c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1079c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1080c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1081c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1082c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1083c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
108722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
109122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
10948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
110622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
111362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
11158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.openFileChooser(uploadMsg, acceptType);
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
11268233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
11278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11288029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
11298029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
11308029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
11318029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
11328029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
11338029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
11348029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            builder.setMessage(R.string.autofill_setup_dialog_message)
11358029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
11368029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       @Override
11378029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       public void onClick(DialogInterface dialog, int id) {
11388029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // Take user to the AutoFill profile editor. When they return,
11398029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // we will send the message that we pass here which will trigger
11408029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // the form to get filled out with their new profile.
11418029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           mWebViewController.setupAutoFill(msg);
11428029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       }
11438029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   })
11448029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
11458029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       @Override
11468029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       public void onClick(DialogInterface dialog, int id) {
11478029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           // Disable autofill and show a toast with how to turn it on again.
11488029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           BrowserSettings s = BrowserSettings.getInstance();
11498029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           s.addObserver(mMainView.getSettings());
11508029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           s.disableAutoFill(mActivity);
11518029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           s.update();
11528029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                           Toast.makeText(mActivity, R.string.autofill_setup_dialog_negative_toast,
11538029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                                   Toast.LENGTH_LONG).show();
11548029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                       }
11558029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                   }).show();
11568029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
115722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
115822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
115922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
116022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
116122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
116222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
116322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
116422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
116522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
116622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
116722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
11688233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
116922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11708233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
117122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
11728233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1173211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1174211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1175211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1176211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1177211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
117801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
11798233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
118022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
118122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
118222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
118322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
118422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
118522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
118622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
118722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
118822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
118922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
119022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
119122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
119222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
119322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
119422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
119522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
119622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
119722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
119922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
120022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
120122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
120222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
120322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
120422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
120522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
120622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
120722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
120822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
121122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
121222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
121322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
121422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
121722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
121822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
122622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
12478233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
125022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
125122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
125222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12538233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // TODO temporarily use activity here
12548233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // remove later
12558233facddcc51865d612a919d450db6954aa48e3Michael Kolb
125622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
12578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    Tab(WebViewController wvcontroller, WebView w, boolean closeOnExit, String appId,
125822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String url) {
12598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
12608233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity = mWebViewController.getActivity();
126122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = closeOnExit;
126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = appId;
126330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState = new PageState(mActivity, w.isPrivateBrowsingEnabled());
12648233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
126522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1268dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1269dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1270dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1271dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
12728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1273dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1274dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1275dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
12760c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
12770c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
12780c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
12790c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
12800c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
12810c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
12820c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
12830c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
12840c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
12850c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
12860c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
12870c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
12880c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
12890c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
12900c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1291dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
129222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
129322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
129722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
129822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
129922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setWebView(WebView w) {
130022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
130122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
130222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1303a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
130422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
130650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
130750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
130850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
130922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1310a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
131122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
131222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
131322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1314dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
131522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
131622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1318dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1319dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1320dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1321dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1322dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
13230c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
132522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
132922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs != null) {
134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            for(Tab t : mChildTabs) {
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                t.setParentTab(null);
134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
135322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mParentTab.mChildTabs.remove(this);
135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
136022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
136122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
136222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
13631514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1364211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
13658233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1368dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1369dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1370dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1371dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1372dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1373dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
13748233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1375dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1376dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1377dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1378dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
13798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1380dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1381dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1382dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
139022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
139122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
139222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
139322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
13948233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
139522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(
139622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mSubView.getSettings());
139722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
139822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
140222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
140322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
140422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
140522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
140622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
140722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setParentTab(Tab parent) {
140822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mParentTab = parent;
140922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
141022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the parent tab index is already saved. If we are changing that index
141122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
141222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // parent tab index in the saved Bundle.
141322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
141422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
141522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
141622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
14178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl()
141822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getTabIndex(parent));
141922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
142022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
142122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
142322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
142422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
142522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
142622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
142722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
142822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
142922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs == null) {
143022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mChildTabs = new Vector<Tab>();
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
143222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mChildTabs.add(child);
143322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        child.setParentTab(this);
143422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
143522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
143622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Vector<Tab> getChildTabs() {
143722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mChildTabs;
143822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
143922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
144022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
144122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
144222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
144322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
144422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
144522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
144622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
144722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
145022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
145322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
145522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
145622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
145722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
145822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
145922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
146022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
146122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(mActivity);
146222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
146322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
146422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
146822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
14691961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
147022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
147322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
147422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
147822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
147922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
14828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
14838233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
14848233facddcc51865d612a919d450db6954aa48e3Michael Kolb
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
148722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
148822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
149122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
150222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
150322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1507a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1508a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1509a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1510a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
15118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
15128233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
15138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15148233facddcc51865d612a919d450db6954aa48e3Michael Kolb
151522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1516f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1517f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1518f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1519f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
15208233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1521f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        WebView webView = getWebView();
1522f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        if (webView == null) {
1523f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            return false;
1524f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        }
1525f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk        return webView.isPrivateBrowsingEnabled();
1526f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1527f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1528f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
152922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
153022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
153122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
153222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
153322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
153422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
153522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15361514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
15371514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
15381514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15391514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
15408233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
15418233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
15428233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15438233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15441514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
15451514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
15461514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15471514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
154822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
154922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
155022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
155122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
155250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
155350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
155450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
155550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
155650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
155750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.init();
155850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
155922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
156022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
156522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
156722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
157222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
157422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
157522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
157622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
157722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
157830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mUrl;
157922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
158022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
158122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
158230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
158322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
158422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
158530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
158630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mActivity.getString(R.string.title_bar_loading);
158722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
158830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
159122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
159230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
159530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mFavicon;
159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1598f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
160722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
160922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole = new ErrorConsoleView(mActivity);
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
161122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * If this Tab was created through another Tab, then this method returns
161722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * that Tab.
161822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return the Tab parent or null
161922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public Tab getParentTab() {
162122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mParentTab;
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
162522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return whether this tab should be closed when it is backing out of the
162622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * first page.
162722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if this tab should be closed when exit.
162822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean closeOnExit() {
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mCloseOnExit;
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private void setLockIconType(LockIcon icon) {
163430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState.mLockIcon = icon;
163530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mWebViewController.onUpdatedLockIcon(this);
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return The tab's lock icon type.
164022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
164130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    LockIcon getLockIconType() {
164230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mLockIcon;
164322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
164422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
164530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
164630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
164730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
164830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
164930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
165522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
16578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
166122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
16628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void clearInPageLoad() {
16638233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
166730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the cached saved state bundle.
166830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return cached state bundle
166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bundle getSavedState() {
167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSavedState;
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
167522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the saved state.
167622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
167722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setSavedState(Bundle state) {
167822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = state;
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
168222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if succeed in saving the state.
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
168422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean saveState() {
168522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
168822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSavedState != null;
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
169022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
169222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.saveState(mSavedState);
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Store some extra info for displaying the tab in the picker.
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
169830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
17058233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
170622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mParentTab));
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
171022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
171122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
171222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
171322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
171422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean restoreState(Bundle b) {
171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (b == null) {
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = null;
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = b.getBoolean(CLOSEONEXIT);
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.restoreState(b);
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (list == null) {
172622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1730211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
17311961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
17321961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        if (mMainView == null) {
17331961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            return;
17341961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        }
17351961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        String url = mMainView.getUrl();
17361961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        if (url == null) {
17371961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            return;
17381961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        }
17391961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        updateBookmarkedStatusForUrl(url);
17401961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
17411961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
17421961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    /**
17431961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins     * Update mIsBookmarkedSite, using urlInQuestion to compare.
17441961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins     * @param urlInQuestion URL of the current page, to be checked in the
17451961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins     *          bookmarks database.
17461961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins     */
17471961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    private void updateBookmarkedStatusForUrl(final String urlInQuestion) {
17481961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        if (mBookmarkAsyncTask != null) {
17491961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            mBookmarkAsyncTask.cancel(true);
17501961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        }
17511961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mBookmarkAsyncTask = new AsyncTask<Void, Void, Boolean>() {
17521961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            @Override
17531961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            protected Boolean doInBackground(Void... unused) {
17541961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                // Check to see if the site is bookmarked
17551961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                Cursor cursor = null;
17561961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                try {
17571961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    cursor = mActivity.getContentResolver().query(
17581961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                            BrowserContract.Bookmarks.CONTENT_URI,
17591961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                            new String[] { BrowserContract.Bookmarks.URL },
17601961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                            BrowserContract.Bookmarks.URL + " == ?",
17611961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                            new String[] { urlInQuestion },
17621961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                            null);
17631961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    return cursor.moveToFirst();
17641961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                } catch (SQLiteException e) {
17651961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    Log.e(LOGTAG, "Error checking for bookmark: " + e);
17661961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    return false;
17671961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                } finally {
17681961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    if (cursor != null) cursor.close();
17691961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                }
17701961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
17711961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            @Override
17721961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            protected void onPostExecute(Boolean isBookmarked) {
17731961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                if (this == mBookmarkAsyncTask) {
17741961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    mIsBookmarkedSite = isBookmarked;
17751961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    mWebViewController.bookmarkedStatusHasChanged(Tab.this);
17761961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                }
17771961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
17781961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        };
17791961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mBookmarkAsyncTask.execute();
17801961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
178122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
1782