Tab.java revision 8cad413fe902010140cf20aad47c2f4e7a51f8d2
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
198233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity;
2022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.app.AlertDialog;
2158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.app.SearchManager;
2222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentResolver;
23d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentValues;
2430c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.content.Context;
2522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface;
26fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.DialogInterface.OnCancelListener;
278ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport android.content.Intent;
2822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
298cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.graphics.Bitmap.CompressFormat;
309ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.BitmapFactory;
319ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.Canvas;
32c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolbimport android.graphics.Color;
33a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolbimport android.graphics.Paint;
349ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.Picture;
35a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolbimport android.graphics.PorterDuff;
36a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolbimport android.graphics.PorterDuffXfermode;
3722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
3922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
409ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.os.Handler;
4122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
424dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
438862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstromimport android.security.KeyChain;
44aa09cd8dc20c9134b69ace4a7b84fe0103220fb4Brian Carlstromimport android.security.KeyChainAliasCallback;
45a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
4624f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reckimport android.text.TextUtils;
4722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
4822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
4922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
5022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
5150c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
528862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstromimport android.webkit.ClientCertRequestHandler;
53c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
54dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
5522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
5822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
5922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
606c2e2f34718043f36488b4a94879dc2605aaac49John Reckimport android.webkit.WebBackForwardList;
610c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
6222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
6322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
64438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport android.webkit.WebResourceResponse;
6522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
6622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
674d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixonimport android.webkit.WebViewClassic;
689ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.webkit.WebView.PictureListener;
6922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
701d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdochimport android.widget.CheckBox;
718029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
7222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
738ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reckimport com.android.browser.TabControl.OnThumbnailUpdatedListener;
74541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.browser.homepages.HomeProvider;
758cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots;
76541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.common.speech.LoggingEvents;
77541f55a0178da7c09fb32aa5385effae031ea071John Reck
78541f55a0178da7c09fb32aa5385effae031ea071John Reckimport java.io.ByteArrayOutputStream;
791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport java.nio.ByteBuffer;
80fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.ArrayList;
81fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.HashMap;
82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Iterator;
83fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
84fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
86a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwoodimport java.util.regex.Pattern;
878cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.util.zip.GZIPOutputStream;
88fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
8922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
9022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
9122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
929ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbclass Tab implements PictureListener {
938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
9522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
961dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
97c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
98c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
99c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
100c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
101c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1029ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private static final int MSG_CAPTURE = 42;
1038ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck    private static final int CAPTURE_DELAY = 100;
104a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb    private static final int INITIAL_PROGRESS = 5;
1059ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static Bitmap sDefaultFavicon;
1071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
108a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    private static Paint sAlphaPaint = new Paint();
109a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    static {
110a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        sAlphaPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
111a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        sAlphaPaint.setColor(Color.TRANSPARENT);
112a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    }
113a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb
1142466effd6ef97aa17396c214d51f9f19a4760260Steve Block    public enum SecurityState {
1154895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource does not use SSL. Note that we use this
1164895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // state irrespective of the SSL authentication state of sub-resources.
1172466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_NOT_SECURE,
1184895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL and the certificate is good. The
1194895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // same is true of all sub-resources.
1202466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_SECURE,
1214895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL and the certificate is good, but
1224895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // some sub-resources either do not use SSL or have problems with their
1234895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // certificates.
1242466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_MIXED,
1254895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL but there is a problem with its
1264895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // certificate.
1274895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        SECURITY_STATE_BAD_CERTIFICATE,
12830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
1298233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1301461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    Context mContext;
131d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected WebViewController mWebViewController;
1328233facddcc51865d612a919d450db6954aa48e3Michael Kolb
133c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    // The tab ID
134d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private long mId = -1;
135c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
13622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
13722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
139a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
14022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
14122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
14222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
14322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
14422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
14522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
14622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
14722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
14822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
14922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
15022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
15122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
152c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Tab mParent;
15322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
155c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Vector<Tab> mChildren;
15622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
15722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1588233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1598233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1608233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
16130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
16230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1634dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1644dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
16522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
16622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
16722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
168e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    // flag to indicate if tab should be closed on back
169e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    private boolean mCloseOnBack;
17022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
17122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
17222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
17322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
174dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
175dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
176dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1770c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1780c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
179e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController mDataController;
1809206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // State of the auto-login request.
1819206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private DeviceAccountLogin mDeviceAccountLogin;
18222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
18422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
18522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18635e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck    private BrowserSettings mSettings;
1879ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureWidth;
1889ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureHeight;
1899ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Bitmap mCapture;
1909ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Handler mHandler;
1919ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1921dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
1939ad1eac377ffa6ffd34afae4c6580b7ba7508c31Mathew Inwood     * See {@link #clearBackStackWhenItemAdded(String)}.
1941dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
195a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood    private Pattern mClearHistoryUrlPattern;
1961dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
1971cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static synchronized Bitmap getDefaultFavicon(Context context) {
1981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (sDefaultFavicon == null) {
1991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            sDefaultFavicon = BitmapFactory.decodeResource(
2001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    context.getResources(), R.drawable.app_web_browser_sm);
2011cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
2021cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return sDefaultFavicon;
2031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
204eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
20530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
206d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected static class PageState {
20730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
208db22ec4ee014900988062d910bc810172a07df56John Reck        String mOriginalUrl;
20930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
2102466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SecurityState mSecurityState;
21108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        // This is non-null only when mSecurityState is SECURITY_STATE_BAD_CERTIFICATE.
21208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        SslError mSslCertificateError;
21330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
21408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        boolean mIsBookmarkedSite;
21508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        boolean mIncognito;
21630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
21730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
218502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
219502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            if (mIncognito) {
220db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "browser:incognito";
22130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
22230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
223db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "";
22430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
22530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2262466effd6ef97aa17396c214d51f9f19a4760260Steve Block            mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
22730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
22830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
22930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
230502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
231db22ec4ee014900988062d910bc810172a07df56John Reck            mOriginalUrl = mUrl = url;
23230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
2332466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mSecurityState = SecurityState.SECURITY_STATE_SECURE;
23430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
2352466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
23630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mFavicon = favicon;
23830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
2391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
24022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
24122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
24230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
243d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected PageState mCurrentState;
24430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
24522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
246c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    static final String ID = "ID";
24722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
24822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
24922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
25022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
2513d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
252b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck    static final String USERAGENT = "useragent";
253e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    static final String CLOSEFLAG = "closeOnBack";
25422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
25522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
25622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
25758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
25858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
25958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
26058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
26158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
26258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
26395d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     * Remove voice search mode from this tab.
26495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     */
26595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    public void revertVoiceSearchMode() {
26695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        if (mVoiceSearchData != null) {
26795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            mVoiceSearchData = null;
26895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            if (mInForeground) {
2698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.revertVoiceSearchMode(this);
27095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            }
27195d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        }
27295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    }
2738233facddcc51865d612a919d450db6954aa48e3Michael Kolb
27495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    /**
27558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
27658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
27758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
27858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
27958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
28058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
281c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Return true if the Tab is in voice search mode and the voice search
282c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Intent came with a String identifying that Google provided the Intent.
2831fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
2841fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
2851fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
2861fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
2871fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
28858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
28958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
29058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
29158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
29258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
29358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
29458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
29558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
29658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
29758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
29858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
29958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
30058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
30158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
30258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
30358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
30458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
30558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
30658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
30758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
30858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
30982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
31058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
311a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
31258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
31382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
31482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
31582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
31682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
31782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
31882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
31982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
32058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
32158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
32282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
32382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
32458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
32558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
32682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
32782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
32882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
32982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
33082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
33182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
33282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
33382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
33482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
3359df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
3369df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
3379df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
3381fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
3391fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
3402ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
341e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
342e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
343e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
344e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
345e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
346e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
347e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
348e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
349e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
350e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
351e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
352e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
353e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
354e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
355e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
356e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
357e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
3581461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                mContext.sendBroadcast(logIntent);
359e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
360e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
3612ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
3622ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
3632ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
3642ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
3652ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
36658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
36758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
36858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
36982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
37058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
37111d1978d8d16004598347abc93918b54a5ef760bMichael Kolb            mWebViewController.activateVoiceSearchMode(
37211d1978d8d16004598347abc93918b54a5ef760bMichael Kolb                    mVoiceSearchData.mLastVoiceSearchTitle,
37311d1978d8d16004598347abc93918b54a5ef760bMichael Kolb                    mVoiceSearchData.mVoiceSearchResults);
37458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
37582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
37682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
37782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
37882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
37982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
38082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
38182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
38282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
38382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
38482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
38582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
38682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
38782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
38882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
38982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
39082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
39182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
39282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
39382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
39482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
39582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
39682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
39758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
39882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
39982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
4008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter(
40182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
40282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
4039df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
4049df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
4059df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
4069df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
4079df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
4089df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
4099df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
4109df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
4119df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
4129df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
4139df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
4149df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
4159df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
4169df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
4179df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
41858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
42058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
42182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
42282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
42358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
42458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
42582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
42682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
42758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
42858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
42958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
43058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
43158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
43258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
43358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
43458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
43558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
43758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
43858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
43982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
44082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
44182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
44282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
44382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
44482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
44582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
44682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
44782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
44882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
44982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
45082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
45158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
45282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
45358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
45458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
45558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
45658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
45758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
45858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
45958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
4601fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4611fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
4621fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
4631fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4641fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
4651fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4669df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
4679df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
4689df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
4699df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
4709df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
4710c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
4720c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
4730c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
4740c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
475e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
4760c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
4771fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
4781fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4791fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
4801fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
48158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
48258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
4938233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
50922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
51022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
51122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
51222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
51322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
51422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
51522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
53622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
53722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
5411461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog d = new AlertDialog.Builder(mContext)
54222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
54322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
54422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
54522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
54622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
54722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
54822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
55022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
55222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
55322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
55422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
5564a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
5574a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
55847bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb
55947bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb        private boolean providersDiffer(String url, String otherUrl) {
56047bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            Uri uri1 = Uri.parse(url);
56147bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            Uri uri2 = Uri.parse(otherUrl);
56247bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            return !uri1.getEncodedAuthority().equals(uri2.getEncodedAuthority());
56347bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb        }
56447bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb
56522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
5678233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
568a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mPageLoadProgress = INITIAL_PROGRESS;
5691461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext,
57030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
5714dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
57258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
57347bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb                    && providersDiffer(url, mVoiceSearchData.mLastVoiceSearchUrl)) {
5741fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
5751fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
5761fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
5771461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mContext.sendBroadcast(i);
5781fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
57995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III                revertVoiceSearchMode();
58058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
58122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
58222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
58322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
58422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
58522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
58622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
58822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
58922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
59022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
59122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
59222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
5948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
59722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
59822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
5999206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            // Cancel the auto-login process.
6009206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (mDeviceAccountLogin != null) {
6019206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin.cancel();
6029206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin = null;
6039206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebViewController.hideAutoLogin(Tab.this);
6049206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
6059206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
607324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageStarted(Tab.this, view, favicon);
6084cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
609e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
61022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
6145b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
6155b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
6165b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
6175b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
6181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            syncCurrentState(view, url);
619324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageFinished(Tab.this);
62022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
62122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
62222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
625c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            if (voiceSearchSourceIsGoogle()) {
626c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // This method is called when the user clicks on a link.
627c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // VoiceSearchMode is turned off when the user leaves the
628c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // Google results page, so at this point the user must be on
629c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that page.  If the user clicked a link on that page, assume
630c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that the voice search was effective, and broadcast an Intent
631c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // so a receiver can take note of that fact.
632c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT);
633c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
634c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                        LoggingEvents.VoiceSearch.RESULT_CLICKED);
6351461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                mContext.sendBroadcast(logIntent);
636c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            }
63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
63818eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
63918eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
64522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
6462466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * Updates the security state. This method is called when we discover
6472466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * another resource to be loaded for this page (for example,
6482466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * javascript). While we update the security state, we do not update
6492466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * the lock icon until we are done loading, as it is slightly more
6502466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * secure this way.
65122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
65222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
65322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
65422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
65522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
6562466effd6ef97aa17396c214d51f9f19a4760260Steve Block                // to update the security state:
6572466effd6ef97aa17396c214d51f9f19a4760260Steve Block                if (mCurrentState.mSecurityState == SecurityState.SECURITY_STATE_SECURE) {
6582466effd6ef97aa17396c214d51f9f19a4760260Steve Block                    // If NOT a 'safe' url, change the state to mixed content!
65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
6612466effd6ef97aa17396c214d51f9f19a4760260Steve Block                        mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_MIXED;
66222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
66322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
66422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
66522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
66622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
66722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
66822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
66922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
67022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
67122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
67222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
67322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
67422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
67522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
67722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
67822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
67922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
68047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
6813da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                // Don't log URLs when in private browsing mode
6823da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                if (!isPrivateBrowsingEnabled()) {
6833da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                    Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
68447654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
6853da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                }
68647654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
7004a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
7014a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
7024a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
7034a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
7044a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
7054a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
7064a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
7074a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
7081461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new AlertDialog.Builder(mContext).setTitle(
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
7154a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
7164a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
7174a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
7184a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
7194a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
7254a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
7264a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
7274a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
7284a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
7294a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
7334a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
7344a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
7354a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
7364a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
7374a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
751324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.doUpdateVisitedHistory(Tab.this, isReload);
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
7622466effd6ef97aa17396c214d51f9f19a4760260Steve Block                setSecurityState(SecurityState.SECURITY_STATE_NOT_SECURE);
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
76535e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            if (mSettings.showSecurityWarnings()) {
766cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                new AlertDialog.Builder(mContext)
767cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setTitle(R.string.security_warning)
768cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setMessage(R.string.ssl_warnings_header)
769cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setIcon(android.R.drawable.ic_dialog_alert)
770cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setPositiveButton(R.string.ssl_continue,
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
772cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
77422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
77522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
7764895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block                                handleProceededAfterSslError(error);
77722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
778cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
779cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setNeutralButton(R.string.view_certificate,
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
781cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
784cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                                mWebViewController.showSslCertificateOnError(
785cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                                        view, handler, error);
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
787cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
788cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setNegativeButton(R.string.ssl_go_back,
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
790cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
79330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
795cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
796cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setOnCancelListener(
79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
798cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
79922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
80022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
8012466effd6ef97aa17396c214d51f9f19a4760260Steve Block                                setSecurityState(SecurityState.SECURITY_STATE_NOT_SECURE);
80230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
80322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
804cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
805cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .show();
80622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
8124895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * Called when an SSL error occurred while loading a resource, but the
8134895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * WebView but chose to proceed anyway based on a decision retained
8144895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * from a previous response to onReceivedSslError(). We update our
8154895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * security state to reflect this.
8164895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         */
8174895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        @Override
8184895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        public void onProceededAfterSslError(WebView view, SslError error) {
8194895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            handleProceededAfterSslError(error);
8204895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        }
8214895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block
8224895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        /**
8238862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom         * Displays client certificate request to the user.
8248862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom         */
8258862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        @Override
8268862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        public void onReceivedClientCertRequest(final WebView view,
8278862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                final ClientCertRequestHandler handler, final String host_and_port) {
8288862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            if (!mInForeground) {
8298862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                handler.ignore();
8308862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                return;
8318862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            }
8326d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            int colon = host_and_port.lastIndexOf(':');
8336d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            String host;
8346d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            int port;
8356d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            if (colon == -1) {
8366d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                host = host_and_port;
8376d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                port = -1;
8386d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            } else {
8396d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                String portString = host_and_port.substring(colon + 1);
8406d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                try {
8416d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    port = Integer.parseInt(portString);
8426d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    host = host_and_port.substring(0, colon);
8436d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                } catch  (NumberFormatException e) {
8446d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    host = host_and_port;
8456d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    port = -1;
8466d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                }
8476d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            }
8481461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            KeyChain.choosePrivateKeyAlias(
8491461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mWebViewController.getActivity(), new KeyChainAliasCallback() {
8508862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                @Override public void alias(String alias) {
8518862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                    if (alias == null) {
8528862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                        handler.cancel();
8538862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                        return;
8548862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                    }
8551461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new KeyChainLookup(mContext, handler, alias).execute();
8568862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                }
8576d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            }, null, null, host, port, null);
8588862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        }
8598862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom
8608862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        /**
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
8718233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
875438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        public WebResourceResponse shouldInterceptRequest(WebView view,
876438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                String url) {
877438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
8781461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mContext, url);
879438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            return res;
880438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        }
881438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck
882438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        @Override
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8878233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8928233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onUnhandledKeyEvent(event);
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
8979206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
8989206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        @Override
8999206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void onReceivedLoginRequest(WebView view, String realm,
9009206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                String account, String args) {
9011461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new DeviceAccountLogin(mWebViewController.getActivity(), view, Tab.this, mWebViewController)
9029206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    .handleLogin(realm, account, args);
9039206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
9049206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void syncCurrentState(WebView view, String url) {
9081cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        // Sync state (in case of stop/timeout)
9091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mUrl = view.getUrl();
9101cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mUrl == null) {
9118bcafc149bc49b84c8dfbaacf88c178d8bc9eda6John Reck            mCurrentState.mUrl = "";
9121cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
9131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mOriginalUrl = view.getOriginalUrl();
9141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = view.getTitle();
9151cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mFavicon = view.getFavicon();
9161cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
9171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // In case we stop when loading an HTTPS page from an HTTP page
9181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // but before a provisional load occurred
9192466effd6ef97aa17396c214d51f9f19a4760260Steve Block            mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
92008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            mCurrentState.mSslCertificateError = null;
9211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
922502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        mCurrentState.mIncognito = view.isPrivateBrowsingEnabled();
9231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
9241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
9259206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
9269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // displayed.
9279206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    void setDeviceAccountLogin(DeviceAccountLogin login) {
9289206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mDeviceAccountLogin = login;
9299206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
9309206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
9319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Returns non-null if the title bar should display the auto-login UI.
9329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    DeviceAccountLogin getDeviceAccountLogin() {
9339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mDeviceAccountLogin;
9349206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
9359206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
94122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
94222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
94322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
94422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
94522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
9478233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
94822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
94922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
9507bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                final Tab newTab = mWebViewController.openTab(null,
9515949c661b51295148706d53a03b41df2eb840ae3John Reck                        Tab.this, true, true);
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
95322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
95422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
95522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
95722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
95922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
96022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
96122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
9661461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
97122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
97222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
9738233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
9741461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
10081461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new AlertDialog.Builder(mContext)
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1022eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
1023eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
1024c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mWebViewController.switchToTab(Tab.this);
1025eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
1026eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
1027eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
1028eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
1030c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            if (mParent != null) {
103122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
1033c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                    mWebViewController.switchToTab(mParent);
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
10358233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
103622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
104022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
104130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
1042b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb            if (newProgress == 100) {
1043b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb                mInPageLoad = false;
1044b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb            }
104530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
104921d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
105030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
10518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
105630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
10578233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
105822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
106022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
106222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
10631461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            final ContentResolver cr = mContext.getContentResolver();
1064c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
1065c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
1066c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
1067c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
1068c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
1069c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
1070c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
1071c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
10728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
10731461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                        mContext, cr, view);
1074c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
10811461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            Activity activity = mWebViewController.getActivity();
10821461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            if (activity != null) {
10831461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                onShowCustomView(view, activity.getRequestedOrientation(), callback);
10841461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            }
10852d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        }
10862d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger
10872d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        @Override
10882d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        public void onShowCustomView(View view, int requestedOrientation,
10892d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                WebChromeClient.CustomViewCallback callback) {
10908233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
10912d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                    requestedOrientation, callback);
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
10968233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
110622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
110722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
111435e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
112822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
112922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
113022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
113222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
113335e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
113422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
113522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
113622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
113722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
113822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
113922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
114022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
114222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
114322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
114522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
114922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
115050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
115322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
115422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
115522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
115622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
115722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
115822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
115950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
116022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
116122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
116222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
116322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
116465acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
116565acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
116665acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1167c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
116822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
116922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1170c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
117122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
117222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
117322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1174c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
11758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
11768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
11778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
117822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
117922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
118022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1181c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
118247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
1183f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
118447654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
1185c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1186c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1187c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1188c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1189c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1190c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1191c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1192c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1193c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1194c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1195c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1196c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1197c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1198c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1199c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1200c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1201c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1202c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1203c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1204c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1205c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1206c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1207c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
120822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
121022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
121122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
121222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
121322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
121422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
121722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
12188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
122622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
12318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
12378cad413fe902010140cf20aad47c2f4e7a51f8d2Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
12398cad413fe902010140cf20aad47c2f4e7a51f8d2Ben Murdoch                mWebViewController.openFileChooser(uploadMsg, acceptType, capture);
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
124722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
12508233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
12518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12528029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
12538029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
12548029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
12558029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
12568029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
12571461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
12581461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
12591d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    Context.LAYOUT_INFLATER_SERVICE);
12601d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null);
12611d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
12621d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            builder.setView(layout)
12631d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
12641d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    @Override
12651d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    public void onClick(DialogInterface dialog, int id) {
12661d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        CheckBox disableAutoFill = (CheckBox) layout.findViewById(
12671d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                R.id.setup_autofill_dialog_disable_autofill);
12681d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
12691d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        if (disableAutoFill.isChecked()) {
12701d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Disable autofill and show a toast with how to turn it on again.
127135e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                            mSettings.setAutofillEnabled(false);
12721461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                            Toast.makeText(mContext,
12731d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    R.string.autofill_setup_dialog_negative_toast,
12741d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    Toast.LENGTH_LONG).show();
12751d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        } else {
12761d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Take user to the AutoFill profile editor. When they return,
12771d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // we will send the message that we pass here which will trigger
12781d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // the form to get filled out with their new profile.
12791d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            mWebViewController.setupAutoFill(msg);
12801d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        }
12811d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    }
12821d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                })
12831d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setNegativeButton(R.string.cancel, null)
12841d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .show();
12858029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
128822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
129122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
129222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
129322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
12978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
129822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
130022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
13018233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1302211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1303211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1304211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1305211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1306211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
130701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
13088233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
130922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
131122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
131222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
131322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
131422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
131622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
131822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
132022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
132122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
132222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
132322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
13258862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        public void onReceivedClientCertRequest(WebView view,
13268862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                ClientCertRequestHandler handler, String host_and_port) {
13278862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            mClient.onReceivedClientCertRequest(view, handler, host_and_port);
13288862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        }
13298862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        @Override
133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
135322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
136122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
136222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
136322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
136522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
137522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
137722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
137822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
138022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
13818233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
13887bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    Tab(WebViewController wvcontroller, WebView w) {
13891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, w, null);
13901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
13911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
13921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, Bundle state) {
13931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, null, state);
13941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
13951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
13961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, WebView w, Bundle state) {
13978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
13981461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mContext = mWebViewController.getContext();
139935e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck        mSettings = BrowserSettings.getInstance();
14001461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mDataController = DataController.getInstance(mContext);
14011461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mCurrentState = new PageState(mContext, w != null
1402847b532045e3cb117a847ebb956c9919401f332dJohn Reck                ? w.isPrivateBrowsingEnabled() : false);
14038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
140422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
140522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1406dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1407dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1408dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1409dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
14108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1411dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1412dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1413dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
14140c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
14150c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
14160c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
14170c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
14180c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
14190c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
1420a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                if (mClearHistoryUrlPattern != null) {
1421a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    boolean match =
1422a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                        mClearHistoryUrlPattern.matcher(item.getOriginalUrl()).matches();
14231dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    if (LOGD_ENABLED) {
1424a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                        Log.d(LOGTAG, "onNewHistoryItem: match=" + match + "\n\t"
1425a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                                + item.getUrl() + "\n\t"
1426a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                                + mClearHistoryUrlPattern);
14271dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
1428a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    if (match) {
14291dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        if (mMainView != null) {
14301dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                            mMainView.clearHistory();
14311dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        }
14321dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
1433a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    mClearHistoryUrlPattern = null;
14341dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                }
14350c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
14360c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
14370c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
14380c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
14390c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
14400c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
14410c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
14420c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
14430c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1444dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
14451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureWidth = mContext.getResources().getDimensionPixelSize(
14461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_width);
14471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureHeight = mContext.getResources().getDimensionPixelSize(
14481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_height);
14491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
14501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        restoreState(state);
145152be4785a258687055515117775d5bcb8bec1c12John Reck        if (getId() == -1) {
145252be4785a258687055515117775d5bcb8bec1c12John Reck            mId = TabControl.getNextId();
145352be4785a258687055515117775d5bcb8bec1c12John Reck        }
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
14559ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        mHandler = new Handler() {
14561dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood            @Override
14579ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            public void handleMessage(Message m) {
14581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                switch (m.what) {
14591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                case MSG_CAPTURE:
14601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    capture();
14611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    break;
14621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
14639ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            }
14649ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        };
14651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
14669ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1467e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    /**
1468e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * This is used to get a new ID when the tab has been preloaded, before it is displayed and
1469e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * added to TabControl. Preloaded tabs can be created before restoreInstanceState, leading
1470e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * to overlapping IDs between the preloaded and restored tabs.
1471e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     */
1472e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    public void refreshIdAfterPreload() {
1473e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood        mId = TabControl.getNextId();
1474e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    }
1475e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood
14761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public void updateShouldCaptureThumbnails() {
14771cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mWebViewController.shouldCaptureThumbnails()) {
14781cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
14791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                if (mCapture == null) {
14801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    mCapture = Bitmap.createBitmap(mCaptureWidth, mCaptureHeight,
14811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                            Bitmap.Config.RGB_565);
1482c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolb                    mCapture.eraseColor(Color.WHITE);
14831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    if (mInForeground) {
14841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        postCapture();
14851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    }
14861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
14871cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
14881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        } else {
14891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
14901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCapture = null;
14911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                deleteThumbnail();
14921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
14931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14961461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    public void setController(WebViewController ctl) {
14971461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mWebViewController = ctl;
14981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
14991461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    }
15001461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb
1501c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public long getId() {
1502c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mId;
1503c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1504c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
150591911a26058418e622950cffc616f99ada49df1dMichael Kolb    void setWebView(WebView w) {
150691911a26058418e622950cffc616f99ada49df1dMichael Kolb        setWebView(w, true);
150791911a26058418e622950cffc616f99ada49df1dMichael Kolb    }
150891911a26058418e622950cffc616f99ada49df1dMichael Kolb
150922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
151022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
151122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
151222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
151391911a26058418e622950cffc616f99ada49df1dMichael Kolb    void setWebView(WebView w, boolean restore) {
151422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
151522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
151622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1517a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
151822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
151922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
152050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
152150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
152250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
152322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1524a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mMainView != null) {
15278ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.setPictureListener(null);
15281cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (w != null) {
15291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                syncCurrentState(w, null);
15301cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            } else {
15311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCurrentState = new PageState(mContext, false);
15321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
15331cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
153422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
153522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1536dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1540dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1541dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1542dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1543dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1544dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
15454d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon            getWebViewClassic().setWebBackForwardListClient(mWebBackForwardListClient);
15468ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            TabControl tc = mWebViewController.getTabControl();
15478ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (tc != null && tc.getOnThumbnailUpdatedListener() != null) {
15488ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                mMainView.setPictureListener(this);
15498ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
155091911a26058418e622950cffc616f99ada49df1dMichael Kolb            if (restore && (mSavedState != null)) {
15518b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck                restoreUserAgent();
15526c2e2f34718043f36488b4a94879dc2605aaac49John Reck                WebBackForwardList restoredState
15536c2e2f34718043f36488b4a94879dc2605aaac49John Reck                        = mMainView.restoreState(mSavedState);
15546c2e2f34718043f36488b4a94879dc2605aaac49John Reck                if (restoredState == null || restoredState.getSize() == 0) {
15556c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    Log.w(LOGTAG, "Failed to restore WebView state!");
15566c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    loadUrl(mCurrentState.mOriginalUrl, null);
15576c2e2f34718043f36488b4a94879dc2605aaac49John Reck                }
15581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mSavedState = null;
15591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
156022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
156522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
156722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
157222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
157322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
157422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
157522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
157622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
157722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
157822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
158022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
1581c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren != null) {
1582c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            for(Tab t : mChildren) {
1583c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                t.setParent(null);
158422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
158522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
158622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
1587c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1588c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mParent.mChildren.remove(this);
158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
15901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        deleteThumbnail();
159122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
15991514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1600211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
16018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1604dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1605dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1606dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1607dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1608dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1609dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
16108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1611dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1612dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1613dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1614dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
16158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1616dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1617dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1618dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
16191461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(mWebViewController.getActivity());
162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
162122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
162522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
162622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
162722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
16308233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
163222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
163322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
163422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
163522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
164022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
1641c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    void setParent(Tab parent) {
164252be4785a258687055515117775d5bcb8bec1c12John Reck        if (parent == this) {
164352be4785a258687055515117775d5bcb8bec1c12John Reck            throw new IllegalStateException("Cannot set parent to self!");
164452be4785a258687055515117775d5bcb8bec1c12John Reck        }
1645c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mParent = parent;
164622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
1647c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // the parent tab id is already saved. If we are changing that id
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
1649c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // parent tab id in the saved Bundle.
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
1654c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mSavedState.putLong(PARENTTAB, parent.getId());
165522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
165622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1657b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck
1658b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        // Sync the WebView useragent with the parent
1659b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        if (parent != null && mSettings.hasDesktopUseragent(parent.getWebView())
1660b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                != mSettings.hasDesktopUseragent(getWebView())) {
1661b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck            mSettings.toggleDesktopUseragent(getWebView());
1662b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        }
166352be4785a258687055515117775d5bcb8bec1c12John Reck
166452be4785a258687055515117775d5bcb8bec1c12John Reck        if (parent != null && parent.getId() == getId()) {
166552be4785a258687055515117775d5bcb8bec1c12John Reck            throw new IllegalStateException("Parent has same ID as child!");
166652be4785a258687055515117775d5bcb8bec1c12John Reck        }
166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1670c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * If this Tab was created through another Tab, then this method returns
1671c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * that Tab.
1672c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * @return the Tab parent or null
1673c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     */
1674c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public Tab getParent() {
1675c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mParent;
1676c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1677c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
1678c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    /**
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
168222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
1684c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren == null) {
1685c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mChildren = new Vector<Tab>();
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1687c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mChildren.add(child);
1688c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        child.setParent(this);
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1691c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    Vector<Tab> getChildren() {
1692c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mChildren;
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
169756c1fcf7774d4ee943fbda808e37840459502e20John Reck            setupHwAcceleration(mMainView);
169822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170556c1fcf7774d4ee943fbda808e37840459502e20John Reck    private void setupHwAcceleration(View web) {
170656c1fcf7774d4ee943fbda808e37840459502e20John Reck        if (web == null) return;
170756c1fcf7774d4ee943fbda808e37840459502e20John Reck        BrowserSettings settings = BrowserSettings.getInstance();
170856c1fcf7774d4ee943fbda808e37840459502e20John Reck        if (settings.isHardwareAccelerated()) {
170956c1fcf7774d4ee943fbda808e37840459502e20John Reck            web.setLayerType(View.LAYER_TYPE_NONE, null);
171056c1fcf7774d4ee943fbda808e37840459502e20John Reck        } else {
171156c1fcf7774d4ee943fbda808e37840459502e20John Reck            web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
171256c1fcf7774d4ee943fbda808e37840459502e20John Reck        }
171356c1fcf7774d4ee943fbda808e37840459502e20John Reck    }
171456c1fcf7774d4ee943fbda808e37840459502e20John Reck
171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
17258ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mInForeground) {
17268ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
17278ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
17301461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        Activity activity = mWebViewController.getActivity();
17311461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mMainView.setOnCreateContextMenuListener(activity);
173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
17331461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(activity);
173422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
17391961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
174022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
174122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
17438ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (!mInForeground) {
17448ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
17458ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
174652be4785a258687055515117775d5bcb8bec1c12John Reck        capture();
174722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
174822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
174922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
175122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
175322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
175422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
17558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
17568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
17578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17588233facddcc51865d612a919d450db6954aa48e3Michael Kolb
175922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
176022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
176122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
176222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
176322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
176422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
176522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
176622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
176722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
176822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
177022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
177222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
177322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
177422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
177522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
177622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
177722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
177822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
177922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
178022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
17814d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon    /**
17824d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     * Return the underlying WebViewClassic implementation. As with getWebView,
17834d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     * this maybe null for background tabs.
17844d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     * @return The main WebView of this tab.
17854d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     */
17864d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon    WebViewClassic getWebViewClassic() {
17874d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon        return WebViewClassic.fromWebView(mMainView);
17884d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon    }
17894d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon
1790a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1791a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1792a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1793a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
17948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
17958233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
17968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17978233facddcc51865d612a919d450db6954aa48e3Michael Kolb
179822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1799f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1800f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1801f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1802f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
18038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1804502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        return mCurrentState.mIncognito;
1805f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1806f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1807f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
180822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
180922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
181022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
181122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
181222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
181322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
181422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18151514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
18161514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
18171514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
18181514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
18198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
18208233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
18218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18228233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18231514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
18241514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
18251514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
18261514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
182722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
182822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
182922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
183022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
183150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
183250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
183350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
183450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
183550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
183650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
183722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
183822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
183922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
184022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
184122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
184222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
184322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
184422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
184522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
184622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
184722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
184822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
184922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
185022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
185122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
185222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
185322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
185422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1855e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    boolean closeOnBack() {
1856e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        return mCloseOnBack;
1857e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1858e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
1859e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    void setCloseOnBack(boolean close) {
1860e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = close;
1861e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1862e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
186322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
1864324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        return UrlUtils.filteredUrl(mCurrentState.mUrl);
186522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
186622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
186749a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    String getOriginalUrl() {
1868db22ec4ee014900988062d910bc810172a07df56John Reck        if (mCurrentState.mOriginalUrl == null) {
1869db22ec4ee014900988062d910bc810172a07df56John Reck            return getUrl();
187049a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        }
1871db22ec4ee014900988062d910bc810172a07df56John Reck        return UrlUtils.filteredUrl(mCurrentState.mOriginalUrl);
187249a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    }
187349a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck
187422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
187530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
187622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
187722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
187830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
18791461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            return mContext.getString(R.string.title_bar_loading);
188022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
188130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
188222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
188322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
188422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
188530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
188622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
188722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
18881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mFavicon != null) {
18891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCurrentState.mFavicon;
18901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
18911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return getDefaultFavicon(mContext);
189222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
189322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1894e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1895e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1896e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1897f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
189822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
189922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
190022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
190122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
190222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
190322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
190422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
190522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
190622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
190722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
19081461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mErrorConsole = new ErrorConsoleView(mContext);
190922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
191022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
191122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
191222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
191322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
191408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    /**
191508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * Sets the security state, clears the SSL certificate error and informs
191608a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * the controller.
191708a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     */
19182466effd6ef97aa17396c214d51f9f19a4760260Steve Block    private void setSecurityState(SecurityState securityState) {
19192466effd6ef97aa17396c214d51f9f19a4760260Steve Block        mCurrentState.mSecurityState = securityState;
192008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        mCurrentState.mSslCertificateError = null;
19212466effd6ef97aa17396c214d51f9f19a4760260Steve Block        mWebViewController.onUpdatedSecurityState(this);
192222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
192322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
192422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
19252466effd6ef97aa17396c214d51f9f19a4760260Steve Block     * @return The tab's security state.
192622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
19272466effd6ef97aa17396c214d51f9f19a4760260Steve Block    SecurityState getSecurityState() {
19282466effd6ef97aa17396c214d51f9f19a4760260Steve Block        return mCurrentState.mSecurityState;
192922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
193022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
193108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    /**
193208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * Gets the SSL certificate error, if any, for the page's main resource.
193308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * This is only non-null when the security state is
193408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * SECURITY_STATE_BAD_CERTIFICATE.
193508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     */
193608a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    SslError getSslCertificateError() {
193708a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        return mCurrentState.mSslCertificateError;
193808a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    }
193908a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block
194030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
194130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
194230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
194330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
194430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
194522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
194622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
194722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
194822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
194922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
195022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
19518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
19528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
195322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
195422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
195522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
195622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
19578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void clearInPageLoad() {
19588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
195922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
196022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
196122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
19621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck     * @return The Bundle with the tab's state if it can be saved, otherwise null
196322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
19641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public Bundle saveState() {
196522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
196622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
196722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
19681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mSavedState;
196922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
19706c2e2f34718043f36488b4a94879dc2605aaac49John Reck
19716c2e2f34718043f36488b4a94879dc2605aaac49John Reck        if (TextUtils.isEmpty(mCurrentState.mUrl)) {
19721cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return null;
197324f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        }
197422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
197522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
19766c2e2f34718043f36488b4a94879dc2605aaac49John Reck        WebBackForwardList savedList = mMainView.saveState(mSavedState);
19776c2e2f34718043f36488b4a94879dc2605aaac49John Reck        if (savedList == null || savedList.getSize() == 0) {
19786c2e2f34718043f36488b4a94879dc2605aaac49John Reck            Log.w(LOGTAG, "Failed to save back/forward list for "
19796c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    + mCurrentState.mUrl);
19806c2e2f34718043f36488b4a94879dc2605aaac49John Reck        }
198122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1982c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mSavedState.putLong(ID, mId);
198330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
198430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
19851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState.putBoolean(INCOGNITO, mMainView.isPrivateBrowsingEnabled());
198622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
198722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
198822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1989e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mSavedState.putBoolean(CLOSEFLAG, mCloseOnBack);
199022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
1991c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1992c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mSavedState.putLong(PARENTTAB, mParent.mId);
199322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1994b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        mSavedState.putBoolean(USERAGENT,
1995b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                mSettings.hasDesktopUseragent(getWebView()));
19961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return mSavedState;
199722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
199822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
199922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
200022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
200122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
20021cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void restoreState(Bundle b) {
20031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState = b;
20041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mSavedState == null) {
20051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return;
200622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
200722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
200822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
2009c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mId = b.getLong(ID);
201022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
2011e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = b.getBoolean(CLOSEFLAG);
20128b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        restoreUserAgent();
20131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String url = b.getString(CURRURL);
20141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String title = b.getString(CURRTITLE);
20151cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        boolean incognito = b.getBoolean(INCOGNITO);
20161cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState = new PageState(mContext, incognito, url, null);
20171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = title;
20181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
20191cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture != null) {
20204eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck                DataController.getInstance(mContext).loadThumbnail(this);
20211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
202222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
202322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2024211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
20258b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck    private void restoreUserAgent() {
20268b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        if (mMainView == null || mSavedState == null) {
20278b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck            return;
20288b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        }
20298b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        if (mSavedState.getBoolean(USERAGENT)
20308b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck                != mSettings.hasDesktopUseragent(mMainView)) {
20318b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck            mSettings.toggleDesktopUseragent(mMainView);
20328b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        }
20338b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck    }
20348b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck
20351961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
2036e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
20371961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
20381961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
2039e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
2040e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
2041e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
2042e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
2043e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
2044e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
2045e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
20461961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
2047e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
2048e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
20491acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
2050eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    public Bitmap getScreenshot() {
20511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
20521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCapture;
20531cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
2054eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    }
2055eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
2056541f55a0178da7c09fb32aa5385effae031ea071John Reck    public boolean isSnapshot() {
2057541f55a0178da7c09fb32aa5385effae031ea071John Reck        return false;
2058541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
2059541f55a0178da7c09fb32aa5385effae031ea071John Reck
2060d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public ContentValues createSnapshotValues() {
2061d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        if (mMainView == null) return null;
20629d2718e7a2d58ce87a18ca4987553fd996180f3cJohn Reck        SnapshotByteArrayOutputStream bos = new SnapshotByteArrayOutputStream();
20638cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        try {
20648cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            GZIPOutputStream stream = new GZIPOutputStream(bos);
20654d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon            if (!getWebViewClassic().saveViewState(stream)) {
20668cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                return null;
20678cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
20688cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            stream.flush();
20698cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            stream.close();
20708cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        } catch (Exception e) {
20718cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            Log.w(LOGTAG, "Failed to save view state", e);
2072541f55a0178da7c09fb32aa5385effae031ea071John Reck            return null;
2073541f55a0178da7c09fb32aa5385effae031ea071John Reck        }
20748cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        byte[] data = bos.toByteArray();
2075d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        ContentValues values = new ContentValues();
2076d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.TITLE, mCurrentState.mTitle);
2077d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.URL, mCurrentState.mUrl);
2078d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.VIEWSTATE, data);
20794d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon        values.put(Snapshots.BACKGROUND, getWebViewClassic().getPageBackgroundColor());
20808cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        values.put(Snapshots.DATE_CREATED, System.currentTimeMillis());
20818cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        values.put(Snapshots.FAVICON, compressBitmap(getFavicon()));
20828cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        Bitmap screenshot = Controller.createScreenshot(mMainView,
20838cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                Controller.getDesiredThumbnailWidth(mContext),
20848cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                Controller.getDesiredThumbnailHeight(mContext));
20858cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot));
2086d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        return values;
2087541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
2088541f55a0178da7c09fb32aa5385effae031ea071John Reck
20898cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public byte[] compressBitmap(Bitmap bitmap) {
20908cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (bitmap == null) {
20918cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
20928cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
20938cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        ByteArrayOutputStream stream = new ByteArrayOutputStream();
20948cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        bitmap.compress(CompressFormat.PNG, 100, stream);
20958cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return stream.toByteArray();
20968cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
20978cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
209826b183292dc087b16af10f482744c3bb30e1f163John Reck    public void loadUrl(String url, Map<String, String> headers) {
209926b183292dc087b16af10f482744c3bb30e1f163John Reck        if (mMainView != null) {
2100a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mPageLoadProgress = INITIAL_PROGRESS;
2101a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mInPageLoad = true;
21021461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext, false, url, null);
210326b183292dc087b16af10f482744c3bb30e1f163John Reck            mWebViewController.onPageStarted(this, mMainView, null);
210426b183292dc087b16af10f482744c3bb30e1f163John Reck            mMainView.loadUrl(url, headers);
210526b183292dc087b16af10f482744c3bb30e1f163John Reck        }
210626b183292dc087b16af10f482744c3bb30e1f163John Reck    }
210726b183292dc087b16af10f482744c3bb30e1f163John Reck
21089ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    protected void capture() {
21099ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (mMainView == null || mCapture == null) return;
21104eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        if (mMainView.getContentWidth() <= 0 || mMainView.getContentHeight() <= 0) {
21114eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck            return;
21124eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        }
21139ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        Canvas c = new Canvas(mCapture);
21149ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int left = mMainView.getScrollX();
21159ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int top = mMainView.getScrollY() + mMainView.getVisibleTitleHeight();
2116a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        int state = c.save();
21179ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.translate(-left, -top);
21189ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        float scale = mCaptureWidth / (float) mMainView.getWidth();
21199ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.scale(scale, scale, left, top);
21208ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mMainView instanceof BrowserWebView) {
21218ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            ((BrowserWebView)mMainView).drawContent(c);
21228ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        } else {
21238ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.draw(c);
21248ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
2125a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.restoreToCount(state);
2126a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        // manually anti-alias the edges for the tilt
2127a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, 0, 1, mCapture.getHeight(), sAlphaPaint);
2128a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(mCapture.getWidth() - 1, 0, mCapture.getWidth(),
2129a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb                mCapture.getHeight(), sAlphaPaint);
2130a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, 0, mCapture.getWidth(), 1, sAlphaPaint);
2131a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, mCapture.getHeight() - 1, mCapture.getWidth(),
2132a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb                mCapture.getHeight(), sAlphaPaint);
213343cfe8a4521b5c153055fbfa181940bc56bb3b06Dianne Hackborn        c.setBitmap(null);
21348ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        mHandler.removeMessages(MSG_CAPTURE);
21351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        persistThumbnail();
21368ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        TabControl tc = mWebViewController.getTabControl();
21378ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (tc != null) {
21388ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            OnThumbnailUpdatedListener updateListener
21398ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                    = tc.getOnThumbnailUpdatedListener();
21408ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (updateListener != null) {
21418ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                updateListener.onThumbnailUpdated(this);
21428ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
21438ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
21449ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
21459ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
21469ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    @Override
21479ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    public void onNewPicture(WebView view, Picture picture) {
21489ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        //update screenshot
21491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        postCapture();
21501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void postCapture() {
21539ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (!mHandler.hasMessages(MSG_CAPTURE)) {
21549ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            mHandler.sendEmptyMessageDelayed(MSG_CAPTURE, CAPTURE_DELAY);
21559ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        }
21569ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
21579ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
2158ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoBack() {
2159ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoBack() : false;
2160ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2161ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
2162ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoForward() {
2163ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoForward() : false;
2164ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2165ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
2166ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goBack() {
2167ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
2168ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goBack();
2169ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
2170ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2171ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
2172ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goForward() {
2173ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
2174ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goForward();
2175ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
2176ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2177ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
21781dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
21791dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * Causes the tab back/forward stack to be cleared once, if the given URL is the next URL
21801dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * to be added to the stack.
21811dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     *
21821dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * This is used to ensure that preloaded URLs that are not subsequently seen by the user do
21831dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * not appear in the back stack.
21841dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
2185a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood    public void clearBackStackWhenItemAdded(Pattern urlPattern) {
2186a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood        mClearHistoryUrlPattern = urlPattern;
21871dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    }
21881dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
21891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void persistThumbnail() {
21904eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        DataController.getInstance(mContext).saveThumbnail(this);
21911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void deleteThumbnail() {
21944eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        DataController.getInstance(mContext).deleteThumbnail(this);
21951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21974eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck    void updateCaptureFromBlob(byte[] blob) {
21981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
21991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture == null) {
22001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                return;
22011cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
2202bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            ByteBuffer buffer = ByteBuffer.wrap(blob);
2203d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            try {
2204d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                mCapture.copyPixelsFromBuffer(buffer);
2205d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            } catch (RuntimeException rex) {
2206d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                Log.e(LOGTAG, "Load capture has mismatched sizes; buffer: "
2207d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + buffer.capacity() + " blob: " + blob.length
2208d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + "capture: " + mCapture.getByteCount());
2209d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                throw rex;
2210bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            }
22111cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
22121cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
22131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
221452be4785a258687055515117775d5bcb8bec1c12John Reck    @Override
221552be4785a258687055515117775d5bcb8bec1c12John Reck    public String toString() {
221652be4785a258687055515117775d5bcb8bec1c12John Reck        StringBuilder builder = new StringBuilder(100);
221752be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(mId);
221852be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(") has parent: ");
221952be4785a258687055515117775d5bcb8bec1c12John Reck        if (getParent() != null) {
222052be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("true[");
222152be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getParent().getId());
222252be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("]");
222352be4785a258687055515117775d5bcb8bec1c12John Reck        } else {
222452be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("false");
222552be4785a258687055515117775d5bcb8bec1c12John Reck        }
222652be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(", incog: ");
222752be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(isPrivateBrowsingEnabled());
222852be4785a258687055515117775d5bcb8bec1c12John Reck        if (!isPrivateBrowsingEnabled()) {
222952be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(", title: ");
223052be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getTitle());
223152be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(", url: ");
223252be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getUrl());
223352be4785a258687055515117775d5bcb8bec1c12John Reck        }
223452be4785a258687055515117775d5bcb8bec1c12John Reck        return builder.toString();
223552be4785a258687055515117775d5bcb8bec1c12John Reck    }
223652be4785a258687055515117775d5bcb8bec1c12John Reck
22374895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block    private void handleProceededAfterSslError(SslError error) {
22384895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        if (error.getUrl().equals(mCurrentState.mUrl)) {
22394895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            // The security state should currently be SECURITY_STATE_SECURE.
22404895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            setSecurityState(SecurityState.SECURITY_STATE_BAD_CERTIFICATE);
224108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            mCurrentState.mSslCertificateError = error;
22424895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        } else if (getSecurityState() == SecurityState.SECURITY_STATE_SECURE) {
224308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            // The page's main resource is secure and this error is for a
224408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            // sub-resource.
22454895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            setSecurityState(SecurityState.SECURITY_STATE_MIXED);
22464895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        }
22474895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block    }
224822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
2249