blob: 8be30416789195ac4469d10bfa3f7d17335df92a [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
The Android Open Source Project0c908882009-03-03 19:32:16 -080019import android.os.Bundle;
The Android Open Source Project0c908882009-03-03 19:32:16 -080020import android.util.Log;
The Android Open Source Project0c908882009-03-03 19:32:16 -080021import android.webkit.WebView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080022
23import java.io.File;
24import java.util.ArrayList;
Elliott Slaughter3d6df162010-08-25 13:17:44 -070025import java.util.HashMap;
Michael Kolb1bf23132010-11-19 12:55:12 -080026import java.util.List;
The Android Open Source Project0c908882009-03-03 19:32:16 -080027import java.util.Vector;
28
29class TabControl {
30 // Log Tag
31 private static final String LOGTAG = "TabControl";
32 // Maximum number of tabs.
Michael Kolb6e4653e2010-09-27 16:22:38 -070033 private int mMaxTabs;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034 // Private array of WebViews that are used as tabs.
Michael Kolb6e4653e2010-09-27 16:22:38 -070035 private ArrayList<Tab> mTabs;
The Android Open Source Project0c908882009-03-03 19:32:16 -080036 // Queue of most recently viewed tabs.
Michael Kolb6e4653e2010-09-27 16:22:38 -070037 private ArrayList<Tab> mTabQueue;
The Android Open Source Project0c908882009-03-03 19:32:16 -080038 // Current position in mTabs.
39 private int mCurrentTab = -1;
Michael Kolb8233fac2010-10-26 16:08:53 -070040 // the main browser controller
41 private final Controller mController;
42
The Android Open Source Project0c908882009-03-03 19:32:16 -080043 private final File mThumbnailDir;
44
45 /**
Michael Kolb8233fac2010-10-26 16:08:53 -070046 * Construct a new TabControl object
The Android Open Source Project0c908882009-03-03 19:32:16 -080047 */
Michael Kolb8233fac2010-10-26 16:08:53 -070048 TabControl(Controller controller) {
49 mController = controller;
50 mThumbnailDir = mController.getActivity()
51 .getDir("thumbnails", 0);
52 mMaxTabs = mController.getMaxTabs();
Michael Kolb6e4653e2010-09-27 16:22:38 -070053 mTabs = new ArrayList<Tab>(mMaxTabs);
54 mTabQueue = new ArrayList<Tab>(mMaxTabs);
The Android Open Source Project0c908882009-03-03 19:32:16 -080055 }
56
57 File getThumbnailDir() {
58 return mThumbnailDir;
59 }
60
Michael Kolb68775752010-08-19 12:42:01 -070061 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -080062 * Return the current tab's main WebView. This will always return the main
63 * WebView for a given tab and not a subwindow.
64 * @return The current tab's WebView.
65 */
66 WebView getCurrentWebView() {
67 Tab t = getTab(mCurrentTab);
68 if (t == null) {
69 return null;
70 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070071 return t.getWebView();
Ben Murdochbff2d602009-07-01 20:19:05 +010072 }
73
74 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -080075 * Return the current tab's top-level WebView. This can return a subwindow
76 * if one exists.
77 * @return The top-level WebView of the current tab.
78 */
79 WebView getCurrentTopWebView() {
80 Tab t = getTab(mCurrentTab);
81 if (t == null) {
82 return null;
83 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070084 return t.getTopWindow();
The Android Open Source Project0c908882009-03-03 19:32:16 -080085 }
86
87 /**
88 * Return the current tab's subwindow if it exists.
89 * @return The subwindow of the current tab or null if it doesn't exist.
90 */
91 WebView getCurrentSubWindow() {
92 Tab t = getTab(mCurrentTab);
93 if (t == null) {
94 return null;
95 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070096 return t.getSubWebView();
The Android Open Source Project0c908882009-03-03 19:32:16 -080097 }
98
99 /**
Michael Kolb1bf23132010-11-19 12:55:12 -0800100 * return the list of tabs
101 */
102 List<Tab> getTabs() {
103 return mTabs;
104 }
105
106 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800107 * Return the tab at the specified index.
108 * @return The Tab for the specified index or null if the tab does not
109 * exist.
110 */
111 Tab getTab(int index) {
112 if (index >= 0 && index < mTabs.size()) {
113 return mTabs.get(index);
114 }
115 return null;
116 }
117
118 /**
119 * Return the current tab.
120 * @return The current tab.
121 */
122 Tab getCurrentTab() {
123 return getTab(mCurrentTab);
124 }
125
126 /**
127 * Return the current tab index.
128 * @return The current tab index
129 */
130 int getCurrentIndex() {
131 return mCurrentTab;
132 }
Michael Kolbfe251992010-07-08 15:41:55 -0700133
The Android Open Source Project0c908882009-03-03 19:32:16 -0800134 /**
135 * Given a Tab, find it's index
136 * @param Tab to find
137 * @return index of Tab or -1 if not found
138 */
139 int getTabIndex(Tab tab) {
Patrick Scottae641ac2009-04-20 13:51:49 -0400140 if (tab == null) {
141 return -1;
142 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800143 return mTabs.indexOf(tab);
144 }
145
Grace Kloba22ac16e2009-10-07 18:00:23 -0700146 boolean canCreateNewTab() {
Michael Kolb6e4653e2010-09-27 16:22:38 -0700147 return mMaxTabs != mTabs.size();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700148 }
149
The Android Open Source Project0c908882009-03-03 19:32:16 -0800150 /**
Elliott Slaughtere440a882010-08-20 13:54:45 -0700151 * Returns true if there are any incognito tabs open.
152 * @return True when any incognito tabs are open, false otherwise.
153 */
154 boolean hasAnyOpenIncognitoTabs() {
155 for (Tab tab : mTabs) {
Elliott Slaughter3d6df162010-08-25 13:17:44 -0700156 if (tab.getWebView() != null && tab.getWebView().isPrivateBrowsingEnabled()) {
Elliott Slaughtere440a882010-08-20 13:54:45 -0700157 return true;
158 }
159 }
160 return false;
161 }
162
163 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700164 * Create a new tab.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800165 * @return The newly createTab or null if we have reached the maximum
166 * number of open tabs.
167 */
Michael Kolb7bcafde2011-05-09 13:55:59 -0700168 Tab createNewTab(boolean privateBrowsing) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800169 int size = mTabs.size();
170 // Return false if we have maxed out on tabs
Michael Kolb6e4653e2010-09-27 16:22:38 -0700171 if (mMaxTabs == size) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800172 return null;
173 }
Elliott Slaughterf0f03952010-07-14 18:10:36 -0700174 final WebView w = createNewWebView(privateBrowsing);
Steve Block2bc69912009-07-30 14:45:13 +0100175
The Android Open Source Project0c908882009-03-03 19:32:16 -0800176 // Create a new tab and add it to the tab list
Michael Kolb7bcafde2011-05-09 13:55:59 -0700177 Tab t = new Tab(mController, w);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800178 mTabs.add(t);
The Android Open Source Project4e5f5872009-03-09 11:52:14 -0700179 // Initially put the tab in the background.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700180 t.putInBackground();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800181 return t;
182 }
183
184 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700185 * Create a new tab with default values for closeOnExit(false),
Elliott Slaughterf0f03952010-07-14 18:10:36 -0700186 * appId(null), url(null), and privateBrowsing(false).
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700187 */
188 Tab createNewTab() {
Michael Kolb7bcafde2011-05-09 13:55:59 -0700189 return createNewTab(false);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700190 }
191
192 /**
Leon Scrogginsfde97462010-01-11 13:06:21 -0500193 * Remove the parent child relationships from all tabs.
194 */
195 void removeParentChildRelationShips() {
196 for (Tab tab : mTabs) {
197 tab.removeFromTree();
198 }
199 }
200
201 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800202 * Remove the tab from the list. If the tab is the current tab shown, the
203 * last created tab will be shown.
204 * @param t The tab to be removed.
205 */
206 boolean removeTab(Tab t) {
207 if (t == null) {
208 return false;
209 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700210
Patrick Scottd944d4d2010-01-27 16:39:11 -0500211 // Grab the current tab before modifying the list.
212 Tab current = getCurrentTab();
213
214 // Remove t from our list of tabs.
215 mTabs.remove(t);
216
217 // Put the tab in the background only if it is the current one.
218 if (current == t) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700219 t.putInBackground();
220 mCurrentTab = -1;
Patrick Scottd944d4d2010-01-27 16:39:11 -0500221 } else {
222 // If a tab that is earlier in the list gets removed, the current
223 // index no longer points to the correct tab.
224 mCurrentTab = getTabIndex(current);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800225 }
226
Grace Kloba22ac16e2009-10-07 18:00:23 -0700227 // destroy the tab
228 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800229 // clear it's references to parent and children
230 t.removeFromTree();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800231
232 // The tab indices have shifted, update all the saved state so we point
233 // to the correct index.
234 for (Tab tab : mTabs) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700235 Vector<Tab> children = tab.getChildTabs();
236 if (children != null) {
237 for (Tab child : children) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800238 child.setParentTab(tab);
239 }
240 }
241 }
242
The Android Open Source Project0c908882009-03-03 19:32:16 -0800243 // Remove it from the queue of viewed tabs.
244 mTabQueue.remove(t);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800245 return true;
246 }
247
248 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800249 * Destroy all the tabs and subwindows
250 */
251 void destroy() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800252 for (Tab t : mTabs) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700253 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800254 }
255 mTabs.clear();
256 mTabQueue.clear();
257 }
258
259 /**
260 * Returns the number of tabs created.
261 * @return The number of tabs created.
262 */
263 int getTabCount() {
264 return mTabs.size();
265 }
266
The Android Open Source Project0c908882009-03-03 19:32:16 -0800267
268 /**
269 * Save the state of all the Tabs.
270 * @param outState The Bundle to save the state to.
271 */
272 void saveState(Bundle outState) {
273 final int numTabs = getTabCount();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700274 outState.putInt(Tab.NUMTABS, numTabs);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800275 final int index = getCurrentIndex();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700276 outState.putInt(Tab.CURRTAB, (index >= 0 && index < numTabs) ? index : 0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800277 for (int i = 0; i < numTabs; i++) {
278 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700279 if (t.saveState()) {
280 outState.putBundle(Tab.WEBVIEW + i, t.getSavedState());
The Android Open Source Project0c908882009-03-03 19:32:16 -0800281 }
282 }
283 }
284
285 /**
Patrick Scott7d50a932011-02-04 09:27:26 -0500286 * Check if the state can be restored. If the state can be restored, the
287 * current tab index is returned. This can be passed to restoreState below
288 * in order to restore the correct tab. Otherwise, -1 is returned and the
289 * state cannot be restored.
290 */
291 int canRestoreState(Bundle inState, boolean restoreIncognitoTabs) {
292 final int numTabs = (inState == null)
293 ? - 1 : inState.getInt(Tab.NUMTABS, -1);
294 if (numTabs == -1) {
295 return -1;
296 }
297 final int oldCurrentTab = inState.getInt(Tab.CURRTAB, -1);
298
299 // Determine whether the saved current tab can be restored, and if not,
300 // which tab will take its place.
301 int currentTab = -1;
302 if (restoreIncognitoTabs ||
303 !inState.getBundle(Tab.WEBVIEW + oldCurrentTab)
304 .getBoolean(Tab.INCOGNITO)) {
305 currentTab = oldCurrentTab;
306 } else {
307 for (int i = 0; i < numTabs; i++) {
308 if (!inState.getBundle(Tab.WEBVIEW + i)
309 .getBoolean(Tab.INCOGNITO)) {
310 currentTab = i;
311 break;
312 }
313 }
314 }
315
316 return currentTab;
317 }
318
319 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800320 * Restore the state of all the tabs.
Patrick Scott7d50a932011-02-04 09:27:26 -0500321 * @param currentTab The tab index to restore.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800322 * @param inState The saved state of all the tabs.
Michael Kolb1bf23132010-11-19 12:55:12 -0800323 * @param restoreIncognitoTabs Restoring private browsing tabs
324 * @param restoreAll All webviews get restored, not just the current tab
325 * (this does not override handling of incognito tabs)
The Android Open Source Project0c908882009-03-03 19:32:16 -0800326 * @return True if there were previous tabs that were restored. False if
327 * there was no saved state or restoring the state failed.
328 */
Patrick Scott7d50a932011-02-04 09:27:26 -0500329 void restoreState(Bundle inState, int currentTab,
330 boolean restoreIncognitoTabs, boolean restoreAll) {
331 if (currentTab == -1) {
332 return;
333 }
Elliott Slaughter3d6df162010-08-25 13:17:44 -0700334
Patrick Scott7d50a932011-02-04 09:27:26 -0500335 // If currentTab is valid, numTabs must be present.
336 final int numTabs = inState.getInt(Tab.NUMTABS, -1);
337
338 // Map saved tab indices to new indices, in case any incognito tabs
339 // need to not be restored.
340 HashMap<Integer, Integer> originalTabIndices = new HashMap<Integer, Integer>();
341 originalTabIndices.put(-1, -1);
342 for (int i = 0; i < numTabs; i++) {
343 Bundle state = inState.getBundle(Tab.WEBVIEW + i);
344
345 if (!restoreIncognitoTabs && state != null && state.getBoolean(Tab.INCOGNITO)) {
346 originalTabIndices.put(i, -1);
347 } else if (i == currentTab || restoreAll) {
348 Tab t = createNewTab();
349 // Me must set the current tab before restoring the state
350 // so that all the client classes are set.
351 if (i == currentTab) {
352 setCurrentTab(t);
353 }
354 if (!t.restoreState(state)) {
355 Log.w(LOGTAG, "Fail in restoreState, load home page.");
356 t.getWebView().loadUrl(BrowserSettings.getInstance()
357 .getHomePage());
358 }
359 originalTabIndices.put(i, getTabCount() - 1);
Elliott Slaughter3d6df162010-08-25 13:17:44 -0700360 } else {
Patrick Scott7d50a932011-02-04 09:27:26 -0500361 // Create a new tab and don't restore the state yet, add it
362 // to the tab list
Michael Kolb7bcafde2011-05-09 13:55:59 -0700363 Tab t = new Tab(mController, null);
Patrick Scott7d50a932011-02-04 09:27:26 -0500364 if (state != null) {
365 t.setSavedState(state);
366 // Need to maintain the app id and original url so we
367 // can possibly reuse this tab.
368 t.setAppId(state.getString(Tab.APPID));
Elliott Slaughter3d6df162010-08-25 13:17:44 -0700369 }
Patrick Scott7d50a932011-02-04 09:27:26 -0500370 mTabs.add(t);
371 // added the tab to the front as they are not current
372 mTabQueue.add(0, t);
373 originalTabIndices.put(i, getTabCount() - 1);
Elliott Slaughter3d6df162010-08-25 13:17:44 -0700374 }
Patrick Scott7d50a932011-02-04 09:27:26 -0500375 }
Elliott Slaughter3d6df162010-08-25 13:17:44 -0700376
Patrick Scott7d50a932011-02-04 09:27:26 -0500377 // Rebuild the tree of tabs. Do this after all tabs have been
378 // created/restored so that the parent tab exists.
379 for (int i = 0; i < numTabs; i++) {
380 final Bundle b = inState.getBundle(Tab.WEBVIEW + i);
381 final Tab t = getTab(i);
382 if (b != null && t != null) {
383 final Integer parentIndex = originalTabIndices.get(b.getInt(Tab.PARENTTAB, -1));
384 if (parentIndex != -1) {
385 final Tab parent = getTab(parentIndex);
386 if (parent != null) {
387 parent.addChildTab(t);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800388 }
389 }
390 }
391 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800392 }
393
394 /**
Grace Klobaf56f68d2010-04-11 22:53:42 -0700395 * Free the memory in this order, 1) free the background tabs; 2) free the
The Android Open Source Project0c908882009-03-03 19:32:16 -0800396 * WebView cache;
397 */
398 void freeMemory() {
Grace Kloba92c18a52009-07-31 23:48:32 -0700399 if (getTabCount() == 0) return;
400
Grace Klobaf56f68d2010-04-11 22:53:42 -0700401 // free the least frequently used background tabs
402 Vector<Tab> tabs = getHalfLeastUsedTabs(getCurrentTab());
403 if (tabs.size() > 0) {
404 Log.w(LOGTAG, "Free " + tabs.size() + " tabs in the browser");
405 for (Tab t : tabs) {
406 // store the WebView's state.
407 t.saveState();
408 // destroy the tab
409 t.destroy();
410 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800411 return;
412 }
413
Derek Sollenberger4433d032009-06-10 15:37:21 -0400414 // free the WebView's unused memory (this includes the cache)
415 Log.w(LOGTAG, "Free WebView's unused memory and cache");
The Android Open Source Project0c908882009-03-03 19:32:16 -0800416 WebView view = getCurrentWebView();
417 if (view != null) {
Derek Sollenberger4433d032009-06-10 15:37:21 -0400418 view.freeMemory();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800419 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800420 }
421
Grace Klobaf56f68d2010-04-11 22:53:42 -0700422 private Vector<Tab> getHalfLeastUsedTabs(Tab current) {
423 Vector<Tab> tabsToGo = new Vector<Tab>();
424
Patrick Scott2a67de42009-08-31 09:48:37 -0400425 // Don't do anything if we only have 1 tab or if the current tab is
426 // null.
427 if (getTabCount() == 1 || current == null) {
Grace Klobaf56f68d2010-04-11 22:53:42 -0700428 return tabsToGo;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800429 }
430
Grace Klobaf56f68d2010-04-11 22:53:42 -0700431 if (mTabQueue.size() == 0) {
432 return tabsToGo;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800433 }
434
Grace Klobaf56f68d2010-04-11 22:53:42 -0700435 // Rip through the queue starting at the beginning and tear down half of
436 // available tabs which are not the current tab or the parent of the
437 // current tab.
438 int openTabCount = 0;
439 for (Tab t : mTabQueue) {
440 if (t != null && t.getWebView() != null) {
441 openTabCount++;
442 if (t != current && t != current.getParentTab()) {
443 tabsToGo.add(t);
444 }
445 }
446 }
447
448 openTabCount /= 2;
449 if (tabsToGo.size() > openTabCount) {
450 tabsToGo.setSize(openTabCount);
451 }
452
453 return tabsToGo;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800454 }
455
The Android Open Source Project0c908882009-03-03 19:32:16 -0800456 /**
457 * Show the tab that contains the given WebView.
458 * @param view The WebView used to find the tab.
459 */
460 Tab getTabFromView(WebView view) {
461 final int size = getTabCount();
462 for (int i = 0; i < size; i++) {
463 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700464 if (t.getSubWebView() == view || t.getWebView() == view) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800465 return t;
466 }
467 }
468 return null;
469 }
470
471 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700472 * Return the tab with the matching application id.
473 * @param id The application identifier.
474 */
475 Tab getTabFromId(String id) {
476 if (id == null) {
477 return null;
478 }
479 final int size = getTabCount();
480 for (int i = 0; i < size; i++) {
481 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700482 if (id.equals(t.getAppId())) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700483 return t;
484 }
485 }
486 return null;
487 }
488
Grace Kloba22ac16e2009-10-07 18:00:23 -0700489 /**
490 * Stop loading in all opened WebView including subWindows.
491 */
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700492 void stopAllLoading() {
493 final int size = getTabCount();
494 for (int i = 0; i < size; i++) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700495 final Tab t = getTab(i);
496 final WebView webview = t.getWebView();
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700497 if (webview != null) {
498 webview.stopLoading();
499 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700500 final WebView subview = t.getSubWebView();
501 if (subview != null) {
502 webview.stopLoading();
503 }
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700504 }
505 }
506
Patrick Scottcd115892009-07-16 09:42:58 -0400507 // This method checks if a non-app tab (one created within the browser)
508 // matches the given url.
509 private boolean tabMatchesUrl(Tab t, String url) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700510 if (t.getAppId() != null) {
Patrick Scottcd115892009-07-16 09:42:58 -0400511 return false;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700512 }
513 WebView webview = t.getWebView();
514 if (webview == null) {
Patrick Scottcd115892009-07-16 09:42:58 -0400515 return false;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700516 } else if (url.equals(webview.getUrl())
517 || url.equals(webview.getOriginalUrl())) {
Patrick Scottcd115892009-07-16 09:42:58 -0400518 return true;
519 }
520 return false;
521 }
522
523 /**
524 * Return the tab that has no app id associated with it and the url of the
525 * tab matches the given url.
526 * @param url The url to search for.
527 */
528 Tab findUnusedTabWithUrl(String url) {
529 if (url == null) {
530 return null;
531 }
532 // Check the current tab first.
533 Tab t = getCurrentTab();
534 if (t != null && tabMatchesUrl(t, url)) {
535 return t;
536 }
537 // Now check all the rest.
538 final int size = getTabCount();
539 for (int i = 0; i < size; i++) {
540 t = getTab(i);
541 if (tabMatchesUrl(t, url)) {
542 return t;
543 }
544 }
545 return null;
546 }
547
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700548 /**
John Reck30c714c2010-12-16 17:30:34 -0800549 * Recreate the main WebView of the given tab.
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700550 */
John Reck30c714c2010-12-16 17:30:34 -0800551 void recreateWebView(Tab t) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700552 final WebView w = t.getWebView();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700553 if (w != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700554 t.destroy();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700555 }
556 // Create a new WebView. If this tab is the current tab, we need to put
557 // back all the clients so force it to be the current tab.
Steve Block2bc69912009-07-30 14:45:13 +0100558 t.setWebView(createNewWebView());
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700559 if (getCurrentTab() == t) {
560 setCurrentTab(t, true);
561 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700562 // Clear the saved state and picker data
563 t.setSavedState(null);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700564 }
565
566 /**
567 * Creates a new WebView and registers it with the global settings.
568 */
569 private WebView createNewWebView() {
Elliott Slaughterf0f03952010-07-14 18:10:36 -0700570 return createNewWebView(false);
571 }
572
573 /**
574 * Creates a new WebView and registers it with the global settings.
575 * @param privateBrowsing When true, enables private browsing in the new
576 * WebView.
577 */
578 private WebView createNewWebView(boolean privateBrowsing) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700579 return mController.getWebViewFactory().createWebView(privateBrowsing);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700580 }
581
582 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800583 * Put the current tab in the background and set newTab as the current tab.
584 * @param newTab The new tab. If newTab is null, the current tab is not
585 * set.
586 */
587 boolean setCurrentTab(Tab newTab) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700588 return setCurrentTab(newTab, false);
589 }
590
591 /**
592 * If force is true, this method skips the check for newTab == current.
593 */
594 private boolean setCurrentTab(Tab newTab, boolean force) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800595 Tab current = getTab(mCurrentTab);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700596 if (current == newTab && !force) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800597 return true;
598 }
599 if (current != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700600 current.putInBackground();
601 mCurrentTab = -1;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800602 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800603 if (newTab == null) {
604 return false;
605 }
606
607 // Move the newTab to the end of the queue
608 int index = mTabQueue.indexOf(newTab);
609 if (index != -1) {
610 mTabQueue.remove(index);
611 }
612 mTabQueue.add(newTab);
613
The Android Open Source Project0c908882009-03-03 19:32:16 -0800614 // Display the new current tab
615 mCurrentTab = mTabs.indexOf(newTab);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700616 WebView mainView = newTab.getWebView();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800617 boolean needRestore = (mainView == null);
618 if (needRestore) {
619 // Same work as in createNewTab() except don't do new Tab()
Steve Block2bc69912009-07-30 14:45:13 +0100620 mainView = createNewWebView();
621 newTab.setWebView(mainView);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800622 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700623 newTab.putInForeground();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800624 if (needRestore) {
625 // Have to finish setCurrentTab work before calling restoreState
Grace Kloba22ac16e2009-10-07 18:00:23 -0700626 if (!newTab.restoreState(newTab.getSavedState())) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800627 mainView.loadUrl(BrowserSettings.getInstance().getHomePage());
628 }
629 }
630 return true;
631 }
Michael Kolbfe251992010-07-08 15:41:55 -0700632
The Android Open Source Project0c908882009-03-03 19:32:16 -0800633}