Tab.java revision 211ba54a3052f7e68bf8af035ea1ef4e9445130c
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
1922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport java.io.File;
2058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport java.util.ArrayList;
219df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scrogginsimport java.util.HashMap;
229df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scrogginsimport java.util.Iterator;
2322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport java.util.LinkedList;
249df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scrogginsimport java.util.Map;
2522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport java.util.Vector;
2622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
2722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.app.AlertDialog;
2858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.app.SearchManager;
2922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentResolver;
3022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentValues;
3122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface;
3222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface.OnCancelListener;
3358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.Intent;
3422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.database.Cursor;
3522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.database.sqlite.SQLiteDatabase;
3622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.database.sqlite.SQLiteException;
3722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
3822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
4022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.AsyncTask;
4122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
4222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
434dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
4422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.provider.Browser;
45a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
4622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
4722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
4822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
4922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
5022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.ViewGroup;
5150c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
5222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View.OnClickListener;
53c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
5422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.CookieSyncManager;
55dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
5822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
5922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
6022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
6122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebBackForwardList;
620c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
6322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
6422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
6522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebIconDatabase;
6622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
6722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
6822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
6922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.FrameLayout;
7022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.ImageButton;
7122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.LinearLayout;
7222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.TextView;
7322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
741fe13a5230e319df42b21939a14d127bd9bf3856Leon Scrogginsimport com.android.common.speech.LoggingEvents;
751fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins
7622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
7722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
7822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
7922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaclass Tab {
8022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
8122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
82c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
83c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
84c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
85c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
86c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
8722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
8822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
8922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
90211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    private LinearLayout mContainer;
9122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
9222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
9322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
9522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
9622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
9722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
9822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
9922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
10022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
10122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Data used when displaying the tab in the picker.
10222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private PickerData mPickerData;
10322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
10422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
10522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mParentTab;
10622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
10722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
10822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Vector<Tab> mChildTabs;
10922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab will be removed when back out of the first page.
11022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mCloseOnExit;
11122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
11222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
11322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in loading state.
11422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInLoad;
1154dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1164dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
11722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
11822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
11922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
12022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
12122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
12222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mOriginalUrl;
12322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
12422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
12522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // the lock icon type and previous lock icon type for the tab
12622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private int mLockIconType;
12722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private int mPrevLockIconType;
12822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Inflation service for making subwindows.
12922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final LayoutInflater mInflateService;
13022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The BrowserActivity which owners the Tab
13122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final BrowserActivity mActivity;
132dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
133dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
134dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1350c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1360c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
13722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
13922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
14022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Extra saved information for displaying the tab in the picker.
14222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class PickerData {
14322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        String  mUrl;
14422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        String  mTitle;
14522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Bitmap  mFavicon;
14622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
14722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
14922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String WEBVIEW = "webview";
15022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String NUMTABS = "numTabs";
15122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTAB = "currentTab";
15222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
15322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRPICTURE = "currentPicture";
15522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CLOSEONEXIT = "closeonexit";
15622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
15722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
15822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String ORIGINALURL = "originalUrl";
15922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
16022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
16122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
16258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
16358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
16458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
16558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
16658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
16758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
16858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
16958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
17058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
17158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
17258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
17358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
1741fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     * Return true if the voice search Intent came with a String identifying
1751fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     * that Google provided the Intent.
1761fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
1771fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
1781fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
1791fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
1801fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
18158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
18258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
18358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
18458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
18558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
18658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
18758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
18858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
18958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
19058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
19158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
19258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
19358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
19458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
19558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
19658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
19758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
19858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
19958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
20058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
20158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
20282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
20358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
204a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
20558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
20682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
20782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
20882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
20982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
21082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
21182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
21282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
21358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
21458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
21582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
21682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
21758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
21858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
21982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
22082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
22182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
22282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
22382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
22482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
22582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
22682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
22782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
2289df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
2299df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
2309df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
2311fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
2321fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
2332ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
234e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
235e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
236e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
237e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
238e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
239e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
240e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
241e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
242e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
243e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
244e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
245e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
246e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
247e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
248e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
249e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
250e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
251e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                mActivity.sendBroadcast(logIntent);
252e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
253e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
2542ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
2552ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
2562ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
2572ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
2582ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
25958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
26058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
26158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
26282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
26358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
26458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mActivity.showVoiceTitleBar(mVoiceSearchData.mLastVoiceSearchTitle);
26558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
26682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
26782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
26882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
26982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
27082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
27182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
27282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
27382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
27482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
27582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
27682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
27782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
27882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
27982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
28082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
28182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
28282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
28382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
28482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
28582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
28682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
28782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
28858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
28982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
29082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
29182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData.mLastVoiceSearchUrl = mActivity.smartUrlFilter(
29282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
29382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
2949df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
2959df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
2969df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
2979df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
2989df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
2999df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
3009df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
3019df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
3029df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
3039df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
3049df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
3059df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
3069df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
3079df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
3089df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
30958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
31058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
31158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
31282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
31382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
31458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
31558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
31682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
31782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
31858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
31958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
32058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
32158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
32258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
32358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
32458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
32558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
32658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
32758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
32858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
32958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
33082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
33182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
33282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
33382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
33482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
33582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
33682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
33782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
33882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
33982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
34082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
34182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
34258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
34382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
34458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
34558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
34658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
34758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
34858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
34958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
35058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
3511fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
3521fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
3531fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
3541fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
3551fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
3561fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
3579df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
3589df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
3599df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
3609df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
3619df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
3620c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
3630c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
3640c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
3650c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
366e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
3670c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
3681fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
3691fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
3701fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
3711fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
37258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
37358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
37422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
37522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
37622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
37722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
37822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
37922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
38022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
38122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
38222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
38322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
38422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
38522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
38622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
38722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
38822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
38922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
39022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
39122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
39222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
39322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
39422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
39522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
39622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
39722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
39822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
39922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
40022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
40122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
40222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
40322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
40422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
40522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
40622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
40722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
40822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
40922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
41022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
41122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
41222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
41322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
41422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
41522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
41622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
41722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
41822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
41922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
42022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
42122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
42222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
42322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
42422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
42522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
42622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
42722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
42822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
42922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
43022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
43122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
43222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            AlertDialog d = new AlertDialog.Builder(mActivity)
43322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
43422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
43522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
43822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
43922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
44022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
44122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
44222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
44322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
44422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
44522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
4474a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
4484a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
44922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
45022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
45122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInLoad = true;
4524dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
45358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
45458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
4551fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
4561fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
4571fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
4581fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    mActivity.sendBroadcast(i);
4591fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
46058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                mVoiceSearchData = null;
46158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                if (mInForeground) {
46258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    mActivity.revertVoiceTitleBar();
46358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                }
46458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
46522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // We've started to load a new page. If there was a pending message
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to save a screenshot then we will now take the new page and save
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // an incorrect screenshot. Therefore, remove any pending thumbnail
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // messages from the queue.
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mActivity.removeMessages(BrowserActivity.UPDATE_BOOKMARK_THUMBNAIL,
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    view);
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
47522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
47622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mActivity.shouldShowErrorConsole()) {
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // update the bookmark database for favicon
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (favicon != null) {
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                BrowserBookmarksAdapter.updateBookmarkFavicon(mActivity
492cc9491236354dd59bffc976f6b55b86e558dc628Patrick Scott                        .getContentResolver(), null, url, favicon);
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset sync timer to avoid sync starts during loading a page
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            CookieSyncManager.getInstance().resetSync();
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mActivity.isNetworkUp()) {
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                view.setNetworkAvailable(false);
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.onPageStarted(view, url, favicon);
50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
50922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
5104dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            LogTag.logPageFinishedLoading(
5114dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen                    url, SystemClock.uptimeMillis() - mLoadStartTime);
51222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInLoad = false;
51322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground && !mActivity.didUserStopLoading()
51522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    || !mInForeground) {
51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Only update the bookmark screenshot if the user did not
51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // cancel the load early.
51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.postMessage(
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        BrowserActivity.UPDATE_BOOKMARK_THUMBNAIL, 0, 0, view,
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        500);
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.onPageFinished(view, url);
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return mActivity.shouldOverrideUrlLoading(view, url);
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
53622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
53722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Updates the lock icon. This method is called when we discover another
54122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * resource to be loaded for this page (for example, javascript). While
54222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we update the icon type, we do not update the lock icon itself until
54322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we are done loading, it is slightly more secure this way.
54422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
54522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
54622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
54722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
54822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // to update the lock:
55022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mLockIconType == BrowserActivity.LOCK_ICON_SECURE) {
55122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // If NOT a 'safe' url, change the lock to mixed content!
55222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
55322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
55422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mLockIconType = BrowserActivity.LOCK_ICON_MIXED;
55522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
55622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
55722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
55822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
55922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
56022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
56122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
56222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
56322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
56422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
56522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
56822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
56922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
57022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
57122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
57222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
57322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
57422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
57522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    + " " + description);
57622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
57722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // We need to reset the title after an error if it is in foreground.
57822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
57922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.resetTitleAndRevertLockIcon();
58022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
58122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
58222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
58322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
58422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
58522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
58622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
58822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
58922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
59022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
59122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
59222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
5944a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
5954a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
5964a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
5974a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
5984a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
5994a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
6004a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
6014a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new AlertDialog.Builder(mActivity).setTitle(
60322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
60522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
60722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
60822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6094a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
6104a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
6114a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6124a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6134a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
61422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
61522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
61622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
61722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
61822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6194a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
6204a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
6214a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6224a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6234a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
62522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
62622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
6274a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
6284a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
6294a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
6304a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
6314a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
63222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
64522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.regionMatches(true, 0, "about:", 0, 6)) {
64622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
64722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
64822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // remove "client" before updating it to the history so that it wont
64922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // show up in the auto-complete list.
65022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            int index = url.indexOf("client=ms-");
65122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (index > 0 && url.contains(".google.")) {
65222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                int end = url.indexOf('&', index);
65322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (end > 0) {
65422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    url = url.substring(0, index)
65522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .concat(url.substring(end + 1));
65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                } else {
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // the url.charAt(index-1) should be either '?' or '&'
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    url = url.substring(0, index-1);
65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6618d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            final ContentResolver cr = mActivity.getContentResolver();
6628d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            final String newUrl = url;
6638d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            new AsyncTask<Void, Void, Void>() {
6648d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                protected Void doInBackground(Void... unused) {
6658d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    Browser.updateVisitedHistory(cr, newUrl, true);
6668d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    return null;
6678d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                }
6688d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            }.execute();
66922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebIconDatabase.getInstance().retainIconForPageUrl(url);
67022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
67122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
67222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
67322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
67422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
67522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
67722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
67822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
67922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
68022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
68122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
68222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (BrowserSettings.getInstance().showSecurityWarnings()) {
68322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LayoutInflater factory =
68422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LayoutInflater.from(mActivity);
68522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final View warningsView =
68622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    factory.inflate(R.layout.ssl_warnings, null);
68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LinearLayout placeholder =
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_UNTRUSTED)) {
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_untrusted);
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_IDMISMATCH)) {
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_mismatch);
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
70622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_EXPIRED)) {
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_expired);
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_NOTYETVALID)) {
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
71722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_not_yet_valid);
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity).setTitle(
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        R.string.security_warning).setIcon(
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        android.R.drawable.ic_dialog_alert).setView(
72522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        warningsView).setPositiveButton(R.string.ssl_continue,
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNeutralButton(R.string.view_certificate,
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                mActivity.showSSLCertificateOnError(view,
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        handler, error);
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNegativeButton(R.string.cancel,
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                mActivity.resetTitleAndRevertLockIcon();
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setOnCancelListener(
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                mActivity.resetTitleAndRevertLockIcon();
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).show();
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String username = null;
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String password = null;
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            boolean reuseHttpAuthUsernamePassword = handler
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .useHttpAuthUsernamePassword();
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
77495a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block            if (reuseHttpAuthUsernamePassword && view != null) {
77595a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block                String[] credentials = view.getHttpAuthUsernamePassword(
77622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        host, realm);
77722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (credentials != null && credentials.length == 2) {
77822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    username = credentials[0];
77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    password = credentials[1];
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (username != null && password != null) {
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed(username, password);
78522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mActivity.showHttpAuthentication(handler, host, realm,
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            null, null, null, 0);
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                } else {
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    handler.cancel();
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
79522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
79822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
79922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
80022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mActivity.isMenuDown()) {
80122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // only check shortcut key when MENU is held
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return mActivity.getWindow().isShortcutKey(event.getKeyCode(),
80322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        event);
80422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
80522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
80622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
81022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8111f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark            if (!mInForeground || mActivity.mActivityInPause) {
81222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (event.isDown()) {
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.onKeyDown(event.getKeyCode(), event);
81622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.onKeyUp(event.getKeyCode(), event);
81822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
81922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
82022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
82122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
82222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
82322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
82422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
82522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
82622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
82722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
82822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
82922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
83022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
83122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
83222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
83322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.attachSubWindow(Tab.this);
83422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
83522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
83622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final Tab newTab = mActivity.openTabAndShow(
83722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        BrowserActivity.EMPTY_URL_DATA, false, null);
83822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (newTab != Tab.this) {
83922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Tab.this.addChildTab(newTab);
84022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
84122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
84222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
84322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
84422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
84522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
84622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
85122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
85322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
85622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
85722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
85822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else if (!mActivity.getTabControl().canCreateNewTab()) {
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                new AlertDialog.Builder(mActivity)
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.Builder(mActivity)
89822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(R.string.attention)
89922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
90022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
90222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
90422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
90822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
90922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
91022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
912eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
913eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
914eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott                mActivity.switchToTab(mActivity.getTabControl().getTabIndex(
915eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott                        Tab.this));
916eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
917eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
918eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
919eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
92022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
92122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mParentTab != null) {
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
92422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mActivity.switchToTab(mActivity.getTabControl()
92522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .getTabIndex(mParentTab));
92622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.closeTab(Tab.this);
92822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
92922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
93022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
93222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (newProgress == 100) {
93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // sync cookies and cache promptly here.
93522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                CookieSyncManager.getInstance().sync();
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.onProgressChanged(view, newProgress);
93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
94122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
94222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
94321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
94421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins            final String pageUrl = view.getUrl();
94522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // here, if url is null, we want to reset the title
94721d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                mActivity.setUrlTitle(pageUrl, title);
94822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
94921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins            if (pageUrl == null || pageUrl.length()
95021d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
95321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins            new AsyncTask<Void, Void, Void>() {
95421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                protected Void doInBackground(Void... unused) {
95521d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    // See if we can find the current url in our history
95621d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    // database and add the new title to it.
95721d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    String url = pageUrl;
95821d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    if (url.startsWith("http://www.")) {
95921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        url = url.substring(11);
96021d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    } else if (url.startsWith("http://")) {
96121d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        url = url.substring(4);
96221d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    }
96321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    Cursor c = null;
96421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    try {
96521d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        final ContentResolver cr
96621d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                = mActivity.getContentResolver();
96721d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        url = "%" + url;
96821d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        String [] selArgs = new String[] { url };
96921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        String where = Browser.BookmarkColumns.URL
97021d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                + " LIKE ? AND "
97121d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                + Browser.BookmarkColumns.BOOKMARK + " = 0";
97221d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        c = cr.query(Browser.BOOKMARKS_URI, new String[]
97321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                { Browser.BookmarkColumns._ID }, where, selArgs,
97421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                null);
97521d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        if (c.moveToFirst()) {
97621d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                            // Current implementation of database only has one
97721d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                            // entry per url.
97821d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                            ContentValues map = new ContentValues();
97921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                            map.put(Browser.BookmarkColumns.TITLE, title);
98021d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                            String[] projection = new String[]
98121d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                    { Integer.valueOf(c.getInt(0)).toString() };
98221d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                            cr.update(Browser.BOOKMARKS_URI, map, "_id = ?",
98321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                    projection);
98421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        }
98521d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    } catch (IllegalStateException e) {
98621d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        Log.e(LOGTAG, "Tab onReceived title", e);
98721d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    } catch (SQLiteException ex) {
98821d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        Log.e(LOGTAG,
98921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                "onReceivedTitle() caught SQLiteException: ",
99021d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                                ex);
99121d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    } finally {
99221d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                        if (c != null) c.close();
99321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    }
99421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins                    return null;
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
99621d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins            }.execute();
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (icon != null) {
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                BrowserBookmarksAdapter.updateBookmarkFavicon(mActivity
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getContentResolver(), view.getOriginalUrl(), view
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getUrl(), icon);
100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.setFavicon(icon);
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final ContentResolver cr = mActivity.getContentResolver();
1015c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
1016c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
1017c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
1018c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
1019c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
1020c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
1021c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
1022c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
1023c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = new DownloadTouchIcon(Tab.this, cr, view);
1024c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
102522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
102622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
103122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) mActivity.onShowCustomView(view, callback);
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
103322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
103622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) mActivity.onHideCustomView();
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
104022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
104122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
104222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
104322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
105722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
105822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
106022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
106222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
106322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
106522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
106622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
106722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
106822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
106922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().getWebStorageSizeManager()
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
108122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
108322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
108722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
109050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
109122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
109950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
110465acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
110565acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
110665acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1107c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1110c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1114c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mActivity.shouldShowErrorConsole()
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        && errorConsole.getShowState() != ErrorConsoleView.SHOW_MAXIMIZED) {
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1120c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1121c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1122c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1123c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1124c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1125c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1126c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1127c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1128c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1129c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1130c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1131c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1132c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1133c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1134c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1135c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1136c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1137c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1138c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1139c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1140c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1141c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1142c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1143c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
114522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
114922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
115022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
115322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
115422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return mActivity.getDefaultVideoPoster();
115522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
115622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
115722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
115822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
115922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
116022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
116122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
116222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
116322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
116422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
116522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
116622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
116722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return mActivity.getVideoLoadingProgressView();
116822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
116922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
117022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
117122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
117222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
117322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void openFileChooser(ValueCallback<Uri> uploadMsg) {
117422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
117522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mActivity.openFileChooser(uploadMsg);
117622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
117722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
117822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
117922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
118022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
118122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
118222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
118322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
118422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
118522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
118622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            AsyncTask<Void, Void, String[]> task = new AsyncTask<Void, Void, String[]>() {
118722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public String[] doInBackground(Void... unused) {
118822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    return Browser.getVisitedHistory(mActivity
118922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            .getContentResolver());
119022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
119122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onPostExecute(String[] result) {
119222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    callback.onReceiveValue(result);
119322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                };
119422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
119522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            task.execute();
119622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        };
119722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
119922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
120022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
120122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
120222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
120322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
120422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
120522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
120622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
120722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
1208211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        private final BrowserActivity mBrowserActivity;
120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1210211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        SubWindowClient(WebViewClient client, BrowserActivity activity) {
121122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
1212211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mBrowserActivity = activity;
1213211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1214211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1215211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1216211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1217211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
1218211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // find dialog.
1219211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            if (view.getFindIsUp()) mBrowserActivity.closeFind();
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
124722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
124922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
125022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
125122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
125222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
125322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
125422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
125522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
125622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
125722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
125822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
126022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
126122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
126422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
126522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
126822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
126922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
127022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
127122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
127222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
127322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
127422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
127522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
127622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
127722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
127822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
127922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
128022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
128122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
128422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
128522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mActivity.dismissSubWindow(Tab.this);
128822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
129122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
129222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
129322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Tab(BrowserActivity activity, WebView w, boolean closeOnExit, String appId,
129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String url) {
129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mActivity = activity;
129722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = closeOnExit;
129822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = appId;
129922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOriginalUrl = url;
130022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mLockIconType = BrowserActivity.LOCK_ICON_UNSECURE;
130122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPrevLockIconType = BrowserActivity.LOCK_ICON_UNSECURE;
130222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInLoad = false;
130322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
130422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInflateService = LayoutInflater.from(activity);
130622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
130722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The tab consists of a container view, which contains the main
130822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView, as well as any other UI elements associated with the tab.
1309211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        mContainer = (LinearLayout) mInflateService.inflate(R.layout.tab, null);
131022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1311dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1312dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1313dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1314dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
1315dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                mActivity.onDownloadStart(url, userAgent, contentDisposition,
1316dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1317dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                if (mMainView.copyBackForwardList().getSize() == 0) {
1318dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    // This Tab was opened for the sole purpose of downloading a
1319dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    // file. Remove it.
1320dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mActivity.getTabControl().getCurrentWebView()
1321dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            == mMainView) {
1322dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // In this case, the Tab is still on top.
1323dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mActivity.goBackOnePageOrQuit();
1324dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    } else {
1325dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // In this case, it is not.
1326dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mActivity.closeTab(Tab.this);
1327dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1328dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1329dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1330dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
13310c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
13320c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
13330c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
13340c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
13350c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
13360c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
13370c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
13380c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
13390c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
13400c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
13410c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
13420c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
13430c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
13440c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
13450c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1346dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
135322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setWebView(WebView w) {
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
136050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
136150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
136250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
136322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Just remove the old one.
136522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        FrameLayout wrapper =
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                (FrameLayout) mContainer.findViewById(R.id.webview_wrapper);
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        wrapper.removeView(mMainView);
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1371dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1375dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1376dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1377dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1378dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1379dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
13800c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
138922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
139022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
139122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
139222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
139322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
139422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
139522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
139622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
139722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
139822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
140222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
140322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs != null) {
140422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            for(Tab t : mChildTabs) {
140522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                t.setParentTab(null);
140622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
140722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
140822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
140922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
141022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mParentTab.mChildTabs.remove(this);
141122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
141222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
141322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
141422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
141522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
141622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
141722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
141822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
141922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
1420211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            if (mMainView.getFindIsUp()) mActivity.closeFind();
142122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = mInflateService.inflate(
142222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.browser_subwindow, null);
142322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = (WebView) mSubViewContainer.findViewById(R.id.webview);
142480380ed1b6b1cd59b5da7474202963f87ec32ab8Grace Kloba            mSubView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
142522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // use trackball directly
142622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setMapTrackballToArrowKeys(false);
1427140b33aa6f3edbb95963d7b594edeec4673ab124Grace Kloba            // Enable the built-in zoom
1428140b33aa6f3edbb95963d7b594edeec4673ab124Grace Kloba            mSubView.getSettings().setBuiltInZoomControls(true);
1429211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
1430211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                    mActivity));
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
143222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1433dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1434dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1435dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1436dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1437dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1438dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
1439dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    mActivity.onDownloadStart(url, userAgent,
1440dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1441dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1442dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1443dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
1444dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        dismissSubWindow();
1445dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1446dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1447dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final BrowserSettings s = BrowserSettings.getInstance();
145022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            s.addObserver(mSubView.getSettings()).update(s, null);
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final ImageButton cancel = (ImageButton) mSubViewContainer
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .findViewById(R.id.subwindow_close);
145322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            cancel.setOnClickListener(new OnClickListener() {
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onClick(View v) {
145522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mSubView.getWebChromeClient().onCloseWindow(mSubView);
145622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
145722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            });
145822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
145922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
146022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
146122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
146222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
146322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
146422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
1468211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            if (mSubView.getFindIsUp()) {
1469211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                mActivity.closeFind();
1470211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            }
147122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            BrowserSettings.getInstance().deleteObserver(
147222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mSubView.getSettings());
147322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
147422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Attach the sub window to the content view.
148122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(ViewGroup content) {
148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
148422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            content.addView(mSubViewContainer,
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    BrowserActivity.COVER_SCREEN_PARAMS);
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the sub window from the content view.
149122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeSubWindow(ViewGroup content) {
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            content.removeView(mSubViewContainer);
1495211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            if (mSubView.getFindIsUp()) mActivity.closeFind();
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * This method attaches both the WebView and any sub window to the
150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * given content view.
150222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
150322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachTabToContentView(ViewGroup content) {
150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
150722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
150822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Attach the WebView to the container and then attach the
150922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // container to the content view.
151022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        FrameLayout wrapper =
151122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                (FrameLayout) mContainer.findViewById(R.id.webview_wrapper);
1512b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        ViewGroup parent = (ViewGroup) mMainView.getParent();
1513b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        if (parent != wrapper) {
1514b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            if (parent != null) {
1515b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                Log.w(LOGTAG, "mMainView already has a parent in"
1516b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                        + " attachTabToContentView!");
1517b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                parent.removeView(mMainView);
1518b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            }
1519b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            wrapper.addView(mMainView);
1520b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        } else {
1521b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            Log.w(LOGTAG, "mMainView is already attached to wrapper in"
1522b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                    + " attachTabToContentView!");
1523b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        }
1524b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        parent = (ViewGroup) mContainer.getParent();
1525b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        if (parent != content) {
1526b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            if (parent != null) {
1527b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                Log.w(LOGTAG, "mContainer already has a parent in"
1528b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                        + " attachTabToContentView!");
1529b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                parent.removeView(mContainer);
1530b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            }
1531b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            content.addView(mContainer, BrowserActivity.COVER_SCREEN_PARAMS);
1532b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        } else {
1533b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III            Log.w(LOGTAG, "mContainer is already attached to content in"
1534b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III                    + " attachTabToContentView!");
1535b00cf3678b212d781d05ff4ba0a461509de3a03bLeon Scroggins III        }
153622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        attachSubWindow(content);
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
154022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the WebView and any sub window from the given content view.
154122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
154222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeTabFromContentView(ViewGroup content) {
154322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
154422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
154522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
154622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
154722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the container from the content and then remove the
154822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView from the container. This will trigger a focus change
154922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // needed by WebView.
155022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        FrameLayout wrapper =
155122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                (FrameLayout) mContainer.findViewById(R.id.webview_wrapper);
155222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        wrapper.removeView(mMainView);
155322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        content.removeView(mContainer);
1554211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (mMainView.getFindIsUp()) mActivity.closeFind();
155522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        removeSubWindow(content);
155622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
155722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
155822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
155922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
156022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setParentTab(Tab parent) {
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mParentTab = parent;
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the parent tab index is already saved. If we are changing that index
156522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // parent tab index in the saved Bundle.
156722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.putInt(PARENTTAB, mActivity.getTabControl()
157222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .getTabIndex(parent));
157322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
157422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
157522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
157622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
157722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
157822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
157922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
158022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
158122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
158222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
158322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mChildTabs == null) {
158422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mChildTabs = new Vector<Tab>();
158522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
158622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mChildTabs.add(child);
158722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        child.setParentTab(this);
158822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
159022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Vector<Tab> getChildTabs() {
159122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mChildTabs;
159222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
160722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
160922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
161522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(mActivity);
161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
161722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(mActivity);
161822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
161922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
162122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
162522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
162622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
162722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
162822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
163222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
163822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
163922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
164022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
164122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
164222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
164322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
164422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
164522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
164622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
164722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
165622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
165722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
166122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
166222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
166850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
166950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
167050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
167150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
167250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
167350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.init();
167450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
167522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
167622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
168222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
168822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
169022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
169122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The original url associated with this Tab
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getOriginalUrl() {
169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mOriginalUrl;
169822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the original url associated with this tab
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setOriginalUrl(String url) {
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOriginalUrl = url;
170522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Get the url of this tab. Valid after calling populatePickerData, but
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * before calling wipePickerData, or if the webview has been destroyed.
171022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The WebView's url or null.
171122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
171222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
171322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mPickerData != null) {
171422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mPickerData.mUrl;
171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return null;
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Get the title of this tab. Valid after calling populatePickerData, but
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * before calling wipePickerData, or if the webview has been destroyed. If
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the url has no title, use the url instead.
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The WebView's title (or url) or null.
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
172622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mPickerData != null) {
172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mPickerData.mTitle;
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return null;
173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
173322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Get the favicon of this tab. Valid after calling populatePickerData, but
173422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * before calling wipePickerData, or if the webview has been destroyed.
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The WebView's favicon or null.
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mPickerData != null) {
173922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mPickerData.mFavicon;
174022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
174122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return null;
174222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
174322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
174522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
174622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
174722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
174822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
174922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
175122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
175322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
175422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole = new ErrorConsoleView(mActivity);
175522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
175622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
175722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
175822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
175922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
176022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
176122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * If this Tab was created through another Tab, then this method returns
176222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * that Tab.
176322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return the Tab parent or null
176422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
176522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public Tab getParentTab() {
176622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mParentTab;
176722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
176822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
177022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return whether this tab should be closed when it is backing out of the
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * first page.
177222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if this tab should be closed when exit.
177322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
177422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean closeOnExit() {
177522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mCloseOnExit;
177622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
177722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
177822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
177922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Saves the current lock-icon state before resetting the lock icon. If we
178022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * have an error, we may need to roll back to the previous state.
178122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
178222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resetLockIcon(String url) {
178322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPrevLockIconType = mLockIconType;
178422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mLockIconType = BrowserActivity.LOCK_ICON_UNSECURE;
178522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (URLUtil.isHttpsUrl(url)) {
178622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mLockIconType = BrowserActivity.LOCK_ICON_SECURE;
178722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
178822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
178922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
179022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
179122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Reverts the lock-icon state to the last saved state, for example, if we
179222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * had an error, and need to cancel the load.
179322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
179422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void revertLockIcon() {
179522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mLockIconType = mPrevLockIconType;
179622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
179722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
179822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
179922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's lock icon type.
180022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
180122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    int getLockIconType() {
180222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mLockIconType;
180322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
180422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
180522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
180622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
180722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
180822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
180922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean inLoad() {
181022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mInLoad;
181122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
181222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
181322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
181422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
181522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void clearInLoad() {
181622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInLoad = false;
181722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
181822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
181922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void populatePickerData() {
182022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
182122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            populatePickerDataFromSavedState();
182222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
182322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
182422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
182522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: The only place we cared about subwindow was for
182622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // bookmarking (i.e. not when saving state). Was this deliberate?
182722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.copyBackForwardList();
182822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
182922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        populatePickerData(item);
183022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
183122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
183222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Populate the picker data using the given history item and the current top
183322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebView.
183422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void populatePickerData(WebHistoryItem item) {
183522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPickerData = new PickerData();
183622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (item != null) {
183722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mPickerData.mUrl = item.getUrl();
183822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mPickerData.mTitle = item.getTitle();
183922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mPickerData.mFavicon = item.getFavicon();
184022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mPickerData.mTitle == null) {
184122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mPickerData.mTitle = mPickerData.mUrl;
184222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
184322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
184422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
184522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
184622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Create the PickerData and populate it using the saved state of the tab.
184722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void populatePickerDataFromSavedState() {
184822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState == null) {
184922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
185022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
185122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPickerData = new PickerData();
185222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPickerData.mUrl = mSavedState.getString(CURRURL);
185322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPickerData.mTitle = mSavedState.getString(CURRTITLE);
185422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
185522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
185622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void clearPickerData() {
185722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPickerData = null;
185822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
185922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
186022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
186122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Get the saved state bundle.
186222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return
186322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
186422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bundle getSavedState() {
186522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSavedState;
186622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
186722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
186822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
186922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the saved state.
187022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
187122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setSavedState(Bundle state) {
187222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = state;
187322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
187422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
187522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
187622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if succeed in saving the state.
187722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
187822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean saveState() {
187922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
188022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
188122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
188222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSavedState != null;
188322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
188422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
188522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
188622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.saveState(mSavedState);
188722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (list != null) {
188822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final File f = new File(mActivity.getTabControl().getThumbnailDir(),
188922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mMainView.hashCode() + "_pic.save");
189022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mMainView.savePicture(mSavedState, f)) {
189122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.putString(CURRPICTURE, f.getPath());
1892d5eee69bc37b5d92d376e6d3e07890550c452e6dMike Reed            } else {
1893d5eee69bc37b5d92d376e6d3e07890550c452e6dMike Reed                // if savePicture returned false, we can't trust the contents,
1894d5eee69bc37b5d92d376e6d3e07890550c452e6dMike Reed                // and it may be large, so we delete it right away
1895d5eee69bc37b5d92d376e6d3e07890550c452e6dMike Reed                f.delete();
189622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
189722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
189822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
189922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Store some extra info for displaying the tab in the picker.
190022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
190122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        populatePickerData(item);
190222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
190322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mPickerData.mUrl != null) {
190422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(CURRURL, mPickerData.mUrl);
190522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
190622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mPickerData.mTitle != null) {
190722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(CURRTITLE, mPickerData.mTitle);
190822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
190922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
191022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
191122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
191222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
191322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mOriginalUrl != null) {
191422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(ORIGINALURL, mOriginalUrl);
191522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
191622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
191722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mParentTab != null) {
191822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putInt(PARENTTAB, mActivity.getTabControl().getTabIndex(
191922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mParentTab));
192022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
192122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
192222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
192322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
192422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
192522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
192622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
192722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean restoreState(Bundle b) {
192822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (b == null) {
192922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
193022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
193122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
193222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
193322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = null;
193422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mPickerData = null;
193522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCloseOnExit = b.getBoolean(CLOSEONEXIT);
193622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
193722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOriginalUrl = b.getString(ORIGINALURL);
193822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
193922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final WebBackForwardList list = mMainView.restoreState(b);
194022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (list == null) {
194122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
194222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
194322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (b.containsKey(CURRPICTURE)) {
194422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final File f = new File(b.getString(CURRPICTURE));
194522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.restorePicture(b, f);
194622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            f.delete();
194722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
194822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return true;
194922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1950211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
1951211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
1952211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     * Open the find dialog.  Called by BrowserActivity.
1953211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
1954211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    void showFind(FindDialog dialog) {
1955211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        LinearLayout container;
1956211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        WebView view;
1957211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (mSubView != null) {
1958211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            view = mSubView;
1959211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            container = (LinearLayout) mSubViewContainer.findViewById(
1960211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                    R.id.inner_container);
1961211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        } else {
1962211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            view = mMainView;
1963211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            container = mContainer;
1964211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1965211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        dialog.show();
1966211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        container.addView(dialog, new LinearLayout.LayoutParams(
1967211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                ViewGroup.LayoutParams.MATCH_PARENT,
1968211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                ViewGroup.LayoutParams.WRAP_CONTENT));
1969211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        dialog.setWebView(view);
1970211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        view.setFindIsUp(true);
1971211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    }
1972211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
1973211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
1974211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     * Close the find dialog.  Called by BrowserActivity.closeFind.
1975211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
1976211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    void closeFind(FindDialog dialog) {
1977211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        // The dialog may be attached to the subwindow.  Ensure that the
1978211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        // correct parent has it removed.
1979211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        LinearLayout parent = (LinearLayout) dialog.getParent();
1980211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (parent != null) parent.removeView(dialog);
1981211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    }
198222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
1983