OSDN Git Service

auto import from //branches/cupcake_rel/...@138607
authorThe Android Open Source Project <initial-contribution@android.com>
Fri, 13 Mar 2009 20:04:24 +0000 (13:04 -0700)
committerThe Android Open Source Project <initial-contribution@android.com>
Fri, 13 Mar 2009 20:04:24 +0000 (13:04 -0700)
20 files changed:
assets/plugins/gears-0.5.15.0/dummy [moved from assets/plugins/gears-0.5.12.0/dummy with 100% similarity]
assets/plugins/gears.so
res/values-cs/strings.xml
res/values-de/strings.xml
res/values-es/strings.xml
res/values-fr/strings.xml
res/values-it/strings.xml
res/values-ja/strings.xml
res/values-ko/strings.xml
res/values-nb/strings.xml
res/values-nl/strings.xml
res/values-pl/strings.xml
res/values-ru/strings.xml
res/values-zh-rCN/strings.xml
res/values-zh-rTW/strings.xml
res/values/strings.xml
src/com/android/browser/BrowserActivity.java
src/com/android/browser/BrowserBookmarksPage.java
src/com/android/browser/ImageAdapter.java
src/com/android/browser/TabControl.java

index d575b14..1fa4264 100644 (file)
Binary files a/assets/plugins/gears.so and b/assets/plugins/gears.so differ
index bc1597a..5f6677e 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Datum vydání:"</string>
     <string name="expires_on">"Platnost vyprší:"</string>
     <string name="retrieving_creds_dlg_msg">"Načítání podrobností pro přihlášení..."</string>
-    <string name="close">"Zavřít"</string>
-    <string name="close_window">"Toto okno bude zavřeno."</string>
     <string name="stopping">"Zastavuji..."</string>
     <string name="stop">"Zastavit"</string>
     <string name="reload">"Obnovit"</string>
index 8e1ee22..ec0ae34 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Ausgegeben am:"</string>
     <string name="expires_on">"Läuft ab am:"</string>
     <string name="retrieving_creds_dlg_msg">"Anmeldedetails werden abgerufen…"</string>
-    <string name="close">"Schließen"</string>
-    <string name="close_window">"Dieses Fenster wird geschlossen."</string>
     <string name="stopping">"Wird angehalten..."</string>
     <string name="stop">"Anhalten"</string>
     <string name="reload">"Aktualisieren"</string>
index fb1b083..cbef856 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Fecha de emisión:"</string>
     <string name="expires_on">"Fecha de caducidad:"</string>
     <string name="retrieving_creds_dlg_msg">"Recuperando detalles de acceso..."</string>
-    <string name="close">"Cerrar"</string>
-    <string name="close_window">"Se cerrará esta ventana."</string>
     <string name="stopping">"Deteniendo..."</string>
     <string name="stop">"Detener"</string>
     <string name="reload">"Actualizar"</string>
index 5a2ec4d..56f865a 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Émis le :"</string>
     <string name="expires_on">"Expire le :"</string>
     <string name="retrieving_creds_dlg_msg">"Récupération des données de connexion..."</string>
-    <string name="close">"Fermer"</string>
-    <string name="close_window">"La fenêtre sera fermée."</string>
     <string name="stopping">"Arrêt..."</string>
     <string name="stop">"Interrompre"</string>
     <string name="reload">"Actualiser"</string>
index 593c4f4..dd3b6ee 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Rilasciato il:"</string>
     <string name="expires_on">"Scade il:"</string>
     <string name="retrieving_creds_dlg_msg">"Recupero dettagli di accesso..."</string>
-    <string name="close">"Chiudi"</string>
-    <string name="close_window">"Questa finestra verrà chiusa."</string>
     <string name="stopping">"Interruzione..."</string>
     <string name="stop">"Interrompi"</string>
     <string name="reload">"Aggiorna"</string>
index b83cfce..bd19f84 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"発行:"</string>
     <string name="expires_on">"有効期限:"</string>
     <string name="retrieving_creds_dlg_msg">"ログイン詳細を取得中..."</string>
-    <string name="close">"閉じる"</string>
-    <string name="close_window">"このウィンドウを閉じます。"</string>
     <string name="stopping">"停止中..."</string>
     <string name="stop">"停止"</string>
     <string name="reload">"再読み込み"</string>
