Tab.java revision e09305e4ad0430571efb8ae880762204ddeaeb33
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; 596c2e2f34718043f36488b4a94879dc2605aaac49John Reckimport android.webkit.WebBackForwardList; 600c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scrogginsimport android.webkit.WebBackForwardListClient; 6122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebChromeClient; 6222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebHistoryItem; 63438bf46c98890b5fe1356e75b4bc759033c6fc57John Reckimport android.webkit.WebResourceResponse; 6422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebStorage; 6522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebView; 669ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbimport android.webkit.WebView.PictureListener; 6722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.webkit.WebViewClient; 681d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdochimport android.widget.CheckBox; 6922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.LinearLayout; 7022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Klobaimport android.widget.TextView; 718029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.widget.Toast; 7222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 738ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reckimport com.android.browser.TabControl.OnThumbnailUpdatedListener; 74541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.browser.homepages.HomeProvider; 751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport com.android.browser.provider.BrowserProvider2.Thumbnails; 768cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots; 77541f55a0178da7c09fb32aa5385effae031ea071John Reckimport com.android.common.speech.LoggingEvents; 78541f55a0178da7c09fb32aa5385effae031ea071John Reck 79541f55a0178da7c09fb32aa5385effae031ea071John Reckimport java.io.ByteArrayOutputStream; 801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport java.nio.ByteBuffer; 81fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.ArrayList; 82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.HashMap; 83fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Iterator; 84fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.LinkedList; 85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Map; 86fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector; 878cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.util.zip.GZIPOutputStream; 88fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb 8922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba/** 9022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Class for maintaining Tabs with a main WebView and a subwindow. 9122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 929ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolbclass Tab implements PictureListener { 938233facddcc51865d612a919d450db6954aa48e3Michael Kolb 9422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Log Tag 9522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private static final String LOGTAG = "Tab"; 961dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED; 97c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch // Special case the logtag for messages for the Console to make it easier to 98c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch // filter them and match the logtag used for these messages in older versions 99c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch // of the browser. 100c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch private static final String CONSOLE_LOGTAG = "browser"; 101c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch 1029ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb private static final int MSG_CAPTURE = 42; 1038ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck private static final int CAPTURE_DELAY = 100; 1049ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb 1051cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private static Bitmap sDefaultFavicon; 1061cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 10730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck public enum LockIcon { 10830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck LOCK_ICON_UNSECURE, 10930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck LOCK_ICON_SECURE, 11030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck LOCK_ICON_MIXED, 11130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } 1128233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1131461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb Context mContext; 114d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck protected WebViewController mWebViewController; 1158233facddcc51865d612a919d450db6954aa48e3Michael Kolb 116c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb // The tab ID 117d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck private long mId = -1; 118c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 11922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // The Geolocation permissions prompt 12022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt; 12122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Main WebView wrapper 122a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb private View mContainer; 12322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Main WebView 12422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private WebView mMainView; 12522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Subwindow container 12622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private View mSubViewContainer; 12722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Subwindow WebView 12822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private WebView mSubView; 12922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Saved bundle for when we are running low on memory. It contains the 13022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // information needed to restore the WebView if the user goes back to the 13122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // tab. 13222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private Bundle mSavedState; 13322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Parent Tab. This is the Tab that created this Tab, or null if the Tab was 13422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // created by the UI 135c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb private Tab mParent; 13622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Tab that constructed by this Tab. This is used when this Tab is 13722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // destroyed, it clears all mParentTab values in the children. 138c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb private Vector<Tab> mChildren; 13922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // If true, the tab is in the foreground of the current activity. 14022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private boolean mInForeground; 1418233facddcc51865d612a919d450db6954aa48e3Michael Kolb // If true, the tab is in page loading state (after onPageStarted, 1428233facddcc51865d612a919d450db6954aa48e3Michael Kolb // before onPageFinsihed) 1438233facddcc51865d612a919d450db6954aa48e3Michael Kolb private boolean mInPageLoad; 14430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck // The last reported progress of the current page 14530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck private int mPageLoadProgress; 1464dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen // The time the load started, used to find load page time 1474dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen private long mLoadStartTime; 14822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Application identifier used to find tabs that another application wants 14922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // to reuse. 15022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private String mAppId; 151e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb // flag to indicate if tab should be closed on back 152e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb private boolean mCloseOnBack; 15322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Keep the original url around to avoid killing the old WebView if the url 15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // has not changed. 15522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Error console for the tab 15622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private ErrorConsoleView mErrorConsole; 157dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // The listener that gets invoked when a download is started from the 158dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // mMainView 159dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins private final DownloadListener mDownloadListener; 1600c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins // Listener used to know when we move forward or back in the history list. 1610c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins private final WebBackForwardListClient mWebBackForwardListClient; 162e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private DataController mDataController; 1639206677e461328f15854c5fcb1366d0e261534c6Patrick Scott // State of the auto-login request. 1649206677e461328f15854c5fcb1366d0e261534c6Patrick Scott private DeviceAccountLogin mDeviceAccountLogin; 16522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 16622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // AsyncTask for downloading touch icons 16722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba DownloadTouchIcon mTouchIconLoader; 16822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 16935e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck private BrowserSettings mSettings; 1709ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb private int mCaptureWidth; 1719ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb private int mCaptureHeight; 1729ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb private Bitmap mCapture; 1739ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb private Handler mHandler; 1749ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb 1751dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood /** 1761dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood * See {@link #clearBackStackWhenItemAdded(String)}. 1771dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood */ 1781dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood private String mClearHistoryMatchUrl; 1791dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood 1801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private static synchronized Bitmap getDefaultFavicon(Context context) { 1811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (sDefaultFavicon == null) { 1821cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck sDefaultFavicon = BitmapFactory.decodeResource( 1831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck context.getResources(), R.drawable.app_web_browser_sm); 1841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 1851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return sDefaultFavicon; 1861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 187eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb 18830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck // All the state needed for a page 189d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck protected static class PageState { 19030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck String mUrl; 191db22ec4ee014900988062d910bc810172a07df56John Reck String mOriginalUrl; 19230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck String mTitle; 19330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck LockIcon mLockIcon; 19430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck Bitmap mFavicon; 195502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck boolean mIsBookmarkedSite = false; 196502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck boolean mIncognito = false; 19730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck 19830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck PageState(Context c, boolean incognito) { 199502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck mIncognito = incognito; 200502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck if (mIncognito) { 201db22ec4ee014900988062d910bc810172a07df56John Reck mOriginalUrl = mUrl = "browser:incognito"; 20230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mTitle = c.getString(R.string.new_incognito_tab); 20330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } else { 204db22ec4ee014900988062d910bc810172a07df56John Reck mOriginalUrl = mUrl = ""; 20530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mTitle = c.getString(R.string.new_tab); 20630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } 2071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mFavicon = null; 20830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mLockIcon = LockIcon.LOCK_ICON_UNSECURE; 20930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } 21030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck 21130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck PageState(Context c, boolean incognito, String url, Bitmap favicon) { 212502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck mIncognito = incognito; 213db22ec4ee014900988062d910bc810172a07df56John Reck mOriginalUrl = mUrl = url; 21430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mTitle = null; 21530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck if (URLUtil.isHttpsUrl(url)) { 21630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mLockIcon = LockIcon.LOCK_ICON_SECURE; 21730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } else { 21830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mLockIcon = LockIcon.LOCK_ICON_UNSECURE; 21930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } 2201cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mFavicon = favicon; 22130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } 2221cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 22322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 22422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 22530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck // The current/loading page's state 226d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck protected PageState mCurrentState; 22730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck 22822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Used for saving and restoring each Tab 229c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb static final String ID = "ID"; 23022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba static final String CURRURL = "currentUrl"; 23122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba static final String CURRTITLE = "currentTitle"; 23222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba static final String PARENTTAB = "parentTab"; 23322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba static final String APPID = "appid"; 2343d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter static final String INCOGNITO = "privateBrowsingEnabled"; 235b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck static final String USERAGENT = "useragent"; 236e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb static final String CLOSEFLAG = "closeOnBack"; 23722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 23822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 23922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 24058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /** 24158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * Private information regarding the latest voice search. If the Tab is not 24258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * in voice search mode, this will be null. 24358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 24458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins private VoiceSearchData mVoiceSearchData; 24558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /** 24695d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III * Remove voice search mode from this tab. 24795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III */ 24895d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III public void revertVoiceSearchMode() { 24995d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III if (mVoiceSearchData != null) { 25095d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III mVoiceSearchData = null; 25195d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III if (mInForeground) { 2528233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.revertVoiceSearchMode(this); 25395d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III } 25495d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III } 25595d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III } 2568233facddcc51865d612a919d450db6954aa48e3Michael Kolb 25795d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III /** 25858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * Return whether the tab is in voice search mode. 25958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 26058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public boolean isInVoiceSearchMode() { 26158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins return mVoiceSearchData != null; 26258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 26358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /** 264c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III * Return true if the Tab is in voice search mode and the voice search 265c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III * Intent came with a String identifying that Google provided the Intent. 2661fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins */ 2671fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins public boolean voiceSearchSourceIsGoogle() { 2681fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins return mVoiceSearchData != null && mVoiceSearchData.mSourceIsGoogle; 2691fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins } 2701fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins /** 27158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * Get the title to display for the current voice search page. If the Tab 27258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * is not in voice search mode, return null. 27358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 27458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public String getVoiceDisplayTitle() { 27558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins if (mVoiceSearchData == null) return null; 27658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins return mVoiceSearchData.mLastVoiceSearchTitle; 27758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 27858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /** 27958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * Get the latest array of voice search results, to be passed to the 28058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * BrowserProvider. If the Tab is not in voice search mode, return null. 28158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 28258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public ArrayList<String> getVoiceSearchResults() { 28358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins if (mVoiceSearchData == null) return null; 28458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins return mVoiceSearchData.mVoiceSearchResults; 28558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 28658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /** 28758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * Activate voice search mode. 28858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * @param intent Intent which has the results to use, or an index into the 28958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * results when reusing the old results. 29058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 29158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /* package */ void activateVoiceSearchMode(Intent intent) { 29282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins int index = 0; 29358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins ArrayList<String> results = intent.getStringArrayListExtra( 294a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS); 29558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins if (results != null) { 29682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins ArrayList<String> urls = intent.getStringArrayListExtra( 29782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS); 29882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins ArrayList<String> htmls = intent.getStringArrayListExtra( 29982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_HTML); 30082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins ArrayList<String> baseUrls = intent.getStringArrayListExtra( 30182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins RecognizerResultsIntent 30282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins .EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS); 30358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins // This tab is now entering voice search mode for the first time, or 30458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins // a new voice search was done. 30582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins int size = results.size(); 30682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins if (urls == null || size != urls.size()) { 30758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins throw new AssertionError("improper extras passed in Intent"); 30858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 30982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins if (htmls == null || htmls.size() != size || baseUrls == null || 31082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins (baseUrls.size() != size && baseUrls.size() != 1)) { 31182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins // If either of these arrays are empty/incorrectly sized, ignore 31282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins // them. 31382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins htmls = null; 31482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins baseUrls = null; 31582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins } 31682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mVoiceSearchData = new VoiceSearchData(results, urls, htmls, 31782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins baseUrls); 3189df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra( 3199df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins RecognizerResultsIntent 3209df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS); 3211fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra( 3221fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins VoiceSearchData.SOURCE_IS_GOOGLE, false); 3232ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins mVoiceSearchData.mVoiceSearchIntent = new Intent(intent); 324e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins } 325e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins String extraData = intent.getStringExtra( 326e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins SearchManager.EXTRA_DATA_KEY); 327e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins if (extraData != null) { 328e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins index = Integer.parseInt(extraData); 329e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins if (index >= mVoiceSearchData.mVoiceSearchResults.size()) { 330e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins throw new AssertionError("index must be less than " 331e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins + "size of mVoiceSearchResults"); 332e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins } 333e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins if (mVoiceSearchData.mSourceIsGoogle) { 334e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins Intent logIntent = new Intent( 335e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins LoggingEvents.ACTION_LOG_EVENT); 336e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins logIntent.putExtra(LoggingEvents.EXTRA_EVENT, 337e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins LoggingEvents.VoiceSearch.N_BEST_CHOOSE); 338e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins logIntent.putExtra( 339e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX, 340e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins index); 3411461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mContext.sendBroadcast(logIntent); 342e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins } 343e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins if (mVoiceSearchData.mVoiceSearchIntent != null) { 3442ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins // Copy the Intent, so that each history item will have its own 3452ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins // Intent, with different (or none) extra data. 3462ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent); 3472ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData); 3482ee4a5acc5c1ef87afa02830b31770cb1359b626Leon Scroggins mVoiceSearchData.mVoiceSearchIntent = latest; 34958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 35058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 35158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins mVoiceSearchData.mLastVoiceSearchTitle 35282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins = mVoiceSearchData.mVoiceSearchResults.get(index); 35358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins if (mInForeground) { 35411d1978d8d16004598347abc93918b54a5ef760bMichael Kolb mWebViewController.activateVoiceSearchMode( 35511d1978d8d16004598347abc93918b54a5ef760bMichael Kolb mVoiceSearchData.mLastVoiceSearchTitle, 35611d1978d8d16004598347abc93918b54a5ef760bMichael Kolb mVoiceSearchData.mVoiceSearchResults); 35758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 35882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins if (mVoiceSearchData.mVoiceSearchHtmls != null) { 35982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins // When index was found it was already ensured that it was valid 36082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins String uriString = mVoiceSearchData.mVoiceSearchHtmls.get(index); 36182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins if (uriString != null) { 36282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins Uri dataUri = Uri.parse(uriString); 36382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins if (RecognizerResultsIntent.URI_SCHEME_INLINE.equals( 36482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins dataUri.getScheme())) { 36582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins // If there is only one base URL, use it. If there are 36682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins // more, there will be one for each index, so use the base 36782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins // URL corresponding to the index. 36882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins String baseUrl = mVoiceSearchData.mVoiceSearchBaseUrls.get( 36982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mVoiceSearchData.mVoiceSearchBaseUrls.size() > 1 ? 37082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins index : 0); 37182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mVoiceSearchData.mLastVoiceSearchUrl = baseUrl; 37282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mMainView.loadDataWithBaseURL(baseUrl, 37382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins uriString.substring(RecognizerResultsIntent 37482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins .URI_SCHEME_INLINE.length() + 1), "text/html", 37582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins "utf-8", baseUrl); 37682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins return; 37782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins } 37882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins } 37982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins } 38058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins mVoiceSearchData.mLastVoiceSearchUrl 38182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins = mVoiceSearchData.mVoiceSearchUrls.get(index); 38282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins if (null == mVoiceSearchData.mLastVoiceSearchUrl) { 3838233facddcc51865d612a919d450db6954aa48e3Michael Kolb mVoiceSearchData.mLastVoiceSearchUrl = UrlUtils.smartUrlFilter( 38482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mVoiceSearchData.mLastVoiceSearchTitle); 38582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins } 3869df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins Map<String, String> headers = null; 3879df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins if (mVoiceSearchData.mHeaders != null) { 3889df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0 3899df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins : index; 3909df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex); 3919df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins if (bundle != null && !bundle.isEmpty()) { 3929df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins Iterator<String> iter = bundle.keySet().iterator(); 3939df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins headers = new HashMap<String, String>(); 3949df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins while (iter.hasNext()) { 3959df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins String key = iter.next(); 3969df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins headers.put(key, bundle.getString(key)); 3979df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins } 3989df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins } 3999df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins } 4009df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers); 40158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 40258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /* package */ static class VoiceSearchData { 40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public VoiceSearchData(ArrayList<String> results, 40482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins ArrayList<String> urls, ArrayList<String> htmls, 40582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins ArrayList<String> baseUrls) { 40658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins mVoiceSearchResults = results; 40758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins mVoiceSearchUrls = urls; 40882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mVoiceSearchHtmls = htmls; 40982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins mVoiceSearchBaseUrls = baseUrls; 41058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 41158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /* 41258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * ArrayList of suggestions to be displayed when opening the 41358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * SearchManager 41458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 41558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public ArrayList<String> mVoiceSearchResults; 41658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /* 41758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * ArrayList of urls, associated with the suggestions in 41858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * mVoiceSearchResults. 41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 42058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public ArrayList<String> mVoiceSearchUrls; 42158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /* 42282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * ArrayList holding content to load for each item in 42382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * mVoiceSearchResults. 42482c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins */ 42582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins public ArrayList<String> mVoiceSearchHtmls; 42682c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins /* 42782c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * ArrayList holding base urls for the items in mVoiceSearchResults. 42882c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * If non null, this will either have the same size as 42982c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * mVoiceSearchResults or have a size of 1, in which case all will use 43082c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * the same base url 43182c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins */ 43282c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins public ArrayList<String> mVoiceSearchBaseUrls; 43382c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins /* 43458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * The last url provided by voice search. Used for comparison to see if 43582c1baa16a66eabdd7fd1eb6569e61cb6caac4fdLeon Scroggins * we are going to a page by some method besides voice search. 43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 43758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public String mLastVoiceSearchUrl; 43858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins /** 43958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * The last title used for voice search. Needed to update the title bar 44058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins * when switching tabs. 44158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins */ 44258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins public String mLastVoiceSearchTitle; 4431fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins /** 4441fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins * Whether the Intent which turned on voice search mode contained the 4451fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins * String signifying that Google was the source. 4461fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins */ 4471fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins public boolean mSourceIsGoogle; 4481fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins /** 4499df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins * List of headers to be passed into the WebView containing location 4509df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins * information 4519df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins */ 4529df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins public ArrayList<Bundle> mHeaders; 4539df949776c726b05ead037a8ba2d2d2c14cb5dcaLeon Scroggins /** 4540c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins * The Intent used to invoke voice search. Placed on the 4550c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins * WebHistoryItem so that when coming back to a previous voice search 4560c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins * page we can again activate voice search. 4570c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins */ 458e10dde5aab881bd791094edd80c6e438d4601787Leon Scroggins public Intent mVoiceSearchIntent; 4590c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins /** 4601fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins * String used to identify Google as the source of voice search. 4611fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins */ 4621fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins public static String SOURCE_IS_GOOGLE 4631fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins = "android.speech.extras.SOURCE_IS_GOOGLE"; 46458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 46558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins 46622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Container class for the next error dialog that needs to be displayed 46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private class ErrorDialog { 46822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public final int mTitle; 46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public final String mDescription; 47022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public final int mError; 47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba ErrorDialog(int title, String desc, int error) { 47222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mTitle = title; 47322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mDescription = desc; 47422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mError = error; 47522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 4768233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 47722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 47822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private void processNextError() { 47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mQueuedErrors == null) { 48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 48122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 48222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // The first one is currently displayed so just remove it. 48322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mQueuedErrors.removeFirst(); 48422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mQueuedErrors.size() == 0) { 48522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mQueuedErrors = null; 48622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 48722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 48822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba showError(mQueuedErrors.getFirst()); 48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 49022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 49122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private DialogInterface.OnDismissListener mDialogListener = 49222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnDismissListener() { 49322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onDismiss(DialogInterface d) { 49422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba processNextError(); 49522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }; 49722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private LinkedList<ErrorDialog> mQueuedErrors; 49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 49922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private void queueError(int err, String desc) { 50022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mQueuedErrors == null) { 50122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mQueuedErrors = new LinkedList<ErrorDialog>(); 50222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 50322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba for (ErrorDialog d : mQueuedErrors) { 50422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (d.mError == err) { 50522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Already saw a similar error, ignore the new one. 50622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 50822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 50922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba ErrorDialog errDialog = new ErrorDialog( 51022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba err == WebViewClient.ERROR_FILE_NOT_FOUND ? 51122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba R.string.browserFrameFileErrorLabel : 51222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba R.string.browserFrameNetworkErrorLabel, 51322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba desc, err); 51422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mQueuedErrors.addLast(errDialog); 51522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 51622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Show the dialog now if the queue was empty and it is in foreground 51722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mQueuedErrors.size() == 1 && mInForeground) { 51822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba showError(errDialog); 51922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 52022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 52122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 52222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private void showError(ErrorDialog errDialog) { 52322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 5241461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb AlertDialog d = new AlertDialog.Builder(mContext) 52522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setTitle(errDialog.mTitle) 52622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setMessage(errDialog.mDescription) 52722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setPositiveButton(R.string.ok, null) 52822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .create(); 52922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba d.setOnDismissListener(mDialogListener); 53022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba d.show(); 53122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 53222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 53322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 53522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // WebViewClient implementation for the main WebView 53622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 53722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 53822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private final WebViewClient mWebViewClient = new WebViewClient() { 5394a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins private Message mDontResend; 5404a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins private Message mResend; 54147bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb 54247bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb private boolean providersDiffer(String url, String otherUrl) { 54347bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb Uri uri1 = Uri.parse(url); 54447bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb Uri uri2 = Uri.parse(otherUrl); 54547bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb return !uri1.getEncodedAuthority().equals(uri2.getEncodedAuthority()); 54647bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb } 54747bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb 54822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 54922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onPageStarted(WebView view, String url, Bitmap favicon) { 5508233facddcc51865d612a919d450db6954aa48e3Michael Kolb mInPageLoad = true; 55130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mPageLoadProgress = 0; 5521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mCurrentState = new PageState(mContext, 55330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck view.isPrivateBrowsingEnabled(), url, favicon); 5544dce3bf588b7eaf4de555a93b67f5ddf9bc1ba77Kristian Monsen mLoadStartTime = SystemClock.uptimeMillis(); 55558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins if (mVoiceSearchData != null 55647bd1e4867a73db641a6f157e4a1f1e278b10cf3Michael Kolb && providersDiffer(url, mVoiceSearchData.mLastVoiceSearchUrl)) { 5571fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins if (mVoiceSearchData.mSourceIsGoogle) { 5581fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT); 5591fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins i.putExtra(LoggingEvents.EXTRA_FLUSH, true); 5601461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mContext.sendBroadcast(i); 5611fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins } 56295d9bfd1d67902a8aa5d2e529db7f7064db081b7Leon Scroggins III revertVoiceSearchMode(); 56358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins } 56422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 56522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // If we start a touch icon load and then load a new page, we don't 56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // want to cancel the current touch icon loader. But, we do want to 56822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // create a new one when the touch icon url is known. 56922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mTouchIconLoader != null) { 57022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mTouchIconLoader.mTab = null; 57122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mTouchIconLoader = null; 57222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 57322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 57422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // reset the error console 57522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mErrorConsole != null) { 57622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mErrorConsole.clearErrorMessages(); 5778233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (mWebViewController.shouldShowErrorConsole()) { 57822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mErrorConsole.showConsole(ErrorConsoleView.SHOW_NONE); 57922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 58022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 58122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 5829206677e461328f15854c5fcb1366d0e261534c6Patrick Scott // Cancel the auto-login process. 5839206677e461328f15854c5fcb1366d0e261534c6Patrick Scott if (mDeviceAccountLogin != null) { 5849206677e461328f15854c5fcb1366d0e261534c6Patrick Scott mDeviceAccountLogin.cancel(); 5859206677e461328f15854c5fcb1366d0e261534c6Patrick Scott mDeviceAccountLogin = null; 5869206677e461328f15854c5fcb1366d0e261534c6Patrick Scott mWebViewController.hideAutoLogin(Tab.this); 5879206677e461328f15854c5fcb1366d0e261534c6Patrick Scott } 5889206677e461328f15854c5fcb1366d0e261534c6Patrick Scott 58922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // finally update the UI in the activity if it is in the foreground 590324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck mWebViewController.onPageStarted(Tab.this, view, favicon); 5914cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins 592e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck updateBookmarkedStatus(); 59322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 59422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 59522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 59622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onPageFinished(WebView view, String url) { 597a169628f9424256e5bcf45807869c4c4eaa114c0John Reck if (!mInPageLoad) { 598a169628f9424256e5bcf45807869c4c4eaa114c0John Reck // In page navigation links (www.something.com#footer) will 599a169628f9424256e5bcf45807869c4c4eaa114c0John Reck // trigger an onPageFinished which we don't care about. 600a169628f9424256e5bcf45807869c4c4eaa114c0John Reck return; 601a169628f9424256e5bcf45807869c4c4eaa114c0John Reck } 6025b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck if (!isPrivateBrowsingEnabled()) { 6035b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck LogTag.logPageFinishedLoading( 6045b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck url, SystemClock.uptimeMillis() - mLoadStartTime); 6055b69184c0f6b1d65eb444832cdff3f1e1304bdbdJohn Reck } 6068233facddcc51865d612a919d450db6954aa48e3Michael Kolb mInPageLoad = false; 6071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck syncCurrentState(view, url); 608324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck mWebViewController.onPageFinished(Tab.this); 60922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 61022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 61122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // return true if want to hijack the url to let another app to handle it 61222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 61322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public boolean shouldOverrideUrlLoading(WebView view, String url) { 614c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III if (voiceSearchSourceIsGoogle()) { 615c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III // This method is called when the user clicks on a link. 616c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III // VoiceSearchMode is turned off when the user leaves the 617c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III // Google results page, so at this point the user must be on 618c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III // that page. If the user clicked a link on that page, assume 619c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III // that the voice search was effective, and broadcast an Intent 620c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III // so a receiver can take note of that fact. 621c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III Intent logIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT); 622c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III logIntent.putExtra(LoggingEvents.EXTRA_EVENT, 623c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III LoggingEvents.VoiceSearch.RESULT_CLICKED); 6241461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mContext.sendBroadcast(logIntent); 625c1f5ae26d76a49e6bac9f3224ddb14eee74d4974Leon Scroggins III } 62622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 62718eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb return mWebViewController.shouldOverrideUrlLoading(Tab.this, 62818eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb view, url); 62922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } else { 63022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return false; 63122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 63222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 63322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 63422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 63522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Updates the lock icon. This method is called when we discover another 63622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * resource to be loaded for this page (for example, javascript). While 63722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * we update the icon type, we do not update the lock icon itself until 63822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * we are done loading, it is slightly more secure this way. 63922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 64022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 64122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onLoadResource(WebView view, String url) { 64222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (url != null && url.length() > 0) { 64322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // It is only if the page claims to be secure that we may have 64422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // to update the lock: 64530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck if (mCurrentState.mLockIcon == LockIcon.LOCK_ICON_SECURE) { 64622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // If NOT a 'safe' url, change the lock to mixed content! 64722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) 64822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba || URLUtil.isAboutUrl(url))) { 64930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mCurrentState.mLockIcon = LockIcon.LOCK_ICON_MIXED; 65022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 65122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 65222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 65322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 65422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 65522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 65622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Show a dialog informing the user of the network error reported by 65722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * WebCore if it is in the foreground. 65822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 65922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 66022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedError(WebView view, int errorCode, 66122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba String description, String failingUrl) { 66222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (errorCode != WebViewClient.ERROR_HOST_LOOKUP && 66322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba errorCode != WebViewClient.ERROR_CONNECT && 66422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba errorCode != WebViewClient.ERROR_BAD_URL && 66522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME && 66622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba errorCode != WebViewClient.ERROR_FILE) { 66722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba queueError(errorCode, description); 66822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 66947654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton 67047654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton // Don't log URLs when in private browsing mode 671f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk if (!isPrivateBrowsingEnabled()) { 67247654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl 67347654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton + " " + description); 67447654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton } 67522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 67622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 67722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 67822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Check with the user if it is ok to resend POST data as the page they 67922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * are trying to navigate to is the result of a POST. 68022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 68122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 68222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onFormResubmission(WebView view, final Message dontResend, 68322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final Message resend) { 68422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (!mInForeground) { 68522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba dontResend.sendToTarget(); 68622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 68722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 6884a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins if (mDontResend != null) { 6894a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins Log.w(LOGTAG, "onFormResubmission should not be called again " 6904a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins + "while dialog is still up"); 6914a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins dontResend.sendToTarget(); 6924a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins return; 6934a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins } 6944a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mDontResend = dontResend; 6954a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mResend = resend; 6961461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb new AlertDialog.Builder(mContext).setTitle( 69722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba R.string.browserFrameFormResubmitLabel).setMessage( 69822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba R.string.browserFrameFormResubmitMessage) 69922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setPositiveButton(R.string.ok, 70022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnClickListener() { 70122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface dialog, 70222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba int which) { 7034a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins if (mResend != null) { 7044a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mResend.sendToTarget(); 7054a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mResend = null; 7064a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mDontResend = null; 7074a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins } 70822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }).setNegativeButton(R.string.cancel, 71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnClickListener() { 71122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface dialog, 71222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba int which) { 7134a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins if (mDontResend != null) { 7144a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mDontResend.sendToTarget(); 7154a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mResend = null; 7164a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mDontResend = null; 7174a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins } 71822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 71922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }).setOnCancelListener(new OnCancelListener() { 72022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onCancel(DialogInterface dialog) { 7214a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins if (mDontResend != null) { 7224a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mDontResend.sendToTarget(); 7234a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mResend = null; 7244a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins mDontResend = null; 7254a64a8a375b1531392a068039e3c4ee3a636b1ecLeon Scroggins } 72622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 72722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }).show(); 72822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 72922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 73022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 73122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Insert the url into the visited history database. 73222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param url The url to be inserted. 73322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param isReload True if this url is being reloaded. 73422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * FIXME: Not sure what to do when reloading the page. 73522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 73622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 73722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void doUpdateVisitedHistory(WebView view, String url, 73822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba boolean isReload) { 739324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck mWebViewController.doUpdateVisitedHistory(Tab.this, isReload); 74022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 74122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Displays SSL error(s) dialog to the user. 74422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedSslError(final WebView view, 74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final SslErrorHandler handler, final SslError error) { 74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (!mInForeground) { 74922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba handler.cancel(); 75030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck setLockIconType(LockIcon.LOCK_ICON_UNSECURE); 75122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 75222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 75335e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck if (mSettings.showSecurityWarnings()) { 754cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck new AlertDialog.Builder(mContext) 755cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setTitle(R.string.security_warning) 756cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setMessage(R.string.ssl_warnings_header) 757cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setIcon(android.R.drawable.ic_dialog_alert) 758cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setPositiveButton(R.string.ssl_continue, 75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnClickListener() { 760cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck @Override 76122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface dialog, 76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba int whichButton) { 76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba handler.proceed(); 76422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 765cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck }) 766cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setNeutralButton(R.string.view_certificate, 76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnClickListener() { 768cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck @Override 76922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface dialog, 77022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba int whichButton) { 771cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck mWebViewController.showSslCertificateOnError( 772cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck view, handler, error); 77322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 774cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck }) 775cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setNegativeButton(R.string.ssl_go_back, 77622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnClickListener() { 777cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck @Override 77822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface dialog, 77922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba int whichButton) { 78030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck dialog.cancel(); 78122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 782cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck }) 783cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .setOnCancelListener( 78422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new DialogInterface.OnCancelListener() { 785cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck @Override 78622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onCancel(DialogInterface dialog) { 78722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba handler.cancel(); 78830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck setLockIconType(LockIcon.LOCK_ICON_UNSECURE); 78930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mWebViewController.onUserCanceledSsl(Tab.this); 79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 791cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck }) 792cb28b2cfe64bb1b8e1fe379aa59bf1b0e93ae790John Reck .show(); 79322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } else { 79422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba handler.proceed(); 79522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 79622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 79722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 79822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 7998862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom * Displays client certificate request to the user. 8008862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom */ 8018862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom @Override 8028862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom public void onReceivedClientCertRequest(final WebView view, 8038862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom final ClientCertRequestHandler handler, final String host_and_port) { 8048862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom if (!mInForeground) { 8058862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom handler.ignore(); 8068862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom return; 8078862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom } 8086d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom int colon = host_and_port.lastIndexOf(':'); 8096d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom String host; 8106d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom int port; 8116d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom if (colon == -1) { 8126d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom host = host_and_port; 8136d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom port = -1; 8146d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom } else { 8156d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom String portString = host_and_port.substring(colon + 1); 8166d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom try { 8176d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom port = Integer.parseInt(portString); 8186d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom host = host_and_port.substring(0, colon); 8196d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom } catch (NumberFormatException e) { 8206d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom host = host_and_port; 8216d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom port = -1; 8226d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom } 8236d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom } 8241461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb KeyChain.choosePrivateKeyAlias( 8251461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mWebViewController.getActivity(), new KeyChainAliasCallback() { 8268862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom @Override public void alias(String alias) { 8278862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom if (alias == null) { 8288862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom handler.cancel(); 8298862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom return; 8308862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom } 8311461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb new KeyChainLookup(mContext, handler, alias).execute(); 8328862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom } 8336d85fab73e2c0359968fc6580594689940f5dabcBrian Carlstrom }, null, null, host, port, null); 8348862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom } 8358862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom 8368862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom /** 83722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Handles an HTTP authentication request. 83822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * 83922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param handler The authentication handler 84022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param host The host 84122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param realm The realm 84222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 84322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 84422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedHttpAuthRequest(WebView view, 84522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final HttpAuthHandler handler, final String host, 84622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final String realm) { 8478233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.onReceivedHttpAuthRequest(Tab.this, view, handler, host, realm); 84822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 84922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 85022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 851438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck public WebResourceResponse shouldInterceptRequest(WebView view, 852438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck String url) { 853438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck WebResourceResponse res = HomeProvider.shouldInterceptRequest( 8541461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mContext, url); 855438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck return res; 856438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck } 857438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck 858438bf46c98890b5fe1356e75b4bc759033c6fc57John Reck @Override 85922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) { 86022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (!mInForeground) { 86122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return false; 86222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 8638233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mWebViewController.shouldOverrideKeyEvent(event); 86422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 86522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 86622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 86722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onUnhandledKeyEvent(WebView view, KeyEvent event) { 8688233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (!mInForeground) { 86922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 87022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 8718233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.onUnhandledKeyEvent(event); 87222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 8739206677e461328f15854c5fcb1366d0e261534c6Patrick Scott 8749206677e461328f15854c5fcb1366d0e261534c6Patrick Scott @Override 8759206677e461328f15854c5fcb1366d0e261534c6Patrick Scott public void onReceivedLoginRequest(WebView view, String realm, 8769206677e461328f15854c5fcb1366d0e261534c6Patrick Scott String account, String args) { 8771461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb new DeviceAccountLogin(mWebViewController.getActivity(), view, Tab.this, mWebViewController) 8789206677e461328f15854c5fcb1366d0e261534c6Patrick Scott .handleLogin(realm, account, args); 8799206677e461328f15854c5fcb1366d0e261534c6Patrick Scott } 8809206677e461328f15854c5fcb1366d0e261534c6Patrick Scott 88122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }; 88222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 8831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private void syncCurrentState(WebView view, String url) { 8841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck // Sync state (in case of stop/timeout) 8851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState.mUrl = view.getUrl(); 8861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mCurrentState.mUrl == null) { 8878bcafc149bc49b84c8dfbaacf88c178d8bc9eda6John Reck mCurrentState.mUrl = ""; 8881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 8891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState.mOriginalUrl = view.getOriginalUrl(); 8901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState.mTitle = view.getTitle(); 8911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState.mFavicon = view.getFavicon(); 8921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (!URLUtil.isHttpsUrl(mCurrentState.mUrl)) { 8931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck // In case we stop when loading an HTTPS page from an HTTP page 8941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck // but before a provisional load occurred 8951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState.mLockIcon = LockIcon.LOCK_ICON_UNSECURE; 8961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 897502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck mCurrentState.mIncognito = view.isPrivateBrowsingEnabled(); 8981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 8991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 9009206677e461328f15854c5fcb1366d0e261534c6Patrick Scott // Called by DeviceAccountLogin when the Tab needs to have the auto-login UI 9019206677e461328f15854c5fcb1366d0e261534c6Patrick Scott // displayed. 9029206677e461328f15854c5fcb1366d0e261534c6Patrick Scott void setDeviceAccountLogin(DeviceAccountLogin login) { 9039206677e461328f15854c5fcb1366d0e261534c6Patrick Scott mDeviceAccountLogin = login; 9049206677e461328f15854c5fcb1366d0e261534c6Patrick Scott } 9059206677e461328f15854c5fcb1366d0e261534c6Patrick Scott 9069206677e461328f15854c5fcb1366d0e261534c6Patrick Scott // Returns non-null if the title bar should display the auto-login UI. 9079206677e461328f15854c5fcb1366d0e261534c6Patrick Scott DeviceAccountLogin getDeviceAccountLogin() { 9089206677e461328f15854c5fcb1366d0e261534c6Patrick Scott return mDeviceAccountLogin; 9099206677e461328f15854c5fcb1366d0e261534c6Patrick Scott } 9109206677e461328f15854c5fcb1366d0e261534c6Patrick Scott 91122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 91222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // WebChromeClient implementation for the main WebView 91322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 91422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 91522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private final WebChromeClient mWebChromeClient = new WebChromeClient() { 91622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Helper method to create a new tab or sub window. 91722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private void createWindow(final boolean dialog, final Message msg) { 91822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebView.WebViewTransport transport = 91922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba (WebView.WebViewTransport) msg.obj; 92022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (dialog) { 92122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba createSubWindow(); 9228233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.attachSubWindow(Tab.this); 92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba transport.setWebView(mSubView); 92422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } else { 9257bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb final Tab newTab = mWebViewController.openTab(null, 9265949c661b51295148706d53a03b41df2eb840ae3John Reck Tab.this, true, true); 92722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba transport.setWebView(newTab.getWebView()); 92822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 92922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba msg.sendToTarget(); 93022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 93122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 93222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 93322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public boolean onCreateWindow(WebView view, final boolean dialog, 93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final boolean userGesture, final Message resultMsg) { 93522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // only allow new window or sub window for the foreground case 93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (!mInForeground) { 93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return false; 93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Short-circuit if we can't create any more tabs or sub windows. 94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (dialog && mSubView != null) { 9411461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb new AlertDialog.Builder(mContext) 94222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setTitle(R.string.too_many_subwindows_dialog_title) 94322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setIcon(android.R.drawable.ic_dialog_alert) 94422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setMessage(R.string.too_many_subwindows_dialog_message) 94522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setPositiveButton(R.string.ok, null) 94622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .show(); 94722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return false; 9488233facddcc51865d612a919d450db6954aa48e3Michael Kolb } else if (!mWebViewController.getTabControl().canCreateNewTab()) { 9491461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb new AlertDialog.Builder(mContext) 95022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setTitle(R.string.too_many_windows_dialog_title) 95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setIcon(android.R.drawable.ic_dialog_alert) 95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setMessage(R.string.too_many_windows_dialog_message) 95322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setPositiveButton(R.string.ok, null) 95422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .show(); 95522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return false; 95622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 95722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Short-circuit if this was a user gesture. 95922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (userGesture) { 96022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba createWindow(dialog, resultMsg); 96122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return true; 96222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Allow the popup and create the appropriate window. 96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final AlertDialog.OnClickListener allowListener = 96622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new AlertDialog.OnClickListener() { 96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface d, 96822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba int which) { 96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba createWindow(dialog, resultMsg); 97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 97122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }; 97222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 97322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Block the popup by returning a null WebView. 97422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final AlertDialog.OnClickListener blockListener = 97522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba new AlertDialog.OnClickListener() { 97622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onClick(DialogInterface d, int which) { 97722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba resultMsg.sendToTarget(); 97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }; 98022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 98122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Build a confirmation dialog to display to the user. 98222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final AlertDialog d = 9831461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb new AlertDialog.Builder(mContext) 98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setTitle(R.string.attention) 98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setIcon(android.R.drawable.ic_dialog_alert) 98622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setMessage(R.string.popup_window_attempt) 98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setPositiveButton(R.string.allow, allowListener) 98822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setNegativeButton(R.string.block, blockListener) 98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .setCancelable(false) 99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .create(); 99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Show the confirmation dialog. 99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba d.show(); 99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return true; 99522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 99622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 99722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 998eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott public void onRequestFocus(WebView view) { 999eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott if (!mInForeground) { 1000c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mWebViewController.switchToTab(Tab.this); 1001eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott } 1002eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott } 1003eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott 1004eb5061b8e5de8ccb3667f002ef3ec6732a7d78baPatrick Scott @Override 100522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onCloseWindow(WebView window) { 1006c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (mParent != null) { 100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // JavaScript can only close popup window. 100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 1009c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mWebViewController.switchToTab(mParent); 101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 10118233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.closeTab(Tab.this); 101222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 101322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 101422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 101522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 101622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onProgressChanged(WebView view, int newProgress) { 101730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mPageLoadProgress = newProgress; 101830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mWebViewController.onProgressChanged(Tab.this); 101922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 102122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 102221d9b907ca3aac7f1ad693cbb8731f5d3e4215a8Leon Scroggins public void onReceivedTitle(WebView view, final String title) { 102330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mCurrentState.mTitle = title; 10248233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.onReceivedTitle(Tab.this, title); 102522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 102622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 102722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedIcon(WebView view, Bitmap icon) { 102930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mCurrentState.mFavicon = icon; 10308233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.onFavicon(Tab.this, view, icon); 103122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 103222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 103322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 103422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedTouchIconUrl(WebView view, String url, 103522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba boolean precomposed) { 10361461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb final ContentResolver cr = mContext.getContentResolver(); 1037c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins // Let precomposed icons take precedence over non-composed 1038c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins // icons. 1039c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins if (precomposed && mTouchIconLoader != null) { 1040c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins mTouchIconLoader.cancel(false); 1041c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins mTouchIconLoader = null; 1042c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins } 1043c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins // Have only one async task at a time. 1044c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins if (mTouchIconLoader == null) { 10458233facddcc51865d612a919d450db6954aa48e3Michael Kolb mTouchIconLoader = new DownloadTouchIcon(Tab.this, 10461461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mContext, cr, view); 1047c8393d9cfa47e3f5f279b17c412fd363e7ea94bdLeon Scroggins mTouchIconLoader.execute(url); 104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 105022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 105122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onShowCustomView(View view, 105322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebChromeClient.CustomViewCallback callback) { 10541461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb Activity activity = mWebViewController.getActivity(); 10551461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb if (activity != null) { 10561461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb onShowCustomView(view, activity.getRequestedOrientation(), callback); 10571461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 10582d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger } 10592d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger 10602d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger @Override 10612d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger public void onShowCustomView(View view, int requestedOrientation, 10622d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger WebChromeClient.CustomViewCallback callback) { 10638233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (mInForeground) mWebViewController.showCustomView(Tab.this, view, 10642d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger requestedOrientation, callback); 106522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 106622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 106722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 106822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onHideCustomView() { 10698233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (mInForeground) mWebViewController.hideCustomView(); 107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * The origin has exceeded its database quota. 107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param url the URL that exceeded the quota 107522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param databaseIdentifier the identifier of the database on which the 107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * transaction that caused the quota overflow was run 107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param currentQuota the current quota for the origin. 107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param estimatedSize the estimated size of the database. 107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param totalUsedQuota is the sum of all origins' quota. 108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param quotaUpdater The callback to run when a decision to allow or 108122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * deny quota has been made. Don't forget to call this! 108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 108322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onExceededDatabaseQuota(String url, 108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba String databaseIdentifier, long currentQuota, long estimatedSize, 108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) { 108735e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck mSettings.getWebStorageSizeManager() 108822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .onExceededDatabaseQuota(url, databaseIdentifier, 108922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba currentQuota, estimatedSize, totalUsedQuota, 109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba quotaUpdater); 109122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * The Application Cache has exceeded its max size. 109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param spaceNeeded is the amount of disk space that would be needed 109622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * in order for the last appcache operation to succeed. 109722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param totalUsedQuota is the sum of all origins' quota. 109822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param quotaUpdater A callback to inform the WebCore thread that a 109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * new app cache size is available. This callback must always 110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * be executed at some point to ensure that the sleeping 110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * WebCore thread is woken up. 110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReachedMaxAppCacheSize(long spaceNeeded, 110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) { 110635e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck mSettings.getWebStorageSizeManager() 110722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba .onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota, 110822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba quotaUpdater); 110922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 111022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 111122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 111222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Instructs the browser to show a prompt to ask the user to set the 111322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Geolocation permission state for the specified origin. 111422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param origin The origin for which Geolocation permissions are 111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * requested. 111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param callback The callback to call once the user has set the 111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Geolocation permission state. 111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onGeolocationPermissionsShowPrompt(String origin, 112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba GeolocationPermissions.Callback callback) { 112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 112350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba getGeolocationPermissionsPrompt().show(origin, callback); 112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 112822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Instructs the browser to hide the Geolocation permissions prompt. 112922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 113022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onGeolocationPermissionsHidePrompt() { 113250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba if (mInForeground && mGeolocationPermissionsPrompt != null) { 113322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mGeolocationPermissionsPrompt.hide(); 113422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 113522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 113622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 113765acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch /* Adds a JavaScript error message to the system log and if the JS 113865acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch * console is enabled in the about:debug options, to that console 113965acc3541e4bcf8d9a0b3f59941c40fdb106c703Ben Murdoch * also. 1140c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch * @param consoleMessage the message object. 114122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 114222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 1143c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch public boolean onConsoleMessage(ConsoleMessage consoleMessage) { 114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 114522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // call getErrorConsole(true) so it will create one if needed 114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba ErrorConsoleView errorConsole = getErrorConsole(true); 1147c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch errorConsole.addErrorMessage(consoleMessage); 11488233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (mWebViewController.shouldShowErrorConsole() 11498233facddcc51865d612a919d450db6954aa48e3Michael Kolb && errorConsole.getShowState() != 11508233facddcc51865d612a919d450db6954aa48e3Michael Kolb ErrorConsoleView.SHOW_MAXIMIZED) { 115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED); 115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 115322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1154c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch 115547654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton // Don't log console messages in private browsing mode 1156f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk if (isPrivateBrowsingEnabled()) return true; 115747654f464e2ecd65fb049817201fb00a9f8fe29cJeff Hamilton 1158c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch String message = "Console: " + consoleMessage.message() + " " 1159c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch + consoleMessage.sourceId() + ":" 1160c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch + consoleMessage.lineNumber(); 1161c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch 1162c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch switch (consoleMessage.messageLevel()) { 1163c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch case TIP: 1164c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch Log.v(CONSOLE_LOGTAG, message); 1165c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch break; 1166c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch case LOG: 1167c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch Log.i(CONSOLE_LOGTAG, message); 1168c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch break; 1169c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch case WARNING: 1170c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch Log.w(CONSOLE_LOGTAG, message); 1171c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch break; 1172c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch case ERROR: 1173c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch Log.e(CONSOLE_LOGTAG, message); 1174c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch break; 1175c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch case DEBUG: 1176c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch Log.d(CONSOLE_LOGTAG, message); 1177c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch break; 1178c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch } 1179c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch 1180c42addfd5c76d543c63a83ef87c1257cea309edfBen Murdoch return true; 118122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 118222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 118322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 118422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Ask the browser for an icon to represent a <video> element. 118522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * This icon will be used if the Web page did not specify a poster attribute. 118622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return Bitmap The icon or null if no such icon is available. 118722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 118822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 118922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public Bitmap getDefaultVideoPoster() { 119022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 11918233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mWebViewController.getDefaultVideoPoster(); 119222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 119322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return null; 119422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 119522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 119622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 119722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Ask the host application for a custom progress view to show while 119822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * a <video> is loading. 119922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return View The progress view. 120022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 120122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 120222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public View getVideoLoadingProgressView() { 120322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 12048233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mWebViewController.getVideoLoadingProgressView(); 120522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 120622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return null; 120722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 120822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 120922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 121062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { 121122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mInForeground) { 12128233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.openFileChooser(uploadMsg, acceptType); 121322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } else { 121422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba uploadMsg.onReceiveValue(null); 121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 121722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 121822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 121922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Deliver a list of already-visited URLs 122022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 122122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 122222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void getVisitedHistory(final ValueCallback<String[]> callback) { 12238233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.getVisitedHistory(callback); 12248233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 12258029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch 12268029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch @Override 12278029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch public void setupAutoFill(Message message) { 12288029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch // Prompt the user to set up their profile. 12298029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch final Message msg = message; 12301461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb AlertDialog.Builder builder = new AlertDialog.Builder(mContext); 12311461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( 12321d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch Context.LAYOUT_INFLATER_SERVICE); 12331d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch final View layout = inflater.inflate(R.layout.setup_autofill_dialog, null); 12341d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch 12351d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch builder.setView(layout) 1236b7e6f94a4728e284764a45b25985a05e0f5c6273Ben Murdoch .setTitle(R.string.autofill_setup_dialog_title) 12371d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 12381d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch @Override 12391d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch public void onClick(DialogInterface dialog, int id) { 12401d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch CheckBox disableAutoFill = (CheckBox) layout.findViewById( 12411d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch R.id.setup_autofill_dialog_disable_autofill); 12421d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch 12431d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch if (disableAutoFill.isChecked()) { 12441d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch // Disable autofill and show a toast with how to turn it on again. 124535e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck mSettings.setAutofillEnabled(false); 12461461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb Toast.makeText(mContext, 12471d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch R.string.autofill_setup_dialog_negative_toast, 12481d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch Toast.LENGTH_LONG).show(); 12491d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch } else { 12501d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch // Take user to the AutoFill profile editor. When they return, 12511d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch // we will send the message that we pass here which will trigger 12521d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch // the form to get filled out with their new profile. 12531d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch mWebViewController.setupAutoFill(msg); 12541d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch } 12551d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch } 12561d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch }) 12571d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch .setNegativeButton(R.string.cancel, null) 12581d676b6d3080ea2e8206e2a601be8390f1bbd0edBen Murdoch .show(); 12598029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch } 126022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba }; 126122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // WebViewClient implementation for the sub window 126422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 126522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Subclass of WebViewClient used in subwindows to notify the main 126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // WebViewClient of certain WebView activities. 126822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private static class SubWindowClient extends WebViewClient { 126922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // The main WebViewClient. 127022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private final WebViewClient mClient; 12718233facddcc51865d612a919d450db6954aa48e3Michael Kolb private final WebViewController mController; 127222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 12738233facddcc51865d612a919d450db6954aa48e3Michael Kolb SubWindowClient(WebViewClient client, WebViewController controller) { 127422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient = client; 12758233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController = controller; 1276211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III } 1277211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III @Override 1278211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III public void onPageStarted(WebView view, String url, Bitmap favicon) { 1279211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III // Unlike the others, do not call mClient's version, which would 1280211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III // change the progress bar. However, we do want to remove the 128101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark // find or select dialog. 12828233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController.endActionMode(); 128322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 128422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 128522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void doUpdateVisitedHistory(WebView view, String url, 128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba boolean isReload) { 128722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.doUpdateVisitedHistory(view, url, isReload); 128822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 128922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public boolean shouldOverrideUrlLoading(WebView view, String url) { 129122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mClient.shouldOverrideUrlLoading(view, url); 129222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 129322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 129422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedSslError(WebView view, SslErrorHandler handler, 129522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba SslError error) { 129622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.onReceivedSslError(view, handler, error); 129722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 129822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 12998862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom public void onReceivedClientCertRequest(WebView view, 13008862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom ClientCertRequestHandler handler, String host_and_port) { 13018862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom mClient.onReceivedClientCertRequest(view, handler, host_and_port); 13028862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom } 13038862c1dd48ac83011411c469afb5065b6d0c32f9Brian Carlstrom @Override 130422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedHttpAuthRequest(WebView view, 130522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba HttpAuthHandler handler, String host, String realm) { 130622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.onReceivedHttpAuthRequest(view, handler, host, realm); 130722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 130822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 130922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onFormResubmission(WebView view, Message dontResend, 131022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba Message resend) { 131122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.onFormResubmission(view, dontResend, resend); 131222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 131322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 131422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onReceivedError(WebView view, int errorCode, 131522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba String description, String failingUrl) { 131622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.onReceivedError(view, errorCode, description, failingUrl); 131722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 131822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public boolean shouldOverrideKeyEvent(WebView view, 132022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba android.view.KeyEvent event) { 132122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mClient.shouldOverrideKeyEvent(view, event); 132222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 132322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onUnhandledKeyEvent(WebView view, 132522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba android.view.KeyEvent event) { 132622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.onUnhandledKeyEvent(view, event); 132722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 132922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 133022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 133122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // WebChromeClient implementation for the sub window 133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 133322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 133422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private class SubWindowChromeClient extends WebChromeClient { 133522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // The main WebChromeClient. 133622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba private final WebChromeClient mClient; 133722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 133822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba SubWindowChromeClient(WebChromeClient client) { 133922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient = client; 134022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 134122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 134222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onProgressChanged(WebView view, int newProgress) { 134322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mClient.onProgressChanged(view, newProgress); 134422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 134522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public boolean onCreateWindow(WebView view, boolean dialog, 134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba boolean userGesture, android.os.Message resultMsg) { 134822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mClient.onCreateWindow(view, dialog, userGesture, resultMsg); 134922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 135022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba @Override 135122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba public void onCloseWindow(WebView window) { 135222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (window != mSubView) { 135322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba Log.e(LOGTAG, "Can't close the window"); 135422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 13558233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.dismissSubWindow(Tab.this); 135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 135722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 135922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // ------------------------------------------------------------------------- 136022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 136122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Construct a new tab 13627bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb Tab(WebViewController wvcontroller, WebView w) { 13631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck this(wvcontroller, w, null); 13641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 13651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 13661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Tab(WebViewController wvcontroller, Bundle state) { 13671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck this(wvcontroller, null, state); 13681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 13691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 13701cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Tab(WebViewController wvcontroller, WebView w, Bundle state) { 13718233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController = wvcontroller; 13721461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mContext = mWebViewController.getContext(); 137335e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck mSettings = BrowserSettings.getInstance(); 13741461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mDataController = DataController.getInstance(mContext); 13751461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mCurrentState = new PageState(mContext, w != null 1376847b532045e3cb117a847ebb956c9919401f332dJohn Reck ? w.isPrivateBrowsingEnabled() : false); 13778233facddcc51865d612a919d450db6954aa48e3Michael Kolb mInPageLoad = false; 137822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mInForeground = false; 137922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1380dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins mDownloadListener = new DownloadListener() { 1381dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins public void onDownloadStart(String url, String userAgent, 1382dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins String contentDisposition, String mimetype, 1383dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins long contentLength) { 13848233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.onDownloadStart(Tab.this, url, userAgent, contentDisposition, 1385dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins mimetype, contentLength); 1386dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins } 1387dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins }; 13880c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins mWebBackForwardListClient = new WebBackForwardListClient() { 13890c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins @Override 13900c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins public void onNewHistoryItem(WebHistoryItem item) { 13910c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins if (isInVoiceSearchMode()) { 13920c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins item.setCustomData(mVoiceSearchData.mVoiceSearchIntent); 13930c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins } 13941dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood if (mClearHistoryMatchUrl != null) { 13951dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood if (LOGD_ENABLED) { 13961dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood Log.d(LOGTAG, "onNewHistoryItem:\n\t" + item.getUrl() + "\n\t" 13971dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood + mClearHistoryMatchUrl); 13981dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood } 13991dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood if (TextUtils.equals(item.getOriginalUrl(), mClearHistoryMatchUrl)) { 14001dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood if (mMainView != null) { 14011dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood mMainView.clearHistory(); 14021dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood } 14031dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood } 14041dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood mClearHistoryMatchUrl = null; 14051dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood } 14060c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins } 14070c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins @Override 14080c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins public void onIndexChanged(WebHistoryItem item, int index) { 14090c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins Object data = item.getCustomData(); 14100c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins if (data != null && data instanceof Intent) { 14110c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins activateVoiceSearchMode((Intent) data); 14120c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins } 14130c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins } 14140c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins }; 1415dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins 14161cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCaptureWidth = mContext.getResources().getDimensionPixelSize( 14171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck R.dimen.tab_thumbnail_width); 14181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCaptureHeight = mContext.getResources().getDimensionPixelSize( 14191cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck R.dimen.tab_thumbnail_height); 14201cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck updateShouldCaptureThumbnails(); 14211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck restoreState(state); 142252be4785a258687055515117775d5bcb8bec1c12John Reck if (getId() == -1) { 142352be4785a258687055515117775d5bcb8bec1c12John Reck mId = TabControl.getNextId(); 142452be4785a258687055515117775d5bcb8bec1c12John Reck } 142522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba setWebView(w); 14269ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb mHandler = new Handler() { 14271dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood @Override 14289ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb public void handleMessage(Message m) { 14291cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck switch (m.what) { 14301cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck case MSG_CAPTURE: 14311cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck capture(); 14321cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck break; 14331cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 14349ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb } 14359ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb }; 14361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 14379ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb 1438e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood /** 1439e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood * This is used to get a new ID when the tab has been preloaded, before it is displayed and 1440e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood * added to TabControl. Preloaded tabs can be created before restoreInstanceState, leading 1441e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood * to overlapping IDs between the preloaded and restored tabs. 1442e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood */ 1443e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood public void refreshIdAfterPreload() { 1444e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood mId = TabControl.getNextId(); 1445e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood } 1446e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood 14471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck public void updateShouldCaptureThumbnails() { 14481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mWebViewController.shouldCaptureThumbnails()) { 14491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck synchronized (Tab.this) { 14501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mCapture == null) { 14511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCapture = Bitmap.createBitmap(mCaptureWidth, mCaptureHeight, 14521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Bitmap.Config.RGB_565); 1453c3af06776be83ba64a0d3549cb72ca6e5e7f03cdMichael Kolb mCapture.eraseColor(Color.WHITE); 14541cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mInForeground) { 14551cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck postCapture(); 14561cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 14571cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 14581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 14591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } else { 14601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck synchronized (Tab.this) { 14611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCapture = null; 14621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck deleteThumbnail(); 14631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 14641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 146622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 14671461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb public void setController(WebViewController ctl) { 14681461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mWebViewController = ctl; 14691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck updateShouldCaptureThumbnails(); 14701461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 14711461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb 1472c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb public long getId() { 1473c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb return mId; 1474c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb } 1475c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 147622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Sets the WebView for this tab, correctly removing the old WebView from 147822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * the container view. 147922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 148022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void setWebView(WebView w) { 148122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mMainView == w) { 148222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return; 148322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1484a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb 148522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // If the WebView is changing, the page will be reloaded, so any ongoing 148622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Geolocation permission requests are void. 148750c241e6339c681c2427a57a31a357d35927c2acGrace Kloba if (mGeolocationPermissionsPrompt != null) { 148850c241e6339c681c2427a57a31a357d35927c2acGrace Kloba mGeolocationPermissionsPrompt.hide(); 148950c241e6339c681c2427a57a31a357d35927c2acGrace Kloba } 149022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1491a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb mWebViewController.onSetWebView(this, w); 149222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 14931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mMainView != null) { 14948ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck mMainView.setPictureListener(null); 14951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (w != null) { 14961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck syncCurrentState(w, null); 14971cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } else { 14981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState = new PageState(mContext, false); 14991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 15001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 150122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // set the new one 150222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mMainView = w; 1503dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // attach the WebViewClient, WebChromeClient and DownloadListener 150422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mMainView != null) { 150522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mMainView.setWebViewClient(mWebViewClient); 150622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mMainView.setWebChromeClient(mWebChromeClient); 1507dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // Attach DownloadManager so that downloads can start in an active 1508dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // or a non-active window. This can happen when going to a site that 1509dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // does a redirect after a period of time. The user could have 1510dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // switched to another tab while waiting for the download to start. 1511dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins mMainView.setDownloadListener(mDownloadListener); 15120c75a8ed8d95d2f5278826222ca5ec4e96b2aee4Leon Scroggins mMainView.setWebBackForwardListClient(mWebBackForwardListClient); 15138ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck TabControl tc = mWebViewController.getTabControl(); 15148ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (tc != null && tc.getOnThumbnailUpdatedListener() != null) { 15158ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck mMainView.setPictureListener(this); 15168ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 15171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mSavedState != null) { 15186c2e2f34718043f36488b4a94879dc2605aaac49John Reck WebBackForwardList restoredState 15196c2e2f34718043f36488b4a94879dc2605aaac49John Reck = mMainView.restoreState(mSavedState); 15206c2e2f34718043f36488b4a94879dc2605aaac49John Reck if (restoredState == null || restoredState.getSize() == 0) { 15216c2e2f34718043f36488b4a94879dc2605aaac49John Reck Log.w(LOGTAG, "Failed to restore WebView state!"); 15226c2e2f34718043f36488b4a94879dc2605aaac49John Reck loadUrl(mCurrentState.mOriginalUrl, null); 15236c2e2f34718043f36488b4a94879dc2605aaac49John Reck } 15241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mSavedState = null; 15251cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 152622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 152722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 152822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 152922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 153022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Destroy the tab's main WebView and subWindow if any 153122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 153222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void destroy() { 153322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mMainView != null) { 153422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba dismissSubWindow(); 1535ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck // Make sure the embedded title bar isn't still attached 1536ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck mMainView.setEmbeddedTitleBar(null); 153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // save the WebView to call destroy() after detach it from the tab 153822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebView webView = mMainView; 153922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba setWebView(null); 154022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba webView.destroy(); 154122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 154222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 154322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 154422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 154522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Remove the tab from the parent 154622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 154722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void removeFromTree() { 154822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // detach the children 1549c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (mChildren != null) { 1550c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for(Tab t : mChildren) { 1551c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb t.setParent(null); 155222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 155322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 155422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // remove itself from the parent list 1555c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (mParent != null) { 1556c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mParent.mChildren.remove(this); 155722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 15581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck deleteThumbnail(); 155922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 156022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 156122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 156222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Create a new subwindow unless a subwindow already exists. 156322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return True if a new subwindow was created. False if one already exists. 156422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 156522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba boolean createSubWindow() { 156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView == null) { 15671514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb mWebViewController.createSubWindow(this); 1568211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III mSubView.setWebViewClient(new SubWindowClient(mWebViewClient, 15698233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController)); 157022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubView.setWebChromeClient(new SubWindowChromeClient( 157122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mWebChromeClient)); 1572dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // Set a different DownloadListener for the mSubView, since it will 1573dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // just need to dismiss the mSubView, rather than close the Tab 1574dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins mSubView.setDownloadListener(new DownloadListener() { 1575dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins public void onDownloadStart(String url, String userAgent, 1576dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins String contentDisposition, String mimetype, 1577dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins long contentLength) { 15788233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.onDownloadStart(Tab.this, url, userAgent, 1579dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins contentDisposition, mimetype, contentLength); 1580dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins if (mSubView.copyBackForwardList().getSize() == 0) { 1581dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // This subwindow was opened for the sole purpose of 1582dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins // downloading a file. Remove it. 15838233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.dismissSubWindow(Tab.this); 1584dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins } 1585dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins } 1586dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins }); 15871461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mSubView.setOnCreateContextMenuListener(mWebViewController.getActivity()); 158822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return true; 158922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 159022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return false; 159122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 159222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 159322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Dismiss the subWindow for the tab. 159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 159622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void dismissSubWindow() { 159722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView != null) { 15988233facddcc51865d612a919d450db6954aa48e3Michael Kolb mWebViewController.endActionMode(); 159922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubView.destroy(); 160022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubView = null; 160122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubViewContainer = null; 160222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 160622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 160722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Set the parent tab of this tab. 160822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 1609c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb void setParent(Tab parent) { 161052be4785a258687055515117775d5bcb8bec1c12John Reck if (parent == this) { 161152be4785a258687055515117775d5bcb8bec1c12John Reck throw new IllegalStateException("Cannot set parent to self!"); 161252be4785a258687055515117775d5bcb8bec1c12John Reck } 1613c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mParent = parent; 161422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // This tab may have been freed due to low memory. If that is the case, 1615c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb // the parent tab id is already saved. If we are changing that id 161622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // (most likely due to removing the parent tab) we must update the 1617c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb // parent tab id in the saved Bundle. 161822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSavedState != null) { 161922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (parent == null) { 162022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSavedState.remove(PARENTTAB); 162122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } else { 1622c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mSavedState.putLong(PARENTTAB, parent.getId()); 162322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 162422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1625b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck 1626b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck // Sync the WebView useragent with the parent 1627b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck if (parent != null && mSettings.hasDesktopUseragent(parent.getWebView()) 1628b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck != mSettings.hasDesktopUseragent(getWebView())) { 1629b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck mSettings.toggleDesktopUseragent(getWebView()); 1630b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck } 163152be4785a258687055515117775d5bcb8bec1c12John Reck 163252be4785a258687055515117775d5bcb8bec1c12John Reck if (parent != null && parent.getId() == getId()) { 163352be4785a258687055515117775d5bcb8bec1c12John Reck throw new IllegalStateException("Parent has same ID as child!"); 163452be4785a258687055515117775d5bcb8bec1c12John Reck } 163522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 163722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 1638c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * If this Tab was created through another Tab, then this method returns 1639c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * that Tab. 1640c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * @return the Tab parent or null 1641c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb */ 1642c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb public Tab getParent() { 1643c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb return mParent; 1644c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb } 1645c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 1646c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb /** 164722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * When a Tab is created through the content of another Tab, then we 164822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * associate the Tabs. 164922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param child the Tab that was created from this Tab 165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 165122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void addChildTab(Tab child) { 1652c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (mChildren == null) { 1653c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mChildren = new Vector<Tab>(); 165422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1655c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mChildren.add(child); 1656c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb child.setParent(this); 165722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 165822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1659c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb Vector<Tab> getChildren() { 1660c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb return mChildren; 166122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 166222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 166322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void resume() { 166422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mMainView != null) { 166556c1fcf7774d4ee943fbda808e37840459502e20John Reck setupHwAcceleration(mMainView); 166622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mMainView.onResume(); 166722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView != null) { 166822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubView.onResume(); 166922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 167022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 167122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 167356c1fcf7774d4ee943fbda808e37840459502e20John Reck private void setupHwAcceleration(View web) { 167456c1fcf7774d4ee943fbda808e37840459502e20John Reck if (web == null) return; 167556c1fcf7774d4ee943fbda808e37840459502e20John Reck BrowserSettings settings = BrowserSettings.getInstance(); 167656c1fcf7774d4ee943fbda808e37840459502e20John Reck if (settings.isHardwareAccelerated()) { 167756c1fcf7774d4ee943fbda808e37840459502e20John Reck web.setLayerType(View.LAYER_TYPE_NONE, null); 167856c1fcf7774d4ee943fbda808e37840459502e20John Reck } else { 167956c1fcf7774d4ee943fbda808e37840459502e20John Reck web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 168056c1fcf7774d4ee943fbda808e37840459502e20John Reck } 168156c1fcf7774d4ee943fbda808e37840459502e20John Reck } 168256c1fcf7774d4ee943fbda808e37840459502e20John Reck 168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void pause() { 168422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mMainView != null) { 168522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mMainView.onPause(); 168622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView != null) { 168722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubView.onPause(); 168822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 169022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 169122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 169222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void putInForeground() { 16938ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (mInForeground) { 16948ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck return; 16958ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mInForeground = true; 169722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba resume(); 16981461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb Activity activity = mWebViewController.getActivity(); 16991461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mMainView.setOnCreateContextMenuListener(activity); 170022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView != null) { 17011461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mSubView.setOnCreateContextMenuListener(activity); 170222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 170322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Show the pending error dialog if the queue is not empty 170422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mQueuedErrors != null && mQueuedErrors.size() > 0) { 170522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba showError(mQueuedErrors.getFirst()); 170622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 17071961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins mWebViewController.bookmarkedStatusHasChanged(this); 170822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 170922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 171022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void putInBackground() { 17118ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (!mInForeground) { 17128ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck return; 17138ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 171452be4785a258687055515117775d5bcb8bec1c12John Reck capture(); 171522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mInForeground = false; 171622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba pause(); 171722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mMainView.setOnCreateContextMenuListener(null); 171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView != null) { 171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSubView.setOnCreateContextMenuListener(null); 172022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 172122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 172222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 17238233facddcc51865d612a919d450db6954aa48e3Michael Kolb boolean inForeground() { 17248233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mInForeground; 17258233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 17268233facddcc51865d612a919d450db6954aa48e3Michael Kolb 172722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 172822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Return the top window of this tab; either the subwindow if it is not 172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * null or the main window. 173022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return The top window of this tab. 173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 173222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebView getTopWindow() { 173322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mSubView != null) { 173422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mSubView; 173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mMainView; 173722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 173922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 174022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Return the main window of this tab. Note: if a tab is freed in the 174122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * background, this can return null. It is only guaranteed to be 174222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * non-null for the current tab. 174322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return The main WebView of this tab. 174422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 174522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebView getWebView() { 174622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mMainView; 174722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 174822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1749a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb void setViewContainer(View container) { 1750a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb mContainer = container; 1751a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb } 1752a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb 17538233facddcc51865d612a919d450db6954aa48e3Michael Kolb View getViewContainer() { 17548233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mContainer; 17558233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 17568233facddcc51865d612a919d450db6954aa48e3Michael Kolb 175722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 1758f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk * Return whether private browsing is enabled for the main window of 1759f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk * this tab. 1760f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk * @return True if private browsing is enabled. 1761f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk */ 17628233facddcc51865d612a919d450db6954aa48e3Michael Kolb boolean isPrivateBrowsingEnabled() { 1763502a353bb815bee8bec6a60f3b741dc62e4729cdJohn Reck return mCurrentState.mIncognito; 1764f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk } 1765f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk 1766f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk /** 176722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Return the subwindow of this tab or null if there is no subwindow. 176822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return The subwindow of this tab or null. 176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 177022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebView getSubWebView() { 177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mSubView; 177222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 177322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 17741514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb void setSubWebView(WebView subView) { 17751514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb mSubView = subView; 17761514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb } 17771514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb 17788233facddcc51865d612a919d450db6954aa48e3Michael Kolb View getSubViewContainer() { 17798233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mSubViewContainer; 17808233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 17818233facddcc51865d612a919d450db6954aa48e3Michael Kolb 17821514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb void setSubViewContainer(View subViewContainer) { 17831514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb mSubViewContainer = subViewContainer; 17841514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb } 17851514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb 178622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 178722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return The geolocation permissions prompt for this tab. 178822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 178922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba GeolocationPermissionsPrompt getGeolocationPermissionsPrompt() { 179050c241e6339c681c2427a57a31a357d35927c2acGrace Kloba if (mGeolocationPermissionsPrompt == null) { 179150c241e6339c681c2427a57a31a357d35927c2acGrace Kloba ViewStub stub = (ViewStub) mContainer 179250c241e6339c681c2427a57a31a357d35927c2acGrace Kloba .findViewById(R.id.geolocation_permissions_prompt); 179350c241e6339c681c2427a57a31a357d35927c2acGrace Kloba mGeolocationPermissionsPrompt = (GeolocationPermissionsPrompt) stub 179450c241e6339c681c2427a57a31a357d35927c2acGrace Kloba .inflate(); 179550c241e6339c681c2427a57a31a357d35927c2acGrace Kloba } 179622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mGeolocationPermissionsPrompt; 179722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 179822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 179922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 180022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return The application id string 180122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 180222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba String getAppId() { 180322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mAppId; 180422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 180522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 180622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 180722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Set the application id string 180822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param id 180922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 181022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba void setAppId(String id) { 181122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mAppId = id; 181222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 181322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1814e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb boolean closeOnBack() { 1815e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb return mCloseOnBack; 1816e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb } 1817e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb 1818e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb void setCloseOnBack(boolean close) { 1819e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb mCloseOnBack = close; 1820e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb } 1821e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb 182222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba String getUrl() { 1823324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck return UrlUtils.filteredUrl(mCurrentState.mUrl); 182422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 182522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 182649a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck String getOriginalUrl() { 1827db22ec4ee014900988062d910bc810172a07df56John Reck if (mCurrentState.mOriginalUrl == null) { 1828db22ec4ee014900988062d910bc810172a07df56John Reck return getUrl(); 182949a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck } 1830db22ec4ee014900988062d910bc810172a07df56John Reck return UrlUtils.filteredUrl(mCurrentState.mOriginalUrl); 183149a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck } 183249a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck 183322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 183430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck * Get the title of this tab. 183522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 183622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba String getTitle() { 183730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck if (mCurrentState.mTitle == null && mInPageLoad) { 18381461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb return mContext.getString(R.string.title_bar_loading); 183922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 184030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck return mCurrentState.mTitle; 184122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 184222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 184322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 184430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck * Get the favicon of this tab. 184522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 184622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba Bitmap getFavicon() { 18471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mCurrentState.mFavicon != null) { 18481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return mCurrentState.mFavicon; 18491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 18501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return getDefaultFavicon(mContext); 185122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 185222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1853e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck public boolean isBookmarkedSite() { 1854e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck return mCurrentState.mIsBookmarkedSite; 1855e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 1856f8bdfce9f2fc93bed2667694dc5b5ddf001d99d2Rob Tsuk 185722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 185822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Return the tab's error console. Creates the console if createIfNEcessary 185922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * is true and we haven't already created the console. 186022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @param createIfNecessary Flag to indicate if the console should be 186122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * created if it has not been already. 186222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return The tab's error console, or null if one has not been created and 186322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * createIfNecessary is false. 186422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 186522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba ErrorConsoleView getErrorConsole(boolean createIfNecessary) { 186622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (createIfNecessary && mErrorConsole == null) { 18671461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mErrorConsole = new ErrorConsoleView(mContext); 186822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mErrorConsole.setWebView(mMainView); 186922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 187022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return mErrorConsole; 187122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 187222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 187330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck private void setLockIconType(LockIcon icon) { 187430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mCurrentState.mLockIcon = icon; 187530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mWebViewController.onUpdatedLockIcon(this); 187622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 187722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 187822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 187930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck * @return The tab's lock icon type. 188022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 188130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck LockIcon getLockIconType() { 188230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck return mCurrentState.mLockIcon; 188322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 188422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 188530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck int getLoadProgress() { 188630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck if (mInPageLoad) { 188730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck return mPageLoadProgress; 188830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck } 188930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck return 100; 189022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 189122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 189222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 189322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * @return TRUE if onPageStarted is called while onPageFinished is not 189422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * called yet. 189522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 18968233facddcc51865d612a919d450db6954aa48e3Michael Kolb boolean inPageLoad() { 18978233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mInPageLoad; 189822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 189922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 190022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // force mInLoad to be false. This should only be called before closing the 190122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // tab to ensure BrowserActivity's pauseWebViewTimers() is called correctly. 19028233facddcc51865d612a919d450db6954aa48e3Michael Kolb void clearInPageLoad() { 19038233facddcc51865d612a919d450db6954aa48e3Michael Kolb mInPageLoad = false; 190422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 190522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 190622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 19071cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck * @return The Bundle with the tab's state if it can be saved, otherwise null 190822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 19091cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck public Bundle saveState() { 191022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // If the WebView is null it means we ran low on memory and we already 191122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // stored the saved state in mSavedState. 191222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mMainView == null) { 19131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return mSavedState; 191422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 19156c2e2f34718043f36488b4a94879dc2605aaac49John Reck 19166c2e2f34718043f36488b4a94879dc2605aaac49John Reck if (TextUtils.isEmpty(mCurrentState.mUrl)) { 19171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return null; 191824f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck } 191922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 192022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSavedState = new Bundle(); 19216c2e2f34718043f36488b4a94879dc2605aaac49John Reck WebBackForwardList savedList = mMainView.saveState(mSavedState); 19226c2e2f34718043f36488b4a94879dc2605aaac49John Reck if (savedList == null || savedList.getSize() == 0) { 19236c2e2f34718043f36488b4a94879dc2605aaac49John Reck Log.w(LOGTAG, "Failed to save back/forward list for " 19246c2e2f34718043f36488b4a94879dc2605aaac49John Reck + mCurrentState.mUrl); 19256c2e2f34718043f36488b4a94879dc2605aaac49John Reck } 192622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1927c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mSavedState.putLong(ID, mId); 192830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mSavedState.putString(CURRURL, mCurrentState.mUrl); 192930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck mSavedState.putString(CURRTITLE, mCurrentState.mTitle); 19301cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mSavedState.putBoolean(INCOGNITO, mMainView.isPrivateBrowsingEnabled()); 193122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (mAppId != null) { 193222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mSavedState.putString(APPID, mAppId); 193322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1934e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb mSavedState.putBoolean(CLOSEFLAG, mCloseOnBack); 193522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Remember the parent tab so the relationship can be restored. 1936c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (mParent != null) { 1937c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mSavedState.putLong(PARENTTAB, mParent.mId); 193822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1939b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck mSavedState.putBoolean(USERAGENT, 1940b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck mSettings.hasDesktopUseragent(getWebView())); 19411cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return mSavedState; 194222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 194322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 194422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /* 194522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Restore the state of the tab. 194622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 19471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private void restoreState(Bundle b) { 19481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mSavedState = b; 19491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mSavedState == null) { 19501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return; 195122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 195222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // Restore the internal state even if the WebView fails to restore. 195322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // This will maintain the app id, original url and close-on-exit values. 1954c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mId = b.getLong(ID); 195522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mAppId = b.getString(APPID); 1956e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb mCloseOnBack = b.getBoolean(CLOSEFLAG); 1957b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck if (b.getBoolean(USERAGENT) 1958b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck != mSettings.hasDesktopUseragent(getWebView())) { 1959b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck mSettings.toggleDesktopUseragent(getWebView()); 1960b0a86db3bfa39863977efd3bac5c9bf527d224aaJohn Reck } 19611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck String url = b.getString(CURRURL); 19621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck String title = b.getString(CURRTITLE); 19631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck boolean incognito = b.getBoolean(INCOGNITO); 19641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState = new PageState(mContext, incognito, url, null); 19651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCurrentState.mTitle = title; 19661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck synchronized (Tab.this) { 19671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mCapture != null) { 19681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck BackgroundHandler.execute(mLoadThumbnail); 19691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 197022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 197122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 1972211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III 19731961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins public void updateBookmarkedStatus() { 1974e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mDataController.queryBookmarkStatus(getUrl(), mIsBookmarkCallback); 19751961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins } 19761961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins 1977e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private DataController.OnQueryUrlIsBookmark mIsBookmarkCallback 1978e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck = new DataController.OnQueryUrlIsBookmark() { 1979e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck @Override 1980e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck public void onQueryUrlIsBookmark(String url, boolean isBookmark) { 1981e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck if (mCurrentState.mUrl.equals(url)) { 1982e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mCurrentState.mIsBookmarkedSite = isBookmark; 1983e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mWebViewController.bookmarkedStatusHasChanged(Tab.this); 19841961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins } 1985e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 1986e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck }; 19871acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1988eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb public Bitmap getScreenshot() { 19891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck synchronized (Tab.this) { 19901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return mCapture; 19911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 1992eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb } 1993eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb 1994541f55a0178da7c09fb32aa5385effae031ea071John Reck public boolean isSnapshot() { 1995541f55a0178da7c09fb32aa5385effae031ea071John Reck return false; 1996541f55a0178da7c09fb32aa5385effae031ea071John Reck } 1997541f55a0178da7c09fb32aa5385effae031ea071John Reck 1998d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck public ContentValues createSnapshotValues() { 1999d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck if (mMainView == null) return null; 20008cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck ByteArrayOutputStream bos = new ByteArrayOutputStream(); 20018cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck try { 20028cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck GZIPOutputStream stream = new GZIPOutputStream(bos); 20038cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck if (!mMainView.saveViewState(stream)) { 20048cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck return null; 20058cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck } 20068cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck stream.flush(); 20078cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck stream.close(); 20088cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck } catch (Exception e) { 20098cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck Log.w(LOGTAG, "Failed to save view state", e); 2010541f55a0178da7c09fb32aa5385effae031ea071John Reck return null; 2011541f55a0178da7c09fb32aa5385effae031ea071John Reck } 20128cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck byte[] data = bos.toByteArray(); 2013d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck ContentValues values = new ContentValues(); 2014d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck values.put(Snapshots.TITLE, mCurrentState.mTitle); 2015d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck values.put(Snapshots.URL, mCurrentState.mUrl); 2016d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck values.put(Snapshots.VIEWSTATE, data); 2017d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck values.put(Snapshots.BACKGROUND, mMainView.getPageBackgroundColor()); 20188cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck values.put(Snapshots.DATE_CREATED, System.currentTimeMillis()); 20198cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck values.put(Snapshots.FAVICON, compressBitmap(getFavicon())); 20208cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck Bitmap screenshot = Controller.createScreenshot(mMainView, 20218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck Controller.getDesiredThumbnailWidth(mContext), 20228cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck Controller.getDesiredThumbnailHeight(mContext)); 20238cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot)); 2024d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck return values; 2025541f55a0178da7c09fb32aa5385effae031ea071John Reck } 2026541f55a0178da7c09fb32aa5385effae031ea071John Reck 20278cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck public byte[] compressBitmap(Bitmap bitmap) { 20288cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck if (bitmap == null) { 20298cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck return null; 20308cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck } 20318cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck ByteArrayOutputStream stream = new ByteArrayOutputStream(); 20328cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck bitmap.compress(CompressFormat.PNG, 100, stream); 20338cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck return stream.toByteArray(); 20348cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck } 20358cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck 203626b183292dc087b16af10f482744c3bb30e1f163John Reck public void loadUrl(String url, Map<String, String> headers) { 203726b183292dc087b16af10f482744c3bb30e1f163John Reck if (mMainView != null) { 20381461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mCurrentState = new PageState(mContext, false, url, null); 203926b183292dc087b16af10f482744c3bb30e1f163John Reck mWebViewController.onPageStarted(this, mMainView, null); 204026b183292dc087b16af10f482744c3bb30e1f163John Reck mMainView.loadUrl(url, headers); 204126b183292dc087b16af10f482744c3bb30e1f163John Reck } 204226b183292dc087b16af10f482744c3bb30e1f163John Reck } 204326b183292dc087b16af10f482744c3bb30e1f163John Reck 20449ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb protected void capture() { 20459ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb if (mMainView == null || mCapture == null) return; 20469ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb Canvas c = new Canvas(mCapture); 20479ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb final int left = mMainView.getScrollX(); 20489ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb final int top = mMainView.getScrollY() + mMainView.getVisibleTitleHeight(); 20499ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb c.translate(-left, -top); 20509ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb float scale = mCaptureWidth / (float) mMainView.getWidth(); 20519ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb c.scale(scale, scale, left, top); 20528ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (mMainView instanceof BrowserWebView) { 20538ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck ((BrowserWebView)mMainView).drawContent(c); 20548ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } else { 20558ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck mMainView.draw(c); 20568ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 205743cfe8a4521b5c153055fbfa181940bc56bb3b06Dianne Hackborn c.setBitmap(null); 20588ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck mHandler.removeMessages(MSG_CAPTURE); 20591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck persistThumbnail(); 20608ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck TabControl tc = mWebViewController.getTabControl(); 20618ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (tc != null) { 20628ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck OnThumbnailUpdatedListener updateListener 20638ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck = tc.getOnThumbnailUpdatedListener(); 20648ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (updateListener != null) { 20658ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck updateListener.onThumbnailUpdated(this); 20668ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 20678ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 20689ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb } 20699ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb 20709ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb @Override 20719ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb public void onNewPicture(WebView view, Picture picture) { 20729ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb //update screenshot 20731cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck postCapture(); 20741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 20751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 20761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private void postCapture() { 20779ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb if (!mHandler.hasMessages(MSG_CAPTURE)) { 20789ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb mHandler.sendEmptyMessageDelayed(MSG_CAPTURE, CAPTURE_DELAY); 20799ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb } 20809ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb } 20819ef259af433edc5aeb11b5d5d94dc9acc697c61eMichael Kolb 2082ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck public boolean canGoBack() { 2083ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck return mMainView != null ? mMainView.canGoBack() : false; 2084ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck } 2085ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck 2086ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck public boolean canGoForward() { 2087ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck return mMainView != null ? mMainView.canGoForward() : false; 2088ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck } 2089ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck 2090ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck public void goBack() { 2091ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck if (mMainView != null) { 2092ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck mMainView.goBack(); 2093ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck } 2094ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck } 2095ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck 2096ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck public void goForward() { 2097ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck if (mMainView != null) { 2098ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck mMainView.goForward(); 2099ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck } 2100ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck } 2101ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck 21021dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood /** 21031dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood * Causes the tab back/forward stack to be cleared once, if the given URL is the next URL 21041dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood * to be added to the stack. 21051dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood * 21061dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood * This is used to ensure that preloaded URLs that are not subsequently seen by the user do 21071dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood * not appear in the back stack. 21081dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood */ 21091dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood public void clearBackStackWhenItemAdded(String urlToMatch) { 21101dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood mClearHistoryMatchUrl = urlToMatch; 21111dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood } 21121dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood 21131cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck protected void persistThumbnail() { 21141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck BackgroundHandler.execute(mSaveThumbnail); 21151cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21161cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21171cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck protected void deleteThumbnail() { 21181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck BackgroundHandler.execute(mDeleteThumbnail); 21191cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21201cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21211cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private void updateCaptureFromBlob(byte[] blob) { 21221cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck synchronized (Tab.this) { 21231cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mCapture == null) { 21241cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return; 21251cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 2126bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb ByteBuffer buffer = ByteBuffer.wrap(blob); 2127d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb try { 2128d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb mCapture.copyPixelsFromBuffer(buffer); 2129d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb } catch (RuntimeException rex) { 2130d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb Log.e(LOGTAG, "Load capture has mismatched sizes; buffer: " 2131d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb + buffer.capacity() + " blob: " + blob.length 2132d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb + "capture: " + mCapture.getByteCount()); 2133d837a11b0ada5a4577af954e4cc0d33047f84ce8Michael Kolb throw rex; 2134bd4c00a61a44637e04efeb837da490a2b51b11c1Michael Kolb } 21351cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private byte[] getCaptureBlob() { 21391cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck synchronized (Tab.this) { 21401cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (mCapture == null) { 21411cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return null; 21421cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck ByteBuffer buffer = ByteBuffer.allocate(mCapture.getByteCount()); 21441cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck mCapture.copyPixelsToBuffer(buffer); 21451cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return buffer.array(); 21461cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21471cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21481cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21491cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private Runnable mSaveThumbnail = new Runnable() { 21501cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21511cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck @Override 21521cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck public void run() { 21531cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck byte[] blob = getCaptureBlob(); 21541cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (blob == null) { 21551cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return; 21561cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21571cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck ContentResolver cr = mContext.getContentResolver(); 21581cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck ContentValues values = new ContentValues(); 21591cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck values.put(Thumbnails._ID, mId); 21601cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck values.put(Thumbnails.THUMBNAIL, blob); 21611cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck cr.insert(Thumbnails.CONTENT_URI, values); 21621cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21631cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck }; 21641cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21651cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private Runnable mDeleteThumbnail = new Runnable() { 21661cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21671cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck @Override 21681cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck public void run() { 21691cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck ContentResolver cr = mContext.getContentResolver(); 21701cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck try { 21711cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck cr.delete(ContentUris.withAppendedId(Thumbnails.CONTENT_URI, mId), 21721cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck null, null); 21731cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } catch (Throwable t) {} 21741cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21751cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck }; 21761cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21771cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck private Runnable mLoadThumbnail = new Runnable() { 21781cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 21791cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck @Override 21801cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck public void run() { 21811cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck ContentResolver cr = mContext.getContentResolver(); 21821cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Cursor c = null; 21831cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck try { 21841cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Uri uri = ContentUris.withAppendedId(Thumbnails.CONTENT_URI, mId); 21851cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck c = cr.query(uri, new String[] {Thumbnails._ID, 21861cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Thumbnails.THUMBNAIL}, null, null, null); 21871cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (c.moveToFirst()) { 21881cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck byte[] data = c.getBlob(1); 21891cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (data != null && data.length > 0) { 21901cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck updateCaptureFromBlob(data); 21911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } finally { 21941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (c != null) { 21951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck c.close(); 21961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21971cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21981cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 21991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck }; 22001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 220152be4785a258687055515117775d5bcb8bec1c12John Reck @Override 220252be4785a258687055515117775d5bcb8bec1c12John Reck public String toString() { 220352be4785a258687055515117775d5bcb8bec1c12John Reck StringBuilder builder = new StringBuilder(100); 220452be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(mId); 220552be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(") has parent: "); 220652be4785a258687055515117775d5bcb8bec1c12John Reck if (getParent() != null) { 220752be4785a258687055515117775d5bcb8bec1c12John Reck builder.append("true["); 220852be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(getParent().getId()); 220952be4785a258687055515117775d5bcb8bec1c12John Reck builder.append("]"); 221052be4785a258687055515117775d5bcb8bec1c12John Reck } else { 221152be4785a258687055515117775d5bcb8bec1c12John Reck builder.append("false"); 221252be4785a258687055515117775d5bcb8bec1c12John Reck } 221352be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(", incog: "); 221452be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(isPrivateBrowsingEnabled()); 221552be4785a258687055515117775d5bcb8bec1c12John Reck if (!isPrivateBrowsingEnabled()) { 221652be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(", title: "); 221752be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(getTitle()); 221852be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(", url: "); 221952be4785a258687055515117775d5bcb8bec1c12John Reck builder.append(getUrl()); 222052be4785a258687055515117775d5bcb8bec1c12John Reck } 222152be4785a258687055515117775d5bcb8bec1c12John Reck return builder.toString(); 222252be4785a258687055515117775d5bcb8bec1c12John Reck } 222352be4785a258687055515117775d5bcb8bec1c12John Reck 222422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba} 2225