Bug 880119 - Improve the API for GeckoView r=blassey
authorMark Finkle <mfinkle@mozilla.com>
Wed, 06 Nov 2013 17:56:23 -0500
changeset 169456 34f82e0245997a06e46015fc4d92177989a23cfc
parent 169455 1238b4fee5b5910e161462e3c4abbffbc5562489
child 169457 43c4eda97a57fe78f538fdd6d3a32615468579be
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey
bugs880119
milestone28.0a1
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
Bug 880119 - Improve the API for GeckoView r=blassey
mobile/android/base/GeckoView.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/GeckoView.java
+++ b/mobile/android/base/GeckoView.java
@@ -24,16 +24,20 @@ import android.graphics.Paint;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 public class GeckoView extends LayerView
     implements GeckoEventListener, ContextGetter {
 
     private static final String LOGTAG = "GeckoView";
 
     public GeckoView(Context context, AttributeSet attrs) {
         super(context, attrs);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GeckoView);
@@ -85,24 +89,78 @@ public class GeckoView extends LayerView
         BrowserDB.initialize(profile.getName());
 
         if (GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.Launched)) {
             GeckoAppShell.setLayerView(this);
             GeckoThread.createAndStart();
         }
     }
 
-    public void loadUrl(String uri) {
-        Tabs.getInstance().loadUrl(uri);
+    /**
+    * Add a Browser to the GeckoView container.
+    * @param url The URL resource to load into the new Browser.
+    */
+    public Browser addBrowser(String url) {
+        Tab tab = Tabs.getInstance().loadUrl(url, Tabs.LOADURL_NEW_TAB);
+        if (tab != null) {
+            return new Browser(tab.getId());
+        }
+        return null;
+    }
+
+    /**
+    * Remove a Browser from the GeckoView container.
+    * @param browser The Browser to remove.
+    */
+    public void removeBrowser(Browser browser) {
+        Tab tab = Tabs.getInstance().getTab(browser.getId());
+        if (tab != null) {
+            Tabs.getInstance().closeTab(tab);
+        }
     }
 
-    public void loadUrlInNewTab(String uri) {
-        Tabs.getInstance().loadUrl(uri, Tabs.LOADURL_NEW_TAB);
-     }
+    /**
+    * Set the active/visible Browser.
+    * @param browser The Browser to make selected.
+    */
+    public void setCurrentBrowser(Browser browser) {
+        Tab tab = Tabs.getInstance().getTab(browser.getId());
+        if (tab != null) {
+            Tabs.getInstance().selectTab(tab.getId());
+        }
+    }
 
+    /**
+    * Get the active/visible Browser.
+    * @return The current selected Browser.
+    */
+    public Browser getCurrentBrowser() {
+        Tab tab = Tabs.getInstance().getSelectedTab();
+        if (tab != null) {
+            return new Browser(tab.getId());
+        }
+        return null;
+    }
+
+    /**
+    * Get the list of current Browsers in the GeckoView container.
+    * @return An unmodifiable List of Browser objects.
+    */
+    public List<Browser> getBrowsers() {
+        ArrayList<Browser> browsers = new ArrayList<Browser>();
+        Iterable<Tab> tabs = Tabs.getInstance().getTabsInOrder();
+        for (Tab tab : tabs) {
+            browsers.add(new Browser(tab.getId()));
+        }
+        return Collections.unmodifiableList(browsers);
+    }
+
+    /**
+    * Not part of the public API. Ignore.
+    */
     public void handleMessage(String event, JSONObject message) {
         if (event.equals("Gecko:Ready")) {
             GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoRunning);
             Tab selectedTab = Tabs.getInstance().getSelectedTab();
             if (selectedTab != null)
                 Tabs.getInstance().notifyListeners(selectedTab, Tabs.TabEvents.SELECTED);
             geckoConnected();
             GeckoAppShell.setLayerClient(getLayerClient());
@@ -114,9 +172,115 @@ public class GeckoView extends LayerView
 
     public static void setGeckoInterface(final BaseGeckoInterface geckoInterface) {
         GeckoAppShell.setGeckoInterface(geckoInterface);
     }
 
     public static GeckoAppShell.GeckoInterface getGeckoInterface() {
         return GeckoAppShell.getGeckoInterface();
     }
+
+    /**
+    * Wrapper for a browser in the GeckoView container. Associated with a browser
+    * element in the Gecko system.
+    */
+    public class Browser {
+        private final int mId;
+        private Browser(int Id) {
+            mId = Id;
+        }
+
+        /**
+        * Get the ID of the Browser. This is the same ID used by Gecko for it's underlying
+        * browser element.
+        * @return The integer ID of the Browser.
+        */
+        private int getId() {
+            return mId;
+        }
+
+        /**
+        * Load a URL resource into the Browser.
+        * @param url The URL string.
+        */
+        public void loadUrl(String url) {
+            JSONObject args = new JSONObject();
+            try {
+                args.put("url", url);
+                args.put("parentId", -1);
+                args.put("newTab", false);
+                args.put("tabID", mId);
+            } catch (Exception e) {
+                Log.w(LOGTAG, "Error building JSON arguments for loadUrl.", e);
+            }
+            GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString()));
+        }
+
+        /**
+        * Reload the current URL resource into the Browser. The URL is force loaded from the
+        * network and is not pulled from cache.
+        */
+        public void reload() {
+            Tab tab = Tabs.getInstance().getTab(mId);
+            if (tab != null) {
+                tab.doReload();
+            }
+        }
+
+        /**
+        * Stop the current loading operation.
+        */
+        public void stop() {
+            Tab tab = Tabs.getInstance().getTab(mId);
+            if (tab != null) {
+                tab.doStop();
+            }
+        }
+
+        /**
+        * Check to see if the Browser has session history and can go back to a
+        * previous page.
+        * @return A boolean flag indicating if previous session exists.
+        * This method will likely be removed and replaced by a callback in GeckoViewContent
+        */
+        public boolean canGoBack() {
+            Tab tab = Tabs.getInstance().getTab(mId);
+            if (tab != null) {
+                return tab.canDoBack();
+            }
+            return false;
+        }
+
+        /**
+        * Move backward in the session history, if that's possible.
+        */
+        public void goBack() {
+            Tab tab = Tabs.getInstance().getTab(mId);
+            if (tab != null) {
+                tab.doBack();
+            }
+        }
+
+        /**
+        * Check to see if the Browser has session history and can go forward to a
+        * new page.
+        * @return A boolean flag indicating if forward session exists.
+        * This method will likely be removed and replaced by a callback in GeckoViewContent
+        */
+        public boolean canGoForward() {
+            Tab tab = Tabs.getInstance().getTab(mId);
+            if (tab != null) {
+                return tab.canDoForward();
+            }
+            return false;
+        }
+
+        /**
+        * Move forward in the session history, if that's possible.
+        */
+        public void goForward() {
+            Tab tab = Tabs.getInstance().getTab(mId);
+            if (tab != null) {
+                tab.doForward();
+            }
+        }
+    }
 }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1392,20 +1392,27 @@ var BrowserApp = {
             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 (data.newTab) {
           this.addTab(url, params);
-        else
+        } else {
+          if (data.tabId) {
+            // Use a specific browser instead of the selected browser, if it exists
+            let specificBrowser = this.getTabForId(data.tabId).browser;
+            if (specificBrowser)
+              browser = specificBrowser;
+          }
           this.loadURI(url, browser, params);
+        }
         break;
       }
 
       case "Tab:Selected":
         this._handleTabSelected(this.getTabForId(parseInt(aData)));
         break;
 
       case "Tab:Closed":