Tab.java revision 502a353bb815bee8bec6a60f3b741dc62e4729cd
122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/*
222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Copyright (C) 2009 The Android Open Source Project
322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *
422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Licensed under the Apache License, Version 2.0 (the "License");
522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * you may not use this file except in compliance with the License.
622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * You may obtain a copy of the License at
722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *
822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *      http://www.apache.org/licenses/LICENSE-2.0
922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba *
1022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Unless required by applicable law or agreed to in writing, software
1122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * distributed under the License is distributed on an "AS IS" BASIS,
1222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * See the License for the specific language governing permissions and
1422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * limitations under the License.
1522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
1622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobapackage com.android.browser;
1822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
198233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity;
2022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.app.AlertDialog;
2158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.app.SearchManager;
2222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.ContentResolver;
231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport android.content.ContentUris;
24d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentValues;
2530c714c853a4239e72ab1e238ce2a92472d06ab0John Reckimport android.content.Context;
2622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.content.DialogInterface;
27fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.DialogInterface.OnCancelListener;
288ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport android.content.Intent;
291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport android.database.Cursor;
3022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.graphics.Bitmap;
318cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.graphics.Bitmap.CompressFormat;
329ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.BitmapFactory;
339ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.Canvas;
34c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolbimport android.graphics.Color;
359ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.graphics.Picture;
3622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.Uri;
3722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.net.http.SslError;
3822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Bundle;
399ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.os.Handler;
4022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.os.Message;
414dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsenimport android.os.SystemClock;
428862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstromimport android.security.KeyChain;
43aa09cd8dc20c9134b69ace4a7b84fe0103220fb4Brian Carlstromimport android.security.KeyChainAliasCallback;
44a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
4524f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reckimport android.text.TextUtils;
4622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.util.Log;
4722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.KeyEvent;
4822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.LayoutInflater;
4922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.view.View;
5050c241e6339c681c2427a57a31a357d35927c2acGrace Klobaimport android.view.ViewStub;
518862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstromimport android.webkit.ClientCertRequestHandler;
52c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdochimport android.webkit.ConsoleMessage;
53dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scrogginsimport android.webkit.DownloadListener;
5422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.GeolocationPermissions;
5522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.HttpAuthHandler;
5622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.SslErrorHandler;
5722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.URLUtil;
5822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.ValueCallback;
590c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient;
6022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient;
6122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem;
62438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport android.webkit.WebResourceResponse;
6322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage;
6422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView;
659ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.webkit.WebView.PictureListener;
6622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient;
671d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdochimport android.widget.CheckBox;
6822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.LinearLayout;
6922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.TextView;
708029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast;
7122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
728ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reckimport com.android.browser.TabControl.OnThumbnailUpdatedListener;
73541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.browser.homepages.HomeProvider;
741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport com.android.browser.provider.BrowserProvider2.Thumbnails;
758cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots;
76541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.common.speech.LoggingEvents;
77541f55a0178da7c09fb32aa5385effae031ea071John Reck
78541f55a0178da7c09fb32aa5385effae031ea071John Reckimport java.io.ByteArrayOutputStream;
791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport java.nio.ByteBuffer;
80fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.ArrayList;
81fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.HashMap;
82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Iterator;
83fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList;
84fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map;
85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
868cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.util.zip.GZIPOutputStream;
87fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
8822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/**
8922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow.
9022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */
919ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbclass Tab implements PictureListener {
928233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Log Tag
9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static final String LOGTAG = "Tab";
951dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
96c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // Special case the logtag for messages for the Console to make it easier to
97c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // filter them and match the logtag used for these messages in older versions
98c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    // of the browser.
99c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch    private static final String CONSOLE_LOGTAG = "browser";
100c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1019ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private static final int MSG_CAPTURE = 42;
1028ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck    private static final int CAPTURE_DELAY = 100;
1039ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static Bitmap sDefaultFavicon;
1051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
10630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public enum LockIcon {
10730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_UNSECURE,
10830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_SECURE,
10930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LOCK_ICON_MIXED,
11030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
1118233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1121461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    Context mContext;
113d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected WebViewController mWebViewController;
1148233facddcc51865d612a919d450db6954aa48e3Michael Kolb
115c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    // The tab ID
116d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private long mId = -1;
117c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
11822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // The Geolocation permissions prompt
11922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
12022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView wrapper
121a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    private View mContainer;
12222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Main WebView
12322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mMainView;
12422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow container
12522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private View mSubViewContainer;
12622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subwindow WebView
12722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private WebView mSubView;
12822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Saved bundle for when we are running low on memory. It contains the
12922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // information needed to restore the WebView if the user goes back to the
13022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab.
13122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Bundle mSavedState;
13222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Parent Tab. This is the Tab that created this Tab, or null if the Tab was
13322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // created by the UI
134c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Tab mParent;
13522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Tab that constructed by this Tab. This is used when this Tab is
13622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // destroyed, it clears all mParentTab values in the children.
137c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Vector<Tab> mChildren;
13822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // If true, the tab is in the foreground of the current activity.
13922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private boolean mInForeground;
1408233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // If true, the tab is in page loading state (after onPageStarted,
1418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // before onPageFinsihed)
1428233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInPageLoad;
14330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The last reported progress of the current page
14430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private int mPageLoadProgress;
1454dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    // The time the load started, used to find load page time
1464dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen    private long mLoadStartTime;
14722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Application identifier used to find tabs that another application wants
14822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // to reuse.
14922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private String mAppId;
150e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    // flag to indicate if tab should be closed on back
151e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    private boolean mCloseOnBack;
15222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Keep the original url around to avoid killing the old WebView if the url
15322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // has not changed.
15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Error console for the tab
15522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private ErrorConsoleView mErrorConsole;
156dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // The listener that gets invoked when a download is started from the
157dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    // mMainView
158dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    private final DownloadListener mDownloadListener;
1590c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    // Listener used to know when we move forward or back in the history list.
1600c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins    private final WebBackForwardListClient mWebBackForwardListClient;
161e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController mDataController;
1629206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // State of the auto-login request.
1639206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    private DeviceAccountLogin mDeviceAccountLogin;
16422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
16522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // AsyncTask for downloading touch icons
16622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    DownloadTouchIcon mTouchIconLoader;
16722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
16835e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck    private BrowserSettings mSettings;
1699ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureWidth;
1709ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private int mCaptureHeight;
1719ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Bitmap mCapture;
1729ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    private Handler mHandler;
1739ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
1741dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
1751dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * See {@link #clearBackStackWhenItemAdded(String)}.
1761dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
1771dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    private String mClearHistoryMatchUrl;
1781dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
1791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private static synchronized Bitmap getDefaultFavicon(Context context) {
1801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (sDefaultFavicon == null) {
1811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            sDefaultFavicon = BitmapFactory.decodeResource(
1821cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    context.getResources(), R.drawable.app_web_browser_sm);
1831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
1841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return sDefaultFavicon;
1851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
186eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
18730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // All the state needed for a page
188d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected static class PageState {
18930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mUrl;
190db22ec4ee014900988062d910bc810172a07df56John Reck        String mOriginalUrl;
19130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String mTitle;
19230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        LockIcon mLockIcon;
19330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        Bitmap mFavicon;
194502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        boolean mIsBookmarkedSite = false;
195502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        boolean mIncognito = false;
19630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
19730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito) {
198502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
199502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            if (mIncognito) {
200db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "browser:incognito";
20130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_incognito_tab);
20230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
203db22ec4ee014900988062d910bc810172a07df56John Reck                mOriginalUrl = mUrl = "";
20430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mTitle = c.getString(R.string.new_tab);
20530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mFavicon = null;
20730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
20830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
20930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
21030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        PageState(Context c, boolean incognito, String url, Bitmap favicon) {
211502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck            mIncognito = incognito;
212db22ec4ee014900988062d910bc810172a07df56John Reck            mOriginalUrl = mUrl = url;
21330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mTitle = null;
21430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (URLUtil.isHttpsUrl(url)) {
21530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_SECURE;
21630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            } else {
21730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
21830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            }
2191cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mFavicon = favicon;
22030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
2211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
22222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
22322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    // The current/loading page's state
225d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    protected PageState mCurrentState;
22630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
22722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Used for saving and restoring each Tab
228c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    static final String ID = "ID";
22922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRURL = "currentUrl";
23022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String CURRTITLE = "currentTitle";
23122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String PARENTTAB = "parentTab";
23222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final String APPID = "appid";
2333d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter    static final String INCOGNITO = "privateBrowsingEnabled";
234b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck    static final String USERAGENT = "useragent";
235e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    static final String CLOSEFLAG = "closeOnBack";
23622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
23722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
23822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
23958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Private information regarding the latest voice search.  If the Tab is not
24158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * in voice search mode, this will be null.
24258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
24358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    private VoiceSearchData mVoiceSearchData;
24458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
24595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     * Remove voice search mode from this tab.
24695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III     */
24795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    public void revertVoiceSearchMode() {
24895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        if (mVoiceSearchData != null) {
24995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            mVoiceSearchData = null;
25095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            if (mInForeground) {
2518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.revertVoiceSearchMode(this);
25295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III            }
25395d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III        }
25495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    }
2558233facddcc51865d612a919d450db6954aa48e3Michael Kolb
25695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III    /**
25758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Return whether the tab is in voice search mode.
25858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
25958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public boolean isInVoiceSearchMode() {
26058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData != null;
26158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
26258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
263c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Return true if the Tab is in voice search mode and the voice search
264c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III     * Intent came with a String identifying that Google provided the Intent.
2651fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins     */
2661fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    public boolean voiceSearchSourceIsGoogle() {
2671fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle;
2681fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    }
2691fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins    /**
27058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the title to display for the current voice search page.  If the Tab
27158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * is not in voice search mode, return null.
27258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
27358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public String getVoiceDisplayTitle() {
27458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
27558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mLastVoiceSearchTitle;
27658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
27758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
27858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Get the latest array of voice search results, to be passed to the
27958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * BrowserProvider.  If the Tab is not in voice search mode, return null.
28058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
28158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    public ArrayList<String> getVoiceSearchResults() {
28258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mVoiceSearchData == null) return null;
28358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return mVoiceSearchData.mVoiceSearchResults;
28458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
28558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
28658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Activate voice search mode.
28758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param intent Intent which has the results to use, or an index into the
28858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     *      results when reusing the old results.
28958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
29058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void activateVoiceSearchMode(Intent intent) {
29182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        int index = 0;
29258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ArrayList<String> results = intent.getStringArrayListExtra(
293a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS);
29458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (results != null) {
29582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> urls = intent.getStringArrayListExtra(
29682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS);
29782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> htmls = intent.getStringArrayListExtra(
29882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML);
29982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            ArrayList<String> baseUrls = intent.getStringArrayListExtra(
30082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        RecognizerResultsIntent
30182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS);
30258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // This tab is now entering voice search mode for the first time, or
30358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            // a new voice search was done.
30482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            int size = results.size();
30582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (urls == null || size != urls.size()) {
30658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                throw new AssertionError("improper extras passed in Intent");
30758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
30882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (htmls == null || htmls.size() != size || baseUrls == null ||
30982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    (baseUrls.size() != size && baseUrls.size() != 1)) {
31082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // If either of these arrays are empty/incorrectly sized, ignore
31182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                // them.
31282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                htmls = null;
31382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                baseUrls = null;
31482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
31582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
31682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    baseUrls);
3179df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
3189df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    RecognizerResultsIntent
3199df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
3201fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins            mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
3211fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    VoiceSearchData.SOURCE_IS_GOOGLE, false);
3222ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
323e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        }
324e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        String extraData = intent.getStringExtra(
325e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                SearchManager.EXTRA_DATA_KEY);
326e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        if (extraData != null) {
327e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            index = Integer.parseInt(extraData);
328e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
329e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                throw new AssertionError("index must be less than "
330e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        + "size of mVoiceSearchResults");
331e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
332e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mSourceIsGoogle) {
333e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                Intent logIntent = new Intent(
334e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.ACTION_LOG_EVENT);
335e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
336e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
337e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                logIntent.putExtra(
338e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
339e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins                        index);
3401461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                mContext.sendBroadcast(logIntent);
341e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            }
342e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins            if (mVoiceSearchData.mVoiceSearchIntent != null) {
3432ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Copy the Intent, so that each history item will have its own
3442ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                // Intent, with different (or none) extra data.
3452ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
3462ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
3472ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins                mVoiceSearchData.mVoiceSearchIntent = latest;
34858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
34958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
35058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchTitle
35182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchResults.get(index);
35258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mInForeground) {
35311d1978d8d16004598347abc93918b54a5ef760bMichael Kolb            mWebViewController.activateVoiceSearchMode(
35411d1978d8d16004598347abc93918b54a5ef760bMichael Kolb                    mVoiceSearchData.mLastVoiceSearchTitle,
35511d1978d8d16004598347abc93918b54a5ef760bMichael Kolb                    mVoiceSearchData.mVoiceSearchResults);
35658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
35782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (mVoiceSearchData.mVoiceSearchHtmls != null) {
35882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            // When index was found it was already ensured that it was valid
35982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index);
36082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            if (uriString != null) {
36182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                Uri dataUri = Uri.parse(uriString);
36282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals(
36382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                        dataUri.getScheme())) {
36482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // If there is only one base URL, use it.  If there are
36582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // more, there will be one for each index, so use the base
36682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    // URL corresponding to the index.
36782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get(
36882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ?
36982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            index : 0);
37082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchUrl = baseUrl;
37182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mMainView.loadDataWithBaseURL(baseUrl,
37282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            uriString.substring(RecognizerResultsIntent
37382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            .URI_SCHEME_INLINE.length() + 1), "text/html",
37482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                            "utf-8", baseUrl);
37582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    return;
37682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                }
37782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            }
37882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
37958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mVoiceSearchData.mLastVoiceSearchUrl
38082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                = mVoiceSearchData.mVoiceSearchUrls.get(index);
38182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        if (null == mVoiceSearchData.mLastVoiceSearchUrl) {
3828233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter(
38382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                    mVoiceSearchData.mLastVoiceSearchTitle);
38482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        }
3859df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        Map<String, String> headers = null;
3869df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        if (mVoiceSearchData.mHeaders != null) {
3879df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
3889df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    : index;
3899df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
3909df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            if (bundle != null && !bundle.isEmpty()) {
3919df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                Iterator<String> iter = bundle.keySet().iterator();
3929df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                headers = new HashMap<String, String>();
3939df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                while (iter.hasNext()) {
3949df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    String key = iter.next();
3959df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                    headers.put(key, bundle.getString(key));
3969df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins                }
3979df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins            }
3989df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        }
3999df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
40058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
40158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ static class VoiceSearchData {
40258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public VoiceSearchData(ArrayList<String> results,
40382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> urls, ArrayList<String> htmls,
40482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins                ArrayList<String> baseUrls) {
40558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchResults = results;
40658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            mVoiceSearchUrls = urls;
40782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchHtmls = htmls;
40882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins            mVoiceSearchBaseUrls = baseUrls;
40958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
41058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
41158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of suggestions to be displayed when opening the
41258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * SearchManager
41358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
41458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchResults;
41558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
41658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * ArrayList of urls, associated with the suggestions in
41758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * mVoiceSearchResults.
41858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public ArrayList<String> mVoiceSearchUrls;
42058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /*
42182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding content to load for each item in
42282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults.
42382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
42482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchHtmls;
42582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
42682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * ArrayList holding base urls for the items in mVoiceSearchResults.
42782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * If non null, this will either have the same size as
42882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * mVoiceSearchResults or have a size of 1, in which case all will use
42982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * the same base url
43082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         */
43182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        public ArrayList<String> mVoiceSearchBaseUrls;
43282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins        /*
43358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last url provided by voice search.  Used for comparison to see if
43482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins         * we are going to a page by some method besides voice search.
43558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchUrl;
43758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        /**
43858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * The last title used for voice search.  Needed to update the title bar
43958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         * when switching tabs.
44058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins         */
44158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public String mLastVoiceSearchTitle;
4421fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4431fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * Whether the Intent which turned on voice search mode contained the
4441fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String signifying that Google was the source.
4451fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4461fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public boolean mSourceIsGoogle;
4471fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        /**
4489df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * List of headers to be passed into the WebView containing location
4499df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         * information
4509df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins         */
4519df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        public ArrayList<Bundle> mHeaders;
4529df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins        /**
4530c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * The Intent used to invoke voice search.  Placed on the
4540c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * WebHistoryItem so that when coming back to a previous voice search
4550c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         * page we can again activate voice search.
4560c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins         */
457e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins        public Intent mVoiceSearchIntent;
4580c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        /**
4591fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         * String used to identify Google as the source of voice search.
4601fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins         */
4611fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins        public static String SOURCE_IS_GOOGLE
4621fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                = "android.speech.extras.SOURCE_IS_GOOGLE";
46358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
46458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
46522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Container class for the next error dialog that needs to be displayed
46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class ErrorDialog {
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mTitle;
46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final String mDescription;
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public final int mError;
47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog(int title, String desc, int error) {
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mTitle = title;
47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDescription = desc;
47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mError = error;
47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
4758233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
47622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void processNextError() {
47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The first one is currently displayed so just remove it.
48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.removeFirst();
48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 0) {
48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = null;
48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        showError(mQueuedErrors.getFirst());
48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private DialogInterface.OnDismissListener mDialogListener =
49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            new DialogInterface.OnDismissListener() {
49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                public void onDismiss(DialogInterface d) {
49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    processNextError();
49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            };
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private LinkedList<ErrorDialog> mQueuedErrors;
49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void queueError(int err, String desc) {
49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors == null) {
50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mQueuedErrors = new LinkedList<ErrorDialog>();
50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        for (ErrorDialog d : mQueuedErrors) {
50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (d.mError == err) {
50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // Already saw a similar error, ignore the new one.
50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
50822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorDialog errDialog = new ErrorDialog(
50922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                err == WebViewClient.ERROR_FILE_NOT_FOUND ?
51022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameFileErrorLabel :
51122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                R.string.browserFrameNetworkErrorLabel,
51222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                desc, err);
51322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mQueuedErrors.addLast(errDialog);
51422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
51522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the dialog now if the queue was empty and it is in foreground
51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors.size() == 1 && mInForeground) {
51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(errDialog);
51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showError(ErrorDialog errDialog) {
52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInForeground) {
5231461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog d = new AlertDialog.Builder(mContext)
52422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(errDialog.mTitle)
52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(errDialog.mDescription)
52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok, null)
52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.setOnDismissListener(mDialogListener);
52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the main WebView
53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
53622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
53722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebViewClient mWebViewClient = new WebViewClient() {
5384a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mDontResend;
5394a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins        private Message mResend;
54022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
54122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageStarted(WebView view, String url, Bitmap favicon) {
5428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = true;
54330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = 0;
5441461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext,
54530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                    view.isPrivateBrowsingEnabled(), url, favicon);
5464dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen            mLoadStartTime = SystemClock.uptimeMillis();
54758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceSearchData != null
54858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
5491fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (mVoiceSearchData.mSourceIsGoogle) {
5501fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
5511fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    i.putExtra(LoggingEvents.EXTRA_FLUSH, true);
5521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mContext.sendBroadcast(i);
5531fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
55495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III                revertVoiceSearchMode();
55558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
55622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
55822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // If we start a touch icon load and then load a new page, we don't
55922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // want to cancel the current touch icon loader. But, we do want to
56022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // create a new one when the touch icon url is known.
56122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mTouchIconLoader != null) {
56222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader.mTab = null;
56322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mTouchIconLoader = null;
56422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
56522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // reset the error console
56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mErrorConsole != null) {
56822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mErrorConsole.clearErrorMessages();
5698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()) {
57022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
57122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
57222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
57322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
5749206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            // Cancel the auto-login process.
5759206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            if (mDeviceAccountLogin != null) {
5769206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin.cancel();
5779206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mDeviceAccountLogin = null;
5789206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                mWebViewController.hideAutoLogin(Tab.this);
5799206677e461328f15854c5fcb1366d0e261534c6Patrick Scott            }
5809206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
58122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // finally update the UI in the activity if it is in the foreground
582324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageStarted(Tab.this, view, favicon);
5834cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
584e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            updateBookmarkedStatus();
58522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
58622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
58722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
58822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onPageFinished(WebView view, String url) {
589a169628f9424256e5bcf45807869c4c4eaa114c0John Reck            if (!mInPageLoad) {
590a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                // In page navigation links (www.something.com#footer) will
591a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                // trigger an onPageFinished which we don't care about.
592a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                return;
593a169628f9424256e5bcf45807869c4c4eaa114c0John Reck            }
5945b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            if (!isPrivateBrowsingEnabled()) {
5955b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                LogTag.logPageFinishedLoading(
5965b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck                        url, SystemClock.uptimeMillis() - mLoadStartTime);
5975b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck            }
5988233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mInPageLoad = false;
5991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            syncCurrentState(view, url);
600324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.onPageFinished(Tab.this);
60122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
60222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
60322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // return true if want to hijack the url to let another app to handle it
60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
60522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
606c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            if (voiceSearchSourceIsGoogle()) {
607c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // This method is called when the user clicks on a link.
608c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // VoiceSearchMode is turned off when the user leaves the
609c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // Google results page, so at this point the user must be on
610c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that page.  If the user clicked a link on that page, assume
611c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // that the voice search was effective, and broadcast an Intent
612c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                // so a receiver can take note of that fact.
613c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT);
614c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
615c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III                        LoggingEvents.VoiceSearch.RESULT_CLICKED);
6161461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                mContext.sendBroadcast(logIntent);
617c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III            }
61822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
61918eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                return mWebViewController.shouldOverrideUrlLoading(Tab.this,
62018eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb                        view, url);
62122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
62222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
62322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
62422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
62522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
62622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
62722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Updates the lock icon. This method is called when we discover another
62822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * resource to be loaded for this page (for example, javascript). While
62922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we update the icon type, we do not update the lock icon itself until
63022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * we are done loading, it is slightly more secure this way.
63122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
63222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onLoadResource(WebView view, String url) {
63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url != null && url.length() > 0) {
63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // It is only if the page claims to be secure that we may have
63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // to update the lock:
63730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) {
63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // If NOT a 'safe' url, change the lock to mixed content!
63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url)
64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            || URLUtil.isAboutUrl(url))) {
64130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                        mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED;
64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }
64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
64522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
64622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
64722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
64822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Show a dialog informing the user of the network error reported by
64922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * WebCore if it is in the foreground.
65022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
65122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
65222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
65322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
65422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
65522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_CONNECT &&
65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_BAD_URL &&
65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorCode != WebViewClient.ERROR_FILE) {
65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                queueError(errorCode, description);
66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
66147654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
66247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log URLs when in private browsing mode
663f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (!isPrivateBrowsingEnabled()) {
66447654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
66547654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton                        + " " + description);
66647654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            }
66722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
66822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
66922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
67022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Check with the user if it is ok to resend POST data as the page they
67122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * are trying to navigate to is the result of a POST.
67222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
67322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
67422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, final Message dontResend,
67522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                       final Message resend) {
67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
67722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                dontResend.sendToTarget();
67822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
67922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
6804a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            if (mDontResend != null) {
6814a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                Log.w(LOGTAG, "onFormResubmission should not be called again "
6824a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                        + "while dialog is still up");
6834a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                dontResend.sendToTarget();
6844a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                return;
6854a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            }
6864a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mDontResend = dontResend;
6874a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins            mResend = resend;
6881461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new AlertDialog.Builder(mContext).setTitle(
68922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitLabel).setMessage(
69022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.string.browserFrameFormResubmitMessage)
69122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.ok,
69222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
69322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
69422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
6954a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mResend != null) {
6964a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend.sendToTarget();
6974a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
6984a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
6994a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setNegativeButton(R.string.cancel,
70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            new DialogInterface.OnClickListener() {
70322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                public void onClick(DialogInterface dialog,
70422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        int which) {
7054a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    if (mDontResend != null) {
7064a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend.sendToTarget();
7074a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mResend = null;
7084a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                        mDontResend = null;
7094a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                    }
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                }
71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }).setOnCancelListener(new OnCancelListener() {
71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onCancel(DialogInterface dialog) {
7134a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            if (mDontResend != null) {
7144a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend.sendToTarget();
7154a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mResend = null;
7164a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                                mDontResend = null;
7174a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins                            }
71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    }).show();
72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
72122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
72222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
72322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Insert the url into the visited history database.
72422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url The url to be inserted.
72522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param isReload True if this url is being reloaded.
72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * FIXME: Not sure what to do when reloading the page.
72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
731324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            mWebViewController.doUpdateVisitedHistory(Tab.this, isReload);
73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Displays SSL error(s) dialog to the user.
73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(final WebView view,
73922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final SslErrorHandler handler, final SslError error) {
74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.cancel();
74230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
74535e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            if (mSettings.showSecurityWarnings()) {
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LayoutInflater factory =
7471461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    LayoutInflater.from(mContext);
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final View warningsView =
74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    factory.inflate(R.layout.ssl_warnings, null);
75022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final LinearLayout placeholder =
75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_UNTRUSTED)) {
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
75522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
75622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
75722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_untrusted);
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
76022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_IDMISMATCH)) {
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
76522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_mismatch);
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
76822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_EXPIRED)) {
77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_expired);
77422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
77522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
77622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
77722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (error.hasError(SslError.SSL_NOTYETVALID)) {
77822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    LinearLayout ll = (LinearLayout)factory
77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .inflate(R.layout.ssl_warning, null);
78022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    ((TextView)ll.findViewById(R.id.warning))
78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setText(R.string.ssl_not_yet_valid);
78222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    placeholder.addView(ll);
78322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
7851461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext).setTitle(
78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        R.string.security_warning).setIcon(
78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        android.R.drawable.ic_dialog_alert).setView(
78822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        warningsView).setPositiveButton(R.string.ssl_continue,
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
79122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
79222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.proceed();
79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setNeutralButton(R.string.view_certificate,
79522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
7988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mWebViewController.showSslCertificateOnError(view,
79922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                        handler, error);
80022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
801a49b829e91ea1290d9e1cf326417fdbf669f9d3aBen Murdoch                        }).setNegativeButton(R.string.ssl_go_back,
80222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnClickListener() {
80322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onClick(DialogInterface dialog,
80422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                    int whichButton) {
80530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                dialog.cancel();
80622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
80722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).setOnCancelListener(
80822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        new DialogInterface.OnCancelListener() {
80922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            public void onCancel(DialogInterface dialog) {
81022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                handler.cancel();
81130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
81230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                                mWebViewController.onUserCanceledSsl(Tab.this);
81322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            }
81422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }).show();
81522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
81622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                handler.proceed();
81722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
81822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
81922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
82022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
8218862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom         * Displays client certificate request to the user.
8228862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom         */
8238862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        @Override
8248862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        public void onReceivedClientCertRequest(final WebView view,
8258862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                final ClientCertRequestHandler handler, final String host_and_port) {
8268862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            if (!mInForeground) {
8278862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                handler.ignore();
8288862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                return;
8298862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            }
8306d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            int colon = host_and_port.lastIndexOf(':');
8316d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            String host;
8326d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            int port;
8336d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            if (colon == -1) {
8346d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                host = host_and_port;
8356d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                port = -1;
8366d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            } else {
8376d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                String portString = host_and_port.substring(colon + 1);
8386d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                try {
8396d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    port = Integer.parseInt(portString);
8406d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    host = host_and_port.substring(0, colon);
8416d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                } catch  (NumberFormatException e) {
8426d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    host = host_and_port;
8436d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                    port = -1;
8446d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom                }
8456d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            }
8461461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            KeyChain.choosePrivateKeyAlias(
8471461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mWebViewController.getActivity(), new KeyChainAliasCallback() {
8488862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                @Override public void alias(String alias) {
8498862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                    if (alias == null) {
8508862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                        handler.cancel();
8518862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                        return;
8528862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                    }
8531461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new KeyChainLookup(mContext, handler, alias).execute();
8548862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                }
8556d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom            }, null, null, host, port, null);
8568862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        }
8578862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom
8588862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        /**
85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Handles an HTTP authentication request.
86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *
86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param handler The authentication handler
86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param host The host
86322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param realm The realm
86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final HttpAuthHandler handler, final String host,
86822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final String realm) {
8698233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm);
87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
87122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
873438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        public WebResourceResponse shouldInterceptRequest(WebView view,
874438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck                String url) {
875438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
8761461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    mContext, url);
877438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck            return res;
878438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        }
879438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck
880438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck        @Override
88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
88422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8858233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mWebViewController.shouldOverrideKeyEvent(event);
88622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
88722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
88822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
88922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
8908233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInForeground) {
89122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return;
89222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
8938233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onUnhandledKeyEvent(event);
89422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
8959206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
8969206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        @Override
8979206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        public void onReceivedLoginRequest(WebView view, String realm,
8989206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                String account, String args) {
8991461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            new DeviceAccountLogin(mWebViewController.getActivity(), view, Tab.this, mWebViewController)
9009206677e461328f15854c5fcb1366d0e261534c6Patrick Scott                    .handleLogin(realm, account, args);
9019206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        }
9029206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
90322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
90422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void syncCurrentState(WebView view, String url) {
9061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        // Sync state (in case of stop/timeout)
9071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mUrl = view.getUrl();
9081cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mUrl == null) {
9091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mCurrentState.mUrl = url != null ? url : "";
9101cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
9111cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mOriginalUrl = view.getOriginalUrl();
9121cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = view.getTitle();
9131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mFavicon = view.getFavicon();
9141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) {
9151cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // In case we stop when loading an HTTPS page from an HTTP page
9161cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            // but before a provisional load occurred
9171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE;
9181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
919502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        mCurrentState.mIncognito = view.isPrivateBrowsingEnabled();
9201cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
9211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
9229206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI
9239206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // displayed.
9249206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    void setDeviceAccountLogin(DeviceAccountLogin login) {
9259206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mDeviceAccountLogin = login;
9269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
9279206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
9289206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    // Returns non-null if the title bar should display the auto-login UI.
9299206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    DeviceAccountLogin getDeviceAccountLogin() {
9309206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        return mDeviceAccountLogin;
9319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
9329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the main WebView
93522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Helper method to create a new tab or sub window.
93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private void createWindow(final boolean dialog, final Message msg) {
94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView.WebViewTransport transport =
94122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    (WebView.WebViewTransport) msg.obj;
94222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog) {
94322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createSubWindow();
9448233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.attachSubWindow(Tab.this);
94522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(mSubView);
94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
9477bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                final Tab newTab = mWebViewController.openTab(null,
9485949c661b51295148706d53a03b41df2eb840ae3John Reck                        Tab.this, true, true);
94922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                transport.setWebView(newTab.getWebView());
95022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            msg.sendToTarget();
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
95322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
95422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
95522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, final boolean dialog,
95622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                final boolean userGesture, final Message resultMsg) {
95722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // only allow new window or sub window for the foreground case
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mInForeground) {
95922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
96022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
96122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if we can't create any more tabs or sub windows.
96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (dialog && mSubView != null) {
9631461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_subwindows_dialog_title)
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
96622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_subwindows_dialog_message)
96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
9708233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else if (!mWebViewController.getTabControl().canCreateNewTab()) {
9711461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                new AlertDialog.Builder(mContext)
97222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setTitle(R.string.too_many_windows_dialog_title)
97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setIcon(android.R.drawable.ic_dialog_alert)
97422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setMessage(R.string.too_many_windows_dialog_message)
97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .setPositiveButton(R.string.ok, null)
97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .show();
97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return false;
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Short-circuit if this was a user gesture.
98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (userGesture) {
98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                createWindow(dialog, resultMsg);
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Allow the popup and create the appropriate window.
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener allowListener =
98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d,
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                int which) {
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            createWindow(dialog, resultMsg);
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Block the popup by returning a null WebView.
99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog.OnClickListener blockListener =
99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    new AlertDialog.OnClickListener() {
99822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        public void onClick(DialogInterface d, int which) {
99922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            resultMsg.sendToTarget();
100022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        }
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    };
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Build a confirmation dialog to display to the user.
100422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final AlertDialog d =
10051461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                    new AlertDialog.Builder(mContext)
100622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setTitle(R.string.attention)
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setIcon(android.R.drawable.ic_dialog_alert)
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setMessage(R.string.popup_window_attempt)
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setPositiveButton(R.string.allow, allowListener)
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setNegativeButton(R.string.block, blockListener)
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .setCancelable(false)
101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .create();
101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // Show the confirmation dialog.
101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            d.show();
101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1020eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        public void onRequestFocus(WebView view) {
1021eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            if (!mInForeground) {
1022c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mWebViewController.switchToTab(Tab.this);
1023eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott            }
1024eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        }
1025eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott
1026eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott        @Override
102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
1028c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            if (mParent != null) {
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // JavaScript can only close popup window.
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (mInForeground) {
1031c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                    mWebViewController.switchToTab(mParent);
103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
10338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.closeTab(Tab.this);
103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
103622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
103722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
103822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
103930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mPageLoadProgress = newProgress;
104030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mWebViewController.onProgressChanged(Tab.this);
104122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
104222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
104421d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins        public void onReceivedTitle(WebView view, final String title) {
104530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mTitle = title;
10468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onReceivedTitle(Tab.this, title);
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedIcon(WebView view, Bitmap icon) {
105130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            mCurrentState.mFavicon = icon;
10528233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.onFavicon(Tab.this, view, icon);
105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedTouchIconUrl(WebView view, String url,
105722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean precomposed) {
10581461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            final ContentResolver cr = mContext.getContentResolver();
1059c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Let precomposed icons take precedence over non-composed
1060c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // icons.
1061c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (precomposed && mTouchIconLoader != null) {
1062c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.cancel(false);
1063c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader = null;
1064c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            }
1065c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            // Have only one async task at a time.
1066c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins            if (mTouchIconLoader == null) {
10678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mTouchIconLoader = new DownloadTouchIcon(Tab.this,
10681461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                        mContext, cr, view);
1069c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins                mTouchIconLoader.execute(url);
107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onShowCustomView(View view,
107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebChromeClient.CustomViewCallback callback) {
10761461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            Activity activity = mWebViewController.getActivity();
10771461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            if (activity != null) {
10781461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                onShowCustomView(view, activity.getRequestedOrientation(), callback);
10791461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            }
10802d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        }
10812d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger
10822d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        @Override
10832d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger        public void onShowCustomView(View view, int requestedOrientation,
10842d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                WebChromeClient.CustomViewCallback callback) {
10858233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
10862d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger                    requestedOrientation, callback);
108722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onHideCustomView() {
10918233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInForeground) mWebViewController.hideCustomView();
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The origin has exceeded its database quota.
109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param url the URL that exceeded the quota
109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param databaseIdentifier the identifier of the database on which the
109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            transaction that caused the quota overflow was run
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param currentQuota the current quota for the origin.
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param estimatedSize the estimated size of the database.
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater The callback to run when a decision to allow or
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            deny quota has been made. Don't forget to call this!
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
110622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onExceededDatabaseQuota(String url,
110722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String databaseIdentifier, long currentQuota, long estimatedSize,
110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
110935e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onExceededDatabaseQuota(url, databaseIdentifier,
111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            currentQuota, estimatedSize, totalUsedQuota,
111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * The Application Cache has exceeded its max size.
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param spaceNeeded is the amount of disk space that would be needed
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            in order for the last appcache operation to succeed.
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param totalUsedQuota is the sum of all origins' quota.
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param quotaUpdater A callback to inform the WebCore thread that a
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            new app cache size is available. This callback must always
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            be executed at some point to ensure that the sleeping
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *            WebCore thread is woken up.
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReachedMaxAppCacheSize(long spaceNeeded,
112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
112835e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck            mSettings.getWebStorageSizeManager()
112922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
113022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            quotaUpdater);
113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
113222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
113322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
113422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to show a prompt to ask the user to set the
113522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Geolocation permission state for the specified origin.
113622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param origin The origin for which Geolocation permissions are
113722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     requested.
113822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @param callback The callback to call once the user has set the
113922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         *     Geolocation permission state.
114022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
114222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsShowPrompt(String origin,
114322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                GeolocationPermissions.Callback callback) {
114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
114550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                getGeolocationPermissionsPrompt().show(origin, callback);
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
114922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
115022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Instructs the browser to hide the Geolocation permissions prompt.
115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
115322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onGeolocationPermissionsHidePrompt() {
115450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            if (mInForeground && mGeolocationPermissionsPrompt != null) {
115522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mGeolocationPermissionsPrompt.hide();
115622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
115722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
115822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
115965acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch        /* Adds a JavaScript error message to the system log and if the JS
116065acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * console is enabled in the about:debug options, to that console
116165acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch         * also.
1162c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch         * @param consoleMessage the message object.
116322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
116422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
1165c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
116622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
116722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // call getErrorConsole(true) so it will create one if needed
116822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                ErrorConsoleView errorConsole = getErrorConsole(true);
1169c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                errorConsole.addErrorMessage(consoleMessage);
11708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mWebViewController.shouldShowErrorConsole()
11718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        && errorConsole.getShowState() !=
11728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            ErrorConsoleView.SHOW_MAXIMIZED) {
117322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
117422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
117522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
1176c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
117747654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton            // Don't log console messages in private browsing mode
1178f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk            if (isPrivateBrowsingEnabled()) return true;
117947654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton
1180c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            String message = "Console: " + consoleMessage.message() + " "
1181c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.sourceId() +  ":"
1182c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    + consoleMessage.lineNumber();
1183c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1184c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            switch (consoleMessage.messageLevel()) {
1185c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case TIP:
1186c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.v(CONSOLE_LOGTAG, message);
1187c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1188c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case LOG:
1189c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.i(CONSOLE_LOGTAG, message);
1190c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1191c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case WARNING:
1192c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.w(CONSOLE_LOGTAG, message);
1193c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1194c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case ERROR:
1195c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.e(CONSOLE_LOGTAG, message);
1196c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1197c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                case DEBUG:
1198c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    Log.d(CONSOLE_LOGTAG, message);
1199c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch                    break;
1200c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            }
1201c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch
1202c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch            return true;
120322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
120422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
120522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
120622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the browser for an icon to represent a <video> element.
120722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * This icon will be used if the Web page did not specify a poster attribute.
120822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return Bitmap The icon or null if no such icon is available.
120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
121022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
121122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public Bitmap getDefaultVideoPoster() {
121222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
12138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getDefaultVideoPoster();
121422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
121722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
121822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Ask the host application for a custom progress view to show while
122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * a <video> is loading.
122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * @return View The progress view.
122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
122322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public View getVideoLoadingProgressView() {
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
12268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return mWebViewController.getVideoLoadingProgressView();
122722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return null;
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
123262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInForeground) {
12348233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.openFileChooser(uploadMsg, acceptType);
123522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
123622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                uploadMsg.onReceiveValue(null);
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        /**
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         * Deliver a list of already-visited URLs
124222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         */
124322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
124422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void getVisitedHistory(final ValueCallback<String[]> callback) {
12458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.getVisitedHistory(callback);
12468233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12478029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
12488029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        @Override
12498029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        public void setupAutoFill(Message message) {
12508029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            // Prompt the user to set up their profile.
12518029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            final Message msg = message;
12521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
12531461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
12541d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    Context.LAYOUT_INFLATER_SERVICE);
12551d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null);
12561d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
12571d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch            builder.setView(layout)
1258b7e6f94a4728e284764a45b25985a05e0f5c6273Ben Murdoch                .setTitle(R.string.autofill_setup_dialog_title)
12591d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
12601d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    @Override
12611d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    public void onClick(DialogInterface dialog, int id) {
12621d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        CheckBox disableAutoFill = (CheckBox) layout.findViewById(
12631d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                R.id.setup_autofill_dialog_disable_autofill);
12641d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch
12651d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        if (disableAutoFill.isChecked()) {
12661d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Disable autofill and show a toast with how to turn it on again.
126735e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                            mSettings.setAutofillEnabled(false);
12681461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                            Toast.makeText(mContext,
12691d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    R.string.autofill_setup_dialog_negative_toast,
12701d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                                    Toast.LENGTH_LONG).show();
12711d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        } else {
12721d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // Take user to the AutoFill profile editor. When they return,
12731d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // we will send the message that we pass here which will trigger
12741d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            // the form to get filled out with their new profile.
12751d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                            mWebViewController.setupAutoFill(msg);
12761d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                        }
12771d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                    }
12781d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                })
12791d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .setNegativeButton(R.string.cancel, null)
12801d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch                .show();
12818029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        }
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    };
128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
128422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
128522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient implementation for the sub window
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
128822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Subclass of WebViewClient used in subwindows to notify the main
128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebViewClient of certain WebView activities.
129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private static class SubWindowClient extends WebViewClient {
129122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebViewClient.
129222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebViewClient mClient;
12938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private final WebViewController mController;
129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12958233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SubWindowClient(WebViewClient client, WebViewController controller) {
129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
12978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController = controller;
1298211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1299211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        @Override
1300211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1301211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // Unlike the others, do not call mClient's version, which would
1302211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            // change the progress bar.  However, we do want to remove the
130301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.
13048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mController.endActionMode();
130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
130622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
130722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void doUpdateVisitedHistory(WebView view, String url,
130822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean isReload) {
130922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.doUpdateVisitedHistory(view, url, isReload);
131022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
131222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideUrlLoading(WebView view, String url) {
131322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideUrlLoading(view, url);
131422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
131522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
131622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedSslError(WebView view, SslErrorHandler handler,
131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                SslError error) {
131822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedSslError(view, handler, error);
131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
132022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
13218862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        public void onReceivedClientCertRequest(WebView view,
13228862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom                ClientCertRequestHandler handler, String host_and_port) {
13238862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom            mClient.onReceivedClientCertRequest(view, handler, host_and_port);
13248862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        }
13258862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom        @Override
132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedHttpAuthRequest(WebView view,
132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                HttpAuthHandler handler, String host, String realm) {
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
132922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onFormResubmission(WebView view, Message dontResend,
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Message resend) {
133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onFormResubmission(view, dontResend, resend);
133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onReceivedError(WebView view, int errorCode,
133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String description, String failingUrl) {
133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onReceivedError(view, errorCode, description, failingUrl);
133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean shouldOverrideKeyEvent(WebView view,
134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.shouldOverrideKeyEvent(view, event);
134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onUnhandledKeyEvent(WebView view,
134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                android.view.KeyEvent event) {
134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onUnhandledKeyEvent(view, event);
134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
135322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // WebChromeClient implementation for the sub window
135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private class SubWindowChromeClient extends WebChromeClient {
135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The main WebChromeClient.
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        private final WebChromeClient mClient;
135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
136022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        SubWindowChromeClient(WebChromeClient client) {
136122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient = client;
136222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
136322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
136422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onProgressChanged(WebView view, int newProgress) {
136522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mClient.onProgressChanged(view, newProgress);
136622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
136722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public boolean onCreateWindow(WebView view, boolean dialog,
136922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                boolean userGesture, android.os.Message resultMsg) {
137022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
137122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        @Override
137322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        public void onCloseWindow(WebView window) {
137422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (window != mSubView) {
137522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Log.e(LOGTAG, "Can't close the window");
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
13778233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.dismissSubWindow(Tab.this);
137822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
138022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Construct a new tab
13847bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    Tab(WebViewController wvcontroller, WebView w) {
13851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, w, null);
13861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
13871cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
13881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, Bundle state) {
13891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        this(wvcontroller, null, state);
13901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
13911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
13921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    Tab(WebViewController wvcontroller, WebView w, Bundle state) {
13938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWebViewController = wvcontroller;
13941461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mContext = mWebViewController.getContext();
139535e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck        mSettings = BrowserSettings.getInstance();
13961461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mDataController = DataController.getInstance(mContext);
13971461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mCurrentState = new PageState(mContext, w != null
1398847b532045e3cb117a847ebb956c9919401f332dJohn Reck                ? w.isPrivateBrowsingEnabled() : false);
13998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
140022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
140122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1402dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        mDownloadListener = new DownloadListener() {
1403dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            public void onDownloadStart(String url, String userAgent,
1404dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    String contentDisposition, String mimetype,
1405dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    long contentLength) {
14068233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition,
1407dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        mimetype, contentLength);
1408dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            }
1409dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        };
14100c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        mWebBackForwardListClient = new WebBackForwardListClient() {
14110c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
14120c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onNewHistoryItem(WebHistoryItem item) {
14130c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (isInVoiceSearchMode()) {
14140c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
14150c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
14161dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                if (mClearHistoryMatchUrl != null) {
14171dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    if (LOGD_ENABLED) {
14181dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        Log.d(LOGTAG, "onNewHistoryItem:\n\t" + item.getUrl() + "\n\t"
14191dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                                + mClearHistoryMatchUrl);
14201dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
14211dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    if (TextUtils.equals(item.getOriginalUrl(), mClearHistoryMatchUrl)) {
14221dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        if (mMainView != null) {
14231dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                            mMainView.clearHistory();
14241dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                        }
14251dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    }
14261dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                    mClearHistoryMatchUrl = null;
14271dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood                }
14280c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
14290c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            @Override
14300c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            public void onIndexChanged(WebHistoryItem item, int index) {
14310c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                Object data = item.getCustomData();
14320c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                if (data != null && data instanceof Intent) {
14330c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                    activateVoiceSearchMode((Intent) data);
14340c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins                }
14350c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            }
14360c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins        };
1437dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins
14381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureWidth = mContext.getResources().getDimensionPixelSize(
14391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_width);
14401cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCaptureHeight = mContext.getResources().getDimensionPixelSize(
14411cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                R.dimen.tab_thumbnail_height);
14421cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
14431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        restoreState(state);
144422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setWebView(w);
14459ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        mHandler = new Handler() {
14461dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood            @Override
14479ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            public void handleMessage(Message m) {
14481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                switch (m.what) {
14491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                case MSG_CAPTURE:
14501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    capture();
14511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    break;
14521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
14539ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            }
14549ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        };
14551cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
14569ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
14571cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public void updateShouldCaptureThumbnails() {
14581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mWebViewController.shouldCaptureThumbnails()) {
14591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
14601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                if (mCapture == null) {
14611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    mCapture = Bitmap.createBitmap(mCaptureWidth, mCaptureHeight,
14621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                            Bitmap.Config.RGB_565);
1463c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolb                    mCapture.eraseColor(Color.WHITE);
14641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    if (mInForeground) {
14651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        postCapture();
14661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    }
14671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
14681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
14691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        } else {
14701cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            synchronized (Tab.this) {
14711cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCapture = null;
14721cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                deleteThumbnail();
14731cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
14741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
14771461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    public void setController(WebViewController ctl) {
14781461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mWebViewController = ctl;
14791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        updateShouldCaptureThumbnails();
14801461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    }
14811461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb
1482c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public void setId(long id) {
1483c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mId = id;
1484c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1485c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
1486c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public long getId() {
1487c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mId;
1488c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1489c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
149122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Sets the WebView for this tab, correctly removing the old WebView from
149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * the container view.
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
149422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setWebView(WebView w) {
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == w) {
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
149722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1498a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
149922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is changing, the page will be reloaded, so any ongoing
150022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Geolocation permission requests are void.
150150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt != null) {
150250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt.hide();
150350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1505a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mWebViewController.onSetWebView(this, w);
150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
15071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mMainView != null) {
15088ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.setPictureListener(null);
15091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (w != null) {
15101cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                syncCurrentState(w, null);
15111cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            } else {
15121cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mCurrentState = new PageState(mContext, false);
15131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
15141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
151522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // set the new one
151622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView = w;
1517dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins        // attach the WebViewClient, WebChromeClient and DownloadListener
151822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
151922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebViewClient(mWebViewClient);
152022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.setWebChromeClient(mWebChromeClient);
1521dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Attach DownloadManager so that downloads can start in an active
1522dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // or a non-active window. This can happen when going to a site that
1523dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // does a redirect after a period of time. The user could have
1524dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // switched to another tab while waiting for the download to start.
1525dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mMainView.setDownloadListener(mDownloadListener);
15260c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
15278ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            TabControl tc = mWebViewController.getTabControl();
15288ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (tc != null && tc.getOnThumbnailUpdatedListener() != null) {
15298ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                mMainView.setPictureListener(this);
15308ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
15311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mSavedState != null) {
15321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mMainView.restoreState(mSavedState);
15331cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                mSavedState = null;
15341cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
153522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
153622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Destroy the tab's main WebView and subWindow if any
154022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
154122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void destroy() {
154222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
154322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            dismissSubWindow();
1544ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            // Make sure the embedded title bar isn't still attached
1545ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.setEmbeddedTitleBar(null);
154622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // save the WebView to call destroy() after detach it from the tab
154722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView webView = mMainView;
154822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            setWebView(null);
154922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            webView.destroy();
155022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
155122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
155222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
155322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
155422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Remove the tab from the parent
155522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
155622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeFromTree() {
155722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // detach the children
1558c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren != null) {
1559c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            for(Tab t : mChildren) {
1560c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                t.setParent(null);
156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // remove itself from the parent list
1564c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1565c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mParent.mChildren.remove(this);
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
15671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        deleteThumbnail();
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Create a new subwindow unless a subwindow already exists.
157222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return True if a new subwindow was created. False if one already exists.
157322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
157422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean createSubWindow() {
157522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView == null) {
15761514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb            mWebViewController.createSubWindow(this);
1577211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
15788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController));
157922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setWebChromeClient(new SubWindowChromeClient(
158022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mWebChromeClient));
1581dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // Set a different DownloadListener for the mSubView, since it will
1582dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            // just need to dismiss the mSubView, rather than close the Tab
1583dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            mSubView.setDownloadListener(new DownloadListener() {
1584dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                public void onDownloadStart(String url, String userAgent,
1585dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        String contentDisposition, String mimetype,
1586dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        long contentLength) {
15878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mWebViewController.onDownloadStart(Tab.this, url, userAgent,
1588dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                            contentDisposition, mimetype, contentLength);
1589dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    if (mSubView.copyBackForwardList().getSize() == 0) {
1590dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // This subwindow was opened for the sole purpose of
1591dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                        // downloading a file. Remove it.
15928233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mWebViewController.dismissSubWindow(Tab.this);
1593dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                    }
1594dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins                }
1595dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins            });
15961461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(mWebViewController.getActivity());
159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return true;
159822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Dismiss the subWindow for the tab.
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void dismissSubWindow() {
160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
16078233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWebViewController.endActionMode();
160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.destroy();
160922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView = null;
161022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubViewContainer = null;
161122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
161222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
161322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
161522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the parent tab of this tab.
161722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
1618c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    void setParent(Tab parent) {
1619c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mParent = parent;
162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This tab may have been freed due to low memory. If that is the case,
1621c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // the parent tab id is already saved. If we are changing that id
162222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // (most likely due to removing the parent tab) we must update the
1623c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        // parent tab id in the saved Bundle.
162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSavedState != null) {
162522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (parent == null) {
162622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSavedState.remove(PARENTTAB);
162722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } else {
1628c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mSavedState.putLong(PARENTTAB, parent.getId());
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1631b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck
1632b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        // Sync the WebView useragent with the parent
1633b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        if (parent != null && mSettings.hasDesktopUseragent(parent.getWebView())
1634b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                != mSettings.hasDesktopUseragent(getWebView())) {
1635b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck            mSettings.toggleDesktopUseragent(getWebView());
1636b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        }
163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
163822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
163922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1640c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * If this Tab was created through another Tab, then this method returns
1641c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * that Tab.
1642c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * @return the Tab parent or null
1643c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     */
1644c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public Tab getParent() {
1645c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mParent;
1646c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    }
1647c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb
1648c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    /**
164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * When a Tab is created through the content of another Tab, then we
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * associate the Tabs.
165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param child the Tab that was created from this Tab
165222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
165322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void addChildTab(Tab child) {
1654c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mChildren == null) {
1655c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mChildren = new Vector<Tab>();
165622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1657c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mChildren.add(child);
1658c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        child.setParent(this);
165922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1661c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    Vector<Tab> getChildren() {
1662c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mChildren;
166322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
166522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void resume() {
166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onResume();
166822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onResume();
167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
167322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
167422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void pause() {
167522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView != null) {
167622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mMainView.onPause();
167722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mSubView != null) {
167822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSubView.onPause();
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
168022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
168122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
168222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInForeground() {
16848ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mInForeground) {
16858ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
16868ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = true;
168822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resume();
16891461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        Activity activity = mWebViewController.getActivity();
16901461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mMainView.setOnCreateContextMenuListener(activity);
169122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
16921461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mSubView.setOnCreateContextMenuListener(activity);
169322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
169422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the pending error dialog if the queue is not empty
169522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            showError(mQueuedErrors.getFirst());
169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
16981961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mWebViewController.bookmarkedStatusHasChanged(this);
169922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
170122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void putInBackground() {
17028ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (!mInForeground) {
17038ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            return;
17048ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
170522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mInForeground = false;
170622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        pause();
170722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMainView.setOnCreateContextMenuListener(null);
170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSubView.setOnCreateContextMenuListener(null);
171022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
171122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
171222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
17138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inForeground() {
17148233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInForeground;
17158233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17168233facddcc51865d612a919d450db6954aa48e3Michael Kolb
171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the top window of this tab; either the subwindow if it is not
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * null or the main window.
172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The top window of this tab.
172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getTopWindow() {
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSubView != null) {
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return mSubView;
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
172622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the main window of this tab. Note: if a tab is freed in the
173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * background, this can return null. It is only guaranteed to be
173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * non-null for the current tab.
173322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The main WebView of this tab.
173422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getWebView() {
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMainView;
173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1739a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    void setViewContainer(View container) {
1740a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mContainer = container;
1741a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
1742a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
17438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getViewContainer() {
17448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mContainer;
17458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17468233facddcc51865d612a919d450db6954aa48e3Michael Kolb
174722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
1748f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * Return whether private browsing is enabled for the main window of
1749f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * this tab.
1750f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     * @return True if private browsing is enabled.
1751f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk     */
17528233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isPrivateBrowsingEnabled() {
1753502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck        return mCurrentState.mIncognito;
1754f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    }
1755f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
1756f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk    /**
175722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the subwindow of this tab or null if there is no subwindow.
175822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The subwindow of this tab or null.
175922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
176022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    WebView getSubWebView() {
176122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mSubView;
176222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
176322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
17641514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubWebView(WebView subView) {
17651514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubView = subView;
17661514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
17671514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
17688233facddcc51865d612a919d450db6954aa48e3Michael Kolb    View getSubViewContainer() {
17698233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSubViewContainer;
17708233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17718233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17721514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    void setSubViewContainer(View subViewContainer) {
17731514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mSubViewContainer = subViewContainer;
17741514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
17751514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
177622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
177722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The geolocation permissions prompt for this tab.
177822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
177922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() {
178050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        if (mGeolocationPermissionsPrompt == null) {
178150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            ViewStub stub = (ViewStub) mContainer
178250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .findViewById(R.id.geolocation_permissions_prompt);
178350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba            mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub
178450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba                    .inflate();
178550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba        }
178622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mGeolocationPermissionsPrompt;
178722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
178822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
178922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
179022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The application id string
179122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
179222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getAppId() {
179322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mAppId;
179422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
179522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
179622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
179722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Set the application id string
179822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param id
179922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
180022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setAppId(String id) {
180122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = id;
180222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
180322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1804e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    boolean closeOnBack() {
1805e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        return mCloseOnBack;
1806e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1807e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
1808e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    void setCloseOnBack(boolean close) {
1809e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = close;
1810e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb    }
1811e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb
181222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getUrl() {
1813324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        return UrlUtils.filteredUrl(mCurrentState.mUrl);
181422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
181522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
181649a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    String getOriginalUrl() {
1817db22ec4ee014900988062d910bc810172a07df56John Reck        if (mCurrentState.mOriginalUrl == null) {
1818db22ec4ee014900988062d910bc810172a07df56John Reck            return getUrl();
181949a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        }
1820db22ec4ee014900988062d910bc810172a07df56John Reck        return UrlUtils.filteredUrl(mCurrentState.mOriginalUrl);
182149a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck    }
182249a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck
182322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
182430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the title of this tab.
182522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
182622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    String getTitle() {
182730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mCurrentState.mTitle == null && mInPageLoad) {
18281461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            return mContext.getString(R.string.title_bar_loading);
182922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
183030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mTitle;
183122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
183222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
183322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
183430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * Get the favicon of this tab.
183522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
183622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getFavicon() {
18371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mCurrentState.mFavicon != null) {
18381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCurrentState.mFavicon;
18391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
18401cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return getDefaultFavicon(mContext);
184122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
184222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1843e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    public boolean isBookmarkedSite() {
1844e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        return mCurrentState.mIsBookmarkedSite;
1845e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    }
1846f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk
184722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
184822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Return the tab's error console. Creates the console if createIfNEcessary
184922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * is true and we haven't already created the console.
185022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @param createIfNecessary Flag to indicate if the console should be
185122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *            created if it has not been already.
185222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return The tab's error console, or null if one has not been created and
185322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         createIfNecessary is false.
185422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
185522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    ErrorConsoleView getErrorConsole(boolean createIfNecessary) {
185622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (createIfNecessary && mErrorConsole == null) {
18571461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mErrorConsole = new ErrorConsoleView(mContext);
185822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsole.setWebView(mMainView);
185922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
186022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mErrorConsole;
186122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
186222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
186330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    private void setLockIconType(LockIcon icon) {
186430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mCurrentState.mLockIcon = icon;
186530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mWebViewController.onUpdatedLockIcon(this);
186622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
186722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
186822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
186930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck     * @return The tab's lock icon type.
187022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
187130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    LockIcon getLockIconType() {
187230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return mCurrentState.mLockIcon;
187322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
187422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
187530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    int getLoadProgress() {
187630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        if (mInPageLoad) {
187730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            return mPageLoadProgress;
187830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
187930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        return 100;
188022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
188122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
188222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
188322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * @return TRUE if onPageStarted is called while onPageFinished is not
188422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     *         called yet.
188522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
18868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean inPageLoad() {
18878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInPageLoad;
188822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
188922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
189022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // force mInLoad to be false. This should only be called before closing the
189122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly.
18928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void clearInPageLoad() {
18938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mInPageLoad = false;
189422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
189522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
189622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /**
18971cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck     * @return The Bundle with the tab's state if it can be saved, otherwise null
189822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
18991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    public Bundle saveState() {
190022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // If the WebView is null it means we ran low on memory and we already
190122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // stored the saved state in mSavedState.
190222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMainView == null) {
19031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mSavedState;
190422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
190524f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        // If the tab is the homepage or has no URL, don't save it
190624f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        String homepage = BrowserSettings.getInstance().getHomePage();
190724f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        if (TextUtils.equals(homepage, mCurrentState.mUrl)
190824f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck                || TextUtils.isEmpty(mCurrentState.mUrl)) {
19091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return null;
191024f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        }
191122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
191222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mSavedState = new Bundle();
1913541f55a0178da7c09fb32aa5385effae031ea071John Reck        mMainView.saveState(mSavedState);
191422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
1915c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mSavedState.putLong(ID, mId);
191630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRURL, mCurrentState.mUrl);
191730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
19181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState.putBoolean(INCOGNITO, mMainView.isPrivateBrowsingEnabled());
191922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mAppId != null) {
192022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mSavedState.putString(APPID, mAppId);
192122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1922e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mSavedState.putBoolean(CLOSEFLAG, mCloseOnBack);
192322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remember the parent tab so the relationship can be restored.
1924c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (mParent != null) {
1925c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mSavedState.putLong(PARENTTAB, mParent.mId);
192622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
1927b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        mSavedState.putBoolean(USERAGENT,
1928b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                mSettings.hasDesktopUseragent(getWebView()));
19291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return mSavedState;
193022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
193122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
193222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /*
193322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     * Restore the state of the tab.
193422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba     */
19351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void restoreState(Bundle b) {
19361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mSavedState = b;
19371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        if (mSavedState == null) {
19381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return;
193922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
194022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Restore the internal state even if the WebView fails to restore.
194122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // This will maintain the app id, original url and close-on-exit values.
1942c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mId = b.getLong(ID);
194322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mAppId = b.getString(APPID);
1944e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb        mCloseOnBack = b.getBoolean(CLOSEFLAG);
1945b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        if (b.getBoolean(USERAGENT)
1946b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck                != mSettings.hasDesktopUseragent(getWebView())) {
1947b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck            mSettings.toggleDesktopUseragent(getWebView());
1948b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck        }
19491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String url = b.getString(CURRURL);
19501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        String title = b.getString(CURRTITLE);
19511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        boolean incognito = b.getBoolean(INCOGNITO);
19521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState = new PageState(mContext, incognito, url, null);
19531cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        mCurrentState.mTitle = title;
19541cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
19551cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture != null) {
19561cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                BackgroundHandler.execute(mLoadThumbnail);
19571cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
195822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
195922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
1960211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III
19611961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    public void updateBookmarkedStatus() {
1962e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback);
19631961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    }
19641961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
1965e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback
1966e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            = new DataController.OnQueryUrlIsBookmark() {
1967e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        @Override
1968e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        public void onQueryUrlIsBookmark(String url, boolean isBookmark) {
1969e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck            if (mCurrentState.mUrl.equals(url)) {
1970e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mCurrentState.mIsBookmarkedSite = isBookmark;
1971e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck                mWebViewController.bookmarkedStatusHasChanged(Tab.this);
19721961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
1973e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        }
1974e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck    };
19751acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1976eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    public Bitmap getScreenshot() {
19771cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
19781cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return mCapture;
19791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
1980eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb    }
1981eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb
1982541f55a0178da7c09fb32aa5385effae031ea071John Reck    public boolean isSnapshot() {
1983541f55a0178da7c09fb32aa5385effae031ea071John Reck        return false;
1984541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
1985541f55a0178da7c09fb32aa5385effae031ea071John Reck
1986d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public ContentValues createSnapshotValues() {
1987d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        if (mMainView == null) return null;
19888cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        ByteArrayOutputStream bos = new ByteArrayOutputStream();
19898cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        try {
19908cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            GZIPOutputStream stream = new GZIPOutputStream(bos);
19918cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            if (!mMainView.saveViewState(stream)) {
19928cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                return null;
19938cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
19948cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            stream.flush();
19958cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            stream.close();
19968cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        } catch (Exception e) {
19978cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            Log.w(LOGTAG, "Failed to save view state", e);
1998541f55a0178da7c09fb32aa5385effae031ea071John Reck            return null;
1999541f55a0178da7c09fb32aa5385effae031ea071John Reck        }
20008cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        byte[] data = bos.toByteArray();
2001d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        ContentValues values = new ContentValues();
2002d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.TITLE, mCurrentState.mTitle);
2003d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.URL, mCurrentState.mUrl);
2004d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.VIEWSTATE, data);
2005d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        values.put(Snapshots.BACKGROUND, mMainView.getPageBackgroundColor());
20068cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        values.put(Snapshots.DATE_CREATED, System.currentTimeMillis());
20078cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        values.put(Snapshots.FAVICON, compressBitmap(getFavicon()));
20088cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        Bitmap screenshot = Controller.createScreenshot(mMainView,
20098cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                Controller.getDesiredThumbnailWidth(mContext),
20108cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                Controller.getDesiredThumbnailHeight(mContext));
20118cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot));
2012d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        return values;
2013541f55a0178da7c09fb32aa5385effae031ea071John Reck    }
2014541f55a0178da7c09fb32aa5385effae031ea071John Reck
20158cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public byte[] compressBitmap(Bitmap bitmap) {
20168cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (bitmap == null) {
20178cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
20188cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
20198cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        ByteArrayOutputStream stream = new ByteArrayOutputStream();
20208cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        bitmap.compress(CompressFormat.PNG, 100, stream);
20218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return stream.toByteArray();
20228cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
20238cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
202426b183292dc087b16af10f482744c3bb30e1f163John Reck    public void loadUrl(String url, Map<String, String> headers) {
202526b183292dc087b16af10f482744c3bb30e1f163John Reck        if (mMainView != null) {
20261461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            mCurrentState = new PageState(mContext, false, url, null);
202726b183292dc087b16af10f482744c3bb30e1f163John Reck            mWebViewController.onPageStarted(this, mMainView, null);
202826b183292dc087b16af10f482744c3bb30e1f163John Reck            mMainView.loadUrl(url, headers);
202926b183292dc087b16af10f482744c3bb30e1f163John Reck        }
203026b183292dc087b16af10f482744c3bb30e1f163John Reck    }
203126b183292dc087b16af10f482744c3bb30e1f163John Reck
20329ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    protected void capture() {
20339ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (mMainView == null || mCapture == null) return;
20349ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        Canvas c = new Canvas(mCapture);
20359ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int left = mMainView.getScrollX();
20369ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        final int top = mMainView.getScrollY() + mMainView.getVisibleTitleHeight();
20379ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.translate(-left, -top);
20389ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        float scale = mCaptureWidth / (float) mMainView.getWidth();
20399ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        c.scale(scale, scale, left, top);
20408ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (mMainView instanceof BrowserWebView) {
20418ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            ((BrowserWebView)mMainView).drawContent(c);
20428ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        } else {
20438ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            mMainView.draw(c);
20448ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
204543cfe8a4521b5c153055fbfa181940bc56bb3b06Dianne Hackborn        c.setBitmap(null);
20468ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        mHandler.removeMessages(MSG_CAPTURE);
20471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        persistThumbnail();
20488ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        TabControl tc = mWebViewController.getTabControl();
20498ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        if (tc != null) {
20508ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            OnThumbnailUpdatedListener updateListener
20518ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                    = tc.getOnThumbnailUpdatedListener();
20528ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            if (updateListener != null) {
20538ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck                updateListener.onThumbnailUpdated(this);
20548ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck            }
20558ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck        }
20569ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
20579ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
20589ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    @Override
20599ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    public void onNewPicture(WebView view, Picture picture) {
20609ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        //update screenshot
20611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        postCapture();
20621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
20631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
20641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void postCapture() {
20659ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        if (!mHandler.hasMessages(MSG_CAPTURE)) {
20669ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb            mHandler.sendEmptyMessageDelayed(MSG_CAPTURE, CAPTURE_DELAY);
20679ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb        }
20689ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb    }
20699ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb
2070ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoBack() {
2071ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoBack() : false;
2072ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2073ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
2074ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoForward() {
2075ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mMainView != null ? mMainView.canGoForward() : false;
2076ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2077ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
2078ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goBack() {
2079ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
2080ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goBack();
2081ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
2082ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2083ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
2084ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goForward() {
2085ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (mMainView != null) {
2086ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mMainView.goForward();
2087ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
2088ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
2089ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
20901dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    /**
20911dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * Causes the tab back/forward stack to be cleared once, if the given URL is the next URL
20921dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * to be added to the stack.
20931dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     *
20941dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * This is used to ensure that preloaded URLs that are not subsequently seen by the user do
20951dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     * not appear in the back stack.
20961dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood     */
20971dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    public void clearBackStackWhenItemAdded(String urlToMatch) {
20981dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood        mClearHistoryMatchUrl = urlToMatch;
20991dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood    }
21001dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood
21011cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void persistThumbnail() {
21021cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        BackgroundHandler.execute(mSaveThumbnail);
21031cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void deleteThumbnail() {
21061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        BackgroundHandler.execute(mDeleteThumbnail);
21071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21081cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private void updateCaptureFromBlob(byte[] blob) {
21101cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
21111cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture == null) {
21121cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                return;
21131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
2114bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            ByteBuffer buffer = ByteBuffer.wrap(blob);
2115d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            try {
2116d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                mCapture.copyPixelsFromBuffer(buffer);
2117d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb            } catch (RuntimeException rex) {
2118d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                Log.e(LOGTAG, "Load capture has mismatched sizes; buffer: "
2119d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + buffer.capacity() + " blob: " + blob.length
2120d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                        + "capture: " + mCapture.getByteCount());
2121d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb                throw rex;
2122bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb            }
21231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
21241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21251cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private byte[] getCaptureBlob() {
21271cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        synchronized (Tab.this) {
21281cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (mCapture == null) {
21291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                return null;
21301cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
21311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            ByteBuffer buffer = ByteBuffer.allocate(mCapture.getByteCount());
21321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            mCapture.copyPixelsToBuffer(buffer);
21331cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            return buffer.array();
21341cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
21351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
21361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private Runnable mSaveThumbnail = new Runnable() {
21381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        @Override
21401cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        public void run() {
21411cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            byte[] blob = getCaptureBlob();
21421cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            if (blob == null) {
21431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                return;
21441cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
21451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            ContentResolver cr = mContext.getContentResolver();
21461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            ContentValues values = new ContentValues();
21471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            values.put(Thumbnails._ID, mId);
21481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            values.put(Thumbnails.THUMBNAIL, blob);
21491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            cr.insert(Thumbnails.CONTENT_URI, values);
21501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
21511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    };
21521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21531cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private Runnable mDeleteThumbnail = new Runnable() {
21541cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21551cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        @Override
21561cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        public void run() {
21571cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            ContentResolver cr = mContext.getContentResolver();
21581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            try {
21591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                cr.delete(ContentUris.withAppendedId(Thumbnails.CONTENT_URI, mId),
21601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        null, null);
21611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            } catch (Throwable t) {}
21621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
21631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    };
21641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    private Runnable mLoadThumbnail = new Runnable() {
21661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
21671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        @Override
21681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        public void run() {
21691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            ContentResolver cr = mContext.getContentResolver();
21701cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            Cursor c = null;
21711cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            try {
21721cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                Uri uri = ContentUris.withAppendedId(Thumbnails.CONTENT_URI, mId);
21731cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                c = cr.query(uri, new String[] {Thumbnails._ID,
21741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        Thumbnails.THUMBNAIL}, null, null, null);
21751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                if (c.moveToFirst()) {
21761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    byte[] data = c.getBlob(1);
21771cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    if (data != null && data.length > 0) {
21781cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                        updateCaptureFromBlob(data);
21791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    }
21801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
21811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            } finally {
21821cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                if (c != null) {
21831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                    c.close();
21841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck                }
21851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck            }
21861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        }
21871cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    };
21881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
218922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba}
2190