blob: 5e64a4b26145819f72f6f0cc10e2bba09c256398 [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.view.View;
The Android Open Source Project0c908882009-03-03 19:32:16 -080022import android.webkit.WebBackForwardList;
The Android Open Source Project0c908882009-03-03 19:32:16 -080023import android.webkit.WebView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080024
25import java.io.File;
26import java.util.ArrayList;
27import java.util.Vector;
28
29class TabControl {
30 // Log Tag
31 private static final String LOGTAG = "TabControl";
32 // Maximum number of tabs.
Grace Kloba22ac16e2009-10-07 18:00:23 -070033 private static final int MAX_TABS = 8;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034 // Private array of WebViews that are used as tabs.
35 private ArrayList<Tab> mTabs = new ArrayList<Tab>(MAX_TABS);
36 // Queue of most recently viewed tabs.
37 private ArrayList<Tab> mTabQueue = new ArrayList<Tab>(MAX_TABS);
38 // Current position in mTabs.
39 private int mCurrentTab = -1;
40 // A private instance of BrowserActivity to interface with when adding and
41 // switching between tabs.
42 private final BrowserActivity mActivity;
The Android Open Source Project0c908882009-03-03 19:32:16 -080043 // Directory to store thumbnails for each WebView.
44 private final File mThumbnailDir;
45
46 /**
47 * Construct a new TabControl object that interfaces with the given
48 * BrowserActivity instance.
49 * @param activity A BrowserActivity instance that TabControl will interface
50 * with.
51 */
52 TabControl(BrowserActivity activity) {
53 mActivity = activity;
The Android Open Source Project0c908882009-03-03 19:32:16 -080054 mThumbnailDir = activity.getDir("thumbnails", 0);
55 }
56
57 File getThumbnailDir() {
58 return mThumbnailDir;
59 }
60
61 BrowserActivity getBrowserActivity() {
62 return mActivity;
63 }
64
65 /**
66 * Return the current tab's main WebView. This will always return the main
67 * WebView for a given tab and not a subwindow.
68 * @return The current tab's WebView.
69 */
70 WebView getCurrentWebView() {
71 Tab t = getTab(mCurrentTab);
72 if (t == null) {
73 return null;
74 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070075 return t.getWebView();
Ben Murdochbff2d602009-07-01 20:19:05 +010076 }
77
78 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -080079 * Return the current tab's top-level WebView. This can return a subwindow
80 * if one exists.
81 * @return The top-level WebView of the current tab.
82 */
83 WebView getCurrentTopWebView() {
84 Tab t = getTab(mCurrentTab);
85 if (t == null) {
86 return null;
87 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070088 return t.getTopWindow();
The Android Open Source Project0c908882009-03-03 19:32:16 -080089 }
90
91 /**
92 * Return the current tab's subwindow if it exists.
93 * @return The subwindow of the current tab or null if it doesn't exist.
94 */
95 WebView getCurrentSubWindow() {
96 Tab t = getTab(mCurrentTab);
97 if (t == null) {
98 return null;
99 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700100 return t.getSubWebView();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800101 }
102
103 /**
104 * Return the tab at the specified index.
105 * @return The Tab for the specified index or null if the tab does not
106 * exist.
107 */
108 Tab getTab(int index) {
109 if (index >= 0 && index < mTabs.size()) {
110 return mTabs.get(index);
111 }
112 return null;
113 }
114
115 /**
116 * Return the current tab.
117 * @return The current tab.
118 */
119 Tab getCurrentTab() {
120 return getTab(mCurrentTab);
121 }
122
123 /**
124 * Return the current tab index.
125 * @return The current tab index
126 */
127 int getCurrentIndex() {
128 return mCurrentTab;
129 }
130
131 /**
132 * Given a Tab, find it's index
133 * @param Tab to find
134 * @return index of Tab or -1 if not found
135 */
136 int getTabIndex(Tab tab) {
Patrick Scottae641ac2009-04-20 13:51:49 -0400137 if (tab == null) {
138 return -1;
139 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800140 return mTabs.indexOf(tab);
141 }
142
Grace Kloba22ac16e2009-10-07 18:00:23 -0700143 boolean canCreateNewTab() {
144 return MAX_TABS != mTabs.size();
145 }
146
The Android Open Source Project0c908882009-03-03 19:32:16 -0800147 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700148 * Create a new tab.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800149 * @return The newly createTab or null if we have reached the maximum
150 * number of open tabs.
151 */
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700152 Tab createNewTab(boolean closeOnExit, String appId, String url) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800153 int size = mTabs.size();
154 // Return false if we have maxed out on tabs
155 if (MAX_TABS == size) {
156 return null;
157 }
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700158 final WebView w = createNewWebView();
Steve Block2bc69912009-07-30 14:45:13 +0100159
The Android Open Source Project0c908882009-03-03 19:32:16 -0800160 // Create a new tab and add it to the tab list
Grace Kloba22ac16e2009-10-07 18:00:23 -0700161 Tab t = new Tab(mActivity, w, closeOnExit, appId, url);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800162 mTabs.add(t);
The Android Open Source Project4e5f5872009-03-09 11:52:14 -0700163 // Initially put the tab in the background.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700164 t.putInBackground();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800165 return t;
166 }
167
168 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700169 * Create a new tab with default values for closeOnExit(false),
170 * appId(null), and url(null).
171 */
172 Tab createNewTab() {
173 return createNewTab(false, null, null);
174 }
175
176 /**
Leon Scrogginsfde97462010-01-11 13:06:21 -0500177 * Remove the parent child relationships from all tabs.
178 */
179 void removeParentChildRelationShips() {
180 for (Tab tab : mTabs) {
181 tab.removeFromTree();
182 }
183 }
184
185 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800186 * Remove the tab from the list. If the tab is the current tab shown, the
187 * last created tab will be shown.
188 * @param t The tab to be removed.
189 */
190 boolean removeTab(Tab t) {
191 if (t == null) {
192 return false;
193 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700194
Patrick Scottd944d4d2010-01-27 16:39:11 -0500195 // Grab the current tab before modifying the list.
196 Tab current = getCurrentTab();
197
198 // Remove t from our list of tabs.
199 mTabs.remove(t);
200
201 // Put the tab in the background only if it is the current one.
202 if (current == t) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700203 t.putInBackground();
204 mCurrentTab = -1;
Patrick Scottd944d4d2010-01-27 16:39:11 -0500205 } else {
206 // If a tab that is earlier in the list gets removed, the current
207 // index no longer points to the correct tab.
208 mCurrentTab = getTabIndex(current);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800209 }
210
Grace Kloba22ac16e2009-10-07 18:00:23 -0700211 // destroy the tab
212 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800213 // clear it's references to parent and children
214 t.removeFromTree();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800215
216 // The tab indices have shifted, update all the saved state so we point
217 // to the correct index.
218 for (Tab tab : mTabs) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700219 Vector<Tab> children = tab.getChildTabs();
220 if (children != null) {
221 for (Tab child : children) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800222 child.setParentTab(tab);
223 }
224 }
225 }
226
The Android Open Source Project0c908882009-03-03 19:32:16 -0800227 // This tab may have been pushed in to the background and then closed.
228 // If the saved state contains a picture file, delete the file.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700229 Bundle savedState = t.getSavedState();
230 if (savedState != null) {
231 if (savedState.containsKey(Tab.CURRPICTURE)) {
232 new File(savedState.getString(Tab.CURRPICTURE)).delete();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800233 }
234 }
235
236 // Remove it from the queue of viewed tabs.
237 mTabQueue.remove(t);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800238 return true;
239 }
240
241 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800242 * Destroy all the tabs and subwindows
243 */
244 void destroy() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800245 for (Tab t : mTabs) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700246 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800247 }
248 mTabs.clear();
249 mTabQueue.clear();
250 }
251
252 /**
253 * Returns the number of tabs created.
254 * @return The number of tabs created.
255 */
256 int getTabCount() {
257 return mTabs.size();
258 }
259
The Android Open Source Project0c908882009-03-03 19:32:16 -0800260
261 /**
262 * Save the state of all the Tabs.
263 * @param outState The Bundle to save the state to.
264 */
265 void saveState(Bundle outState) {
266 final int numTabs = getTabCount();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700267 outState.putInt(Tab.NUMTABS, numTabs);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800268 final int index = getCurrentIndex();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700269 outState.putInt(Tab.CURRTAB, (index >= 0 && index < numTabs) ? index : 0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800270 for (int i = 0; i < numTabs; i++) {
271 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700272 if (t.saveState()) {
273 outState.putBundle(Tab.WEBVIEW + i, t.getSavedState());
The Android Open Source Project0c908882009-03-03 19:32:16 -0800274 }
275 }
276 }
277
278 /**
279 * Restore the state of all the tabs.
280 * @param inState The saved state of all the tabs.
281 * @return True if there were previous tabs that were restored. False if
282 * there was no saved state or restoring the state failed.
283 */
284 boolean restoreState(Bundle inState) {
285 final int numTabs = (inState == null)
Grace Kloba22ac16e2009-10-07 18:00:23 -0700286 ? -1 : inState.getInt(Tab.NUMTABS, -1);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800287 if (numTabs == -1) {
288 return false;
289 } else {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700290 final int currentTab = inState.getInt(Tab.CURRTAB, -1);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800291 for (int i = 0; i < numTabs; i++) {
292 if (i == currentTab) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700293 Tab t = createNewTab();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800294 // Me must set the current tab before restoring the state
295 // so that all the client classes are set.
296 setCurrentTab(t);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700297 if (!t.restoreState(inState.getBundle(Tab.WEBVIEW + i))) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800298 Log.w(LOGTAG, "Fail in restoreState, load home page.");
Grace Kloba22ac16e2009-10-07 18:00:23 -0700299 t.getWebView().loadUrl(BrowserSettings.getInstance()
The Android Open Source Project0c908882009-03-03 19:32:16 -0800300 .getHomePage());
301 }
302 } else {
303 // Create a new tab and don't restore the state yet, add it
304 // to the tab list
Grace Kloba22ac16e2009-10-07 18:00:23 -0700305 Tab t = new Tab(mActivity, null, false, null, null);
306 Bundle state = inState.getBundle(Tab.WEBVIEW + i);
307 if (state != null) {
308 t.setSavedState(state);
309 t.populatePickerDataFromSavedState();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700310 // Need to maintain the app id and original url so we
311 // can possibly reuse this tab.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700312 t.setAppId(state.getString(Tab.APPID));
313 t.setOriginalUrl(state.getString(Tab.ORIGINALURL));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800314 }
315 mTabs.add(t);
316 mTabQueue.add(t);
317 }
318 }
319 // Rebuild the tree of tabs. Do this after all tabs have been
320 // created/restored so that the parent tab exists.
321 for (int i = 0; i < numTabs; i++) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700322 final Bundle b = inState.getBundle(Tab.WEBVIEW + i);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800323 final Tab t = getTab(i);
324 if (b != null && t != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700325 final int parentIndex = b.getInt(Tab.PARENTTAB, -1);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800326 if (parentIndex != -1) {
327 final Tab parent = getTab(parentIndex);
328 if (parent != null) {
329 parent.addChildTab(t);
330 }
331 }
332 }
333 }
334 }
335 return true;
336 }
337
338 /**
339 * Free the memory in this order, 1) free the background tab; 2) free the
340 * WebView cache;
341 */
342 void freeMemory() {
Grace Kloba92c18a52009-07-31 23:48:32 -0700343 if (getTabCount() == 0) return;
344
The Android Open Source Project0c908882009-03-03 19:32:16 -0800345 // free the least frequently used background tab
Patrick Scott2a67de42009-08-31 09:48:37 -0400346 Tab t = getLeastUsedTab(getCurrentTab());
The Android Open Source Project0c908882009-03-03 19:32:16 -0800347 if (t != null) {
348 Log.w(LOGTAG, "Free a tab in the browser");
Grace Kloba22ac16e2009-10-07 18:00:23 -0700349 // store the WebView's state.
350 t.saveState();
351 // destroy the tab
352 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800353 return;
354 }
355
Derek Sollenberger4433d032009-06-10 15:37:21 -0400356 // free the WebView's unused memory (this includes the cache)
357 Log.w(LOGTAG, "Free WebView's unused memory and cache");
The Android Open Source Project0c908882009-03-03 19:32:16 -0800358 WebView view = getCurrentWebView();
359 if (view != null) {
Derek Sollenberger4433d032009-06-10 15:37:21 -0400360 view.freeMemory();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800361 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800362 }
363
Patrick Scott2a67de42009-08-31 09:48:37 -0400364 private Tab getLeastUsedTab(Tab current) {
365 // Don't do anything if we only have 1 tab or if the current tab is
366 // null.
367 if (getTabCount() == 1 || current == null) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800368 return null;
369 }
370
Grace Kloba22ac16e2009-10-07 18:00:23 -0700371 // Rip through the queue starting at the beginning and tear down the
The Android Open Source Project0c908882009-03-03 19:32:16 -0800372 // next available tab.
373 Tab t = null;
374 int i = 0;
375 final int queueSize = mTabQueue.size();
376 if (queueSize == 0) {
377 return null;
378 }
379 do {
380 t = mTabQueue.get(i++);
Grace Kloba92c18a52009-07-31 23:48:32 -0700381 } while (i < queueSize
Grace Kloba22ac16e2009-10-07 18:00:23 -0700382 && ((t != null && t.getWebView() == null)
383 || t == current.getParentTab()));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800384
Patrick Scottd068f802009-06-22 11:46:06 -0400385 // Don't do anything if the last remaining tab is the current one or if
386 // the last tab has been freed already.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700387 if (t == current || t.getWebView() == null) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800388 return null;
389 }
390
391 return t;
392 }
393
The Android Open Source Project0c908882009-03-03 19:32:16 -0800394 /**
395 * Show the tab that contains the given WebView.
396 * @param view The WebView used to find the tab.
397 */
398 Tab getTabFromView(WebView view) {
399 final int size = getTabCount();
400 for (int i = 0; i < size; i++) {
401 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700402 if (t.getSubWebView() == view || t.getWebView() == view) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800403 return t;
404 }
405 }
406 return null;
407 }
408
409 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700410 * Return the tab with the matching application id.
411 * @param id The application identifier.
412 */
413 Tab getTabFromId(String id) {
414 if (id == null) {
415 return null;
416 }
417 final int size = getTabCount();
418 for (int i = 0; i < size; i++) {
419 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700420 if (id.equals(t.getAppId())) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700421 return t;
422 }
423 }
424 return null;
425 }
426
Grace Kloba22ac16e2009-10-07 18:00:23 -0700427 /**
428 * Stop loading in all opened WebView including subWindows.
429 */
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700430 void stopAllLoading() {
431 final int size = getTabCount();
432 for (int i = 0; i < size; i++) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700433 final Tab t = getTab(i);
434 final WebView webview = t.getWebView();
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700435 if (webview != null) {
436 webview.stopLoading();
437 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700438 final WebView subview = t.getSubWebView();
439 if (subview != null) {
440 webview.stopLoading();
441 }
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700442 }
443 }
444
Patrick Scottcd115892009-07-16 09:42:58 -0400445 // This method checks if a non-app tab (one created within the browser)
446 // matches the given url.
447 private boolean tabMatchesUrl(Tab t, String url) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700448 if (t.getAppId() != null) {
Patrick Scottcd115892009-07-16 09:42:58 -0400449 return false;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700450 }
451 WebView webview = t.getWebView();
452 if (webview == null) {
Patrick Scottcd115892009-07-16 09:42:58 -0400453 return false;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700454 } else if (url.equals(webview.getUrl())
455 || url.equals(webview.getOriginalUrl())) {
Patrick Scottcd115892009-07-16 09:42:58 -0400456 return true;
457 }
458 return false;
459 }
460
461 /**
462 * Return the tab that has no app id associated with it and the url of the
463 * tab matches the given url.
464 * @param url The url to search for.
465 */
466 Tab findUnusedTabWithUrl(String url) {
467 if (url == null) {
468 return null;
469 }
470 // Check the current tab first.
471 Tab t = getCurrentTab();
472 if (t != null && tabMatchesUrl(t, url)) {
473 return t;
474 }
475 // Now check all the rest.
476 final int size = getTabCount();
477 for (int i = 0; i < size; i++) {
478 t = getTab(i);
479 if (tabMatchesUrl(t, url)) {
480 return t;
481 }
482 }
483 return null;
484 }
485
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700486 /**
487 * Recreate the main WebView of the given tab. Returns true if the WebView
488 * was deleted.
489 */
490 boolean recreateWebView(Tab t, String url) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700491 final WebView w = t.getWebView();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700492 if (w != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700493 if (url != null && url.equals(t.getOriginalUrl())) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700494 // The original url matches the current url. Just go back to the
495 // first history item so we can load it faster than if we
496 // rebuilt the WebView.
497 final WebBackForwardList list = w.copyBackForwardList();
498 if (list != null) {
499 w.goBackOrForward(-list.getCurrentIndex());
500 w.clearHistory(); // maintains the current page.
501 return false;
502 }
503 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700504 t.destroy();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700505 }
506 // Create a new WebView. If this tab is the current tab, we need to put
507 // back all the clients so force it to be the current tab.
Steve Block2bc69912009-07-30 14:45:13 +0100508 t.setWebView(createNewWebView());
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700509 if (getCurrentTab() == t) {
510 setCurrentTab(t, true);
511 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700512 // Clear the saved state and picker data
513 t.setSavedState(null);
514 t.clearPickerData();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700515 // Save the new url in order to avoid deleting the WebView.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700516 t.setOriginalUrl(url);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700517 return true;
518 }
519
520 /**
521 * Creates a new WebView and registers it with the global settings.
522 */
523 private WebView createNewWebView() {
524 // Create a new WebView
525 WebView w = new WebView(mActivity);
Grace Kloba67f0a562009-09-28 21:24:51 -0700526 w.setScrollbarFadingEnabled(true);
527 w.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700528 w.setMapTrackballToArrowKeys(false); // use trackball directly
The Android Open Source Projecta3c0aab2009-03-18 17:39:48 -0700529 // Enable the built-in zoom
530 w.getSettings().setBuiltInZoomControls(true);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700531 // Attach DownloadManager so that downloads can start in an active or
532 // a non-active window. This can happen when going to a site that does
533 // a redirect after a period of time. The user could have switched to
534 // another tab while waiting for the download to start.
535 w.setDownloadListener(mActivity);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700536 // Add this WebView to the settings observer list and update the
537 // settings
538 final BrowserSettings s = BrowserSettings.getInstance();
539 s.addObserver(w.getSettings()).update(s, null);
Mike Reedd5a80a52009-11-12 12:49:34 -0500540
Mike Reeda947d2d2010-01-14 14:57:45 -0800541 // pick a default
542 w.setDragTracker(new MeshTracker(1));
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700543 return w;
544 }
545
546 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800547 * Put the current tab in the background and set newTab as the current tab.
548 * @param newTab The new tab. If newTab is null, the current tab is not
549 * set.
550 */
551 boolean setCurrentTab(Tab newTab) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700552 return setCurrentTab(newTab, false);
553 }
554
Grace Kloba22ac16e2009-10-07 18:00:23 -0700555 void pauseCurrentTab() {
Mike Reed7bfa63b2009-05-28 11:08:32 -0400556 Tab t = getCurrentTab();
557 if (t != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700558 t.pause();
Mike Reed7bfa63b2009-05-28 11:08:32 -0400559 }
560 }
561
Grace Kloba22ac16e2009-10-07 18:00:23 -0700562 void resumeCurrentTab() {
Mike Reed7bfa63b2009-05-28 11:08:32 -0400563 Tab t = getCurrentTab();
564 if (t != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700565 t.resume();
Mike Reed7bfa63b2009-05-28 11:08:32 -0400566 }
567 }
568
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700569 /**
570 * If force is true, this method skips the check for newTab == current.
571 */
572 private boolean setCurrentTab(Tab newTab, boolean force) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800573 Tab current = getTab(mCurrentTab);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700574 if (current == newTab && !force) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800575 return true;
576 }
577 if (current != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700578 current.putInBackground();
579 mCurrentTab = -1;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800580 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800581 if (newTab == null) {
582 return false;
583 }
584
585 // Move the newTab to the end of the queue
586 int index = mTabQueue.indexOf(newTab);
587 if (index != -1) {
588 mTabQueue.remove(index);
589 }
590 mTabQueue.add(newTab);
591
The Android Open Source Project0c908882009-03-03 19:32:16 -0800592 // Display the new current tab
593 mCurrentTab = mTabs.indexOf(newTab);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700594 WebView mainView = newTab.getWebView();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800595 boolean needRestore = (mainView == null);
596 if (needRestore) {
597 // Same work as in createNewTab() except don't do new Tab()
Steve Block2bc69912009-07-30 14:45:13 +0100598 mainView = createNewWebView();
599 newTab.setWebView(mainView);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800600 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700601 newTab.putInForeground();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800602 if (needRestore) {
603 // Have to finish setCurrentTab work before calling restoreState
Grace Kloba22ac16e2009-10-07 18:00:23 -0700604 if (!newTab.restoreState(newTab.getSavedState())) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800605 mainView.loadUrl(BrowserSettings.getInstance().getHomePage());
606 }
607 }
608 return true;
609 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800610}