index 90ba10a..d85caee 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"발급일:"</string>
     <string name="expires_on">"만료일:"</string>
     <string name="retrieving_creds_dlg_msg">"로그인 세부정보를 가져오는 중..."</string>
-    <string name="close">"닫기"</string>
-    <string name="close_window">"창이 닫힙니다."</string>
     <string name="stopping">"중지하는 중..."</string>
     <string name="stop">"중지"</string>
     <string name="reload">"새로고침"</string>
index d356f7d..3c149fb 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Utstedt:"</string>
     <string name="expires_on">"Går ut:"</string>
     <string name="retrieving_creds_dlg_msg">"Henter innloggingsinformasjon…"</string>
-    <string name="close">"Lukk"</string>
-    <string name="close_window">"Dette vinduet vil bli lukket."</string>
     <string name="stopping">"Avbryter…"</string>
     <string name="stop">"Avbryt"</string>
     <string name="reload">"Last på nytt"</string>
index 7f45a44..58b6a97 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Uitgegeven op:"</string>
     <string name="expires_on">"Verloopt op:"</string>
     <string name="retrieving_creds_dlg_msg">"Aanmeldingsgegevens ophalen..."</string>
-    <string name="close">"Sluiten"</string>
-    <string name="close_window">"Dit venster wordt gesloten."</string>
     <string name="stopping">"Stoppen..."</string>
     <string name="stop">"Stoppen"</string>
     <string name="reload">"Vernieuwen"</string>
index 6523df1..186128b 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Data wystawienia:"</string>
     <string name="expires_on">"Wygasa:"</string>
     <string name="retrieving_creds_dlg_msg">"Pobieranie szczegółów logowania…"</string>
-    <string name="close">"Zamknij"</string>
-    <string name="close_window">"To okno zostanie zamknięte."</string>
     <string name="stopping">"Trwa zatrzymywanie…"</string>
     <string name="stop">"Zatrzymaj"</string>
     <string name="reload">"Odśwież"</string>
index 4b4b677..eedcbb0 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"Когда выдан:"</string>
     <string name="expires_on">"Действителен до:"</string>
     <string name="retrieving_creds_dlg_msg">"Получение сведений о входе…"</string>
-    <string name="close">"Закрыть"</string>
-    <string name="close_window">"Это окно будето закрыто."</string>
     <string name="stopping">"Остановка загрузки…"</string>
     <string name="stop">"Остановить"</string>
     <string name="reload">"Обновить"</string>
index a55556b..6cc0db8 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"发布时间:"</string>
     <string name="expires_on">"有效期至:"</string>
     <string name="retrieving_creds_dlg_msg">"正在检索登录详细信息..."</string>
-    <string name="close">"关闭"</string>
-    <string name="close_window">"该窗口会关闭。"</string>
     <string name="stopping">"正在停止..."</string>
     <string name="stop">"停止"</string>
     <string name="reload">"刷新"</string>
index 3dd3ec7..45241be 100644 (file)
@@ -51,8 +51,6 @@
     <string name="issued_on">"發給:"</string>
     <string name="expires_on">"有效日期:"</string>
     <string name="retrieving_creds_dlg_msg">"取回登入資訊…"</string>
-    <string name="close">"關閉"</string>
-    <string name="close_window">"視窗即將關閉。"</string>
     <string name="stopping">"停止中…"</string>
     <string name="stop">"停止"</string>
     <string name="reload">"重新整理"</string>
index d605657..83cc639 100644 (file)
 
     <!-- Dialog that is shown while we are retrieving the login creds from the system -->
     <string name="retrieving_creds_dlg_msg">Retrieving sign-in details\u2026</string>
-    <!-- Menu item in a context menu for closing a browser window. -->
-    <string name="close">Close</string>
-    <!-- Confirmation dialog message stating that a browser window will be closed -->
-    <string name="close_window">This window will be closed.</string>
     <!-- Toast informing the user that loading has stopped for the current page. -->
     <string name="stopping">Stopping\u2026</string>
     <!-- Menu item to stop the current page from loading. -->
index fc80fcd..bd6fdc6 100644 (file)
@@ -686,9 +686,11 @@ public class BrowserActivity extends Activity
             // If the intent is ACTION_VIEW and data is not null, the Browser is
             // invoked to view the content by another application. In this case,
             // the tab will be close when exit.
