10c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project/* 20c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 30c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * 40c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 50c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * you may not use this file except in compliance with the License. 60c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * You may obtain a copy of the License at 70c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * 80c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 90c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * 100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * See the License for the specific language governing permissions and 140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * limitations under the License. 150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpackage com.android.browser; 180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle; 200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log; 210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView; 220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.ArrayList; 243d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughterimport java.util.HashMap; 251bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolbimport java.util.List; 260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Vector; 270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectclass TabControl { 290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Log Tag 300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project private static final String LOGTAG = "TabControl"; 31c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 32d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck // next Tab ID, starting at 1 33d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck private static long sNextId = 1; 34c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 35c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb private static final String POSITIONS = "positions"; 36c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb private static final String CURRENT = "current"; 37c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 388ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck public static interface OnThumbnailUpdatedListener { 398ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck void onThumbnailUpdated(Tab t); 408ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 418ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck 420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Maximum number of tabs. 436e4653ee2adbee765d210e44ed38600d79135a06Michael Kolb private int mMaxTabs; 440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Private array of WebViews that are used as tabs. 456e4653ee2adbee765d210e44ed38600d79135a06Michael Kolb private ArrayList<Tab> mTabs; 460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Queue of most recently viewed tabs. 476e4653ee2adbee765d210e44ed38600d79135a06Michael Kolb private ArrayList<Tab> mTabQueue; 480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Current position in mTabs. 490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project private int mCurrentTab = -1; 508233facddcc51865d612a919d450db6954aa48e3Michael Kolb // the main browser controller 518233facddcc51865d612a919d450db6954aa48e3Michael Kolb private final Controller mController; 528233facddcc51865d612a919d450db6954aa48e3Michael Kolb 538ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck private OnThumbnailUpdatedListener mOnThumbnailUpdatedListener; 540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 568233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Construct a new TabControl object 570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 588233facddcc51865d612a919d450db6954aa48e3Michael Kolb TabControl(Controller controller) { 598233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController = controller; 608233facddcc51865d612a919d450db6954aa48e3Michael Kolb mMaxTabs = mController.getMaxTabs(); 616e4653ee2adbee765d210e44ed38600d79135a06Michael Kolb mTabs = new ArrayList<Tab>(mMaxTabs); 626e4653ee2adbee765d210e44ed38600d79135a06Michael Kolb mTabQueue = new ArrayList<Tab>(mMaxTabs); 630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 6552be4785a258687055515117775d5bcb8bec1c12John Reck synchronized static long getNextId() { 66c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb return sNextId++; 67c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb } 68c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb 6968775756e20243d73f273e4ce25ff3edeb148e41Michael Kolb /** 700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Return the current tab's main WebView. This will always return the main 710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * WebView for a given tab and not a subwindow. 720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @return The current tab's WebView. 730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project WebView getCurrentWebView() { 750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project Tab t = getTab(mCurrentTab); 760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (t == null) { 770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return null; 780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 7922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return t.getWebView(); 80bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch } 81bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch 82bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch /** 830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Return the current tab's top-level WebView. This can return a subwindow 840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * if one exists. 850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @return The top-level WebView of the current tab. 860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project WebView getCurrentTopWebView() { 880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project Tab t = getTab(mCurrentTab); 890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (t == null) { 900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return null; 910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 9222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return t.getTopWindow(); 930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Return the current tab's subwindow if it exists. 970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @return The subwindow of the current tab or null if it doesn't exist. 980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project WebView getCurrentSubWindow() { 1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project Tab t = getTab(mCurrentTab); 1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (t == null) { 1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return null; 1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 10422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba return t.getSubWebView(); 1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 1081bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb * return the list of tabs 1091bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb */ 1101bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb List<Tab> getTabs() { 1111bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb return mTabs; 1121bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb } 1131bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb 1141bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb /** 115c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * Return the tab at the specified position. 116c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * @return The Tab for the specified position or null if the tab does not 1170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * exist. 1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 119c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb Tab getTab(int position) { 120c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (position >= 0 && position < mTabs.size()) { 121c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb return mTabs.get(position); 1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return null; 1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Return the current tab. 1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @return The current tab. 1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project Tab getCurrentTab() { 1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return getTab(mCurrentTab); 1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 135c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * Return the current tab position. 136c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * @return The current tab position 1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 138c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb int getCurrentPosition() { 1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return mCurrentTab; 1400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 141fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb 1420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 143c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * Given a Tab, find it's position 1440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @param Tab to find 145c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * @return position of Tab or -1 if not found 1460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 147c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb int getTabPosition(Tab tab) { 148ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott if (tab == null) { 149ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott return -1; 150ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott } 1510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return mTabs.indexOf(tab); 1520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 1530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 15422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba boolean canCreateNewTab() { 155c3ad9eada3ab7acac5d194fd4a8d30443079e80eNarayan Kamath return mMaxTabs > mTabs.size(); 15622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 15722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 159e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter * Returns true if there are any incognito tabs open. 160e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter * @return True when any incognito tabs are open, false otherwise. 161e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter */ 162e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter boolean hasAnyOpenIncognitoTabs() { 163e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter for (Tab tab : mTabs) { 164c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (tab.getWebView() != null 165c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb && tab.getWebView().isPrivateBrowsingEnabled()) { 166e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter return true; 167e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter } 168e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter } 169e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter return false; 170e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter } 171e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter 1721461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb void addPreloadedTab(Tab tab) { 173e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood for (Tab current : mTabs) { 174e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood if (current != null && current.getId() == tab.getId()) { 175e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood throw new IllegalStateException("Tab with id " + tab.getId() + " already exists: " 176e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood + current.toString()); 177e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood } 178e09305e4ad0430571efb8ae880762204ddeaeb33Mathew Inwood } 1791461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mTabs.add(tab); 1801461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb tab.setController(mController); 1811461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb mController.onSetWebView(tab, tab.getWebView()); 1821461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb tab.putInBackground(); 1831461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 1841461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb 185e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter /** 186f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project * Create a new tab. 1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @return The newly createTab or null if we have reached the maximum 1880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * number of open tabs. 1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 1907bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb Tab createNewTab(boolean privateBrowsing) { 1911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck return createNewTab(null, privateBrowsing); 1921cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck } 1931cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck 1941cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Tab createNewTab(Bundle state, boolean privateBrowsing) { 1951cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck int size = mTabs.size(); 1961cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck // Return false if we have maxed out on tabs 197c3ad9eada3ab7acac5d194fd4a8d30443079e80eNarayan Kamath if (!canCreateNewTab()) { 1980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return null; 1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 200c3ad9eada3ab7acac5d194fd4a8d30443079e80eNarayan Kamath 201f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter final WebView w = createNewWebView(privateBrowsing); 2022bc69918d97a767a02132090e58718077381ba1aSteve Block 2030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Create a new tab and add it to the tab list 2041cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Tab t = new Tab(mController, w, state); 2050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mTabs.add(t); 2064e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project // Initially put the tab in the background. 20722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba t.putInBackground(); 2080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return t; 2090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 2100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 2110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 212f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project * Create a new tab with default values for closeOnExit(false), 213f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter * appId(null), url(null), and privateBrowsing(false). 214f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project */ 215f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project Tab createNewTab() { 2167bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb return createNewTab(false); 217f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 218f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project 219f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project /** 220fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins * Remove the parent child relationships from all tabs. 221fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins */ 222fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins void removeParentChildRelationShips() { 223fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins for (Tab tab : mTabs) { 224fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins tab.removeFromTree(); 225fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins } 226fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins } 227fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins 228fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins /** 2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Remove the tab from the list. If the tab is the current tab shown, the 2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * last created tab will be shown. 2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @param t The tab to be removed. 2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project boolean removeTab(Tab t) { 2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (t == null) { 2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return false; 2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 23722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba 238d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott // Grab the current tab before modifying the list. 239d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott Tab current = getCurrentTab(); 240d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott 241d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott // Remove t from our list of tabs. 242d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott mTabs.remove(t); 243d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott 244d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott // Put the tab in the background only if it is the current one. 245d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott if (current == t) { 24622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba t.putInBackground(); 24722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mCurrentTab = -1; 248d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott } else { 249d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott // If a tab that is earlier in the list gets removed, the current 250d944d4d63c9e93b51fae38fc86f0d87fff0e3a21Patrick Scott // index no longer points to the correct tab. 251c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb mCurrentTab = getTabPosition(current); 2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 25422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba // destroy the tab 25522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba t.destroy(); 2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // clear it's references to parent and children 2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project t.removeFromTree(); 2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Remove it from the queue of viewed tabs. 2600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mTabQueue.remove(t); 2610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return true; 2620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 2630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 2650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Destroy all the tabs and subwindows 2660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project void destroy() { 2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project for (Tab t : mTabs) { 26922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba t.destroy(); 2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mTabs.clear(); 2720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mTabQueue.clear(); 2730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 2740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 2750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 2760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Returns the number of tabs created. 2770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @return The number of tabs created. 2780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 2790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project int getTabCount() { 2800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return mTabs.size(); 2810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 2820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 2830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 284c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * save the tab state: 285c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * current position 286c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * position sorted array of tab ids 287c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * for each tab id, save the tab state 288c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * @param outState 289aed9c54d8e67bb683a5a415b3775525a3ac00508John Reck * @param saveImages 2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 2911cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck void saveState(Bundle outState) { 2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project final int numTabs = getTabCount(); 29324f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck if (numTabs == 0) { 29424f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck return; 29524f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck } 296c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb long[] ids = new long[numTabs]; 297c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb int i = 0; 298c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (Tab tab : mTabs) { 2991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Bundle tabState = tab.saveState(); 3001cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck if (tabState != null) { 3013ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb ids[i++] = tab.getId(); 30252be4785a258687055515117775d5bcb8bec1c12John Reck String key = Long.toString(tab.getId()); 30352be4785a258687055515117775d5bcb8bec1c12John Reck if (outState.containsKey(key)) { 30452be4785a258687055515117775d5bcb8bec1c12John Reck // Dump the tab state for debugging purposes 30552be4785a258687055515117775d5bcb8bec1c12John Reck for (Tab dt : mTabs) { 30652be4785a258687055515117775d5bcb8bec1c12John Reck Log.e(LOGTAG, dt.toString()); 30752be4785a258687055515117775d5bcb8bec1c12John Reck } 30852be4785a258687055515117775d5bcb8bec1c12John Reck throw new IllegalStateException( 30952be4785a258687055515117775d5bcb8bec1c12John Reck "Error saving state, duplicate tab ids!"); 31052be4785a258687055515117775d5bcb8bec1c12John Reck } 31152be4785a258687055515117775d5bcb8bec1c12John Reck outState.putBundle(key, tabState); 3123ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb } else { 3133ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb ids[i++] = -1; 31452be4785a258687055515117775d5bcb8bec1c12John Reck // Since we won't be restoring the thumbnail, delete it 31552be4785a258687055515117775d5bcb8bec1c12John Reck tab.deleteThumbnail(); 3160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 31824f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck if (!outState.isEmpty()) { 31924f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck outState.putLongArray(POSITIONS, ids); 32024f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck Tab current = getCurrentTab(); 32124f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck long cid = -1; 32224f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck if (current != null) { 32324f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck cid = current.getId(); 32424f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck } 32524f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck outState.putLong(CURRENT, cid); 326dbf3981ccbacb11a99c262fc5ebbece62b207a2dMichael Kolb } 3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 3307d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott * Check if the state can be restored. If the state can be restored, the 331c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * current tab id is returned. This can be passed to restoreState below 3327d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott * in order to restore the correct tab. Otherwise, -1 is returned and the 3337d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott * state cannot be restored. 3347d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott */ 335c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb long canRestoreState(Bundle inState, boolean restoreIncognitoTabs) { 336c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final long[] ids = (inState == null) ? null : inState.getLongArray(POSITIONS); 337c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (ids == null) { 3387d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott return -1; 3397d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 340c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final long oldcurrent = inState.getLong(CURRENT); 341c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb long current = -1; 3423ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb if (restoreIncognitoTabs || (hasState(oldcurrent, inState) && !isIncognito(oldcurrent, inState))) { 3431cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck current = oldcurrent; 3447d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } else { 345c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb // pick first non incognito tab 346c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (long id : ids) { 3473ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb if (hasState(id, inState) && !isIncognito(id, inState)) { 348c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb current = id; 3497d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott break; 3507d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 3517d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 3527d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 353c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb return current; 3547d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 3557d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott 3563ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb private boolean hasState(long id, Bundle state) { 3573ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb if (id == -1) return false; 3583ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb Bundle tab = state.getBundle(Long.toString(id)); 3593ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb return ((tab != null) && !tab.isEmpty()); 3603ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb } 3613ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb 3623ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb private boolean isIncognito(long id, Bundle state) { 3633ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb Bundle tabstate = state.getBundle(Long.toString(id)); 3643ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb if ((tabstate != null) && !tabstate.isEmpty()) { 3653ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb return tabstate.getBoolean(Tab.INCOGNITO); 3663ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb } 3673ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb return false; 3683ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb } 3693ae7f74a64fd1dc101910f1b14f315b34d1f1274Michael Kolb 3707d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott /** 3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Restore the state of all the tabs. 372c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb * @param currentId The tab id to restore. 3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @param inState The saved state of all the tabs. 3741bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb * @param restoreIncognitoTabs Restoring private browsing tabs 3751bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb * @param restoreAll All webviews get restored, not just the current tab 3761bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb * (this does not override handling of incognito tabs) 3770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 378c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb void restoreState(Bundle inState, long currentId, 3797d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott boolean restoreIncognitoTabs, boolean restoreAll) { 380c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (currentId == -1) { 3817d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott return; 3827d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 383c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb long[] ids = inState.getLongArray(POSITIONS); 384c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb long maxId = -Long.MAX_VALUE; 385c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb HashMap<Long, Tab> tabMap = new HashMap<Long, Tab>(); 386c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (long id : ids) { 387c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (id > maxId) { 388c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb maxId = id; 389c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb } 390c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final String idkey = Long.toString(id); 391c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb Bundle state = inState.getBundle(idkey); 392d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck if (state == null || state.isEmpty()) { 393d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck // Skip tab 394d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck continue; 395d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck } else if (!restoreIncognitoTabs 396c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb && state.getBoolean(Tab.INCOGNITO)) { 397c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb // ignore tab 398c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb } else if (id == currentId || restoreAll) { 3991cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Tab t = createNewTab(state, false); 40079e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath if (t == null) { 40179e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath // We could "break" at this point, but we want 40279e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath // sNextId to be set correctly. 40379e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath continue; 40479e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath } 405c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb tabMap.put(id, t); 4067d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // Me must set the current tab before restoring the state 4077d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // so that all the client classes are set. 408c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (id == currentId) { 4097d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott setCurrentTab(t); 4107d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 4117d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } else { 4127d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // Create a new tab and don't restore the state yet, add it 4137d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // to the tab list 4141cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck Tab t = new Tab(mController, state); 415c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb tabMap.put(id, t); 4167d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott mTabs.add(t); 4177d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // added the tab to the front as they are not current 4187d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott mTabQueue.add(0, t); 4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 420c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb } 42179e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath 42279e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath // make sure that there is no id overlap between the restored 42379e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath // and new tabs 42479e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath sNextId = maxId + 1; 42579e5d8d14609a2d5bc5cac8daf7cad1cc9a98d4eNarayan Kamath 426d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck if (mCurrentTab == -1) { 427d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck if (getTabCount() > 0) { 428d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck setCurrentTab(getTab(0)); 429d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck } 430d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck } 431c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb // restore parent/child relationships 432c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (long id : ids) { 433c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final Tab tab = tabMap.get(id); 434c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final Bundle b = inState.getBundle(Long.toString(id)); 435c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if ((b != null) && (tab != null)) { 436c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final long parentId = b.getLong(Tab.PARENTTAB, -1); 437c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (parentId != -1) { 438c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb final Tab parent = tabMap.get(parentId); 4397d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott if (parent != null) { 440c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb parent.addChildTab(tab); 4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 448f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba * Free the memory in this order, 1) free the background tabs; 2) free the 4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * WebView cache; 4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project void freeMemory() { 45292c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba if (getTabCount() == 0) return; 45392c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba 454f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba // free the least frequently used background tabs 455f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba Vector<Tab> tabs = getHalfLeastUsedTabs(getCurrentTab()); 456f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba if (tabs.size() > 0) { 457f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba Log.w(LOGTAG, "Free " + tabs.size() + " tabs in the browser"); 458f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba for (Tab t : tabs) { 459f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba // store the WebView's state. 460f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba t.saveState(); 461f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba // destroy the tab 462f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba t.destroy(); 463f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba } 4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return; 4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 4674433d0333f18ea1e5c5c531db48908665c6f8446Derek Sollenberger // free the WebView's unused memory (this includes the cache) 4684433d0333f18ea1e5c5c531db48908665c6f8446Derek Sollenberger Log.w(LOGTAG, "Free WebView's unused memory and cache"); 4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project WebView view = getCurrentWebView(); 4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (view != null) { 4714433d0333f18ea1e5c5c531db48908665c6f8446Derek Sollenberger view.freeMemory(); 4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 475f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba private Vector<Tab> getHalfLeastUsedTabs(Tab current) { 476f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba Vector<Tab> tabsToGo = new Vector<Tab>(); 477f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba 4782a67de4059775466071da52c07b18627c51c677cPatrick Scott // Don't do anything if we only have 1 tab or if the current tab is 4792a67de4059775466071da52c07b18627c51c677cPatrick Scott // null. 4802a67de4059775466071da52c07b18627c51c677cPatrick Scott if (getTabCount() == 1 || current == null) { 481f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba return tabsToGo; 4820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 4830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 484f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba if (mTabQueue.size() == 0) { 485f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba return tabsToGo; 4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 487f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba 488f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba // Rip through the queue starting at the beginning and tear down half of 489f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba // available tabs which are not the current tab or the parent of the 490f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba // current tab. 491f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba int openTabCount = 0; 492f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba for (Tab t : mTabQueue) { 493f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba if (t != null && t.getWebView() != null) { 494f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba openTabCount++; 495c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (t != current && t != current.getParent()) { 496f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba tabsToGo.add(t); 497f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba } 498f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba } 4990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 501f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba openTabCount /= 2; 502f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba if (tabsToGo.size() > openTabCount) { 503f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba tabsToGo.setSize(openTabCount); 504f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba } 505f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba 506f56f68d291ae26ff25db4dc62122692c1dd1f4f9Grace Kloba return tabsToGo; 5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 509ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb Tab getLeastUsedTab(Tab current) { 510ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb if (getTabCount() == 1 || current == null) { 511ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb return null; 512ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb } 513ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb if (mTabQueue.size() == 0) { 514ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb return null; 515ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb } 516ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb // find a tab which is not the current tab or the parent of the 517ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb // current tab 518ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb for (Tab t : mTabQueue) { 519ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb if (t != null && t.getWebView() != null) { 520ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb if (t != current && t != current.getParent()) { 521ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb return t; 522ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb } 523ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb } 524ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb } 525ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb return null; 526ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb } 527ff6a748ae78165cc2298f5120a4374b4ed6f836bMichael Kolb 5280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 5290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Show the tab that contains the given WebView. 5300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @param view The WebView used to find the tab. 5310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 5320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project Tab getTabFromView(WebView view) { 533c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (Tab t : mTabs) { 53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (t.getSubWebView() == view || t.getWebView() == view) { 5350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return t; 5360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 5370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 5380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return null; 5390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 5400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project /** 542f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project * Return the tab with the matching application id. 543f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project * @param id The application identifier. 544f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project */ 545c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb Tab getTabFromAppId(String id) { 546f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project if (id == null) { 547f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project return null; 548f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 549c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (Tab t : mTabs) { 55022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (id.equals(t.getAppId())) { 551f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project return t; 552f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 553f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 554f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project return null; 555f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 556f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project 55722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba /** 55822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba * Stop loading in all opened WebView including subWindows. 55922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba */ 5605d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba void stopAllLoading() { 561c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (Tab t : mTabs) { 56222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final WebView webview = t.getWebView(); 5635d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba if (webview != null) { 5645d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba webview.stopLoading(); 5655d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba } 56622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final WebView subview = t.getSubWebView(); 56722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba if (subview != null) { 5689727af8453990808bd0a104bd9ceb8671e335ab5Mattias Nilsson subview.stopLoading(); 56922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba } 5705d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba } 5715d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba } 5725d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba 573db22ec4ee014900988062d910bc810172a07df56John Reck // This method checks if a tab matches the given url. 574cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott private boolean tabMatchesUrl(Tab t, String url) { 575db22ec4ee014900988062d910bc810172a07df56John Reck return url.equals(t.getUrl()) || url.equals(t.getOriginalUrl()); 576cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott } 577cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott 578cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott /** 579db22ec4ee014900988062d910bc810172a07df56John Reck * Return the tab that matches the given url. 580cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott * @param url The url to search for. 581cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott */ 582db22ec4ee014900988062d910bc810172a07df56John Reck Tab findTabWithUrl(String url) { 583cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott if (url == null) { 584cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott return null; 585cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott } 586cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott // Check the current tab first. 587db22ec4ee014900988062d910bc810172a07df56John Reck Tab currentTab = getCurrentTab(); 588db22ec4ee014900988062d910bc810172a07df56John Reck if (currentTab != null && tabMatchesUrl(currentTab, url)) { 589db22ec4ee014900988062d910bc810172a07df56John Reck return currentTab; 590cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott } 591cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott // Now check all the rest. 592c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb for (Tab tab : mTabs) { 593c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb if (tabMatchesUrl(tab, url)) { 594db22ec4ee014900988062d910bc810172a07df56John Reck return tab; 595cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott } 596cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott } 597cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott return null; 598cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott } 599cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott 600f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project /** 60130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck * Recreate the main WebView of the given tab. 602f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project */ 60330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck void recreateWebView(Tab t) { 60422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba final WebView w = t.getWebView(); 605f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project if (w != null) { 60622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba t.destroy(); 607f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 608f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project // Create a new WebView. If this tab is the current tab, we need to put 609f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project // back all the clients so force it to be the current tab. 61091911a26058418e622950cffc616f99ada49df1dMichael Kolb t.setWebView(createNewWebView(), false); 611f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project if (getCurrentTab() == t) { 612f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project setCurrentTab(t, true); 613f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 614f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 615f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project 616f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project /** 617f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project * Creates a new WebView and registers it with the global settings. 618f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project */ 619f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project private WebView createNewWebView() { 620f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter return createNewWebView(false); 621f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter } 622f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter 623f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter /** 624f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter * Creates a new WebView and registers it with the global settings. 625f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter * @param privateBrowsing When true, enables private browsing in the new 626f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter * WebView. 627f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter */ 628f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter private WebView createNewWebView(boolean privateBrowsing) { 6298233facddcc51865d612a919d450db6954aa48e3Michael Kolb return mController.getWebViewFactory().createWebView(privateBrowsing); 630f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 631f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project 632f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project /** 6330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Put the current tab in the background and set newTab as the current tab. 6340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * @param newTab The new tab. If newTab is null, the current tab is not 6350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * set. 6360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */ 6370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project boolean setCurrentTab(Tab newTab) { 638f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project return setCurrentTab(newTab, false); 639f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project } 640f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project 641f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project /** 642f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project * If force is true, this method skips the check for newTab == current. 643f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project */ 644f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project private boolean setCurrentTab(Tab newTab, boolean force) { 6450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project Tab current = getTab(mCurrentTab); 646f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project if (current == newTab && !force) { 6470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return true; 6480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (current != null) { 65022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba current.putInBackground(); 65122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba mCurrentTab = -1; 6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 6530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (newTab == null) { 6540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return false; 6550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 6560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 6570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Move the newTab to the end of the queue 6580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project int index = mTabQueue.indexOf(newTab); 6590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (index != -1) { 6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mTabQueue.remove(index); 6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mTabQueue.add(newTab); 6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project 6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Display the new current tab 6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project mCurrentTab = mTabs.indexOf(newTab); 66622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba WebView mainView = newTab.getWebView(); 667f9e1705d4012706664a2bdf63a50b8a784b833ddJonathan Dixon boolean needRestore = mainView == null; 6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project if (needRestore) { 6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project // Same work as in createNewTab() except don't do new Tab() 6702bc69918d97a767a02132090e58718077381ba1aSteve Block mainView = createNewWebView(); 6712bc69918d97a767a02132090e58718077381ba1aSteve Block newTab.setWebView(mainView); 6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 67322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba newTab.putInForeground(); 6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project return true; 6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project } 676fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb 677e6db7dcd06e8ea0dee6a476c03640dd61d9d54aePaul Miller // Used by Tab.onJsAlert() and friends 678e6db7dcd06e8ea0dee6a476c03640dd61d9d54aePaul Miller void setActiveTab(Tab tab) { 679e6db7dcd06e8ea0dee6a476c03640dd61d9d54aePaul Miller // Calls TabControl.setCurrentTab() 680e6db7dcd06e8ea0dee6a476c03640dd61d9d54aePaul Miller mController.setActiveTab(tab); 681e6db7dcd06e8ea0dee6a476c03640dd61d9d54aePaul Miller } 682e6db7dcd06e8ea0dee6a476c03640dd61d9d54aePaul Miller 6838ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck public void setOnThumbnailUpdatedListener(OnThumbnailUpdatedListener listener) { 6848ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck mOnThumbnailUpdatedListener = listener; 6858ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck for (Tab t : mTabs) { 6868ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck WebView web = t.getWebView(); 6878ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck if (web != null) { 6888ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck web.setPictureListener(listener != null ? t : null); 6898ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 6908ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 6918ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 6928ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck 6938ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck public OnThumbnailUpdatedListener getOnThumbnailUpdatedListener() { 6948ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck return mOnThumbnailUpdatedListener; 6958ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck } 6968ee633fd62f94cd66c85c2904232d7c9e204cc9cJohn Reck 6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project} 698