Backed out changesets c644dacaf9a9 and 454ec577c741
authorBrian Nicholson <bnicholson@mozilla.com>
Fri, 05 Oct 2012 16:36:15 -0700
changeset 109460 0c5a323056774e9b5794dd2885b0735f9cbd24d1
parent 109459 9456e53577df458aee45ad4d4d6c60557c1e9a10
child 109461 b9de5da14ab049ea18dcc757488c654e38db69ad
push id16039
push userbnicholson@mozilla.com
push dateFri, 05 Oct 2012 23:39:09 +0000
treeherdermozilla-inbound@0c5a32305677 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone18.0a1
backs outc644dacaf9a9e584098224db687d46478fb0dd1b
454ec577c741134f8eb95b8a575dfc117ccb4de2
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changesets c644dacaf9a9 and 454ec577c741
mobile/android/base/AboutHomeContent.java.in
mobile/android/base/AwesomeBar.java
mobile/android/base/AwesomebarResultHandler.java
mobile/android/base/BrowserApp.java
mobile/android/base/DoorHanger.java
mobile/android/base/GeckoApp.java
mobile/android/base/LinkPreference.java
mobile/android/base/Tab.java
mobile/android/base/Tabs.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/AboutHomeContent.java.in
+++ b/mobile/android/base/AboutHomeContent.java.in
@@ -556,34 +556,34 @@ public class AboutHomeContent extends Sc
                     View container = mInflater.inflate(R.layout.abouthome_last_tabs_row, mLastTabs.getItemsContainer(), false);
                     ((TextView) container.findViewById(R.id.last_tab_title)).setText(title);
                     ((TextView) container.findViewById(R.id.last_tab_url)).setText(url);
                     if (favicon != null)
                         ((ImageView) container.findViewById(R.id.last_tab_favicon)).setImageDrawable(favicon);
 
                     container.setOnClickListener(new View.OnClickListener() {
                         public void onClick(View v) {
-                            Tabs.getInstance().loadUrlInTab(url);
+                            mActivity.loadUrlInTab(url);
                         }
                     });
 
                     mLastTabs.addItem(container);
                 }
             });
         }
 
         final int numLastTabs = lastTabUrlsList.size();
         post(new Runnable() {
             public void run() {
                 if (numLastTabs > 1) {
                     mLastTabs.showMoreText();
                     mLastTabs.setOnMoreTextClickListener(new View.OnClickListener() {
                         public void onClick(View v) {
                             for (String url : lastTabUrlsList)
-                                Tabs.getInstance().loadUrlInTab(url);
+                                mActivity.loadUrlInTab(url);
                         }
                     });
                     mLastTabs.show();
                 } else if (numLastTabs == 1) {
                     mLastTabs.hideMoreText();
                     mLastTabs.show();
                 }
             }
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -514,17 +514,17 @@ public class AwesomeBar extends GeckoAct
 
         switch (item.getItemId()) {
             case R.id.open_new_tab: {
                 if (url == null) {
                     Log.e(LOGTAG, "Can't open in new tab because URL is null");
                     break;
                 }
 
-                Tabs.getInstance().loadUrl(url, Tabs.LOADURL_NEW_TAB);
+                GeckoApp.mAppContext.loadUrl(url, AwesomeBar.Target.NEW_TAB);
                 Toast.makeText(this, R.string.new_tab_opened, Toast.LENGTH_SHORT).show();
                 break;
             }
             case R.id.open_in_reader: {
                 if (url == null) {
                     Log.e(LOGTAG, "Can't open in reader mode because URL is null");
                     break;
                 }
--- a/mobile/android/base/AwesomebarResultHandler.java
+++ b/mobile/android/base/AwesomebarResultHandler.java
@@ -11,21 +11,14 @@ import android.content.Intent;
 class AwesomebarResultHandler implements ActivityResultHandler {
     private static final String LOGTAG = "GeckoAwesomebarResultHandler";
 
     public void onActivityResult(int resultCode, Intent data) {
         if (data != null) {
             String url = data.getStringExtra(AwesomeBar.URL_KEY);
             AwesomeBar.Target target = AwesomeBar.Target.valueOf(data.getStringExtra(AwesomeBar.TARGET_KEY));
             String searchEngine = data.getStringExtra(AwesomeBar.SEARCH_KEY);
-            if (url != null && url.length() > 0) {
-                int flags = Tabs.LOADURL_NONE;
-                if (target == AwesomeBar.Target.NEW_TAB) {
-                    flags |= Tabs.LOADURL_NEW_TAB;
-                }
-                if (data.getBooleanExtra(AwesomeBar.USER_ENTERED_KEY, false)) {
-                    flags |= Tabs.LOADURL_USER_ENTERED;
-                }
-                Tabs.getInstance().loadUrl(url, searchEngine, -1, flags);
-            }
+            boolean userEntered = data.getBooleanExtra(AwesomeBar.USER_ENTERED_KEY, false);
+            if (url != null && url.length() > 0)
+                GeckoApp.mAppContext.loadRequest(url, target, searchEngine, userEntered);
         }
     }
 }
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -186,16 +186,22 @@ abstract public class BrowserApp extends
                     mAboutHomeContent.setLastTabsVisibility(false);
             }
         });
 
         super.onStatePurged();
     }
 
     @Override