+            String url = getUrlFromIntent(intent);
             final TabControl.Tab t = mTabControl.createNewTab(
                     Intent.ACTION_VIEW.equals(intent.getAction()) &&
-                    intent.getData() != null);
+                    intent.getData() != null,
+                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), url);
             mTabControl.setCurrentTab(t);
             // This is one of the only places we call attachTabToContentView
             // without animating from the tab picker.
@@ -710,7 +712,6 @@ public class BrowserActivity extends Activity
             }
             copyPlugins(true);
 
-            String url = getUrlFromIntent(intent);
             if (url == null || url.length() == 0) {
                 if (mSettings.isLoginInitialized()) {
                     webView.loadUrl(mSettings.getHomePage());
@@ -778,11 +779,44 @@ public class BrowserActivity extends Activity
             }
             if (Intent.ACTION_VIEW.equals(action) &&
                     (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
+                final String appId =
+                        intent.getStringExtra(Browser.EXTRA_APPLICATION_ID);
+                final TabControl.Tab appTab = mTabControl.getTabFromId(appId);
+                if (appTab != null) {
+                    Log.i(LOGTAG, "Reusing tab for " + appId);
+                    // Dismiss the subwindow if applicable.
+                    dismissSubWindow(appTab);
+                    // Since we might kill the WebView, remove it from the
+                    // content view first.
+                    removeTabFromContentView(appTab);
+                    // Recreate the main WebView after destroying the old one.
+                    // If the WebView has the same original url and is on that
+                    // page, it can be reused.
+                    boolean needsLoad =
+                            mTabControl.recreateWebView(appTab, url);
+                    if (current != appTab) {
+                        showTab(appTab, needsLoad ? url : null);
+                    } else {
+                        if (mTabOverview != null && mAnimationCount == 0) {
+                            sendAnimateFromOverview(appTab, false,
+                                    needsLoad ? url : null, TAB_OVERVIEW_DELAY,
+                                    null);
+                        } else {
+                            // If the tab was the current tab, we have to attach
+                            // it to the view system again.
+                            attachTabToContentView(appTab);
+                            if (needsLoad) {
+                                appTab.getWebView().loadUrl(url);
+                            }
+                        }
+                    }
+                    return;
+                }
                 // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url will be
                 // opened in a new tab unless we have reached MAX_TABS. Then the
                 // url will be opened in the current tab. If a new tab is
                 // created, it will have "true" for exit on close.
-                openTabAndShow(url, null, true);
+                openTabAndShow(url, null, true, appId);
             } else {
                 if ("about:debug".equals(url)) {
                     mSettings.toggleDebugSettings();
@@ -1329,7 +1363,7 @@ public class BrowserActivity extends Activity
 
             case R.id.windows_menu_id:
                 if (mTabControl.getTabCount() == 1) {
-                    openTabAndShow(mSettings.getHomePage(), null, false);
+                    openTabAndShow(mSettings.getHomePage(), null, false, null);
                 } else {
                     tabPicker(true, mTabControl.getCurrentIndex(), false);
                 }
@@ -1808,6 +1842,10 @@ public class BrowserActivity extends Activity
 
     // Called by TabControl when a tab is requesting focus
     /* package */ void showTab(TabControl.Tab t) {
+        showTab(t, null);
+    }
+
+    private void showTab(TabControl.Tab t, String url) {
         // Disallow focus change during a tab animation.
         if (mAnimationCount > 0) {
             return;
@@ -1819,7 +1857,7 @@ public class BrowserActivity extends Activity
             delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
             tabPicker(false, mTabControl.getTabIndex(t), false);
         }
-        sendAnimateFromOverview(t, false, null, delay, null);
+        sendAnimateFromOverview(t, false, url, delay, null);
     }
 
     // This method does a ton of stuff. It will attempt to create a new tab
@@ -1831,7 +1869,7 @@ public class BrowserActivity extends Activity
     // method is called from TabListener.onClick(), the method will animate
     // away from the tab overview.
     private void openTabAndShow(String url, final Message msg,
-            boolean closeOnExit) {
+            boolean closeOnExit, String appId) {
         final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
         final TabControl.Tab currentTab = mTabControl.getCurrentTab();
         if (newTab) {
@@ -1859,8 +1897,9 @@ public class BrowserActivity extends Activity
                 }
                 // Animate from the Tab overview after any animations have
                 // finished.
-                sendAnimateFromOverview(mTabControl.createNewTab(closeOnExit),
-                        true, url, delay, msg);
+                sendAnimateFromOverview(
+                        mTabControl.createNewTab(closeOnExit, appId, url), true,
+                        url, delay, msg);
             }
         } else if (url != null) {
             // We should not have a msg here.
@@ -2093,12 +2132,12 @@ public class BrowserActivity extends Activity
 
     private void openTab(String url) {
         if (mSettings.openInBackground()) {
-            TabControl.Tab t = mTabControl.createNewTab(false);
+            TabControl.Tab t = mTabControl.createNewTab();
             if (t != null) {
                 t.getWebView().loadUrl(url);
             }
         } else {
-            openTabAndShow(url, null, false);
+            openTabAndShow(url, null, false, null);
         }
     }
 
@@ -2512,7 +2551,7 @@ public class BrowserActivity extends Activity
                     // the method relies on the value being 0 to start the next
                     // animation.
                     mAnimationCount--;
-                    openTabAndShow((String) msg.obj, null, false);
+                    openTabAndShow((String) msg.obj, null, false, null);
                     break;
 
                 case FOCUS_NODE_HREF:
@@ -3130,7 +3169,7 @@ public class BrowserActivity extends Activity
                 // openTabAndShow will dispatch the message after creating the
                 // new WebView. This will prevent another request from coming
                 // in during the animation.
-                openTabAndShow(null, msg, false);
+                openTabAndShow(null, msg, false, null);
                 parent.addChildTab(mTabControl.getCurrentTab());
                 WebView.WebViewTransport transport =
                         (WebView.WebViewTransport) msg.obj;
@@ -4052,7 +4091,7 @@ public class BrowserActivity extends Activity
                 // If the user removes the last tab, act like the New Tab item
                 // was clicked on.
                 if (mTabControl.getTabCount() == 0) {
-                    current = mTabControl.createNewTab(false);
+                    current = mTabControl.createNewTab();
                     sendAnimateFromOverview(current, true,
                             mSettings.getHomePage(), TAB_OVERVIEW_DELAY, null);
                 } else {
@@ -4092,7 +4131,7 @@ public class BrowserActivity extends Activity
 
             // NEW_TAB means that the "New Tab" cell was clicked on.
             if (index == ImageGrid.NEW_TAB) {
-                openTabAndShow(mSettings.getHomePage(), null, false);
+                openTabAndShow(mSettings.getHomePage(), null, false, null);
             } else {
                 sendAnimateFromOverview(mTabControl.getTab(index),
                         false, null, 0, null);
index 7708e8b..a7d45f9 100644 (file)
@@ -212,8 +212,13 @@ public class BrowserBookmarksPage extends Activity implements
 
     private Intent createShortcutIntent(String url, String title) {
         final Intent i = new Intent();
-        i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_VIEW,
-                    Uri.parse(url)));
+        final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW,
+                Uri.parse(url));
+        long urlHash = url.hashCode();
+        long uniqueId = (urlHash << 32) | shortcutIntent.hashCode();
+        shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID,
+                Long.toString(uniqueId));
+        i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
         i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
         i.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                 Intent.ShortcutIconResource.fromContext(BrowserBookmarksPage.this,
index b4c1209..e957143 100644 (file)
@@ -231,20 +231,7 @@ public class ImageAdapter implements ListAdapter {
         if (l == null) {
             return;
         }
-        DialogInterface.OnClickListener confirm =
-                new DialogInterface.OnClickListener() {
-                    public void onClick(DialogInterface dialog,
-                            int whichButton) {
-                        l.remove(position);
-                    }
-                };
-        new AlertDialog.Builder(mContext)
-                .setTitle(R.string.close)
-                .setIcon(android.R.drawable.ic_dialog_alert)
-                .setMessage(R.string.close_window)
-                .setPositiveButton(R.string.ok, confirm)
-                .setNegativeButton(R.string.cancel, null)
-                .show();
+        l.remove(position);
     }
 
     /* (non-Javadoc)
index 57e55c4..d58ee22 100644 (file)
@@ -174,11 +174,19 @@ class TabControl {
         private Vector<Tab> mChildTabs;
 
         private Boolean mCloseOnExit;
+        // Application identifier used to find tabs that another application
+        // wants to reuse.
+        private String mAppId;
+        // Keep the original url around to avoid killing the old WebView if the
+        // url has not changed.
+        private String mOriginalUrl;
 
         // Construct a new tab
-        private Tab(WebView w, boolean closeOnExit) {
+        private Tab(WebView w, boolean closeOnExit, String appId, String url) {
             mMainView = w;
             mCloseOnExit = closeOnExit;
+            mAppId = appId;
+            mOriginalUrl = url;
         }
 
         /**
@@ -403,25 +411,19 @@ class TabControl {
     }
 
     /**
-     * Create a new tab and display the new tab immediately.
+     * Create a new tab.
      * @return The newly createTab or null if we have reached the maximum
      *         number of open tabs.
      */
-    Tab createNewTab(boolean closeOnExit) {
+    Tab createNewTab(boolean closeOnExit, String appId, String url) {
         int size = mTabs.size();
         // Return false if we have maxed out on tabs
         if (MAX_TABS == size) {
             return null;
         }
-        // Create a new WebView
-        WebView w = new WebView(mActivity);
-        w.setMapTrackballToArrowKeys(false); // use trackball directly
-        // Add this WebView to the settings observer list and update the
-        // settings
-        final BrowserSettings s = BrowserSettings.getInstance();
-        s.addObserver(w.getSettings()).update(s, null);
+        final WebView w = createNewWebView();
         // Create a new tab and add it to the tab list
-        Tab t = new Tab(w, closeOnExit);
+        Tab t = new Tab(w, closeOnExit, appId, url);
         mTabs.add(t);
         // Initially put the tab in the background.
         putTabInBackground(t);
@@ -429,6 +431,14 @@ class TabControl {
     }
 
     /**
+     * Create a new tab with default values for closeOnExit(false),
+     * appId(null), and url(null).
+     */
+    Tab createNewTab() {
+        return createNewTab(false, null, null);
+    }
+
+    /**
      * Remove the tab from the list. If the tab is the current tab shown, the
      * last created tab will be shown.
      * @param t The tab to be removed.
@@ -536,6 +546,8 @@ class TabControl {
     private static final String CURRTITLE = "currentTitle";
     private static final String CLOSEONEXIT = "closeonexit";
     private static final String PARENTTAB = "parentTab";
+    private static final String APPID = "appid";
+    private static final String ORIGINALURL = "originalUrl";
 
     /**
      * Save the state of all the Tabs.
@@ -569,7 +581,7 @@ class TabControl {
             final int currentTab = inState.getInt(CURRTAB, -1);
             for (int i = 0; i < numTabs; i++) {
                 if (i == currentTab) {
-                    Tab t = createNewTab(false);
+                    Tab t = createNewTab();
                     // Me must set the current tab before restoring the state
                     // so that all the client classes are set.
                     setCurrentTab(t);
@@ -581,11 +593,15 @@ class TabControl {
                 } else {
                     // Create a new tab and don't restore the state yet, add it
                     // to the tab list
-                    Tab t = new Tab(null, false);
+                    Tab t = new Tab(null, false, null, null);
                     t.mSavedState = inState.getBundle(WEBVIEW + i);
                     if (t.mSavedState != null) {
                         t.mUrl = t.mSavedState.getString(CURRURL);
                         t.mTitle = t.mSavedState.getString(CURRTITLE);
+                        // Need to maintain the app id and original url so we
+                        // can possibly reuse this tab.
+                        t.mAppId = t.mSavedState.getString(APPID);
+                        t.mOriginalUrl = t.mSavedState.getString(ORIGINALURL);
                     }
                     mTabs.add(t);
                     mTabQueue.add(t);
@@ -727,13 +743,92 @@ class TabControl {
     }
 
     /**
+     * Return the tab with the matching application id.
+     * @param id The application identifier.
+     */
+    Tab getTabFromId(String id) {
+        if (id == null) {
+            return null;
+        }
+        final int size = getTabCount();
+        for (int i = 0; i < size; i++) {
+            final Tab t = getTab(i);
+            if (id.equals(t.mAppId)) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Recreate the main WebView of the given tab. Returns true if the WebView
+     * was deleted.
+     */
+    boolean recreateWebView(Tab t, String url) {
+        final WebView w = t.mMainView;
+        if (w != null) {
+            if (url != null && url.equals(t.mOriginalUrl)) {
+                // The original url matches the current url. Just go back to the
+                // first history item so we can load it faster than if we
+                // rebuilt the WebView.
+                final WebBackForwardList list = w.copyBackForwardList();
+                if (list != null) {
+                    w.goBackOrForward(-list.getCurrentIndex());
+                    w.clearHistory(); // maintains the current page.
+                    return false;
+                }
+            }
+            // Remove the settings object from the global settings and destroy
+            // the WebView.
+            BrowserSettings.getInstance().deleteObserver(
+                    t.mMainView.getSettings());
+            t.mMainView.destroy();
+        }
+        // Create a new WebView. If this tab is the current tab, we need to put
+        // back all the clients so force it to be the current tab.
+        t.mMainView = createNewWebView();
+        if (getCurrentTab() == t) {
+            setCurrentTab(t, true);
+        }
+        // Clear the saved state except for the app id and close-on-exit
+        // values.
+        t.mSavedState = null;
+        t.mUrl = null;
+        t.mTitle = null;
+        // Save the new url in order to avoid deleting the WebView.
+        t.mOriginalUrl = url;
+        return true;
+    }
+
+    /**
+     * Creates a new WebView and registers it with the global settings.
+     */
+    private WebView createNewWebView() {
+        // Create a new WebView
+        WebView w = new WebView(mActivity);
+        w.setMapTrackballToArrowKeys(false); // use trackball directly
+        // Add this WebView to the settings observer list and update the
+        // settings
+        final BrowserSettings s = BrowserSettings.getInstance();
+        s.addObserver(w.getSettings()).update(s, null);
+        return w;
+    }
+
+    /**
      * Put the current tab in the background and set newTab as the current tab.
      * @param newTab The new tab. If newTab is null, the current tab is not
      *               set.
      */
     boolean setCurrentTab(Tab newTab) {
+        return setCurrentTab(newTab, false);
+    }
+
+    /**
+     * If force is true, this method skips the check for newTab == current.
+     */
+    private boolean setCurrentTab(Tab newTab, boolean force) {
         Tab current = getTab(mCurrentTab);
-        if (current == newTab) {
+        if (current == newTab && !force) {
             return true;
         }
         if (current != null) {
@@ -761,13 +856,7 @@ class TabControl {
         boolean needRestore = (mainView == null);
         if (needRestore) {
             // Same work as in createNewTab() except don't do new Tab()
-            newTab.mMainView = mainView = new WebView(mActivity);
-            mainView.setMapTrackballToArrowKeys(false); // use t-ball directly
-
-            // Add this WebView to the settings observer list and update the
-            // settings
-            final BrowserSettings s = BrowserSettings.getInstance();
-            s.addObserver(mainView.getSettings()).update(s, null);
+            newTab.mMainView = mainView = createNewWebView();
         }
         mainView.setWebViewClient(mActivity.getWebViewClient());
         mainView.setWebChromeClient(mActivity.getWebChromeClient());
@@ -900,6 +989,12 @@ class TabControl {
                 b.putString(CURRTITLE, t.mTitle);
             }
             b.putBoolean(CLOSEONEXIT, t.mCloseOnExit);
+            if (t.mAppId != null) {
+                b.putString(APPID, t.mAppId);
+            }
+            if (t.mOriginalUrl != null) {
+                b.putString(ORIGINALURL, t.mOriginalUrl);
+            }
 
             // Remember the parent tab so the relationship can be restored.
             if (t.mParentTab != null) {
@@ -920,6 +1015,15 @@ class TabControl {
         if (b == null) {
             return false;
         }
+        // Restore the internal state even if the WebView fails to restore.
+        // This will maintain the app id, original url and close-on-exit values.
+        t.mSavedState = null;
+        t.mUrl = null;
+        t.mTitle = null;
+        t.mCloseOnExit = b.getBoolean(CLOSEONEXIT);
+        t.mAppId = b.getString(APPID);
+        t.mOriginalUrl = b.getString(ORIGINALURL);
+
         final WebView w = t.mMainView;
         final WebBackForwardList list = w.restoreState(b);
         if (list == null) {
@@ -930,10 +1034,6 @@ class TabControl {
             w.restorePicture(b, f);
             f.delete();
         }
-        t.mSavedState = null;
-        t.mUrl = null;
-        t.mTitle = null;
-        t.mCloseOnExit = b.getBoolean(CLOSEONEXIT);
         return true;
     }
 }