blob: de32b033db6539fbd6697a54adc92215e89a7254 [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
Mike Reede5073c22010-01-29 11:31:39 -050019import android.graphics.Bitmap;
20import android.graphics.BitmapFactory;
21import android.graphics.BitmapShader;
22import android.graphics.Paint;
23import android.graphics.Shader;
The Android Open Source Project0c908882009-03-03 19:32:16 -080024import android.os.Bundle;
The Android Open Source Project0c908882009-03-03 19:32:16 -080025import android.util.Log;
The Android Open Source Project0c908882009-03-03 19:32:16 -080026import android.view.View;
The Android Open Source Project0c908882009-03-03 19:32:16 -080027import android.webkit.WebBackForwardList;
The Android Open Source Project0c908882009-03-03 19:32:16 -080028import android.webkit.WebView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080029
30import java.io.File;
31import java.util.ArrayList;
32import java.util.Vector;
33
34class TabControl {
35 // Log Tag
36 private static final String LOGTAG = "TabControl";
37 // Maximum number of tabs.
Grace Kloba22ac16e2009-10-07 18:00:23 -070038 private static final int MAX_TABS = 8;
The Android Open Source Project0c908882009-03-03 19:32:16 -080039 // Private array of WebViews that are used as tabs.
40 private ArrayList<Tab> mTabs = new ArrayList<Tab>(MAX_TABS);
41 // Queue of most recently viewed tabs.
42 private ArrayList<Tab> mTabQueue = new ArrayList<Tab>(MAX_TABS);
43 // Current position in mTabs.
44 private int mCurrentTab = -1;
45 // A private instance of BrowserActivity to interface with when adding and
46 // switching between tabs.
47 private final BrowserActivity mActivity;
The Android Open Source Project0c908882009-03-03 19:32:16 -080048 // Directory to store thumbnails for each WebView.
49 private final File mThumbnailDir;
50
51 /**
52 * Construct a new TabControl object that interfaces with the given
53 * BrowserActivity instance.
54 * @param activity A BrowserActivity instance that TabControl will interface
55 * with.
56 */
57 TabControl(BrowserActivity activity) {
58 mActivity = activity;
The Android Open Source Project0c908882009-03-03 19:32:16 -080059 mThumbnailDir = activity.getDir("thumbnails", 0);
60 }
61
62 File getThumbnailDir() {
63 return mThumbnailDir;
64 }
65
66 BrowserActivity getBrowserActivity() {
67 return mActivity;
68 }
69
70 /**
71 * Return the current tab's main WebView. This will always return the main
72 * WebView for a given tab and not a subwindow.
73 * @return The current tab's WebView.
74 */
75 WebView getCurrentWebView() {
76 Tab t = getTab(mCurrentTab);
77 if (t == null) {
78 return null;
79 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070080 return t.getWebView();
Ben Murdochbff2d602009-07-01 20:19:05 +010081 }
82
83 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -080084 * Return the current tab's top-level WebView. This can return a subwindow
85 * if one exists.
86 * @return The top-level WebView of the current tab.
87 */
88 WebView getCurrentTopWebView() {
89 Tab t = getTab(mCurrentTab);
90 if (t == null) {
91 return null;
92 }
Grace Kloba22ac16e2009-10-07 18:00:23 -070093 return t.getTopWindow();
The Android Open Source Project0c908882009-03-03 19:32:16 -080094 }
95
96 /**
97 * Return the current tab's subwindow if it exists.
98 * @return The subwindow of the current tab or null if it doesn't exist.
99 */
100 WebView getCurrentSubWindow() {
101 Tab t = getTab(mCurrentTab);
102 if (t == null) {
103 return null;
104 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700105 return t.getSubWebView();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800106 }
107
108 /**
109 * Return the tab at the specified index.
110 * @return The Tab for the specified index or null if the tab does not
111 * exist.
112 */
113 Tab getTab(int index) {
114 if (index >= 0 && index < mTabs.size()) {
115 return mTabs.get(index);
116 }
117 return null;
118 }
119
120 /**
121 * Return the current tab.
122 * @return The current tab.
123 */
124 Tab getCurrentTab() {
125 return getTab(mCurrentTab);
126 }
127
128 /**
129 * Return the current tab index.
130 * @return The current tab index
131 */
132 int getCurrentIndex() {
133 return mCurrentTab;
134 }
135
136 /**
137 * Given a Tab, find it's index
138 * @param Tab to find
139 * @return index of Tab or -1 if not found
140 */
141 int getTabIndex(Tab tab) {
Patrick Scottae641ac2009-04-20 13:51:49 -0400142 if (tab == null) {
143 return -1;
144 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800145 return mTabs.indexOf(tab);
146 }
147
Grace Kloba22ac16e2009-10-07 18:00:23 -0700148 boolean canCreateNewTab() {
149 return MAX_TABS != mTabs.size();
150 }
151
The Android Open Source Project0c908882009-03-03 19:32:16 -0800152 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700153 * Create a new tab.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800154 * @return The newly createTab or null if we have reached the maximum
155 * number of open tabs.
156 */
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700157 Tab createNewTab(boolean closeOnExit, String appId, String url) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800158 int size = mTabs.size();
159 // Return false if we have maxed out on tabs
160 if (MAX_TABS == size) {
161 return null;
162 }
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700163 final WebView w = createNewWebView();
Steve Block2bc69912009-07-30 14:45:13 +0100164
The Android Open Source Project0c908882009-03-03 19:32:16 -0800165 // Create a new tab and add it to the tab list
Grace Kloba22ac16e2009-10-07 18:00:23 -0700166 Tab t = new Tab(mActivity, w, closeOnExit, appId, url);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800167 mTabs.add(t);
The Android Open Source Project4e5f5872009-03-09 11:52:14 -0700168 // Initially put the tab in the background.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700169 t.putInBackground();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800170 return t;
171 }
172
173 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700174 * Create a new tab with default values for closeOnExit(false),
175 * appId(null), and url(null).
176 */
177 Tab createNewTab() {
178 return createNewTab(false, null, null);
179 }
180
181 /**
Leon Scrogginsfde97462010-01-11 13:06:21 -0500182 * Remove the parent child relationships from all tabs.
183 */
184 void removeParentChildRelationShips() {
185 for (Tab tab : mTabs) {
186 tab.removeFromTree();
187 }
188 }
189
190 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800191 * Remove the tab from the list. If the tab is the current tab shown, the
192 * last created tab will be shown.
193 * @param t The tab to be removed.
194 */
195 boolean removeTab(Tab t) {
196 if (t == null) {
197 return false;
198 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700199
Patrick Scottd944d4d2010-01-27 16:39:11 -0500200 // Grab the current tab before modifying the list.
201 Tab current = getCurrentTab();
202
203 // Remove t from our list of tabs.
204 mTabs.remove(t);
205
206 // Put the tab in the background only if it is the current one.
207 if (current == t) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700208 t.putInBackground();
209 mCurrentTab = -1;
Patrick Scottd944d4d2010-01-27 16:39:11 -0500210 } else {
211 // If a tab that is earlier in the list gets removed, the current
212 // index no longer points to the correct tab.
213 mCurrentTab = getTabIndex(current);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800214 }
215
Grace Kloba22ac16e2009-10-07 18:00:23 -0700216 // destroy the tab
217 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800218 // clear it's references to parent and children
219 t.removeFromTree();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800220
221 // The tab indices have shifted, update all the saved state so we point
222 // to the correct index.
223 for (Tab tab : mTabs) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700224 Vector<Tab> children = tab.getChildTabs();
225 if (children != null) {
226 for (Tab child : children) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800227 child.setParentTab(tab);
228 }
229 }
230 }
231
The Android Open Source Project0c908882009-03-03 19:32:16 -0800232 // This tab may have been pushed in to the background and then closed.
233 // If the saved state contains a picture file, delete the file.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700234 Bundle savedState = t.getSavedState();
235 if (savedState != null) {
236 if (savedState.containsKey(Tab.CURRPICTURE)) {
237 new File(savedState.getString(Tab.CURRPICTURE)).delete();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800238 }
239 }
240
241 // Remove it from the queue of viewed tabs.
242 mTabQueue.remove(t);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800243 return true;
244 }
245
246 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800247 * Destroy all the tabs and subwindows
248 */
249 void destroy() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800250 for (Tab t : mTabs) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700251 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800252 }
253 mTabs.clear();
254 mTabQueue.clear();
255 }
256
257 /**
258 * Returns the number of tabs created.
259 * @return The number of tabs created.
260 */
261 int getTabCount() {
262 return mTabs.size();
263 }
264
The Android Open Source Project0c908882009-03-03 19:32:16 -0800265
266 /**
267 * Save the state of all the Tabs.
268 * @param outState The Bundle to save the state to.
269 */
270 void saveState(Bundle outState) {
271 final int numTabs = getTabCount();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700272 outState.putInt(Tab.NUMTABS, numTabs);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800273 final int index = getCurrentIndex();
Grace Kloba22ac16e2009-10-07 18:00:23 -0700274 outState.putInt(Tab.CURRTAB, (index >= 0 && index < numTabs) ? index : 0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800275 for (int i = 0; i < numTabs; i++) {
276 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700277 if (t.saveState()) {
278 outState.putBundle(Tab.WEBVIEW + i, t.getSavedState());
The Android Open Source Project0c908882009-03-03 19:32:16 -0800279 }
280 }
281 }
282
283 /**
284 * Restore the state of all the tabs.
285 * @param inState The saved state of all the tabs.
286 * @return True if there were previous tabs that were restored. False if
287 * there was no saved state or restoring the state failed.
288 */
289 boolean restoreState(Bundle inState) {
290 final int numTabs = (inState == null)
Grace Kloba22ac16e2009-10-07 18:00:23 -0700291 ? -1 : inState.getInt(Tab.NUMTABS, -1);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800292 if (numTabs == -1) {
293 return false;
294 } else {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700295 final int currentTab = inState.getInt(Tab.CURRTAB, -1);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800296 for (int i = 0; i < numTabs; i++) {
297 if (i == currentTab) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700298 Tab t = createNewTab();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800299 // Me must set the current tab before restoring the state
300 // so that all the client classes are set.
301 setCurrentTab(t);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700302 if (!t.restoreState(inState.getBundle(Tab.WEBVIEW + i))) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800303 Log.w(LOGTAG, "Fail in restoreState, load home page.");
Grace Kloba22ac16e2009-10-07 18:00:23 -0700304 t.getWebView().loadUrl(BrowserSettings.getInstance()
The Android Open Source Project0c908882009-03-03 19:32:16 -0800305 .getHomePage());
306 }
307 } else {
308 // Create a new tab and don't restore the state yet, add it
309 // to the tab list
Grace Kloba22ac16e2009-10-07 18:00:23 -0700310 Tab t = new Tab(mActivity, null, false, null, null);
311 Bundle state = inState.getBundle(Tab.WEBVIEW + i);
312 if (state != null) {
313 t.setSavedState(state);
314 t.populatePickerDataFromSavedState();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700315 // Need to maintain the app id and original url so we
316 // can possibly reuse this tab.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700317 t.setAppId(state.getString(Tab.APPID));
318 t.setOriginalUrl(state.getString(Tab.ORIGINALURL));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800319 }
320 mTabs.add(t);
321 mTabQueue.add(t);
322 }
323 }
324 // Rebuild the tree of tabs. Do this after all tabs have been
325 // created/restored so that the parent tab exists.
326 for (int i = 0; i < numTabs; i++) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700327 final Bundle b = inState.getBundle(Tab.WEBVIEW + i);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800328 final Tab t = getTab(i);
329 if (b != null && t != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700330 final int parentIndex = b.getInt(Tab.PARENTTAB, -1);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800331 if (parentIndex != -1) {
332 final Tab parent = getTab(parentIndex);
333 if (parent != null) {
334 parent.addChildTab(t);
335 }
336 }
337 }
338 }
339 }
340 return true;
341 }
342
343 /**
344 * Free the memory in this order, 1) free the background tab; 2) free the
345 * WebView cache;
346 */
347 void freeMemory() {
Grace Kloba92c18a52009-07-31 23:48:32 -0700348 if (getTabCount() == 0) return;
349
The Android Open Source Project0c908882009-03-03 19:32:16 -0800350 // free the least frequently used background tab
Patrick Scott2a67de42009-08-31 09:48:37 -0400351 Tab t = getLeastUsedTab(getCurrentTab());
The Android Open Source Project0c908882009-03-03 19:32:16 -0800352 if (t != null) {
353 Log.w(LOGTAG, "Free a tab in the browser");
Grace Kloba22ac16e2009-10-07 18:00:23 -0700354 // store the WebView's state.
355 t.saveState();
356 // destroy the tab
357 t.destroy();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800358 return;
359 }
360
Derek Sollenberger4433d032009-06-10 15:37:21 -0400361 // free the WebView's unused memory (this includes the cache)
362 Log.w(LOGTAG, "Free WebView's unused memory and cache");
The Android Open Source Project0c908882009-03-03 19:32:16 -0800363 WebView view = getCurrentWebView();
364 if (view != null) {
Derek Sollenberger4433d032009-06-10 15:37:21 -0400365 view.freeMemory();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800366 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800367 }
368
Patrick Scott2a67de42009-08-31 09:48:37 -0400369 private Tab getLeastUsedTab(Tab current) {
370 // Don't do anything if we only have 1 tab or if the current tab is
371 // null.
372 if (getTabCount() == 1 || current == null) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800373 return null;
374 }
375
Grace Kloba22ac16e2009-10-07 18:00:23 -0700376 // Rip through the queue starting at the beginning and tear down the
The Android Open Source Project0c908882009-03-03 19:32:16 -0800377 // next available tab.
378 Tab t = null;
379 int i = 0;
380 final int queueSize = mTabQueue.size();
381 if (queueSize == 0) {
382 return null;
383 }
384 do {
385 t = mTabQueue.get(i++);
Grace Kloba92c18a52009-07-31 23:48:32 -0700386 } while (i < queueSize
Grace Kloba22ac16e2009-10-07 18:00:23 -0700387 && ((t != null && t.getWebView() == null)
388 || t == current.getParentTab()));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800389
Patrick Scottd068f802009-06-22 11:46:06 -0400390 // Don't do anything if the last remaining tab is the current one or if
391 // the last tab has been freed already.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700392 if (t == current || t.getWebView() == null) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800393 return null;
394 }
395
396 return t;
397 }
398
The Android Open Source Project0c908882009-03-03 19:32:16 -0800399 /**
400 * Show the tab that contains the given WebView.
401 * @param view The WebView used to find the tab.
402 */
403 Tab getTabFromView(WebView view) {
404 final int size = getTabCount();
405 for (int i = 0; i < size; i++) {
406 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700407 if (t.getSubWebView() == view || t.getWebView() == view) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800408 return t;
409 }
410 }
411 return null;
412 }
413
414 /**
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700415 * Return the tab with the matching application id.
416 * @param id The application identifier.
417 */
418 Tab getTabFromId(String id) {
419 if (id == null) {
420 return null;
421 }
422 final int size = getTabCount();
423 for (int i = 0; i < size; i++) {
424 final Tab t = getTab(i);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700425 if (id.equals(t.getAppId())) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700426 return t;
427 }
428 }
429 return null;
430 }
431
Grace Kloba22ac16e2009-10-07 18:00:23 -0700432 /**
433 * Stop loading in all opened WebView including subWindows.
434 */
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700435 void stopAllLoading() {
436 final int size = getTabCount();
437 for (int i = 0; i < size; i++) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700438 final Tab t = getTab(i);
439 final WebView webview = t.getWebView();
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700440 if (webview != null) {
441 webview.stopLoading();
442 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700443 final WebView subview = t.getSubWebView();
444 if (subview != null) {
445 webview.stopLoading();
446 }
Grace Kloba5d0e02e2009-10-05 15:15:36 -0700447 }
448 }
449
Patrick Scottcd115892009-07-16 09:42:58 -0400450 // This method checks if a non-app tab (one created within the browser)
451 // matches the given url.
452 private boolean tabMatchesUrl(Tab t, String url) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700453 if (t.getAppId() != null) {
Patrick Scottcd115892009-07-16 09:42:58 -0400454 return false;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700455 }
456 WebView webview = t.getWebView();
457 if (webview == null) {
Patrick Scottcd115892009-07-16 09:42:58 -0400458 return false;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700459 } else if (url.equals(webview.getUrl())
460 || url.equals(webview.getOriginalUrl())) {
Patrick Scottcd115892009-07-16 09:42:58 -0400461 return true;
462 }
463 return false;
464 }
465
466 /**
467 * Return the tab that has no app id associated with it and the url of the
468 * tab matches the given url.
469 * @param url The url to search for.
470 */
471 Tab findUnusedTabWithUrl(String url) {
472 if (url == null) {
473 return null;
474 }
475 // Check the current tab first.
476 Tab t = getCurrentTab();
477 if (t != null && tabMatchesUrl(t, url)) {
478 return t;
479 }
480 // Now check all the rest.
481 final int size = getTabCount();
482 for (int i = 0; i < size; i++) {
483 t = getTab(i);
484 if (tabMatchesUrl(t, url)) {
485 return t;
486 }
487 }
488 return null;
489 }
490
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700491 /**
492 * Recreate the main WebView of the given tab. Returns true if the WebView
Leon Scroggins6eac63e2010-03-15 18:19:14 -0400493 * requires a load, whether it was due to the fact that it was deleted, or
494 * it is because it was a voice search.
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700495 */
Leon Scroggins6eac63e2010-03-15 18:19:14 -0400496 boolean recreateWebView(Tab t, BrowserActivity.UrlData urlData) {
497 final String url = urlData.mUrl;
Grace Kloba22ac16e2009-10-07 18:00:23 -0700498 final WebView w = t.getWebView();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700499 if (w != null) {
Leon Scroggins6eac63e2010-03-15 18:19:14 -0400500 if (urlData.mVoiceIntent != null) {
501 // In the case of a voice search, we do not want to destroy the
502 // back forward list, so that we can go back to the prior search
503 return true;
504 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700505 if (url != null && url.equals(t.getOriginalUrl())) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700506 // The original url matches the current url. Just go back to the
507 // first history item so we can load it faster than if we
508 // rebuilt the WebView.
509 final WebBackForwardList list = w.copyBackForwardList();
510 if (list != null) {
511 w.goBackOrForward(-list.getCurrentIndex());
512 w.clearHistory(); // maintains the current page.
513 return false;
514 }
515 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700516 t.destroy();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700517 }
518 // Create a new WebView. If this tab is the current tab, we need to put
519 // back all the clients so force it to be the current tab.
Steve Block2bc69912009-07-30 14:45:13 +0100520 t.setWebView(createNewWebView());
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700521 if (getCurrentTab() == t) {
522 setCurrentTab(t, true);
523 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700524 // Clear the saved state and picker data
525 t.setSavedState(null);
526 t.clearPickerData();
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700527 // Save the new url in order to avoid deleting the WebView.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700528 t.setOriginalUrl(url);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700529 return true;
530 }
531
532 /**
533 * Creates a new WebView and registers it with the global settings.
534 */
535 private WebView createNewWebView() {
536 // Create a new WebView
537 WebView w = new WebView(mActivity);
Grace Kloba67f0a562009-09-28 21:24:51 -0700538 w.setScrollbarFadingEnabled(true);
539 w.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700540 w.setMapTrackballToArrowKeys(false); // use trackball directly
The Android Open Source Projecta3c0aab2009-03-18 17:39:48 -0700541 // Enable the built-in zoom
542 w.getSettings().setBuiltInZoomControls(true);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700543 // Add this WebView to the settings observer list and update the
544 // settings
545 final BrowserSettings s = BrowserSettings.getInstance();
546 s.addObserver(w.getSettings()).update(s, null);
Mike Reedd5a80a52009-11-12 12:49:34 -0500547
Mike Reeda947d2d2010-01-14 14:57:45 -0800548 // pick a default
Mike Reedd5c3e0f2010-02-24 11:12:54 -0500549 if (false) {
Mike Reede5073c22010-01-29 11:31:39 -0500550 MeshTracker mt = new MeshTracker(2);
551 Paint paint = new Paint();
552 Bitmap bm = BitmapFactory.decodeResource(mActivity.getResources(),
553 R.drawable.pattern_carbon_fiber_dark);
554 paint.setShader(new BitmapShader(bm, Shader.TileMode.REPEAT,
555 Shader.TileMode.REPEAT));
556 mt.setBGPaint(paint);
557 w.setDragTracker(mt);
558 }
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700559 return w;
560 }
561
562 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800563 * Put the current tab in the background and set newTab as the current tab.
564 * @param newTab The new tab. If newTab is null, the current tab is not
565 * set.
566 */
567 boolean setCurrentTab(Tab newTab) {
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700568 return setCurrentTab(newTab, false);
569 }
570
Grace Kloba22ac16e2009-10-07 18:00:23 -0700571 void pauseCurrentTab() {
Mike Reed7bfa63b2009-05-28 11:08:32 -0400572 Tab t = getCurrentTab();
573 if (t != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700574 t.pause();
Mike Reed7bfa63b2009-05-28 11:08:32 -0400575 }
576 }
577
Grace Kloba22ac16e2009-10-07 18:00:23 -0700578 void resumeCurrentTab() {
Mike Reed7bfa63b2009-05-28 11:08:32 -0400579 Tab t = getCurrentTab();
580 if (t != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700581 t.resume();
Mike Reed7bfa63b2009-05-28 11:08:32 -0400582 }
583 }
584
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700585 /**
586 * If force is true, this method skips the check for newTab == current.
587 */
588 private boolean setCurrentTab(Tab newTab, boolean force) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800589 Tab current = getTab(mCurrentTab);
The Android Open Source Projectf59ec872009-03-13 13:04:24 -0700590 if (current == newTab && !force) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800591 return true;
592 }
593 if (current != null) {
Grace Kloba22ac16e2009-10-07 18:00:23 -0700594 current.putInBackground();
595 mCurrentTab = -1;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800596 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800597 if (newTab == null) {
598 return false;
599 }
600
601 // Move the newTab to the end of the queue
602 int index = mTabQueue.indexOf(newTab);
603 if (index != -1) {
604 mTabQueue.remove(index);
605 }
606 mTabQueue.add(newTab);
607
The Android Open Source Project0c908882009-03-03 19:32:16 -0800608 // Display the new current tab
609 mCurrentTab = mTabs.indexOf(newTab);
Grace Kloba22ac16e2009-10-07 18:00:23 -0700610 WebView mainView = newTab.getWebView();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800611 boolean needRestore = (mainView == null);
612 if (needRestore) {
613 // Same work as in createNewTab() except don't do new Tab()
Steve Block2bc69912009-07-30 14:45:13 +0100614 mainView = createNewWebView();
615 newTab.setWebView(mainView);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800616 }
Grace Kloba22ac16e2009-10-07 18:00:23 -0700617 newTab.putInForeground();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800618 if (needRestore) {
619 // Have to finish setCurrentTab work before calling restoreState
Grace Kloba22ac16e2009-10-07 18:00:23 -0700620 if (!newTab.restoreState(newTab.getSavedState())) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800621 mainView.loadUrl(BrowserSettings.getInstance().getHomePage());
622 }
623 }
624 return true;
625 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800626}