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;
2122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentResolver;
22d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentValues;
2330c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.content.Context;
2422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface;
25fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.DialogInterface.OnCancelListener;
2622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
278cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.graphics.Bitmap.CompressFormat;
289ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.BitmapFactory;
299ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.Canvas;
30c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolbimport android.graphics.Color;
31a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolbimport android.graphics.Paint;
329ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.Picture;
33a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolbimport android.graphics.PorterDuff;
34a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolbimport android.graphics.PorterDuffXfermode;
3522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
3722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
389ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.os.Handler;
3922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
404dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
418862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstromimport android.security.KeyChain;
42aa09cd8dc20c9134b69ace4a7b84fe0103220fb4Brian Carlstromimport android.security.KeyChainAliasCallback;
4324f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reckimport android.text.TextUtils;
4422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
4522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
4622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
4722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
4850c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
498862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstromimport android.webkit.ClientCertRequestHandler;
50c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
51dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
5222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
5322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
5422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
5522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
576c2e2f34718043f36488b4a94879dc2605aaac49John Reckimport android.webkit.WebBackForwardList;
580c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
5922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
6022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
61438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport android.webkit.WebResourceResponse;
6222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
6322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
649ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.webkit.WebView.PictureListener;
652b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport android.webkit.WebViewClassic;
6622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
671d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdochimport android.widget.CheckBox;
688029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
6922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
708ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reckimport com.android.browser.TabControl.OnThumbnailUpdatedListener;
71541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.browser.homepages.HomeProvider;
728cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots;
73541f55a0178da7c09fb32aa5385effae031ea071John Reck
74541f55a0178da7c09fb32aa5385effae031ea071John Reckimport java.io.ByteArrayOutputStream;
752b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.io.File;
7668234a9351dfca2e68769de46e60d22ec2f03818John Reckimport java.io.IOException;
772b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.io.OutputStream;
781cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport java.nio.ByteBuffer;
79fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
80fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
812b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.util.UUID;
82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
83a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwoodimport java.util.regex.Pattern;
848cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.util.zip.GZIPOutputStream;
85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
8622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
8722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
8822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
899ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbclass Tab implements PictureListener {
908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
9222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
931dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
94c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
95c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
96c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
97c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
98c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
999ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private static final int MSG_CAPTURE = 42;
1008ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck    private static final int CAPTURE_DELAY = 100;
101a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb    private static final int INITIAL_PROGRESS = 5;
1029ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static Bitmap sDefaultFavicon;
1041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
105a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    private static Paint sAlphaPaint = new Paint();
106a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    static {
107a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        sAlphaPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
108a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        sAlphaPaint.setColor(Color.TRANSPARENT);
109a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    }
110a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb
1112466effd6ef97aa17396c214d51f9f19a4760260Steve Block    public enum SecurityState {
1124895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource does not use SSL. Note that we use this
1134895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // state irrespective of the SSL authentication state of sub-resources.
1142466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_NOT_SECURE,
1154895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL and the certificate is good. The
1164895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // same is true of all sub-resources.
1172466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_SECURE,
1184895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL and the certificate is good, but
1194895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // some sub-resources either do not use SSL or have problems with their
1204895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // certificates.
1212466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_MIXED,
1224895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL but there is a problem with its
1234895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // certificate.
1244895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        SECURITY_STATE_BAD_CERTIFICATE,
12530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
1268233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1271461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    Context mContext;
128d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected WebViewController mWebViewController;
1298233facddcc51865d612a919d450db6954aa48e3Michael Kolb
130c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    // The tab ID
131d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private long mId = -1;
132c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
13322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
13422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
13522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
136a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
13722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
13922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
14022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
14122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
14222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
14322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
14422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
14522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
14622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
14722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
14822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
149c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Tab mParent;
15022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
15122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
152c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Vector<Tab> mChildren;
15322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
15830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
15930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1604dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1614dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
16222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
16322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
16422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
165e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    // flag to indicate if tab should be closed on back
166e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    private boolean mCloseOnBack;
16722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
16822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
16922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
17022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
171dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
172dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
173dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1740c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1750c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
176e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController mDataController;
1779206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // State of the auto-login request.
1789206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private DeviceAccountLogin mDeviceAccountLogin;
17922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
18122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
18222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18335e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck    private BrowserSettings mSettings;
1849ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureWidth;
1859ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureHeight;
1869ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Bitmap mCapture;
1879ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Handler mHandler;
1887286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb    private boolean mUpdateThumbnail;
1899ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1901dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
1919ad1eac377ffa6ffd34afae4c6580b7ba7508c31Mathew Inwood     * See {@link #clearBackStackWhenItemAdded(String)}.
1921dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
193a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood    private Pattern mClearHistoryUrlPattern;
1941dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
1951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static synchronized Bitmap getDefaultFavicon(Context context) {
1961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (sDefaultFavicon == null) {
1971cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            sDefaultFavicon = BitmapFactory.decodeResource(
1981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    context.getResources(), R.drawable.app_web_browser_sm);
1991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
2001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return sDefaultFavicon;
2011cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
202eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
20330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
204d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected static class PageState {
20530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
206db22ec4ee014900988062d910bc810172a07df56John Reck        String mOriginalUrl;
20730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
2082466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SecurityState mSecurityState;
20908a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        // This is non-null only when mSecurityState is SECURITY_STATE_BAD_CERTIFICATE.
21008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        SslError mSslCertificateError;
21130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
21208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        boolean mIsBookmarkedSite;
21308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        boolean mIncognito;
21430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
21530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
216502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
217502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            if (mIncognito) {
218db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "browser:incognito";
21930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
22030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
221db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "";
22230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
22330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2242466effd6ef97aa17396c214d51f9f19a4760260Steve Block            mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
22530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
22630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
22730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
228502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
229db22ec4ee014900988062d910bc810172a07df56John Reck            mOriginalUrl = mUrl = url;
23030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
2312466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mSecurityState = SecurityState.SECURITY_STATE_SECURE;
23230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
2332466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
23430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mFavicon = favicon;
23630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
2371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
23822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
23922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
24030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
241d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected PageState mCurrentState;
24230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
24322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
244c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    static final String ID = "ID";
24522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
24622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
24722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
24822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
2493d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
250b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck    static final String USERAGENT = "useragent";
251e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    static final String CLOSEFLAG = "closeOnBack";
25222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
25322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
25422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
25522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
25622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
25722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
25822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
25922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
26022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
26122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
26222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
2638233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
26422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
26522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
26622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
26722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
26822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
26922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
27022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
27122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
27222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
27322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
27622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
27822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
27922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
28022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
28122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
28222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
28322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
28422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
28522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
28722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
28822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
28922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
29022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
29122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
29222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
29322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
29422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
29522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
29622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
29722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
29822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
29922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
30022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
30122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
30222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
30422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
30522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
30622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
30722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
30822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
31022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
3111461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog d = new AlertDialog.Builder(mContext)
31222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
31322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
31422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
31522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
31622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
31722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
31822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
31922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
32022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
32122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
32222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
32322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
32422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
32522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
3264a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
3274a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
32847bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb
32947bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb        private boolean providersDiffer(String url, String otherUrl) {
33047bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            Uri uri1 = Uri.parse(url);
33147bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            Uri uri2 = Uri.parse(otherUrl);
33247bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            return !uri1.getEncodedAuthority().equals(uri2.getEncodedAuthority());
33347bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb        }
33447bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb
33522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
33622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
3378233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
3387286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb            mUpdateThumbnail = true;
339a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mPageLoadProgress = INITIAL_PROGRESS;
3401461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext,
34130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
3424dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
34322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
34422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
34522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
34622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
34722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
34822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
34922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
35022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
35122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
35222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
35322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
35422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
3558233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
35622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
35722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
35822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
35922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3609206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            // Cancel the auto-login process.
3619206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (mDeviceAccountLogin != null) {
3629206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin.cancel();
3639206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin = null;
3649206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebViewController.hideAutoLogin(Tab.this);
3659206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
3669206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
36722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
368324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageStarted(Tab.this, view, favicon);
3694cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
370e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
37122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
37222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
37322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
37422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
3755b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
3765b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
3775b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
3785b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
3791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            syncCurrentState(view, url);
380324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageFinished(Tab.this);
38122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
38222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
38322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
38422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
38522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
38622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
38718eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
38818eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
38922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
39022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
39122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
39222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
39322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
39422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
3952466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * Updates the security state. This method is called when we discover
3962466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * another resource to be loaded for this page (for example,
3972466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * javascript). While we update the security state, we do not update
3982466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * the lock icon until we are done loading, as it is slightly more
3992466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * secure this way.
40022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
40122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
40222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
40322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
40422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
4052466effd6ef97aa17396c214d51f9f19a4760260Steve Block                // to update the security state:
4062466effd6ef97aa17396c214d51f9f19a4760260Steve Block                if (mCurrentState.mSecurityState == SecurityState.SECURITY_STATE_SECURE) {
4072466effd6ef97aa17396c214d51f9f19a4760260Steve Block                    // If NOT a 'safe' url, change the state to mixed content!
40822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
40922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
4102466effd6ef97aa17396c214d51f9f19a4760260Steve Block                        mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_MIXED;
41122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
41222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
41322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
41422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
41522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
41622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
41722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
41822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
41922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
42022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
42122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
42222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
42322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
42422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
42522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
42622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
42722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
42822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
42947654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
4303da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                // Don't log URLs when in private browsing mode
4313da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                if (!isPrivateBrowsingEnabled()) {
4323da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                    Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
43347654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
4343da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                }
43547654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
43822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
43922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
44022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
44122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
44222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
44322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
44422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
44522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
44722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
44822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
4494a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
4504a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
4514a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
4524a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
4534a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
4544a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
4554a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
4564a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
4571461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new AlertDialog.Builder(mContext).setTitle(
45822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
45922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
46022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
46122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
46222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
46322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
4644a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
4654a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
4664a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
4674a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
4684a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
4744a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
4754a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
4764a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
4774a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
4784a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
4824a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
4834a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
4844a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
4854a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
4864a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
500324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.doUpdateVisitedHistory(Tab.this, isReload);
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
50822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
50922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
51022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
5112466effd6ef97aa17396c214d51f9f19a4760260Steve Block                setSecurityState(SecurityState.SECURITY_STATE_NOT_SECURE);
51222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
51322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
51435e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            if (mSettings.showSecurityWarnings()) {
515cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                new AlertDialog.Builder(mContext)
516cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setTitle(R.string.security_warning)
517cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setMessage(R.string.ssl_warnings_header)
518cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setIcon(android.R.drawable.ic_dialog_alert)
519cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setPositiveButton(R.string.ssl_continue,
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
521cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
5254895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block                                handleProceededAfterSslError(error);
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
527cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
528cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setNeutralButton(R.string.view_certificate,
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
530cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
533cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                                mWebViewController.showSslCertificateOnError(
534cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                                        view, handler, error);
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
536cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
537cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setNegativeButton(R.string.ssl_go_back,
53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
539cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
54122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
54230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
54322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
544cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
545cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setOnCancelListener(
54622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
547cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
54822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
5502466effd6ef97aa17396c214d51f9f19a4760260Steve Block                                setSecurityState(SecurityState.SECURITY_STATE_NOT_SECURE);
55130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
55222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
553cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
554cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .show();
55522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
55622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
55722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
55822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
55922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
56022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
5614895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * Called when an SSL error occurred while loading a resource, but the
5624895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * WebView but chose to proceed anyway based on a decision retained
5634895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * from a previous response to onReceivedSslError(). We update our
5644895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         * security state to reflect this.
5654895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block         */
5664895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        @Override
5674895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        public void onProceededAfterSslError(WebView view, SslError error) {
5684895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            handleProceededAfterSslError(error);
5694895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        }
5704895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block
5714895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        /**
5728862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom         * Displays client certificate request to the user.
5738862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom         */
5748862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        @Override
5758862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        public void onReceivedClientCertRequest(final WebView view,
5768862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                final ClientCertRequestHandler handler, final String host_and_port) {
5778862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            if (!mInForeground) {
5788862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                handler.ignore();
5798862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                return;
5808862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            }
5816d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            int colon = host_and_port.lastIndexOf(':');
5826d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            String host;
5836d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            int port;
5846d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            if (colon == -1) {
5856d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                host = host_and_port;
5866d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                port = -1;
5876d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            } else {
5886d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                String portString = host_and_port.substring(colon + 1);
5896d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                try {
5906d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    port = Integer.parseInt(portString);
5916d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    host = host_and_port.substring(0, colon);
5926d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                } catch  (NumberFormatException e) {
5936d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    host = host_and_port;
5946d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    port = -1;
5956d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                }
5966d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            }
5971461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            KeyChain.choosePrivateKeyAlias(
5981461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mWebViewController.getActivity(), new KeyChainAliasCallback() {
5998862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                @Override public void alias(String alias) {
6008862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                    if (alias == null) {
6018862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                        handler.cancel();
6028862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                        return;
6038862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                    }
6041461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new KeyChainLookup(mContext, handler, alias).execute();
6058862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                }
6066d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            }, null, null, host, port, null);
6078862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        }
6088862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom
6098862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        /**
61022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
61422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
61522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
61622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
61722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
61822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
61922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
6208233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
62122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
62222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
624438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        public WebResourceResponse shouldInterceptRequest(WebView view,
625438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                String url) {
626438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
6271461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mContext, url);
628438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            return res;
629438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        }
630438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck
631438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        @Override
63222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6368233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
6418233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
644997b1b7695822cb2dc2deca0458a5649d00b9953John Reck            if (!mWebViewController.onUnhandledKeyEvent(event)) {
645997b1b7695822cb2dc2deca0458a5649d00b9953John Reck                super.onUnhandledKeyEvent(view, event);
646997b1b7695822cb2dc2deca0458a5649d00b9953John Reck            }
64722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
6489206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
6499206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        @Override
6509206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void onReceivedLoginRequest(WebView view, String realm,
6519206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                String account, String args) {
6521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new DeviceAccountLogin(mWebViewController.getActivity(), view, Tab.this, mWebViewController)
6539206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    .handleLogin(realm, account, args);
6549206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
6559206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
6581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void syncCurrentState(WebView view, String url) {
6591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        // Sync state (in case of stop/timeout)
6601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mUrl = view.getUrl();
6611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mUrl == null) {
6628bcafc149bc49b84c8dfbaacf88c178d8bc9eda6John Reck            mCurrentState.mUrl = "";
6631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
6641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mOriginalUrl = view.getOriginalUrl();
6651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = view.getTitle();
6661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mFavicon = view.getFavicon();
6671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
6681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // In case we stop when loading an HTTPS page from an HTTP page
6691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // but before a provisional load occurred
6702466effd6ef97aa17396c214d51f9f19a4760260Steve Block            mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
67108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            mCurrentState.mSslCertificateError = null;
6721cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
673502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        mCurrentState.mIncognito = view.isPrivateBrowsingEnabled();
6741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
6751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
6769206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
6779206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // displayed.
6789206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    void setDeviceAccountLogin(DeviceAccountLogin login) {
6799206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mDeviceAccountLogin = login;
6809206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
6819206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
6829206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Returns non-null if the title bar should display the auto-login UI.
6839206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    DeviceAccountLogin getDeviceAccountLogin() {
6849206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mDeviceAccountLogin;
6859206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
6869206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
6988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
7017bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                final Tab newTab = mWebViewController.openTab(null,
7025949c661b51295148706d53a03b41df2eb840ae3John Reck                        Tab.this, true, true);
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
70622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
7171461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
7248233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
7251461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
7591461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new AlertDialog.Builder(mContext)
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
773eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
774eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
775c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mWebViewController.switchToTab(Tab.this);
776eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
777eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
778eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
779eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
781c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            if (mParent != null) {
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
784c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                    mWebViewController.switchToTab(mParent);
78522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
7868233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
79230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
793b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb            if (newProgress == 100) {
794b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb                mInPageLoad = false;
795b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb            }
79630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
7977286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb            if (mUpdateThumbnail && newProgress == 100) {
7987286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb                mUpdateThumbnail = false;
7997286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb            }
80022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
80321d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
80430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
8058233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
80622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
81030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
8118233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
81222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
81622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
8171461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            final ContentResolver cr = mContext.getContentResolver();
818c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
819c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
820c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
821c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
822c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
823c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
824c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
825c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
8268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
8271461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                        mContext, cr, view);
828c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
82922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
83022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
83122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
83222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
83322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
83422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
8351461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            Activity activity = mWebViewController.getActivity();
8361461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            if (activity != null) {
8371461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                onShowCustomView(view, activity.getRequestedOrientation(), callback);
8381461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            }
8392d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        }
8402d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger
8412d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        @Override
8422d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        public void onShowCustomView(View view, int requestedOrientation,
8432d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                WebChromeClient.CustomViewCallback callback) {
8448233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
8452d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                    requestedOrientation, callback);
84622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
8508233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
85122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
85322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
85622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
85722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
85822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
86835e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
88735e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
89822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
89922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
90022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
90222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
90450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
90922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
91022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
91222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
91350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
91422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
91522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
91865acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
91965acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
92065acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
921c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
924c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
92522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
92622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
928c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
9298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
9308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
9318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
93222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
935c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
93647654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
937f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
93847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
939c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
940c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
941c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
942c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
943c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
944c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
945c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
946c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
947c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
948c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
949c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
950c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
951c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
952c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
953c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
954c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
955c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
956c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
957c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
958c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
959c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
960c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
961c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
96622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
97122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
9728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
97422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
9858233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
9918cad413fe902010140cf20aad47c2f4e7a51f8d2Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
9938cad413fe902010140cf20aad47c2f4e7a51f8d2Ben Murdoch                mWebViewController.openFileChooser(uploadMsg, acceptType, capture);
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
10048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
10058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
10068029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
10078029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
10088029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
10098029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
10108029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
10111461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
10121461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
10131d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    Context.LAYOUT_INFLATER_SERVICE);
10141d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null);
10151d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
10161d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            builder.setView(layout)
10171d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
10181d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    @Override
10191d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    public void onClick(DialogInterface dialog, int id) {
10201d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        CheckBox disableAutoFill = (CheckBox) layout.findViewById(
10211d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                R.id.setup_autofill_dialog_disable_autofill);
10221d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
10231d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        if (disableAutoFill.isChecked()) {
10241d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Disable autofill and show a toast with how to turn it on again.
102535e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                            mSettings.setAutofillEnabled(false);
10261461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                            Toast.makeText(mContext,
10271d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    R.string.autofill_setup_dialog_negative_toast,
10281d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    Toast.LENGTH_LONG).show();
10291d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        } else {
10301d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Take user to the AutoFill profile editor. When they return,
10311d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // we will send the message that we pass here which will trigger
10321d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // the form to get filled out with their new profile.
10331d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            mWebViewController.setupAutoFill(msg);
10341d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        }
10351d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    }
10361d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                })
10371d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setNegativeButton(R.string.cancel, null)
10381d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .show();
10398029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
104022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
104122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
104322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
10518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
10538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
10558233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1056211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1057211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1058211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1059211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1060211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
106101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
10628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
106322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
106522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
106622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
106722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
106822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
106922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
10798862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        public void onReceivedClientCertRequest(WebView view,
10808862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                ClientCertRequestHandler handler, String host_and_port) {
10818862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            mClient.onReceivedClientCertRequest(view, handler, host_and_port);
10828862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        }
10838862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        @Override
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
108722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
109122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
110622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
110722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
112822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
112922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
113022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
113222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
113322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
113422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
11358233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
113622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
113722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
113822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
113922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
114022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
11427bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    Tab(WebViewController wvcontroller, WebView w) {
11431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, w, null);
11441cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
11451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
11461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, Bundle state) {
11471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, null, state);
11481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
11491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
11501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, WebView w, Bundle state) {
11518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
11521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mContext = mWebViewController.getContext();
115335e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck        mSettings = BrowserSettings.getInstance();
11541461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mDataController = DataController.getInstance(mContext);
11551461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mCurrentState = new PageState(mContext, w != null
1156847b532045e3cb117a847ebb956c9919401f332dJohn Reck                ? w.isPrivateBrowsingEnabled() : false);
11578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
115822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
115922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1160dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1161dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1162dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1163dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
11648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1165dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1166dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1167dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
11680c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
11690c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
11700c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
1171a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                if (mClearHistoryUrlPattern != null) {
1172a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    boolean match =
1173a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                        mClearHistoryUrlPattern.matcher(item.getOriginalUrl()).matches();
11741dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    if (LOGD_ENABLED) {
1175a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                        Log.d(LOGTAG, "onNewHistoryItem: match=" + match + "\n\t"
1176a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                                + item.getUrl() + "\n\t"
1177a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                                + mClearHistoryUrlPattern);
11781dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
1179a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    if (match) {
11801dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        if (mMainView != null) {
11811dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                            mMainView.clearHistory();
11821dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        }
11831dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
1184a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    mClearHistoryUrlPattern = null;
11851dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                }
11860c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
11870c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1188dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
11891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureWidth = mContext.getResources().getDimensionPixelSize(
11901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_width);
11911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureHeight = mContext.getResources().getDimensionPixelSize(
11921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_height);
11931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
11941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        restoreState(state);
119552be4785a258687055515117775d5bcb8bec1c12John Reck        if (getId() == -1) {
119652be4785a258687055515117775d5bcb8bec1c12John Reck            mId = TabControl.getNextId();
119752be4785a258687055515117775d5bcb8bec1c12John Reck        }
119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
11999ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        mHandler = new Handler() {
12001dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood            @Override
12019ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            public void handleMessage(Message m) {
12021cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                switch (m.what) {
12031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                case MSG_CAPTURE:
12041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    capture();
12051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    break;
12061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
12079ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            }
12089ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        };
12091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
12109ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
12117286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb    public boolean shouldUpdateThumbnail() {
12127286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb        return mUpdateThumbnail;
12137286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb    }
12147286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb
1215e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    /**
1216e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * This is used to get a new ID when the tab has been preloaded, before it is displayed and
1217e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * added to TabControl. Preloaded tabs can be created before restoreInstanceState, leading
1218e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * to overlapping IDs between the preloaded and restored tabs.
1219e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     */
1220e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    public void refreshIdAfterPreload() {
1221e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood        mId = TabControl.getNextId();
1222e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    }
1223e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood
12241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public void updateShouldCaptureThumbnails() {
12251cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mWebViewController.shouldCaptureThumbnails()) {
12261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
12271cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                if (mCapture == null) {
12281cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    mCapture = Bitmap.createBitmap(mCaptureWidth, mCaptureHeight,
12291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                            Bitmap.Config.RGB_565);
1230c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolb                    mCapture.eraseColor(Color.WHITE);
12311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    if (mInForeground) {
12321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        postCapture();
12331cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    }
12341cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
12351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
12361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        } else {
12371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
12381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCapture = null;
12391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                deleteThumbnail();
12401cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
12411cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12441461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    public void setController(WebViewController ctl) {
12451461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mWebViewController = ctl;
12461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
12471461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    }
12481461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb
1249c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public long getId() {
1250c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mId;
1251c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1252c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
125391911a26058418e622950cffc616f99ada49df1dMichael Kolb    void setWebView(WebView w) {
125491911a26058418e622950cffc616f99ada49df1dMichael Kolb        setWebView(w, true);
125591911a26058418e622950cffc616f99ada49df1dMichael Kolb    }
125691911a26058418e622950cffc616f99ada49df1dMichael Kolb
125722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
125822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
126022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
126191911a26058418e622950cffc616f99ada49df1dMichael Kolb    void setWebView(WebView w, boolean restore) {
126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
126422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1265a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
126850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
126950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
127050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
127122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1272a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
127322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mMainView != null) {
12758ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.setPictureListener(null);
12761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (w != null) {
12771cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                syncCurrentState(w, null);
12781cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            } else {
12791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCurrentState = new PageState(mContext, false);
12801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
12811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1284dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
128522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1288dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1289dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1290dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1291dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1292dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
12934d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon            getWebViewClassic().setWebBackForwardListClient(mWebBackForwardListClient);
12948ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            TabControl tc = mWebViewController.getTabControl();
12958ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (tc != null && tc.getOnThumbnailUpdatedListener() != null) {
12968ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                mMainView.setPictureListener(this);
12978ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
129891911a26058418e622950cffc616f99ada49df1dMichael Kolb            if (restore && (mSavedState != null)) {
12998b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck                restoreUserAgent();
13006c2e2f34718043f36488b4a94879dc2605aaac49John Reck                WebBackForwardList restoredState
13016c2e2f34718043f36488b4a94879dc2605aaac49John Reck                        = mMainView.restoreState(mSavedState);
13026c2e2f34718043f36488b4a94879dc2605aaac49John Reck                if (restoredState == null || restoredState.getSize() == 0) {
13036c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    Log.w(LOGTAG, "Failed to restore WebView state!");
13046c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    loadUrl(mCurrentState.mOriginalUrl, null);
13056c2e2f34718043f36488b4a94879dc2605aaac49John Reck                }
13061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mSavedState = null;
13071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
130822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
130922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
131022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
131122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
131222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
131322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
131422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
131522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
131622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
131822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
132022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
132122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
132222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
132322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
132522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
1329c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren != null) {
1330c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            for(Tab t : mChildren) {
1331c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                t.setParent(null);
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
1335c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1336c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mParent.mChildren.remove(this);
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
13381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        deleteThumbnail();
133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
13471514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1348211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
13498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1352dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1353dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1354dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1355dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1356dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1357dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
13588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1359dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1360dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1361dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1362dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
13638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1364dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1365dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1366dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
13671461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(mWebViewController.getActivity());
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
137122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
137522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
137722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
13788233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
138022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
1389c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    void setParent(Tab parent) {
139052be4785a258687055515117775d5bcb8bec1c12John Reck        if (parent == this) {
139152be4785a258687055515117775d5bcb8bec1c12John Reck            throw new IllegalStateException("Cannot set parent to self!");
139252be4785a258687055515117775d5bcb8bec1c12John Reck        }
1393c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mParent = parent;
139422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
1395c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // the parent tab id is already saved. If we are changing that id
139622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
1397c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // parent tab id in the saved Bundle.
139822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
1402c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mSavedState.putLong(PARENTTAB, parent.getId());
140322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
140422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1405b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck
1406b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        // Sync the WebView useragent with the parent
1407b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        if (parent != null && mSettings.hasDesktopUseragent(parent.getWebView())
1408b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                != mSettings.hasDesktopUseragent(getWebView())) {
1409b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck            mSettings.toggleDesktopUseragent(getWebView());
1410b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        }
141152be4785a258687055515117775d5bcb8bec1c12John Reck
141252be4785a258687055515117775d5bcb8bec1c12John Reck        if (parent != null && parent.getId() == getId()) {
141352be4785a258687055515117775d5bcb8bec1c12John Reck            throw new IllegalStateException("Parent has same ID as child!");
141452be4785a258687055515117775d5bcb8bec1c12John Reck        }
141522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
141622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
141722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1418c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * If this Tab was created through another Tab, then this method returns
1419c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * that Tab.
1420c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * @return the Tab parent or null
1421c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     */
1422c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public Tab getParent() {
1423c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mParent;
1424c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1425c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
1426c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    /**
142722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
142822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
142922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
143022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
1432c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren == null) {
1433c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mChildren = new Vector<Tab>();
143422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1435c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mChildren.add(child);
1436c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        child.setParent(this);
143722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
143822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1439c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    Vector<Tab> getChildren() {
1440c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mChildren;
144122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
144222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
144322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
144422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
144556c1fcf7774d4ee943fbda808e37840459502e20John Reck            setupHwAcceleration(mMainView);
144622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
144722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
145022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
145356c1fcf7774d4ee943fbda808e37840459502e20John Reck    private void setupHwAcceleration(View web) {
145456c1fcf7774d4ee943fbda808e37840459502e20John Reck        if (web == null) return;
145556c1fcf7774d4ee943fbda808e37840459502e20John Reck        BrowserSettings settings = BrowserSettings.getInstance();
145656c1fcf7774d4ee943fbda808e37840459502e20John Reck        if (settings.isHardwareAccelerated()) {
145756c1fcf7774d4ee943fbda808e37840459502e20John Reck            web.setLayerType(View.LAYER_TYPE_NONE, null);
145856c1fcf7774d4ee943fbda808e37840459502e20John Reck        } else {
145956c1fcf7774d4ee943fbda808e37840459502e20John Reck            web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
146056c1fcf7774d4ee943fbda808e37840459502e20John Reck        }
146156c1fcf7774d4ee943fbda808e37840459502e20John Reck    }
146256c1fcf7774d4ee943fbda808e37840459502e20John Reck
146322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
146422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
146822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
146922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
147022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
14738ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mInForeground) {
14748ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
14758ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
14781461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        Activity activity = mWebViewController.getActivity();
14791461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mMainView.setOnCreateContextMenuListener(activity);
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
14811461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(activity);
148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
148422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
14871961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
148822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
14918ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (!mInForeground) {
14928ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
14938ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
149452be4785a258687055515117775d5bcb8bec1c12John Reck        capture();
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
150222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
15048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
15058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15068233facddcc51865d612a919d450db6954aa48e3Michael Kolb
150722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
150822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
150922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
151022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
151122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
151222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
151322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
151422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
151522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
151622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
151722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
151822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
151922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
152022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
152122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
152222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
152322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
152422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
152622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
152722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
152822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15294d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon    /**
15304d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     * Return the underlying WebViewClassic implementation. As with getWebView,
15314d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     * this maybe null for background tabs.
15324d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     * @return The main WebView of this tab.
15334d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon     */
15344d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon    WebViewClassic getWebViewClassic() {
15354d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon        return WebViewClassic.fromWebView(mMainView);
15364d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon    }
15374d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon
1538a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1539a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1540a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1541a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
15428233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
15438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
15448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
154622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1547f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1548f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1549f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1550f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
15518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1552502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        return mCurrentState.mIncognito;
1553f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1554f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1555f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
155622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
155722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
155822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
155922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
156022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15631514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
15641514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
15651514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15661514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
15678233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
15688233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
15698233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15708233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15711514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
15721514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
15731514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15741514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
157522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
157622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
157722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
157950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
158050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
158150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
158250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
158350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
158450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
158522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
158622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
158722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
158822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
159022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
159122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
159222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1603e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    boolean closeOnBack() {
1604e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        return mCloseOnBack;
1605e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1606e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
1607e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    void setCloseOnBack(boolean close) {
1608e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = close;
1609e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1610e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
161122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
1612324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        return UrlUtils.filteredUrl(mCurrentState.mUrl);
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161549a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    String getOriginalUrl() {
1616db22ec4ee014900988062d910bc810172a07df56John Reck        if (mCurrentState.mOriginalUrl == null) {
1617db22ec4ee014900988062d910bc810172a07df56John Reck            return getUrl();
161849a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        }
1619db22ec4ee014900988062d910bc810172a07df56John Reck        return UrlUtils.filteredUrl(mCurrentState.mOriginalUrl);
162049a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    }
162149a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
162330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
162630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
16271461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            return mContext.getString(R.string.title_bar_loading);
162822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
162930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
163422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
163522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
16361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mFavicon != null) {
16371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCurrentState.mFavicon;
16381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
16391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return getDefaultFavicon(mContext);
164022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
164122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1642e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1643e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1644e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1645f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
164622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
164722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
165522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
16561461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mErrorConsole = new ErrorConsoleView(mContext);
165722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    /**
166308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * Sets the security state, clears the SSL certificate error and informs
166408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * the controller.
166508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     */
16662466effd6ef97aa17396c214d51f9f19a4760260Steve Block    private void setSecurityState(SecurityState securityState) {
16672466effd6ef97aa17396c214d51f9f19a4760260Steve Block        mCurrentState.mSecurityState = securityState;
166808a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        mCurrentState.mSslCertificateError = null;
16692466effd6ef97aa17396c214d51f9f19a4760260Steve Block        mWebViewController.onUpdatedSecurityState(this);
167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
16732466effd6ef97aa17396c214d51f9f19a4760260Steve Block     * @return The tab's security state.
167422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16752466effd6ef97aa17396c214d51f9f19a4760260Steve Block    SecurityState getSecurityState() {
16762466effd6ef97aa17396c214d51f9f19a4760260Steve Block        return mCurrentState.mSecurityState;
167722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167908a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    /**
168008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * Gets the SSL certificate error, if any, for the page's main resource.
168108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * This is only non-null when the security state is
168208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * SECURITY_STATE_BAD_CERTIFICATE.
168308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     */
168408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    SslError getSslCertificateError() {
168508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        return mCurrentState.mSslCertificateError;
168608a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    }
168708a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block
168830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
168930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
169030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
169130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
169230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
169822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16998233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
17008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
17041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck     * @return The Bundle with the tab's state if it can be saved, otherwise null
170522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
17061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public Bundle saveState() {
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
17101cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mSavedState;
171122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
17126c2e2f34718043f36488b4a94879dc2605aaac49John Reck
17136c2e2f34718043f36488b4a94879dc2605aaac49John Reck        if (TextUtils.isEmpty(mCurrentState.mUrl)) {
17141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return null;
171524f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        }
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
17186c2e2f34718043f36488b4a94879dc2605aaac49John Reck        WebBackForwardList savedList = mMainView.saveState(mSavedState);
17196c2e2f34718043f36488b4a94879dc2605aaac49John Reck        if (savedList == null || savedList.getSize() == 0) {
17206c2e2f34718043f36488b4a94879dc2605aaac49John Reck            Log.w(LOGTAG, "Failed to save back/forward list for "
17216c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    + mCurrentState.mUrl);
17226c2e2f34718043f36488b4a94879dc2605aaac49John Reck        }
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1724c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mSavedState.putLong(ID, mId);
172530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
172630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
17271cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState.putBoolean(INCOGNITO, mMainView.isPrivateBrowsingEnabled());
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1731e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mSavedState.putBoolean(CLOSEFLAG, mCloseOnBack);
173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
1733c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1734c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mSavedState.putLong(PARENTTAB, mParent.mId);
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1736b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        mSavedState.putBoolean(USERAGENT,
1737b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                mSettings.hasDesktopUseragent(getWebView()));
17381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return mSavedState;
173922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
174022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
174122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
174222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
174322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
17441cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void restoreState(Bundle b) {
17451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState = b;
17461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mSavedState == null) {
17471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return;
174822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
174922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
1751c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mId = b.getLong(ID);
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
1753e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = b.getBoolean(CLOSEFLAG);
17548b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        restoreUserAgent();
17551cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String url = b.getString(CURRURL);
17561cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String title = b.getString(CURRTITLE);
17571cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        boolean incognito = b.getBoolean(INCOGNITO);
17581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState = new PageState(mContext, incognito, url, null);
17591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = title;
17601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
17611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture != null) {
17624eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck                DataController.getInstance(mContext).loadThumbnail(this);
17631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
176422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
176522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1766211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
17678b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck    private void restoreUserAgent() {
17688b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        if (mMainView == null || mSavedState == null) {
17698b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck            return;
17708b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        }
17718b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        if (mSavedState.getBoolean(USERAGENT)
17728b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck                != mSettings.hasDesktopUseragent(mMainView)) {
17738b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck            mSettings.toggleDesktopUseragent(mMainView);
17748b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        }
17758b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck    }
17768b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck
17771961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
1778e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
17791961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
17801961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
1781e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
1782e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
1783e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
1784e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
1785e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
1786e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
1787e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
17881961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
1789e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
1790e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
17911acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1792eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    public Bitmap getScreenshot() {
17931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
17941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCapture;
17951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
1796eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    }
1797eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
1798541f55a0178da7c09fb32aa5385effae031ea071John Reck    public boolean isSnapshot() {
1799541f55a0178da7c09fb32aa5385effae031ea071John Reck        return false;
1800541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
1801541f55a0178da7c09fb32aa5385effae031ea071John Reck
180268234a9351dfca2e68769de46e60d22ec2f03818John Reck    private static class SaveCallback implements ValueCallback<Boolean> {
180368234a9351dfca2e68769de46e60d22ec2f03818John Reck        boolean mResult;
180468234a9351dfca2e68769de46e60d22ec2f03818John Reck
180568234a9351dfca2e68769de46e60d22ec2f03818John Reck        @Override
180668234a9351dfca2e68769de46e60d22ec2f03818John Reck        public void onReceiveValue(Boolean value) {
180768234a9351dfca2e68769de46e60d22ec2f03818John Reck            mResult = value;
180868234a9351dfca2e68769de46e60d22ec2f03818John Reck            synchronized (this) {
180968234a9351dfca2e68769de46e60d22ec2f03818John Reck                notifyAll();
181068234a9351dfca2e68769de46e60d22ec2f03818John Reck            }
181168234a9351dfca2e68769de46e60d22ec2f03818John Reck        }
181268234a9351dfca2e68769de46e60d22ec2f03818John Reck
181368234a9351dfca2e68769de46e60d22ec2f03818John Reck    }
181468234a9351dfca2e68769de46e60d22ec2f03818John Reck
181568234a9351dfca2e68769de46e60d22ec2f03818John Reck    /**
181668234a9351dfca2e68769de46e60d22ec2f03818John Reck     * Must be called on the UI thread
181768234a9351dfca2e68769de46e60d22ec2f03818John Reck     */
1818d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public ContentValues createSnapshotValues() {
181968234a9351dfca2e68769de46e60d22ec2f03818John Reck        WebViewClassic web = getWebViewClassic();
182068234a9351dfca2e68769de46e60d22ec2f03818John Reck        if (web == null) return null;
182168234a9351dfca2e68769de46e60d22ec2f03818John Reck        ContentValues values = new ContentValues();
182268234a9351dfca2e68769de46e60d22ec2f03818John Reck        values.put(Snapshots.TITLE, mCurrentState.mTitle);
182368234a9351dfca2e68769de46e60d22ec2f03818John Reck        values.put(Snapshots.URL, mCurrentState.mUrl);
182468234a9351dfca2e68769de46e60d22ec2f03818John Reck        values.put(Snapshots.BACKGROUND, web.getPageBackgroundColor());
182568234a9351dfca2e68769de46e60d22ec2f03818John Reck        values.put(Snapshots.DATE_CREATED, System.currentTimeMillis());
182668234a9351dfca2e68769de46e60d22ec2f03818John Reck        values.put(Snapshots.FAVICON, compressBitmap(getFavicon()));
182768234a9351dfca2e68769de46e60d22ec2f03818John Reck        Bitmap screenshot = Controller.createScreenshot(mMainView,
182868234a9351dfca2e68769de46e60d22ec2f03818John Reck                Controller.getDesiredThumbnailWidth(mContext),
182968234a9351dfca2e68769de46e60d22ec2f03818John Reck                Controller.getDesiredThumbnailHeight(mContext));
183068234a9351dfca2e68769de46e60d22ec2f03818John Reck        values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot));
183168234a9351dfca2e68769de46e60d22ec2f03818John Reck        return values;
183268234a9351dfca2e68769de46e60d22ec2f03818John Reck    }
183368234a9351dfca2e68769de46e60d22ec2f03818John Reck
183468234a9351dfca2e68769de46e60d22ec2f03818John Reck    /**
183568234a9351dfca2e68769de46e60d22ec2f03818John Reck     * Probably want to call this on a background thread
183668234a9351dfca2e68769de46e60d22ec2f03818John Reck     */
183768234a9351dfca2e68769de46e60d22ec2f03818John Reck    public boolean saveViewState(ContentValues values) {
183868234a9351dfca2e68769de46e60d22ec2f03818John Reck        WebViewClassic web = getWebViewClassic();
183968234a9351dfca2e68769de46e60d22ec2f03818John Reck        if (web == null) return false;
18402b71d6dad1cbdc84da3eed140429a102971a1106John Reck        String path = UUID.randomUUID().toString();
184168234a9351dfca2e68769de46e60d22ec2f03818John Reck        SaveCallback callback = new SaveCallback();
184268234a9351dfca2e68769de46e60d22ec2f03818John Reck        OutputStream outs = null;
18438cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        try {
184468234a9351dfca2e68769de46e60d22ec2f03818John Reck            outs = mContext.openFileOutput(path, Context.MODE_PRIVATE);
18452b71d6dad1cbdc84da3eed140429a102971a1106John Reck            GZIPOutputStream stream = new GZIPOutputStream(outs);
184668234a9351dfca2e68769de46e60d22ec2f03818John Reck            synchronized (callback) {
184768234a9351dfca2e68769de46e60d22ec2f03818John Reck                web.saveViewState(stream, callback);
184868234a9351dfca2e68769de46e60d22ec2f03818John Reck                callback.wait();
18498cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
18508cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            stream.flush();
18518cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            stream.close();
18528cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        } catch (Exception e) {
18538cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            Log.w(LOGTAG, "Failed to save view state", e);
185468234a9351dfca2e68769de46e60d22ec2f03818John Reck            if (outs != null) {
185568234a9351dfca2e68769de46e60d22ec2f03818John Reck                try {
185668234a9351dfca2e68769de46e60d22ec2f03818John Reck                    outs.close();
185768234a9351dfca2e68769de46e60d22ec2f03818John Reck                } catch (IOException ignore) {}
185868234a9351dfca2e68769de46e60d22ec2f03818John Reck            }
185968234a9351dfca2e68769de46e60d22ec2f03818John Reck            File file = mContext.getFileStreamPath(path);
186068234a9351dfca2e68769de46e60d22ec2f03818John Reck            if (file.exists() && !file.delete()) {
186168234a9351dfca2e68769de46e60d22ec2f03818John Reck                file.deleteOnExit();
186268234a9351dfca2e68769de46e60d22ec2f03818John Reck            }
186368234a9351dfca2e68769de46e60d22ec2f03818John Reck            return false;
1864541f55a0178da7c09fb32aa5385effae031ea071John Reck        }
18652b71d6dad1cbdc84da3eed140429a102971a1106John Reck        File savedFile = mContext.getFileStreamPath(path);
186668234a9351dfca2e68769de46e60d22ec2f03818John Reck        if (!callback.mResult) {
186768234a9351dfca2e68769de46e60d22ec2f03818John Reck            if (!savedFile.delete()) {
186868234a9351dfca2e68769de46e60d22ec2f03818John Reck                savedFile.deleteOnExit();
186968234a9351dfca2e68769de46e60d22ec2f03818John Reck            }
187068234a9351dfca2e68769de46e60d22ec2f03818John Reck            return false;
187168234a9351dfca2e68769de46e60d22ec2f03818John Reck        }
18722b71d6dad1cbdc84da3eed140429a102971a1106John Reck        long size = savedFile.length();
18732b71d6dad1cbdc84da3eed140429a102971a1106John Reck        values.put(Snapshots.VIEWSTATE_PATH, path);
18742b71d6dad1cbdc84da3eed140429a102971a1106John Reck        values.put(Snapshots.VIEWSTATE_SIZE, size);
187568234a9351dfca2e68769de46e60d22ec2f03818John Reck        return true;
1876541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
1877541f55a0178da7c09fb32aa5385effae031ea071John Reck
18788cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public byte[] compressBitmap(Bitmap bitmap) {
18798cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (bitmap == null) {
18808cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
18818cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
18828cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        ByteArrayOutputStream stream = new ByteArrayOutputStream();
18838cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        bitmap.compress(CompressFormat.PNG, 100, stream);
18848cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return stream.toByteArray();
18858cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
18868cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
188726b183292dc087b16af10f482744c3bb30e1f163John Reck    public void loadUrl(String url, Map<String, String> headers) {
188826b183292dc087b16af10f482744c3bb30e1f163John Reck        if (mMainView != null) {
1889a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mPageLoadProgress = INITIAL_PROGRESS;
1890a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mInPageLoad = true;
18911461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext, false, url, null);
189226b183292dc087b16af10f482744c3bb30e1f163John Reck            mWebViewController.onPageStarted(this, mMainView, null);
189326b183292dc087b16af10f482744c3bb30e1f163John Reck            mMainView.loadUrl(url, headers);
189426b183292dc087b16af10f482744c3bb30e1f163John Reck        }
189526b183292dc087b16af10f482744c3bb30e1f163John Reck    }
189626b183292dc087b16af10f482744c3bb30e1f163John Reck
18979ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    protected void capture() {
18989ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (mMainView == null || mCapture == null) return;
18994eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        if (mMainView.getContentWidth() <= 0 || mMainView.getContentHeight() <= 0) {
19004eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck            return;
19014eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        }
19029ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        Canvas c = new Canvas(mCapture);
19039ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int left = mMainView.getScrollX();
19049ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int top = mMainView.getScrollY() + mMainView.getVisibleTitleHeight();
1905a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        int state = c.save();
19069ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.translate(-left, -top);
19079ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        float scale = mCaptureWidth / (float) mMainView.getWidth();
19089ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.scale(scale, scale, left, top);
19098ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mMainView instanceof BrowserWebView) {
19108ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            ((BrowserWebView)mMainView).drawContent(c);
19118ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        } else {
19128ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.draw(c);
19138ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
1914a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.restoreToCount(state);
1915a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        // manually anti-alias the edges for the tilt
1916a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, 0, 1, mCapture.getHeight(), sAlphaPaint);
1917a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(mCapture.getWidth() - 1, 0, mCapture.getWidth(),
1918a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb                mCapture.getHeight(), sAlphaPaint);
1919a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, 0, mCapture.getWidth(), 1, sAlphaPaint);
1920a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, mCapture.getHeight() - 1, mCapture.getWidth(),
1921a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb                mCapture.getHeight(), sAlphaPaint);
192243cfe8a4521b5c153055fbfa181940bc56bb3b06Dianne Hackborn        c.setBitmap(null);
19238ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        mHandler.removeMessages(MSG_CAPTURE);
19241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        persistThumbnail();
19258ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        TabControl tc = mWebViewController.getTabControl();
19268ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (tc != null) {
19278ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            OnThumbnailUpdatedListener updateListener
19288ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                    = tc.getOnThumbnailUpdatedListener();
19298ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (updateListener != null) {
19308ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                updateListener.onThumbnailUpdated(this);
19318ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
19328ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
19339ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
19349ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
19359ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    @Override
19369ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    public void onNewPicture(WebView view, Picture picture) {
19371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        postCapture();
19381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
19391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
19401cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void postCapture() {
19419ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (!mHandler.hasMessages(MSG_CAPTURE)) {
19429ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            mHandler.sendEmptyMessageDelayed(MSG_CAPTURE, CAPTURE_DELAY);
19439ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        }
19449ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
19459ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1946ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoBack() {
1947ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoBack() : false;
1948ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1949ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
1950ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoForward() {
1951ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoForward() : false;
1952ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1953ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
1954ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goBack() {
1955ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
1956ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goBack();
1957ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
1958ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1959ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
1960ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goForward() {
1961ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
1962ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goForward();
1963ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
1964ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1965ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
19661dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
19671dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * Causes the tab back/forward stack to be cleared once, if the given URL is the next URL
19681dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * to be added to the stack.
19691dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     *
19701dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * This is used to ensure that preloaded URLs that are not subsequently seen by the user do
19711dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * not appear in the back stack.
19721dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
1973a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood    public void clearBackStackWhenItemAdded(Pattern urlPattern) {
1974a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood        mClearHistoryUrlPattern = urlPattern;
19751dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    }
19761dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
19771cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void persistThumbnail() {
19784eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        DataController.getInstance(mContext).saveThumbnail(this);
19791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
19801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
19811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void deleteThumbnail() {
19824eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        DataController.getInstance(mContext).deleteThumbnail(this);
19831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
19841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
19854eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck    void updateCaptureFromBlob(byte[] blob) {
19861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
19871cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture == null) {
19881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                return;
19891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
1990bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            ByteBuffer buffer = ByteBuffer.wrap(blob);
1991d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            try {
1992d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                mCapture.copyPixelsFromBuffer(buffer);
1993d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            } catch (RuntimeException rex) {
1994d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                Log.e(LOGTAG, "Load capture has mismatched sizes; buffer: "
1995d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + buffer.capacity() + " blob: " + blob.length
1996d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + "capture: " + mCapture.getByteCount());
1997d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                throw rex;
1998bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            }
19991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
20001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
20011cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
200252be4785a258687055515117775d5bcb8bec1c12John Reck    @Override
200352be4785a258687055515117775d5bcb8bec1c12John Reck    public String toString() {
200452be4785a258687055515117775d5bcb8bec1c12John Reck        StringBuilder builder = new StringBuilder(100);
200552be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(mId);
200652be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(") has parent: ");
200752be4785a258687055515117775d5bcb8bec1c12John Reck        if (getParent() != null) {
200852be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("true[");
200952be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getParent().getId());
201052be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("]");
201152be4785a258687055515117775d5bcb8bec1c12John Reck        } else {
201252be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("false");
201352be4785a258687055515117775d5bcb8bec1c12John Reck        }
201452be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(", incog: ");
201552be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(isPrivateBrowsingEnabled());
201652be4785a258687055515117775d5bcb8bec1c12John Reck        if (!isPrivateBrowsingEnabled()) {
201752be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(", title: ");
201852be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getTitle());
201952be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(", url: ");
202052be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getUrl());
202152be4785a258687055515117775d5bcb8bec1c12John Reck        }
202252be4785a258687055515117775d5bcb8bec1c12John Reck        return builder.toString();
202352be4785a258687055515117775d5bcb8bec1c12John Reck    }
202452be4785a258687055515117775d5bcb8bec1c12John Reck
20254895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block    private void handleProceededAfterSslError(SslError error) {
20264895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        if (error.getUrl().equals(mCurrentState.mUrl)) {
20274895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            // The security state should currently be SECURITY_STATE_SECURE.
20284895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            setSecurityState(SecurityState.SECURITY_STATE_BAD_CERTIFICATE);
202908a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            mCurrentState.mSslCertificateError = error;
20304895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        } else if (getSecurityState() == SecurityState.SECURITY_STATE_SECURE) {
203108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            // The page's main resource is secure and this error is for a
203208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            // sub-resource.
20334895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            setSecurityState(SecurityState.SECURITY_STATE_MIXED);
20344895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        }
20354895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block    }
203622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
2037