+    protected void loadRequest(String url, AwesomeBar.Target target, String searchEngine, boolean userEntered) {
+        mBrowserToolbar.setTitle(url);
+        super.loadRequest(url, target, searchEngine, userEntered);
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         LinearLayout actionBar = (LinearLayout) getActionBarLayout();
         mMainLayout.addView(actionBar, 0);
 
         mBrowserToolbar = new BrowserToolbar(this);
         mBrowserToolbar.from(actionBar);
@@ -625,17 +631,17 @@ abstract public class BrowserApp extends
             if (mShow) {
                 if (mAboutHomeContent == null) {
                     mAboutHomeContent = (AboutHomeContent) findViewById(R.id.abouthome_content);
                     mAboutHomeContent.init();
                     mAboutHomeContent.update(AboutHomeContent.UpdateFlags.ALL);
                     mAboutHomeContent.setUriLoadCallback(new AboutHomeContent.UriLoadCallback() {
                         public void callback(String url) {
                             mBrowserToolbar.setProgressVisibility(true);
-                            Tabs.getInstance().loadUrl(url);
+                            loadUrl(url, AwesomeBar.Target.CURRENT_TAB);
                         }
                     });
                     mAboutHomeContent.setLoadCompleteCallback(new AboutHomeContent.VoidCallback() {
                          public void callback() {
                              mAboutHomeStartupTimer.stop();
                          }
                     });
                     mAboutHomeContent.setOnInterceptTouchListener(new ContentTouchListener());
@@ -863,23 +869,23 @@ abstract public class BrowserApp extends
             case R.id.save_as_pdf:
                 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SaveAs:PDF", null));
                 return true;
             case R.id.settings:
                 intent = new Intent(this, GeckoPreferences.class);
                 startActivity(intent);
                 return true;
             case R.id.addons:
-                Tabs.getInstance().loadUrlInTab("about:addons");
+                loadUrlInTab("about:addons");
                 return true;
             case R.id.downloads:
-                Tabs.getInstance().loadUrlInTab("about:downloads");
+                loadUrlInTab("about:downloads");
                 return true;
             case R.id.apps:
-                Tabs.getInstance().loadUrlInTab("about:apps");
+                loadUrlInTab("about:apps");
                 return true;
             case R.id.char_encoding:
                 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("CharEncoding:Get", null));
                 return true;
             case R.id.find_in_page:
                 mFindInPageBar.show();
                 return true;
             case R.id.desktop_mode:
@@ -927,17 +933,17 @@ abstract public class BrowserApp extends
 
                 // If we've reached our magic number, show the feedback page.
                 return launchCount == FEEDBACK_LAUNCH_COUNT;
             }
 
             @Override
             public void onPostExecute(Boolean shouldShowFeedbackPage) {
                 if (shouldShowFeedbackPage)
-                    Tabs.getInstance().loadUrlInTab("about:feedback");
+                    loadUrlInTab("about:feedback");
             }
         }).execute();
     }
 
     private void resetFeedbackLaunchCount() {
         GeckoBackgroundThread.post(new Runnable() {
             @Override
             public synchronized void run() {
--- a/mobile/android/base/DoorHanger.java
+++ b/mobile/android/base/DoorHanger.java
@@ -145,17 +145,17 @@ public class DoorHanger extends LinearLa
             JSONObject link = options.getJSONObject("link");
             String title = mTextView.getText().toString();
             String linkLabel = link.getString("label");
             String linkUrl = link.getString("url");
             SpannableString titleWithLink = new SpannableString(title + " " + linkLabel);
             URLSpan linkSpan = new URLSpan(linkUrl) {
                 @Override
                 public void onClick(View view) {
-                    Tabs.getInstance().loadUrlInTab(this.getURL());
+                    mActivity.loadUrlInTab(this.getURL());
                 }
             };
 
             // prevent text outside the link from flashing when clicked
             ForegroundColorSpan colorSpan = new ForegroundColorSpan(mTextView.getCurrentTextColor());
             titleWithLink.setSpan(colorSpan, 0, title.length(), 0);
 
             titleWithLink.setSpan(linkSpan, title.length() + 1, titleWithLink.length(), 0);
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1922,17 +1922,17 @@ abstract public class GeckoApp
         final String action = intent.getAction();
 
         if (Intent.ACTION_MAIN.equals(action)) {
             Log.i(LOGTAG, "Intent : ACTION_MAIN");
             GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(""));
         }
         else if (ACTION_LOAD.equals(action)) {
             String uri = intent.getDataString();
-            Tabs.getInstance().loadUrl(uri);
+            loadUrl(uri, AwesomeBar.Target.CURRENT_TAB);
         }
         else if (Intent.ACTION_VIEW.equals(action)) {
             String uri = intent.getDataString();
             GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(uri));
         }
         else if (action != null && action.startsWith(ACTION_WEBAPP_PREFIX)) {
             String uri = getURIFromIntent(intent);
             GeckoAppShell.sendEventToGecko(GeckoEvent.createWebappLoadEvent(uri));
@@ -2450,16 +2450,72 @@ abstract public class GeckoApp
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (!GeckoAppShell.sActivityHelper.handleActivityResult(requestCode, resultCode, data)) {
             super.onActivityResult(requestCode, resultCode, data);
         }
     }
 
+    // If searchEngine is provided, url will be used as the search query.
+    // Otherwise, the url is loaded.
+    protected void loadRequest(String url, AwesomeBar.Target target, String searchEngine, boolean userEntered) {
+        Log.d(LOGTAG, target.name());
+        JSONObject args = new JSONObject();
+        try {
+            args.put("url", url);
+            args.put("engine", searchEngine);
+            args.put("userEntered", userEntered);
+        } catch (Exception e) {
+            Log.e(LOGTAG, "error building JSON arguments");
+        }
+
+        if (target == AwesomeBar.Target.NEW_TAB) {
+            Log.d(LOGTAG, "Sending message to Gecko: " + SystemClock.uptimeMillis() + " - Tab:Add");
+            GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Add", args.toString()));
+        } else {
+            GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString()));
+        }
+    }
+
+    public void loadUrl(String url) {
+        loadRequest(url, AwesomeBar.Target.CURRENT_TAB, null, false);
+    }
+
+    public void loadUrl(String url, AwesomeBar.Target target) {
+        loadRequest(url, target, null, false);
+    }
+
+    /**
+     * Open the url as a new tab, and mark the selected tab as its "parent".
+     * If the url is already open in a tab, the existing tab is selected.
+     * Use this for tabs opened by the browser chrome, so users can press the
+     * "Back" button to return to the previous tab.
+     */
+    public void loadUrlInTab(String url) {
+        Tabs tabsInstance = Tabs.getInstance();
+        Iterable<Tab> tabs = tabsInstance.getTabsInOrder();
+        for (Tab tab : tabs) {
+            if (url.equals(tab.getURL())) {
+                tabsInstance.selectTab(tab.getId());
+                return;
+            }
+        }
+
+        JSONObject args = new JSONObject();
+        try {
+            args.put("url", url);
+            args.put("parentId", tabsInstance.getSelectedTab().getId());
+        } catch (Exception e) {
+            Log.e(LOGTAG, "error building JSON arguments");
+        }
+        Log.i(LOGTAG, "Sending message to Gecko: " + SystemClock.uptimeMillis() + " - Tab:Add");
+        GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Add", args.toString()));
+    }
+
     public LayerView getLayerView() {
         return mLayerView;
     }
 
     public AbsoluteLayout getPluginContainer() { return mPluginContainer; }
 
     // accelerometer
     public void onAccuracyChanged(Sensor sensor, int accuracy) {}
