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;
49531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurunimport android.webkit.ClientCertRequest;
50c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
51934dfe5246cd151ffd60eb6277088f58f657b81cTao Baiimport android.webkit.CookieManager;
5222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
53e1b6b3b2f9c0dbf201234162101023770835df9eTao Baiimport android.webkit.GeolocationPermissions.Callback;
5422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
55e1b6b3b2f9c0dbf201234162101023770835df9eTao Baiimport android.webkit.PermissionRequest;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
5822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
596c2e2f34718043f36488b4a94879dc2605aaac49John Reckimport android.webkit.WebBackForwardList;
6022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
614d59434c396e3d414ed4266103d6990a340331e1Selim Gurunimport android.webkit.WebChromeClient.FileChooserParams;
6222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
63438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport android.webkit.WebResourceResponse;
6422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
6522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
669ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.webkit.WebView.PictureListener;
6722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
681d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdochimport android.widget.CheckBox;
698029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
7022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
718ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reckimport com.android.browser.TabControl.OnThumbnailUpdatedListener;
72541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.browser.homepages.HomeProvider;
738cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots;
74541f55a0178da7c09fb32aa5385effae031ea071John Reck
756243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurunimport java.io.ByteArrayInputStream;
76541f55a0178da7c09fb32aa5385effae031ea071John Reckimport java.io.ByteArrayOutputStream;
772b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.io.File;
7868234a9351dfca2e68769de46e60d22ec2f03818John Reckimport java.io.IOException;
792b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.io.OutputStream;
801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport java.nio.ByteBuffer;
81531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurunimport java.security.Principal;
82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
83fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
842b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.util.UUID;
85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
86a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwoodimport java.util.regex.Pattern;
878cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.util.zip.GZIPOutputStream;
88fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
8922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
9022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
9122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
929ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbclass Tab implements PictureListener {
938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
9522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
961dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
97c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
98c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
99c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
100c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
101c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1029ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private static final int MSG_CAPTURE = 42;
1038ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck    private static final int CAPTURE_DELAY = 100;
104a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb    private static final int INITIAL_PROGRESS = 5;
1059ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1066243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun    private static final String RESTRICTED = "<html><body>not allowed</body></html>";
1076243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun
1081cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static Bitmap sDefaultFavicon;
1091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
110a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    private static Paint sAlphaPaint = new Paint();
111a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    static {
112a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        sAlphaPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
113a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        sAlphaPaint.setColor(Color.TRANSPARENT);
114a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb    }
115a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb
1162466effd6ef97aa17396c214d51f9f19a4760260Steve Block    public enum SecurityState {
1174895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource does not use SSL. Note that we use this
1184895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // state irrespective of the SSL authentication state of sub-resources.
1192466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_NOT_SECURE,
1204895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL and the certificate is good. The
1214895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // same is true of all sub-resources.
1222466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_SECURE,
1234895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL and the certificate is good, but
1244895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // some sub-resources either do not use SSL or have problems with their
1254895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // certificates.
1262466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SECURITY_STATE_MIXED,
1274895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // The page's main resource uses SSL but there is a problem with its
1284895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        // certificate.
1294895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        SECURITY_STATE_BAD_CERTIFICATE,
13030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
1318233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1321461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    Context mContext;
133d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected WebViewController mWebViewController;
1348233facddcc51865d612a919d450db6954aa48e3Michael Kolb
135c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    // The tab ID
136d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private long mId = -1;
137c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
13922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
140e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai    // The permissions prompt
141e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai    private PermissionsPrompt mPermissionsPrompt;
14222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
143a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
14422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
14522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
14622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
14722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
14822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
14922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
15022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
15122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
15222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
15322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
15522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
156c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Tab mParent;
15722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
15822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
159c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Vector<Tab> mChildren;
16022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
16122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1638233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
16538b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck    private boolean mDisableOverrideUrlLoading;
16630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
16730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1684dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1694dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
17022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
17122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
17222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
173e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    // flag to indicate if tab should be closed on back
174e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    private boolean mCloseOnBack;
17522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
17622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
17722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
17822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
179dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
180dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
1810b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun    private final BrowserDownloadListener mDownloadListener;
1820c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1830c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
184e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController mDataController;
1859206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // State of the auto-login request.
1869206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private DeviceAccountLogin mDeviceAccountLogin;
18722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
18822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
18922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
19022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
19135e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck    private BrowserSettings mSettings;
1929ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureWidth;
1939ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureHeight;
1949ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Bitmap mCapture;
1959ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Handler mHandler;
1967286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb    private boolean mUpdateThumbnail;
1979ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1981dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
1999ad1eac377ffa6ffd34afae4c6580b7ba7508c31Mathew Inwood     * See {@link #clearBackStackWhenItemAdded(String)}.
2001dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
201a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood    private Pattern mClearHistoryUrlPattern;
2021dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
2031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static synchronized Bitmap getDefaultFavicon(Context context) {
2041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (sDefaultFavicon == null) {
2051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            sDefaultFavicon = BitmapFactory.decodeResource(
2061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    context.getResources(), R.drawable.app_web_browser_sm);
2071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
2081cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return sDefaultFavicon;
2091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
210eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
21130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
212d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected static class PageState {
21330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
214db22ec4ee014900988062d910bc810172a07df56John Reck        String mOriginalUrl;
21530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
2162466effd6ef97aa17396c214d51f9f19a4760260Steve Block        SecurityState mSecurityState;
21708a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        // This is non-null only when mSecurityState is SECURITY_STATE_BAD_CERTIFICATE.
21808a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        SslError mSslCertificateError;
21930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
22008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        boolean mIsBookmarkedSite;
22108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        boolean mIncognito;
22230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
22330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
224502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
225502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            if (mIncognito) {
226db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "browser:incognito";
22730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
22830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
229db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "";
23030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
23130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2322466effd6ef97aa17396c214d51f9f19a4760260Steve Block            mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
23330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
23430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
23530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
236502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
237db22ec4ee014900988062d910bc810172a07df56John Reck            mOriginalUrl = mUrl = url;
23830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
2392466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mSecurityState = SecurityState.SECURITY_STATE_SECURE;
24030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
2412466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
24230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mFavicon = favicon;
24430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
2451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
24622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
24722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
24830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
249d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected PageState mCurrentState;
25030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
25122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
252c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    static final String ID = "ID";
25322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
25422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
25522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
25622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
2573d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
258b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck    static final String USERAGENT = "useragent";
259e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    static final String CLOSEFLAG = "closeOnBack";
26022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
26122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
26222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
26322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
26422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
26522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
26622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
26722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
26822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
26922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
27022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
2718233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
27222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
27322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
27422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
27522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
27822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
27922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
28022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
28122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
28322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
28422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
28722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
28822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
28922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
29022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
29122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
29222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
29322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
29422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
29522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
29622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
29722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
29822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
29922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
30022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
30122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
30222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
30322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
30422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
30522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
30622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
30722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
30822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
30922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
31022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
31122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
31222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
31322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
31422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
31522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
31622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
31722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
31822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
3191461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog d = new AlertDialog.Builder(mContext)
32022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
32122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
32222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
32322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
32422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
32522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
32622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
32722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
32822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
32922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
33022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
33122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
33222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
333f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon    private final WebViewClient mWebViewClient = new WebViewClient() {
3344a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
3354a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
33647bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb
33747bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb        private boolean providersDiffer(String url, String otherUrl) {
33847bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            Uri uri1 = Uri.parse(url);
33947bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            Uri uri2 = Uri.parse(otherUrl);
34047bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb            return !uri1.getEncodedAuthority().equals(uri2.getEncodedAuthority());
34147bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb        }
34247bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb
34322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
34422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
3458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
3467286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb            mUpdateThumbnail = true;
347a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mPageLoadProgress = INITIAL_PROGRESS;
3481461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext,
34930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
3504dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
35122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
35222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
35322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
35422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
35522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
35622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
35722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
35822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
35922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
36022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
36122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
36222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
3638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
36422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
36522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
36622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
36722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3689206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            // Cancel the auto-login process.
3699206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (mDeviceAccountLogin != null) {
3709206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin.cancel();
3719206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin = null;
3729206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebViewController.hideAutoLogin(Tab.this);
3739206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
3749206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
37522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
376324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageStarted(Tab.this, view, favicon);
3774cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
378e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
37922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
38022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
38122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
38222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
38338b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck            mDisableOverrideUrlLoading = false;
3845b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
3855b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
3865b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
3875b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
3881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            syncCurrentState(view, url);
389324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageFinished(Tab.this);
39022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
39122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
39222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
39322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
39422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
39538b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck            if (!mDisableOverrideUrlLoading && mInForeground) {
39618eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
39718eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
39822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
39922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
40022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
40122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
40222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
40322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
4042466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * Updates the security state. This method is called when we discover
4052466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * another resource to be loaded for this page (for example,
4062466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * javascript). While we update the security state, we do not update
4072466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * the lock icon until we are done loading, as it is slightly more
4082466effd6ef97aa17396c214d51f9f19a4760260Steve Block         * secure this way.
40922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
41022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
41122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
41222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
41322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
4142466effd6ef97aa17396c214d51f9f19a4760260Steve Block                // to update the security state:
4152466effd6ef97aa17396c214d51f9f19a4760260Steve Block                if (mCurrentState.mSecurityState == SecurityState.SECURITY_STATE_SECURE) {
4162466effd6ef97aa17396c214d51f9f19a4760260Steve Block                    // If NOT a 'safe' url, change the state to mixed content!
41722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
41822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
4192466effd6ef97aa17396c214d51f9f19a4760260Steve Block                        mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_MIXED;
42022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
42122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
42222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
42322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
42422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
42522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
42622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
42722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
42822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
42922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
43022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
43122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
43222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
43322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
43422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
43522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
43622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
43722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
43847654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
4393da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                // Don't log URLs when in private browsing mode
4403da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                if (!isPrivateBrowsingEnabled()) {
4413da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                    Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
44247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
4433da06b83df87c0dc4fd173b86c60fdccd3174cd6Selim Gurun                }
44447654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
44522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
44622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
44722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
44822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
44922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
45022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
45122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
45222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
45322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
45522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
45622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
45722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
4584a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
4594a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
4604a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
4614a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
4624a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
4634a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
4644a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
4654a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
4661461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new AlertDialog.Builder(mContext).setTitle(
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
4734a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
4744a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
4754a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
4764a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
4774a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
4834a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
4844a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
4854a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
4864a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
4874a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
4914a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
4924a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
4934a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
4944a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
4954a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
50822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
509324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.doUpdateVisitedHistory(Tab.this, isReload);
51022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
51122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
51322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
51422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
51522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
5202466effd6ef97aa17396c214d51f9f19a4760260Steve Block                setSecurityState(SecurityState.SECURITY_STATE_NOT_SECURE);
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
52335e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            if (mSettings.showSecurityWarnings()) {
524cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                new AlertDialog.Builder(mContext)
525cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setTitle(R.string.security_warning)
526cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setMessage(R.string.ssl_warnings_header)
5272aa8ba254d128ca75f97a62b8d48d1305183e93cBjörn Lundén                    .setIconAttribute(android.R.attr.alertDialogIcon)
528cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setPositiveButton(R.string.ssl_continue,
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
530cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
5344895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block                                handleProceededAfterSslError(error);
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
536cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
537cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setNeutralButton(R.string.view_certificate,
53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
539cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
54122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
542cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                                mWebViewController.showSslCertificateOnError(
543cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                                        view, handler, error);
54422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
545cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
546cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setNegativeButton(R.string.ssl_go_back,
54722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
548cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
55022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
55130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
55222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
553cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
554cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .setOnCancelListener(
55522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
556cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                            @Override
55722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
55822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
5592466effd6ef97aa17396c214d51f9f19a4760260Steve Block                                setSecurityState(SecurityState.SECURITY_STATE_NOT_SECURE);
56030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
56122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
562cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                        })
563cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck                    .show();
56422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
56522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
56822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
569531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        /**
570531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun         * Displays client certificate request to the user.
571531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun         */
572531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        @Override
573531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        public void onReceivedClientCertRequest(final WebView view,
574531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                final ClientCertRequest request) {
575531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun            if (!mInForeground) {
576531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                request.ignore();
577531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                return;
578531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun            }
579531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun            KeyChain.choosePrivateKeyAlias(
580531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                    mWebViewController.getActivity(), new KeyChainAliasCallback() {
581531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                @Override public void alias(String alias) {
582531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                    if (alias == null) {
583531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                        request.cancel();
584531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                        return;
585531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                    }
586531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                    new KeyChainLookup(mContext, request, alias).execute();
587531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                }
588531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun            }, request.getKeyTypes(), request.getPrincipals(), request.getHost(),
589531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun                request.getPort(), null);
590531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        }
591531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun
592f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon       /**
59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
59422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
59722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
59822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
59922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
60022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
60122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
6038233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
60522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
607438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        public WebResourceResponse shouldInterceptRequest(WebView view,
608438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                String url) {
6096243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun            Uri uri = Uri.parse(url);
6106243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun            if (uri.getScheme().toLowerCase().equals("file")) {
6116243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                File file = new File(uri.getPath());
6126243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                try {
6136243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                    if (file.getCanonicalPath().startsWith(
614d2391b492dec778452238bc6d9d549d56d41c107Selim Gurun                            mContext.getApplicationContext().getApplicationInfo().dataDir)) {
6156243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                        return new WebResourceResponse("text/html","UTF-8",
6166243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                                new ByteArrayInputStream(RESTRICTED.getBytes("UTF-8")));
6176243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                    }
6186243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                } catch (Exception ex) {
6196243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                    Log.e(LOGTAG, "Bad canonical path" + ex.toString());
6206243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                    try {
6216243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                        return new WebResourceResponse("text/html","UTF-8",
6226243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                                new ByteArrayInputStream(RESTRICTED.getBytes("UTF-8")));
6236243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                    } catch (java.io.UnsupportedEncodingException e) {
6246243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                    }
6256243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun                }
6266243e7cb0eb836af28b23a2e00d89627b90496e4Selim Gurun            }
627438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
6281461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mContext, url);
629438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            return res;
630438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        }
631438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck
632438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        @Override
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6378233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
6428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
645997b1b7695822cb2dc2deca0458a5649d00b9953John Reck            if (!mWebViewController.onUnhandledKeyEvent(event)) {
646997b1b7695822cb2dc2deca0458a5649d00b9953John Reck                super.onUnhandledKeyEvent(view, event);
647997b1b7695822cb2dc2deca0458a5649d00b9953John Reck            }
64822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
6499206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
6509206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        @Override
6519206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void onReceivedLoginRequest(WebView view, String realm,
6529206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                String account, String args) {
6531461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new DeviceAccountLogin(mWebViewController.getActivity(), view, Tab.this, mWebViewController)
6549206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    .handleLogin(realm, account, args);
6559206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
6569206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
6591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void syncCurrentState(WebView view, String url) {
6601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        // Sync state (in case of stop/timeout)
6611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mUrl = view.getUrl();
6621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mUrl == null) {
6638bcafc149bc49b84c8dfbaacf88c178d8bc9eda6John Reck            mCurrentState.mUrl = "";
6641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
6651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mOriginalUrl = view.getOriginalUrl();
6661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = view.getTitle();
6671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mFavicon = view.getFavicon();
6681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
6691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // In case we stop when loading an HTTPS page from an HTTP page
6701cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // but before a provisional load occurred
6712466effd6ef97aa17396c214d51f9f19a4760260Steve Block            mCurrentState.mSecurityState = SecurityState.SECURITY_STATE_NOT_SECURE;
67208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            mCurrentState.mSslCertificateError = null;
6731cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
674502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        mCurrentState.mIncognito = view.isPrivateBrowsingEnabled();
6751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
6761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
6779206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
6789206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // displayed.
6799206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    void setDeviceAccountLogin(DeviceAccountLogin login) {
6809206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mDeviceAccountLogin = login;
6819206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
6829206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
6839206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Returns non-null if the title bar should display the auto-login UI.
6849206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    DeviceAccountLogin getDeviceAccountLogin() {
6859206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mDeviceAccountLogin;
6869206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
6879206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
68822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
69522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
69622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
6998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
7027bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                final Tab newTab = mWebViewController.openTab(null,
7035949c661b51295148706d53a03b41df2eb840ae3John Reck                        Tab.this, true, true);
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
70522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
70622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
70722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
71322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
71422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
71522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
71622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
71722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
7181461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
7202aa8ba254d128ca75f97a62b8d48d1305183e93cBjörn Lundén                        .setIconAttribute(android.R.attr.alertDialogIcon)
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
7258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
7261461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
7282aa8ba254d128ca75f97a62b8d48d1305183e93cBjörn Lundén                        .setIconAttribute(android.R.attr.alertDialogIcon)
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
7601461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new AlertDialog.Builder(mContext)
7612aa8ba254d128ca75f97a62b8d48d1305183e93cBjörn Lundén                    .setIconAttribute(android.R.attr.alertDialogIcon)
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
774eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
775eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
776c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mWebViewController.switchToTab(Tab.this);
777eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
778eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
779eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
780eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
782c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            if (mParent != null) {
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
785c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                    mWebViewController.switchToTab(mParent);
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
7878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
79330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
794b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb            if (newProgress == 100) {
795b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb                mInPageLoad = false;
796b1fb70cee9e24f3f9e648dff1816403c427976d1Michael Kolb            }
79730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
7987286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb            if (mUpdateThumbnail && newProgress == 100) {
7997286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb                mUpdateThumbnail = false;
8007286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb            }
80122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
80421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
80530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
8068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
81022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
81130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
8128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
81622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
8181461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            final ContentResolver cr = mContext.getContentResolver();
819c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
820c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
821c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
822c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
823c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
824c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
825c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
826c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
8278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
8281461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                        mContext, cr, view);
829c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
83022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
83122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
83222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
83322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
83422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
83522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
8361461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            Activity activity = mWebViewController.getActivity();
8371461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            if (activity != null) {
8381461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                onShowCustomView(view, activity.getRequestedOrientation(), callback);
8391461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            }
8402d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        }
8412d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger
8422d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        @Override
8432d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        public void onShowCustomView(View view, int requestedOrientation,
8442d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                WebChromeClient.CustomViewCallback callback) {
8458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
8462d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                    requestedOrientation, callback);
84722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
8518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
85222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
85322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
85422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
85522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
85622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
85722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
85822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
86935e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
87322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
87422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
87722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
87822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
88022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
88522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
88835e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
89022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
89522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
89622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
89722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
89822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
89922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
90022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
90222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
90422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
90550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
90622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
90822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
90922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
91022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
91222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
91322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
91450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
91522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
91822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
919e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        @Override
920e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        public void onPermissionRequest(PermissionRequest request) {
921e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            if (!mInForeground) return;
922e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            getPermissionsPrompt().show(request);
923e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        }
924e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai
925e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        @Override
926e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        public void onPermissionRequestCanceled(PermissionRequest request) {
927e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            if (mInForeground && mPermissionsPrompt != null) {
928e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai                mPermissionsPrompt.hide();
929e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            }
930e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        }
931e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai
93265acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
93365acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
93465acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
935c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
938c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
94122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
942c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
9438233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
9448233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
9458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
94722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
94822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
949c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
95047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
951f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
95247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
953c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
954c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
955c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
956c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
957c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
958c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
959c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
960c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
961c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
962c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
963c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
964c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
965c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
966c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
967c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
968c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
969c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
970c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
971c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
972c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
973c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
974c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
975c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
9868233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
9998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
100579ff1e36c4660c532fd8e5f4ab264e967fe308d0Selim Gurun        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> callback,
10064d59434c396e3d414ed4266103d6990a340331e1Selim Gurun            FileChooserParams params) {
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
10084d59434c396e3d414ed4266103d6990a340331e1Selim Gurun                mWebViewController.showFileChooser(callback, params);
10094d59434c396e3d414ed4266103d6990a340331e1Selim Gurun                return true;
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
10114d59434c396e3d414ed4266103d6990a340331e1Selim Gurun                return false;
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
10208233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
10218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
10228029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
102322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
102422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
102622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
1031f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon    private static class SubWindowClient extends WebViewClient {
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
1033f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon        private final WebViewClient mClient;
10348233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1036f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon        SubWindowClient(WebViewClient client, WebViewController controller) {
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
10388233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1039211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1040211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1041211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1042211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1043211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
104401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
10458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
105122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
105822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
105922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
106022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1062531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
1063531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun            mClient.onReceivedClientCertRequest(view, request);
1064531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        }
1065531ac8b4732d9bfaa0de89be888511e6db03c1cbSelim Gurun        @Override
106622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
106722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
106822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
106922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
108122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
108322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
108722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
109122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
110622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
110722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
11178233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
11247bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    Tab(WebViewController wvcontroller, WebView w) {
11251cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, w, null);
11261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
11271cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
11281cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, Bundle state) {
11291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, null, state);
11301cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
11311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
11321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, WebView w, Bundle state) {
11338233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
11341461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mContext = mWebViewController.getContext();
113535e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck        mSettings = BrowserSettings.getInstance();
11361461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mDataController = DataController.getInstance(mContext);
11371461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mCurrentState = new PageState(mContext, w != null
1138847b532045e3cb117a847ebb956c9919401f332dJohn Reck                ? w.isPrivateBrowsingEnabled() : false);
11398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
114022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11420b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun        mDownloadListener = new BrowserDownloadListener() {
1143dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
11440b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun                    String contentDisposition, String mimetype, String referer,
1145dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
11468233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
11470b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun                        mimetype, referer, contentLength);
1148dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1149dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
11500c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
11510c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
11520c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
1153a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                if (mClearHistoryUrlPattern != null) {
1154a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    boolean match =
1155a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                        mClearHistoryUrlPattern.matcher(item.getOriginalUrl()).matches();
11561dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    if (LOGD_ENABLED) {
1157a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                        Log.d(LOGTAG, "onNewHistoryItem: match=" + match + "\n\t"
1158a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                                + item.getUrl() + "\n\t"
1159a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                                + mClearHistoryUrlPattern);
11601dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
1161a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    if (match) {
11621dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        if (mMainView != null) {
11631dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                            mMainView.clearHistory();
11641dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        }
11651dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
1166a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood                    mClearHistoryUrlPattern = null;
11671dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                }
11680c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
11690c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1170dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
11711cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureWidth = mContext.getResources().getDimensionPixelSize(
11721cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_width);
11731cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureHeight = mContext.getResources().getDimensionPixelSize(
11741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_height);
11751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
11761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        restoreState(state);
117752be4785a258687055515117775d5bcb8bec1c12John Reck        if (getId() == -1) {
117852be4785a258687055515117775d5bcb8bec1c12John Reck            mId = TabControl.getNextId();
117952be4785a258687055515117775d5bcb8bec1c12John Reck        }
118022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
11819ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        mHandler = new Handler() {
11821dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood            @Override
11839ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            public void handleMessage(Message m) {
11841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                switch (m.what) {
11851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                case MSG_CAPTURE:
11861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    capture();
11871cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    break;
11881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
11899ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            }
11909ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        };
11911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
11929ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
11937286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb    public boolean shouldUpdateThumbnail() {
11947286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb        return mUpdateThumbnail;
11957286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb    }
11967286427ee44435acf5f0ccd1146d9d0b15a36d02Michael Kolb
1197e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    /**
1198e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * This is used to get a new ID when the tab has been preloaded, before it is displayed and
1199e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * added to TabControl. Preloaded tabs can be created before restoreInstanceState, leading
1200e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     * to overlapping IDs between the preloaded and restored tabs.
1201e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood     */
1202e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    public void refreshIdAfterPreload() {
1203e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood        mId = TabControl.getNextId();
1204e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood    }
1205e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood
12061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public void updateShouldCaptureThumbnails() {
12071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mWebViewController.shouldCaptureThumbnails()) {
12081cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
12091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                if (mCapture == null) {
12101cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    mCapture = Bitmap.createBitmap(mCaptureWidth, mCaptureHeight,
12111cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                            Bitmap.Config.RGB_565);
1212c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolb                    mCapture.eraseColor(Color.WHITE);
12131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    if (mInForeground) {
12141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        postCapture();
12151cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    }
12161cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
12171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
12181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        } else {
12191cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
12201cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCapture = null;
12211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                deleteThumbnail();
12221cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
12231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12261461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    public void setController(WebViewController ctl) {
12271461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mWebViewController = ctl;
12281cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
12291461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    }
12301461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb
1231c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public long getId() {
1232c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mId;
1233c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1234c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
123591911a26058418e622950cffc616f99ada49df1dMichael Kolb    void setWebView(WebView w) {
123691911a26058418e622950cffc616f99ada49df1dMichael Kolb        setWebView(w, true);
123791911a26058418e622950cffc616f99ada49df1dMichael Kolb    }
123891911a26058418e622950cffc616f99ada49df1dMichael Kolb
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
124391911a26058418e622950cffc616f99ada49df1dMichael Kolb    void setWebView(WebView w, boolean restore) {
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1247a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
124822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
124922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
125050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
125150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
125250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
125322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1254e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        if (mPermissionsPrompt != null) {
1255e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            mPermissionsPrompt.hide();
1256e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        }
1257e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai
1258a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mMainView != null) {
12618ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.setPictureListener(null);
12621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (w != null) {
12631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                syncCurrentState(w, null);
12641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            } else {
12651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCurrentState = new PageState(mContext, false);
12661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
12671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
126822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
126922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1270dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
127122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
127222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
127322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1274dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1275dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1276dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1277dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1278dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
12798ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            TabControl tc = mWebViewController.getTabControl();
12808ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (tc != null && tc.getOnThumbnailUpdatedListener() != null) {
12818ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                mMainView.setPictureListener(this);
12828ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
128391911a26058418e622950cffc616f99ada49df1dMichael Kolb            if (restore && (mSavedState != null)) {
12848b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck                restoreUserAgent();
12856c2e2f34718043f36488b4a94879dc2605aaac49John Reck                WebBackForwardList restoredState
12866c2e2f34718043f36488b4a94879dc2605aaac49John Reck                        = mMainView.restoreState(mSavedState);
12876c2e2f34718043f36488b4a94879dc2605aaac49John Reck                if (restoredState == null || restoredState.getSize() == 0) {
12886c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    Log.w(LOGTAG, "Failed to restore WebView state!");
12896c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    loadUrl(mCurrentState.mOriginalUrl, null);
12906c2e2f34718043f36488b4a94879dc2605aaac49John Reck                }
12911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mSavedState = null;
12921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
129322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
129722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
129822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
129922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
130022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
130122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
130222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
130322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
130422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
130622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
130722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
130822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
130922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
131022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
131122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
131222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
131322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
1314c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren != null) {
1315c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            for(Tab t : mChildren) {
1316c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                t.setParent(null);
131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
131822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
1320c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1321c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mParent.mChildren.remove(this);
132222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
13231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        deleteThumbnail();
132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
132522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
132922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
13321514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1333211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
13348233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1337dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1338dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
13390b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun            mSubView.setDownloadListener(new BrowserDownloadListener() {
1340dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
13410b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun                        String contentDisposition, String mimetype, String referer,
1342dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
13438233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
13440b3d66fc2275fb5270cb7166cc991be7dc9d8ff7Selim Gurun                            contentDisposition, mimetype, referer, contentLength);
1345dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1346dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1347dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
13488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1349dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1350dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1351dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
13521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(mWebViewController.getActivity());
135322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
136022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
136122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
136222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
13638233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
136422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
136522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
137122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
1374c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    void setParent(Tab parent) {
137552be4785a258687055515117775d5bcb8bec1c12John Reck        if (parent == this) {
137652be4785a258687055515117775d5bcb8bec1c12John Reck            throw new IllegalStateException("Cannot set parent to self!");
137752be4785a258687055515117775d5bcb8bec1c12John Reck        }
1378c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mParent = parent;
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
1380c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // the parent tab id is already saved. If we are changing that id
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
1382c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // parent tab id in the saved Bundle.
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
138422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
138622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
1387c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mSavedState.putLong(PARENTTAB, parent.getId());
138822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
138922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1390b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck
1391b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        // Sync the WebView useragent with the parent
1392b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        if (parent != null && mSettings.hasDesktopUseragent(parent.getWebView())
1393b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                != mSettings.hasDesktopUseragent(getWebView())) {
1394b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck            mSettings.toggleDesktopUseragent(getWebView());
1395b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        }
139652be4785a258687055515117775d5bcb8bec1c12John Reck
139752be4785a258687055515117775d5bcb8bec1c12John Reck        if (parent != null && parent.getId() == getId()) {
139852be4785a258687055515117775d5bcb8bec1c12John Reck            throw new IllegalStateException("Parent has same ID as child!");
139952be4785a258687055515117775d5bcb8bec1c12John Reck        }
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
140222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1403c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * If this Tab was created through another Tab, then this method returns
1404c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * that Tab.
1405c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * @return the Tab parent or null
1406c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     */
1407c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public Tab getParent() {
1408c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mParent;
1409c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1410c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
1411c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    /**
141222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
141322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
141422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
141522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
141622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
1417c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren == null) {
1418c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mChildren = new Vector<Tab>();
141922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1420c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mChildren.add(child);
1421c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        child.setParent(this);
142222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1424c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    Vector<Tab> getChildren() {
1425c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mChildren;
142622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
142722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
142822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
142922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
143056c1fcf7774d4ee943fbda808e37840459502e20John Reck            setupHwAcceleration(mMainView);
143122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
143222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
143322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
143422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
143522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
143622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
143722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
143856c1fcf7774d4ee943fbda808e37840459502e20John Reck    private void setupHwAcceleration(View web) {
143956c1fcf7774d4ee943fbda808e37840459502e20John Reck        if (web == null) return;
144056c1fcf7774d4ee943fbda808e37840459502e20John Reck        BrowserSettings settings = BrowserSettings.getInstance();
144156c1fcf7774d4ee943fbda808e37840459502e20John Reck        if (settings.isHardwareAccelerated()) {
144256c1fcf7774d4ee943fbda808e37840459502e20John Reck            web.setLayerType(View.LAYER_TYPE_NONE, null);
144356c1fcf7774d4ee943fbda808e37840459502e20John Reck        } else {
144456c1fcf7774d4ee943fbda808e37840459502e20John Reck            web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
144556c1fcf7774d4ee943fbda808e37840459502e20John Reck        }
144656c1fcf7774d4ee943fbda808e37840459502e20John Reck    }
144756c1fcf7774d4ee943fbda808e37840459502e20John Reck
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
144922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
145022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
145122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
145222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
145322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
145422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
145522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
145622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
145722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
14588ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mInForeground) {
14598ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
14608ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
146122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
146222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
14631461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        Activity activity = mWebViewController.getActivity();
14641461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mMainView.setOnCreateContextMenuListener(activity);
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
14661461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(activity);
146722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
146822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
146922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
147022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
147122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
14721961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
147322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
14768ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (!mInForeground) {
14778ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
14788ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
147952be4785a258687055515117775d5bcb8bec1c12John Reck        capture();
148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
148122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
148422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
148722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
14898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
14908233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
14918233facddcc51865d612a919d450db6954aa48e3Michael Kolb
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
150222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
150322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
150722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
150822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
150922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
151022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
151122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
151222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
151322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1514a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1515a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1516a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1517a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
15188233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
15198233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
15208233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15218233facddcc51865d612a919d450db6954aa48e3Michael Kolb
152222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1523f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1524f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1525f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1526f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
15278233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1528502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        return mCurrentState.mIncognito;
1529f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1530f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1531f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
153222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
153322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
153422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
153522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
153622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15391514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
15401514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
15411514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15421514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
15438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
15448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
15458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15468233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15471514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
15481514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
15491514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
15501514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
155122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
155222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
155322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
155422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
155550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
155650c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
155750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
155850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
155950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
156050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1565e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai     * @return The permissions prompt for this tab.
1566e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai     */
1567e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai    PermissionsPrompt getPermissionsPrompt() {
1568e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        if (mPermissionsPrompt == null) {
1569e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            ViewStub stub = (ViewStub) mContainer
1570e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai                    .findViewById(R.id.permissions_prompt);
1571e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai            mPermissionsPrompt = (PermissionsPrompt) stub.inflate();
1572e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        }
1573e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai        return mPermissionsPrompt;
1574e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai    }
1575e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai
1576e1b6b3b2f9c0dbf201234162101023770835df9eTao Bai    /**
157722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
157822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
158022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
158122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
158222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
158322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
158422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
158522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
158622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
158722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
158822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
159022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1591e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    boolean closeOnBack() {
1592e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        return mCloseOnBack;
1593e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1594e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
1595e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    void setCloseOnBack(boolean close) {
1596e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = close;
1597e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1598e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
1600324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        return UrlUtils.filteredUrl(mCurrentState.mUrl);
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160349a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    String getOriginalUrl() {
1604db22ec4ee014900988062d910bc810172a07df56John Reck        if (mCurrentState.mOriginalUrl == null) {
1605db22ec4ee014900988062d910bc810172a07df56John Reck            return getUrl();
160649a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        }
1607db22ec4ee014900988062d910bc810172a07df56John Reck        return UrlUtils.filteredUrl(mCurrentState.mOriginalUrl);
160849a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    }
160949a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
161130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
161430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
16151461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            return mContext.getString(R.string.title_bar_loading);
161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
161730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
161822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
162130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
16241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mFavicon != null) {
16251cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCurrentState.mFavicon;
16261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
16271cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return getDefaultFavicon(mContext);
162822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1630e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1631e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1632e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1633f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
163422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
163522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
163822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
163922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
164022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
164122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
164222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
164322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
16441461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mErrorConsole = new ErrorConsoleView(mContext);
164522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
164622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
164722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
165008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    /**
165108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * Sets the security state, clears the SSL certificate error and informs
165208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * the controller.
165308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     */
16542466effd6ef97aa17396c214d51f9f19a4760260Steve Block    private void setSecurityState(SecurityState securityState) {
16552466effd6ef97aa17396c214d51f9f19a4760260Steve Block        mCurrentState.mSecurityState = securityState;
165608a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        mCurrentState.mSslCertificateError = null;
16572466effd6ef97aa17396c214d51f9f19a4760260Steve Block        mWebViewController.onUpdatedSecurityState(this);
165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
16612466effd6ef97aa17396c214d51f9f19a4760260Steve Block     * @return The tab's security state.
166222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16632466effd6ef97aa17396c214d51f9f19a4760260Steve Block    SecurityState getSecurityState() {
16642466effd6ef97aa17396c214d51f9f19a4760260Steve Block        return mCurrentState.mSecurityState;
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166708a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    /**
166808a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * Gets the SSL certificate error, if any, for the page's main resource.
166908a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * This is only non-null when the security state is
167008a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     * SECURITY_STATE_BAD_CERTIFICATE.
167108a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block     */
167208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    SslError getSslCertificateError() {
167308a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        return mCurrentState.mSslCertificateError;
167408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block    }
167508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block
167630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
167730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
167830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
167930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
168030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
168422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
168522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16878233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
16888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
169022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
169122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
16921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck     * @return The Bundle with the tab's state if it can be saved, otherwise null
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
16941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public Bundle saveState() {
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
16981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mSavedState;
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
17006c2e2f34718043f36488b4a94879dc2605aaac49John Reck
17016c2e2f34718043f36488b4a94879dc2605aaac49John Reck        if (TextUtils.isEmpty(mCurrentState.mUrl)) {
17021cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return null;
170324f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        }
170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
17066c2e2f34718043f36488b4a94879dc2605aaac49John Reck        WebBackForwardList savedList = mMainView.saveState(mSavedState);
17076c2e2f34718043f36488b4a94879dc2605aaac49John Reck        if (savedList == null || savedList.getSize() == 0) {
17086c2e2f34718043f36488b4a94879dc2605aaac49John Reck            Log.w(LOGTAG, "Failed to save back/forward list for "
17096c2e2f34718043f36488b4a94879dc2605aaac49John Reck                    + mCurrentState.mUrl);
17106c2e2f34718043f36488b4a94879dc2605aaac49John Reck        }
171122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1712c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mSavedState.putLong(ID, mId);
171330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
171430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
17151cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState.putBoolean(INCOGNITO, mMainView.isPrivateBrowsingEnabled());
171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1719e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mSavedState.putBoolean(CLOSEFLAG, mCloseOnBack);
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
1721c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1722c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mSavedState.putLong(PARENTTAB, mParent.mId);
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1724b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        mSavedState.putBoolean(USERAGENT,
1725b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                mSettings.hasDesktopUseragent(getWebView()));
17261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return mSavedState;
172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
17321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void restoreState(Bundle b) {
17331cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState = b;
17341cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mSavedState == null) {
17351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return;
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
1739c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mId = b.getLong(ID);
174022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
1741e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = b.getBoolean(CLOSEFLAG);
17428b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        restoreUserAgent();
17431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String url = b.getString(CURRURL);
17441cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String title = b.getString(CURRTITLE);
17451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        boolean incognito = b.getBoolean(INCOGNITO);
17461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState = new PageState(mContext, incognito, url, null);
17471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = title;
17481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
17491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture != null) {
17504eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck                DataController.getInstance(mContext).loadThumbnail(this);
17511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
175322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1754211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
17558b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck    private void restoreUserAgent() {
17568b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        if (mMainView == null || mSavedState == null) {
17578b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck            return;
17588b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        }
17598b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        if (mSavedState.getBoolean(USERAGENT)
17608b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck                != mSettings.hasDesktopUseragent(mMainView)) {
17618b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck            mSettings.toggleDesktopUseragent(mMainView);
17628b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck        }
17638b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck    }
17648b9bb8bf4df182b43b4b7b9293bcb7b1d8a2f3aeJohn Reck
17651961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
1766e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
17671961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
17681961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
1769e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
1770e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
1771e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
1772e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
1773e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
1774e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
1775e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
17761961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
1777e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
1778e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
17791acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1780eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    public Bitmap getScreenshot() {
17811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
17821cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCapture;
17831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
1784eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    }
1785eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
1786541f55a0178da7c09fb32aa5385effae031ea071John Reck    public boolean isSnapshot() {
1787541f55a0178da7c09fb32aa5385effae031ea071John Reck        return false;
1788541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
1789541f55a0178da7c09fb32aa5385effae031ea071John Reck
179068234a9351dfca2e68769de46e60d22ec2f03818John Reck    private static class SaveCallback implements ValueCallback<Boolean> {
179168234a9351dfca2e68769de46e60d22ec2f03818John Reck        boolean mResult;
179268234a9351dfca2e68769de46e60d22ec2f03818John Reck
179368234a9351dfca2e68769de46e60d22ec2f03818John Reck        @Override
179468234a9351dfca2e68769de46e60d22ec2f03818John Reck        public void onReceiveValue(Boolean value) {
179568234a9351dfca2e68769de46e60d22ec2f03818John Reck            mResult = value;
179668234a9351dfca2e68769de46e60d22ec2f03818John Reck            synchronized (this) {
179768234a9351dfca2e68769de46e60d22ec2f03818John Reck                notifyAll();
179868234a9351dfca2e68769de46e60d22ec2f03818John Reck            }
179968234a9351dfca2e68769de46e60d22ec2f03818John Reck        }
180068234a9351dfca2e68769de46e60d22ec2f03818John Reck
180168234a9351dfca2e68769de46e60d22ec2f03818John Reck    }
180268234a9351dfca2e68769de46e60d22ec2f03818John Reck
180368234a9351dfca2e68769de46e60d22ec2f03818John Reck    /**
180468234a9351dfca2e68769de46e60d22ec2f03818John Reck     * Must be called on the UI thread
180568234a9351dfca2e68769de46e60d22ec2f03818John Reck     */
1806d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public ContentValues createSnapshotValues() {
1807f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon        return null;
180868234a9351dfca2e68769de46e60d22ec2f03818John Reck    }
180968234a9351dfca2e68769de46e60d22ec2f03818John Reck
181068234a9351dfca2e68769de46e60d22ec2f03818John Reck    /**
181168234a9351dfca2e68769de46e60d22ec2f03818John Reck     * Probably want to call this on a background thread
181268234a9351dfca2e68769de46e60d22ec2f03818John Reck     */
181368234a9351dfca2e68769de46e60d22ec2f03818John Reck    public boolean saveViewState(ContentValues values) {
1814f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon        return false;
1815541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
1816541f55a0178da7c09fb32aa5385effae031ea071John Reck
18178cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public byte[] compressBitmap(Bitmap bitmap) {
18188cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (bitmap == null) {
18198cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
18208cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
18218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        ByteArrayOutputStream stream = new ByteArrayOutputStream();
18228cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        bitmap.compress(CompressFormat.PNG, 100, stream);
18238cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return stream.toByteArray();
18248cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
18258cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
182626b183292dc087b16af10f482744c3bb30e1f163John Reck    public void loadUrl(String url, Map<String, String> headers) {
182726b183292dc087b16af10f482744c3bb30e1f163John Reck        if (mMainView != null) {
1828a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mPageLoadProgress = INITIAL_PROGRESS;
1829a53c98902be0f9f959b6af06227254e5ad2130c9Michael Kolb            mInPageLoad = true;
18301461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext, false, url, null);
183126b183292dc087b16af10f482744c3bb30e1f163John Reck            mWebViewController.onPageStarted(this, mMainView, null);
183226b183292dc087b16af10f482744c3bb30e1f163John Reck            mMainView.loadUrl(url, headers);
183326b183292dc087b16af10f482744c3bb30e1f163John Reck        }
183426b183292dc087b16af10f482744c3bb30e1f163John Reck    }
183526b183292dc087b16af10f482744c3bb30e1f163John Reck
183638b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck    public void disableUrlOverridingForLoad() {
183738b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck        mDisableOverrideUrlLoading = true;
183838b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck    }
183938b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck
18409ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    protected void capture() {
18419ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (mMainView == null || mCapture == null) return;
18424eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        if (mMainView.getContentWidth() <= 0 || mMainView.getContentHeight() <= 0) {
18434eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck            return;
18444eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        }
18459ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        Canvas c = new Canvas(mCapture);
18469ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int left = mMainView.getScrollX();
18479ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int top = mMainView.getScrollY() + mMainView.getVisibleTitleHeight();
1848a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        int state = c.save();
18499ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.translate(-left, -top);
18509ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        float scale = mCaptureWidth / (float) mMainView.getWidth();
18519ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.scale(scale, scale, left, top);
18528ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mMainView instanceof BrowserWebView) {
18538ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            ((BrowserWebView)mMainView).drawContent(c);
18548ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        } else {
18558ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.draw(c);
18568ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
1857a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.restoreToCount(state);
1858a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        // manually anti-alias the edges for the tilt
1859a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, 0, 1, mCapture.getHeight(), sAlphaPaint);
1860a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(mCapture.getWidth() - 1, 0, mCapture.getWidth(),
1861a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb                mCapture.getHeight(), sAlphaPaint);
1862a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, 0, mCapture.getWidth(), 1, sAlphaPaint);
1863a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb        c.drawRect(0, mCapture.getHeight() - 1, mCapture.getWidth(),
1864a3194d0b9c9c36be29598cac8faf8453cdaebe55Michael Kolb                mCapture.getHeight(), sAlphaPaint);
186543cfe8a4521b5c153055fbfa181940bc56bb3b06Dianne Hackborn        c.setBitmap(null);
18668ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        mHandler.removeMessages(MSG_CAPTURE);
18671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        persistThumbnail();
18688ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        TabControl tc = mWebViewController.getTabControl();
18698ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (tc != null) {
18708ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            OnThumbnailUpdatedListener updateListener
18718ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                    = tc.getOnThumbnailUpdatedListener();
18728ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (updateListener != null) {
18738ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                updateListener.onThumbnailUpdated(this);
18748ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
18758ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
18769ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
18779ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
18789ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    @Override
18799ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    public void onNewPicture(WebView view, Picture picture) {
18801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        postCapture();
18811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
18821cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
18831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void postCapture() {
18849ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (!mHandler.hasMessages(MSG_CAPTURE)) {
18859ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            mHandler.sendEmptyMessageDelayed(MSG_CAPTURE, CAPTURE_DELAY);
18869ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        }
18879ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
18889ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1889ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoBack() {
1890ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoBack() : false;
1891ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1892ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
1893ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoForward() {
1894ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoForward() : false;
1895ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1896ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
1897ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goBack() {
1898ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
1899ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goBack();
1900ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
1901ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1902ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
1903ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goForward() {
1904ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
1905ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goForward();
1906ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
1907ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
1908ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
19091dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
19101dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * Causes the tab back/forward stack to be cleared once, if the given URL is the next URL
19111dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * to be added to the stack.
19121dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     *
19131dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * This is used to ensure that preloaded URLs that are not subsequently seen by the user do
19141dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * not appear in the back stack.
19151dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
1916a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood    public void clearBackStackWhenItemAdded(Pattern urlPattern) {
1917a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood        mClearHistoryUrlPattern = urlPattern;
19181dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    }
19191dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
19201cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void persistThumbnail() {
19214eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        DataController.getInstance(mContext).saveThumbnail(this);
19221cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
19231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
19241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void deleteThumbnail() {
19254eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck        DataController.getInstance(mContext).deleteThumbnail(this);
19261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
19271cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
19284eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck    void updateCaptureFromBlob(byte[] blob) {
19291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
19301cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture == null) {
19311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                return;
19321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
1933bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            ByteBuffer buffer = ByteBuffer.wrap(blob);
1934d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            try {
1935d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                mCapture.copyPixelsFromBuffer(buffer);
1936d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            } catch (RuntimeException rex) {
1937d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                Log.e(LOGTAG, "Load capture has mismatched sizes; buffer: "
1938d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + buffer.capacity() + " blob: " + blob.length
1939d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + "capture: " + mCapture.getByteCount());
1940d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                throw rex;
1941bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            }
19421cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
19431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
19441cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
194552be4785a258687055515117775d5bcb8bec1c12John Reck    @Override
194652be4785a258687055515117775d5bcb8bec1c12John Reck    public String toString() {
194752be4785a258687055515117775d5bcb8bec1c12John Reck        StringBuilder builder = new StringBuilder(100);
194852be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(mId);
194952be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(") has parent: ");
195052be4785a258687055515117775d5bcb8bec1c12John Reck        if (getParent() != null) {
195152be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("true[");
195252be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getParent().getId());
195352be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("]");
195452be4785a258687055515117775d5bcb8bec1c12John Reck        } else {
195552be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append("false");
195652be4785a258687055515117775d5bcb8bec1c12John Reck        }
195752be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(", incog: ");
195852be4785a258687055515117775d5bcb8bec1c12John Reck        builder.append(isPrivateBrowsingEnabled());
195952be4785a258687055515117775d5bcb8bec1c12John Reck        if (!isPrivateBrowsingEnabled()) {
196052be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(", title: ");
196152be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getTitle());
196252be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(", url: ");
196352be4785a258687055515117775d5bcb8bec1c12John Reck            builder.append(getUrl());
196452be4785a258687055515117775d5bcb8bec1c12John Reck        }
196552be4785a258687055515117775d5bcb8bec1c12John Reck        return builder.toString();
196652be4785a258687055515117775d5bcb8bec1c12John Reck    }
196752be4785a258687055515117775d5bcb8bec1c12John Reck
19684895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block    private void handleProceededAfterSslError(SslError error) {
19694895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        if (error.getUrl().equals(mCurrentState.mUrl)) {
19704895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            // The security state should currently be SECURITY_STATE_SECURE.
19714895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            setSecurityState(SecurityState.SECURITY_STATE_BAD_CERTIFICATE);
197208a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            mCurrentState.mSslCertificateError = error;
19734895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        } else if (getSecurityState() == SecurityState.SECURITY_STATE_SECURE) {
197408a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            // The page's main resource is secure and this error is for a
197508a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block            // sub-resource.
19764895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block            setSecurityState(SecurityState.SECURITY_STATE_MIXED);
19774895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block        }
19784895b0133c337a8d55bf7e9eac64fcecab4e3e79Steve Block    }
1979934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai
1980934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai    public void setAcceptThirdPartyCookies(boolean accept) {
1981934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai        CookieManager cookieManager = CookieManager.getInstance();
1982934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai        if (mMainView != null)
1983934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai            cookieManager.setAcceptThirdPartyCookies(mMainView, accept);
1984934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai        if (mSubView != null)
1985934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai            cookieManager.setAcceptThirdPartyCookies(mSubView, accept);
1986934dfe5246cd151ffd60eb6277088f58f657b81cTao Bai    }
198722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
1988