@@ -2637,17 +2693,17 @@ abstract public class GeckoApp
     }
 
     @Override
     public boolean onContextItemSelected(MenuItem item) {
         switch(item.getItemId()) {
             case R.id.pasteandgo: {
                 String text = GeckoAppShell.getClipboardText();
                 if (text != null && !TextUtils.isEmpty(text)) {
-                    Tabs.getInstance().loadUrl(text);
+                    loadUrl(text, AwesomeBar.Target.CURRENT_TAB);
                 }
                 return true;
             }
             case R.id.site_settings: {
                 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Permissions:Get", null));
                 return true;
             }
             case R.id.paste: {
--- a/mobile/android/base/LinkPreference.java
+++ b/mobile/android/base/LinkPreference.java
@@ -18,12 +18,12 @@ class LinkPreference extends Preference 
     }
     public LinkPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         mUrl = attrs.getAttributeValue(null, "url");
     }
 
     @Override
     protected void onClick() {
-        Tabs.getInstance().loadUrlInTab(mUrl);
+        GeckoApp.mAppContext.loadUrlInTab(mUrl);
         callChangeListener(mUrl);
     }
 }
--- a/mobile/android/base/Tab.java
+++ b/mobile/android/base/Tab.java
@@ -449,17 +449,17 @@ public final class Tab {
         });
     }
 
     public void readerMode() {
         if (!mReaderEnabled)
             return;
 
         mEnteringReaderMode = true;
-        Tabs.getInstance().loadUrl(ReaderModeUtils.getAboutReaderForUrl(getURL(), mId, mReadingListItem));
+        GeckoApp.mAppContext.loadUrl(ReaderModeUtils.getAboutReaderForUrl(getURL(), mId, mReadingListItem));
     }
 
     public boolean isEnteringReaderMode() {
         return mEnteringReaderMode;
     }
 
     public void doReload() {
         GeckoEvent e = GeckoEvent.createBroadcastEvent("Session:Reload", "");
--- a/mobile/android/base/Tabs.java
+++ b/mobile/android/base/Tabs.java
@@ -16,42 +16,36 @@ import android.content.Intent;
 import android.os.SystemClock;
 import android.util.Log;
 import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicInteger;
 
 public class Tabs implements GeckoEventListener {
     private static final String LOGTAG = "GeckoTabs";
 
     private Tab mSelectedTab;
     private final HashMap<Integer, Tab> mTabs = new HashMap<Integer, Tab>();
     private final CopyOnWriteArrayList<Tab> mOrder = new CopyOnWriteArrayList<Tab>();
     private boolean mRestoringSession;
 
     // Keeps track of how much has happened since we last updated our persistent tab store.
     private volatile int mScore = 0;
 
-    public static final int LOADURL_NONE = 0;
-    public static final int LOADURL_NEW_TAB = 1;
-    public static final int LOADURL_USER_ENTERED = 2;
-
     private static final int SCORE_INCREMENT_TAB_LOCATION_CHANGE = 5;
     private static final int SCORE_INCREMENT_TAB_SELECTED = 10;
     private static final int SCORE_THRESHOLD = 30;
 
-    private static AtomicInteger sTabId = new AtomicInteger(0);
-
     private GeckoApp mActivity;
 
     private Tabs() {
+
         registerEventListener("SessionHistory:New");
         registerEventListener("SessionHistory:Back");
         registerEventListener("SessionHistory:Forward");
         registerEventListener("SessionHistory:Goto");
         registerEventListener("SessionHistory:Purge");
         registerEventListener("Tab:Added");
         registerEventListener("Tab:Close");
         registerEventListener("Tab:Select");
@@ -66,17 +60,27 @@ public class Tabs implements GeckoEventL
     public void attachToActivity(GeckoApp activity) {
         mActivity = activity;
     }
 
     public int getCount() {
         return mTabs.size();
     }
 
-    private Tab addTab(int id, String url, boolean external, int parentId, String title) {
+    public Tab addTab(JSONObject params) throws JSONException {
+        int id = params.getInt("tabID");
+        if (mTabs.containsKey(id))
+           return mTabs.get(id);
+
+        // null strings return "null" (http://code.google.com/p/android/issues/detail?id=13830)
+        String url = params.isNull("uri") ? null : params.getString("uri");
+        Boolean external = params.getBoolean("external");
+        int parentId = params.getInt("parentId");
+        String title = params.getString("title");
+
         final Tab tab = new Tab(id, url, external, parentId, title);
         mTabs.put(id, tab);
         mOrder.add(tab);
 
         if (!mRestoringSession) {
             mActivity.runOnUiThread(new Runnable() {
                 public void run() {
                     notifyListeners(tab, TabEvents.ADDED);
@@ -233,30 +237,17 @@ public class Tabs implements GeckoEventL
             if (event.startsWith("SessionHistory:")) {
                 Tab tab = getTab(message.getInt("tabID"));
                 if (tab != null) {
                     event = event.substring("SessionHistory:".length());
                     tab.handleSessionHistoryMessage(event, message);
                 }
             } else if (event.equals("Tab:Added")) {
                 Log.i(LOGTAG, "Received message from Gecko: " + SystemClock.uptimeMillis() + " - Tab:Added");
-
-                int id = message.getInt("tabID");
-                Tab tab = null;
-
-                if (mTabs.containsKey(id)) {
-                    tab = mTabs.get(id);
-                } else {
-                    tab = addTab(id,
-                                 message.isNull("uri") ? null : message.getString("uri"),
-                                 message.getBoolean("external"),
-                                 message.getInt("parentId"),
-                                 message.getString("title"));
-                }
-
+                Tab tab = addTab(message);
                 if (message.getBoolean("selected"))
                     selectTab(tab.getId());
                 if (message.getBoolean("delayLoad"))
                     tab.setState(Tab.STATE_DELAYED);
                 if (message.getBoolean("desktopMode"))
                     tab.setDesktopMode(true);
             } else if (event.equals("Tab:Close")) {
                 Tab tab = getTab(message.getInt("tabID"));
@@ -416,95 +407,9 @@ public class Tabs implements GeckoEventL
                 TabsAccessor.persistLocalTabs(getContentResolver(), tabs);
             }
         });
     }
 
     private void registerEventListener(String event) {
         GeckoAppShell.getEventDispatcher().registerEventListener(event, this);
     }
-
-    /**
-     * Loads a tab with the given URL in the currently selected tab.
-     *
-     * @param url URL of page to load, or search term used if searchEngine is given
-     */
-    public void loadUrl(String url) {
-        loadUrl(url, LOADURL_NONE);
-    }
-
-    /**
-     * Loads a tab with the given URL.
-     *
-     * @param url   URL of page to load, or search term used if searchEngine is given
-     * @param flags flags used to load tab
-     */
-    public void loadUrl(String url, int flags) {
-        loadUrl(url, null, -1, flags);
-    }
-
-    /**
-     * Loads a tab with the given URL.
-     *
-     * @param url          URL of page to load, or search term used if searchEngine is given
-     * @param searchEngine if given, the search engine with this name is used
-     *                     to search for the url string; if null, the URL is loaded directly
-     * @param parentId     ID of this tab's parent, or -1 if it has no parent
-     * @param flags        flags used to load tab
-     */
-    public void loadUrl(String url, String searchEngine, int parentId, int flags) {
-        JSONObject args = new JSONObject();
-        int tabId = -1;
-
-        try {
-            args.put("url", url);
-            args.put("engine", searchEngine);
-            args.put("parentId", parentId);
-            args.put("userEntered", (flags & LOADURL_USER_ENTERED) != 0);
-            args.put("newTab", (flags & LOADURL_NEW_TAB) != 0);
-
-            if ((flags & LOADURL_NEW_TAB) != 0) {
-                tabId = getNextTabId();
-                args.put("tabID", tabId);
-                addTab(tabId, null, false, parentId, url);
-            }
-        } catch (Exception e) {
-            Log.e(LOGTAG, "error building JSON arguments");
-        }
-
-        Log.d(LOGTAG, "Sending message to Gecko: " + SystemClock.uptimeMillis() + " - Tab:Load");
-        GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString()));
-
-        if (tabId != -1) {
-            selectTab(tabId);
-        }
-    }
-
-    /**
-     * Open the url as a new tab, and mark the selected tab as its "parent".
-     *
-     * If the url is already open in a tab, the existing tab is selected.
-     * Use this for tabs opened by the browser chrome, so users can press the
-     * "Back" button to return to the previous tab.
-     *
-     * @param url URL of page to load
-     */
-    public void loadUrlInTab(String url) {
-        Iterable<Tab> tabs = getTabsInOrder();
-        for (Tab tab : tabs) {
-            if (url.equals(tab.getURL())) {
-                selectTab(tab.getId());
-                return;
-            }
-        }
-
-        loadUrl(url, null, getSelectedTab().getId(), LOADURL_NEW_TAB);
-    }
-
-    /**
-     * Gets the next tab ID.
-     *
-     * This method is invoked via JNI.
-     */
-    public static int getNextTabId() {
-        return sTabId.getAndIncrement();
-    }
 }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -8,17 +8,16 @@ let Cc = Components.classes;
 let Ci = Components.interfaces;
 let Cu = Components.utils;
 let Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/JNI.jsm");
 
 #ifdef ACCESSIBILITY
 Cu.import("resource://gre/modules/accessibility/AccessFu.jsm");
 #endif
 
 XPCOMUtils.defineLazyGetter(this, "PluralForm", function() {
   Cu.import("resource://gre/modules/PluralForm.jsm");
   return PluralForm;
@@ -158,16 +157,17 @@ var BrowserApp = {
     dump("zerdatime " + Date.now() + " - browser chrome startup finished.");
 
     this.deck = document.getElementById("browsers");
     BrowserEventHandler.init();
     ViewportHandler.init();
 
     getBridge().browserApp = this;
 
+    Services.obs.addObserver(this, "Tab:Add", false);
     Services.obs.addObserver(this, "Tab:Load", false);
     Services.obs.addObserver(this, "Tab:Selected", false);
     Services.obs.addObserver(this, "Tab:Closed", false);
     Services.obs.addObserver(this, "Session:Back", false);
     Services.obs.addObserver(this, "Session:Forward", false);
     Services.obs.addObserver(this, "Session:Reload", false);
     Services.obs.addObserver(this, "Session:Stop", false);
     Services.obs.addObserver(this, "SaveAs:PDF", false);
@@ -1068,47 +1068,46 @@ var BrowserApp = {
     if (aTopic == "Session:Back") {
       browser.goBack();
     } else if (aTopic == "Session:Forward") {
       browser.goForward();
     } else if (aTopic == "Session:Reload") {
       browser.reload();
     } else if (aTopic == "Session:Stop") {
       browser.stop();
-    } else if (aTopic == "Tab:Load") {
+    } else if (aTopic == "Tab:Add" || aTopic == "Tab:Load") {
       let data = JSON.parse(aData);
 
       // Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
       // inheriting the currently loaded document's principal.
       let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
       if (data.userEntered)
         flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
 
       let params = {
         selected: true,
         parentId: ("parentId" in data) ? data.parentId : -1,
-        flags: flags,
-        tabID: data.tabID
+        flags: flags
       };
 
       let url = data.url;
       if (data.engine) {
         let engine = Services.search.getEngineByName(data.engine);
         if (engine) {
           let submission = engine.getSubmission(url);
           url = submission.uri.spec;
           params.postData = submission.postData;
         }
       }
 
       // Don't show progress throbber for about:home or about:reader
       if (!shouldShowProgress(url))
         params.showProgress = false;
 
-      if (data.newTab)
+      if (aTopic == "Tab:Add")
         this.addTab(url, params);
       else
         this.loadURI(url, browser, params);
     } else if (aTopic == "Tab:Selected") {
       this._handleTabSelected(this.getTabForId(parseInt(aData)));
     } else if (aTopic == "Tab:Closed") {
       this._handleTabClosed(this.getTabForId(parseInt(aData)));
     } else if (aTopic == "Browser:Quit") {
@@ -2231,16 +2230,18 @@ nsBrowserAccess.prototype = {
   },
 
   isTabContentWindow: function(aWindow) {
     return BrowserApp.getBrowserForWindow(aWindow) != null;
   }
 };
 
 
+let gTabIDFactory = 0;
+
 // track the last known screen size so that new tabs
 // get created with the right size rather than being 1x1
 let gScreenWidth = 1;
 let gScreenHeight = 1;
 
 function Tab(aURL, aParams) {
   this.browser = null;
   this.id = 0;
@@ -2286,26 +2287,17 @@ Tab.prototype = {
 
     // only set tab uri if uri is valid
     let uri = null;
     try {
       uri = Services.io.newURI(aURL, null, null).spec;
     } catch (e) {}
 
     if (!aParams.zombifying) {
-      if ("tabID" in aParams) {
-        this.id = aParams.tabID;
-      } else {
-        let jni = new JNI();
-        let cls = jni.findClass("org.mozilla.gecko.Tabs");
-        let method = jni.getStaticMethodID(cls, "getNextTabId", "()I");
-        this.id = jni.callStaticIntMethod(cls, method);
-        jni.close();
-      }
-
+      this.id = ++gTabIDFactory;
       this.desktopMode = ("desktopMode" in aParams) ? aParams.desktopMode : false;
 
       let message = {
         gecko: {
           type: "Tab:Added",
           tabID: this.id,
           uri: uri,
           parentId: ("parentId" in aParams) ? aParams.parentId : -1,
@@ -6638,16 +6630,17 @@ var WebappsUI = {
         origin: aOrigin
       }
     });
   },
 
   get iconSize() {
     let iconSize = 64;
     try {
+      Cu.import("resource://gre/modules/JNI.jsm");
       let jni = new JNI();
       let cls = jni.findClass("org.mozilla.gecko.GeckoAppShell");
       let method = jni.getStaticMethodID(cls, "getPreferredIconSize", "()I");
       iconSize = jni.callStaticIntMethod(cls, method);
       jni.close();
     } catch(ex) {
       console.log(ex);
     }