Bug 1330411 - 2. Convert FindInPageBar events to bundle events; r=sebastian
authorJim Chen <nchen@mozilla.com>
Wed, 25 Jan 2017 18:53:58 -0500
changeset 331153 14bd5683877aca3615acb06b92edb9ec4bd31eab
parent 331152 65b07eac83b329667ae01b036e7e5f5b067c31c4
child 331154 d3c8b390c953ac092935591d83eaa20fe3b41a33
push id31261
push usercbook@mozilla.com
push dateThu, 26 Jan 2017 11:32:02 +0000
treeherdermozilla-central@a338e596b1d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1330411
milestone54.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 1330411 - 2. Convert FindInPageBar events to bundle events; r=sebastian Convert events used in FindInPageBar to GeckoBundle/BundleEventListener events. UI thread events are used because the listener performs UI operations. FindInPageBar also sends some events like "FindInPage:Find" from Java to Gecko; those events will be converted in another bug.
mobile/android/base/java/org/mozilla/gecko/FindInPageBar.java
mobile/android/chrome/content/FindHelper.js
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/java/org/mozilla/gecko/FindInPageBar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/FindInPageBar.java
@@ -1,40 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
-import org.mozilla.gecko.util.GeckoEventListener;
-import org.mozilla.gecko.util.GeckoRequest;
+import org.mozilla.gecko.util.BundleEventListener;
+import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.NativeJSObject;
 import org.mozilla.gecko.util.ThreadUtils;
 
-import org.json.JSONObject;
-
 import android.content.Context;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener  {
+public class FindInPageBar extends LinearLayout
+        implements TextWatcher, View.OnClickListener, BundleEventListener {
     private static final String LOGTAG = "GeckoFindInPageBar";
     private static final String REQUEST_ID = "FindInPageBar";
 
     private final Context mContext;
-    private CustomEditText mFindText;
+    /* package */ CustomEditText mFindText;
     private TextView mStatusText;
     private boolean mInflated;
 
     public FindInPageBar(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
         setFocusable(true);
     }
@@ -62,31 +62,42 @@ public class FindInPageBar extends Linea
                 }
                 return false;
             }
         });
 
         mStatusText = (TextView) content.findViewById(R.id.find_status);
 
         mInflated = true;
-        EventDispatcher.getInstance().registerGeckoThreadListener(this,
-            "FindInPage:MatchesCountResult",
-            "TextSelection:Data");
+        EventDispatcher.getInstance().registerUiThreadListener(this,
+            "FindInPage:MatchesCountResult");
     }
 
     public void show() {
         if (!mInflated)
             inflateContent();
 
         setVisibility(VISIBLE);
         mFindText.requestFocus();
 
         // handleMessage() receives response message and determines initial state of softInput
-        GeckoAppShell.notifyObservers("TextSelection:Get", REQUEST_ID);
-        GeckoAppShell.notifyObservers("FindInPage:Opened", null);
+
+        GeckoApp.getEventDispatcher().dispatch("TextSelection:Get", null, new EventCallback() {
+            @Override
+            public void sendSuccess(final Object result) {
+                onTextSelectionData((String) result);
+            }
+
+            @Override
+            public void sendError(final Object error) {
+                Log.e(LOGTAG, "TextSelection:Get failed: " + error);
+            }
+        });
+
+        EventDispatcher.getInstance().dispatch("FindInPage:Opened", null);
     }
 
     public void hide() {
         if (!mInflated || getVisibility() == View.GONE) {
             // There's nothing to hide yet.
             return;
         }
 
@@ -95,31 +106,30 @@ public class FindInPageBar extends Linea
 
         // Only close the IMM if its EditText is the one with focus.
         if (mFindText.isFocused()) {
           getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
         }
 
         // Close the FIPB / FindHelper state.
         setVisibility(GONE);
-        GeckoAppShell.notifyObservers("FindInPage:Closed", null);
+        EventDispatcher.getInstance().dispatch("FindInPage:Closed", null);
     }
 
     private InputMethodManager getInputMethodManager(View view) {
         Context context = view.getContext();
         return (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
      }
 
     public void onDestroy() {
         if (!mInflated) {
             return;
         }
-        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
-            "FindInPage:MatchesCountResult",
-            "TextSelection:Data");
+        EventDispatcher.getInstance().unregisterUiThreadListener(this,
+            "FindInPage:MatchesCountResult");
     }
 
     private void onMatchesCountResult(final int total, final int current, final int limit, final String searchString) {
         if (total == -1) {
             updateResult(Integer.toString(limit) + "+");
         } else if (total > 0) {
             updateResult(Integer.toString(current) + "/" + Integer.toString(total));
         } else if (TextUtils.isEmpty(searchString)) {
@@ -128,23 +138,18 @@ public class FindInPageBar extends Linea
             // We display 0/0, when there were no
             // matches found, or if matching has been turned off by setting
             // pref accessibility.typeaheadfind.matchesCountLimit to 0.
             updateResult("0/0");
         }
     }
 
     private void updateResult(final String statusText) {
-        ThreadUtils.postToUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mStatusText.setVisibility(statusText.isEmpty() ? View.GONE : View.VISIBLE);
-                mStatusText.setText(statusText);
-            }
-        });
+        mStatusText.setVisibility(statusText.isEmpty() ? View.GONE : View.VISIBLE);
+        mStatusText.setText(statusText);
     }
 
     // TextWatcher implementation
 
     @Override
     public void afterTextChanged(Editable s) {
         sendRequestToFinderHelper("FindInPage:Find", s.toString());
     }
@@ -180,43 +185,33 @@ public class FindInPageBar extends Linea
             return;
         }
 
         if (viewId == R.id.find_close) {
             hide();
         }
     }
 
-    // GeckoEventListener implementation
-
-    @Override
-    public void handleMessage(String event, JSONObject message) {
-        if (event.equals("FindInPage:MatchesCountResult")) {
-            onMatchesCountResult(message.optInt("total", 0),
-                message.optInt("current", 0),
-                message.optInt("limit", 0),
-                message.optString("searchString"));
+    @Override // BundleEventListener
+    public void handleMessage(final String event, final GeckoBundle message,
+                              final EventCallback callback) {
+        if ("FindInPage:MatchesCountResult".equals(event)) {
+            onMatchesCountResult(message.getInt("total", 0),
+                message.getInt("current", 0),
+                message.getInt("limit", 0),
+                message.getString("searchString"));
             return;
         }
+    }
 
-        if (!event.equals("TextSelection:Data") || !REQUEST_ID.equals(message.optString("requestId"))) {
-            return;
-        }
-
-        final String text = message.optString("text");
-
+    /* package */ void onTextSelectionData(final String text) {
         // Populate an initial find string, virtual keyboard not required.
         if (!TextUtils.isEmpty(text)) {
             // Populate initial selection
-            ThreadUtils.postToUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    mFindText.setText(text);
-                }
-            });
+            mFindText.setText(text);
             return;
         }
 
         // Show the virtual keyboard.
         if (mFindText.hasWindowFocus()) {
             getInputMethodManager(mFindText).showSoftInput(mFindText, 0);
         } else {
             // showSoftInput won't work until after the window is focused.
@@ -232,25 +227,13 @@ public class FindInPageBar extends Linea
             });
         }
     }
 
     /**
      * Request find operation, and update matchCount results (current count and total).
      */
     private void sendRequestToFinderHelper(final String request, final String searchString) {
-        GeckoAppShell.sendRequestToGecko(new GeckoRequest(request, searchString) {
-            @Override
-            public void onResponse(NativeJSObject nativeJSObject) {
-                // We don't care about the return value, because `onMatchesCountResult`
-                // does the heavy lifting.
-            }
-
-            @Override
-            public void onError(NativeJSObject error) {
-                // Gecko didn't respond due to state change, javascript error, etc.
-                Log.d(LOGTAG, "No response from Gecko on request to match string: [" +
-                    searchString + "]");
-                updateResult("");
-            }
-        });
+        final GeckoBundle data = new GeckoBundle(1);
+        data.putString("searchString", searchString);
+        EventDispatcher.getInstance().dispatch(request, data);
     }
 }
--- a/mobile/android/chrome/content/FindHelper.js
+++ b/mobile/android/chrome/content/FindHelper.js
@@ -7,49 +7,63 @@ var FindHelper = {
   _finder: null,
   _targetTab: null,
   _initialViewport: null,
   _viewportChanged: false,
   _result: null,
 
   // Start of nsIObserver implementation.
 
-  observe: function(aMessage, aTopic, aData) {
-    switch(aTopic) {
+  onEvent: function(event, data, callback) {
+    switch (event) {
       case "FindInPage:Opened": {
         this._findOpened();
         break;
       }
 
-      case "FindInPage:Closed":
+      case "FindInPage:Closed": {
         this._uninit();
         this._findClosed();
         break;
-    }
-  },
+      }
 
-  onEvent: function(event, message, callback) {
-    switch (event) {
       case "Tab:Selected": {
         // Allow for page switching.
         this._uninit();
         break;
       }
+
+      case "FindInPage:Find": {
+        this.doFind(data.searchString);
+        break;
+      }
+
+      case "FindInPage:Next": {
+        this.findAgain(data.searchString, false);
+        break;
+      }
+
+      case "FindInPage:Prev": {
+        this.findAgain(data.searchString, true);
+        break;
+      }
     }
   },
 
   /**
    * When the FindInPageBar opens/ becomes visible, it's time to:
    * 1. Add listeners for other message types sent from the FindInPageBar
    * 2. initialize the Finder instance, if necessary.
    */
   _findOpened: function() {
-    Messaging.addListener(data => this.doFind(data), "FindInPage:Find");
-    Messaging.addListener(data => this.findAgain(data, false), "FindInPage:Next");
-    Messaging.addListener(data => this.findAgain(data, true), "FindInPage:Prev");
+    GlobalEventDispatcher.registerListener(this, [
+      "FindInPage:Find",
+      "FindInPage:Next",
+      "FindInPage:Prev",
+    ]);
 
     // Initialize the finder component for the current page by performing a fake find.
     this._init();
     this._finder.requestMatchesCount("");
   },
 
   /**
    * Fetch the Finder instance from the active tabs' browser and start tracking
@@ -99,19 +113,21 @@ var FindHelper = {
       "Tab:Selected",
     ]);
   },
 
   /**
    * When the FindInPageBar closes, it's time to stop listening for its messages.
    */
   _findClosed: function() {
-    Messaging.removeListener("FindInPage:Find");
-    Messaging.removeListener("FindInPage:Next");
-    Messaging.removeListener("FindInPage:Prev");
+    GlobalEventDispatcher.unregisterListener(this, [
+      "FindInPage:Find",
+      "FindInPage:Next",
+      "FindInPage:Prev",
+    ]);
   },
 
   /**
    * Start an asynchronous find-in-page operation, using the current Finder
    * instance and request to count the amount of matches.
    * If no Finder instance is currently active, we'll lazily initialize it here.
    *
    * @param  {String} searchString Word to search for in the current document
@@ -157,17 +173,17 @@ var FindHelper = {
    *                        the following properties:
    *                        - {Number} total   The total amount of matches found
    *                        - {Number} current The index of current found range
    *                                           in the document
    */
   onMatchesCountResult: function(result) {
     this._result = result;
 
-    Messaging.sendRequest(Object.assign({
+    GlobalEventDispatcher.sendRequest(Object.assign({
       type: "FindInPage:MatchesCountResult"
     }, this._result));
   },
 
   /**
    * When a find-in-page action finishes, this method is invoked. This is mainly
    * used at the moment to detect if the current viewport has changed, which might
    * be indicated by not finding a string in the current page.
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -150,17 +150,16 @@ lazilyLoadedBrowserScripts.forEach(funct
     Services.scriptloader.loadSubScript(script, sandbox);
     return sandbox[name];
   });
 });
 
 var lazilyLoadedObserverScripts = [
   ["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"],
   ["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"],
-  ["FindHelper", ["FindInPage:Opened", "FindInPage:Closed"], "chrome://browser/content/FindHelper.js"],
   ["PermissionsHelper", ["Permissions:Check", "Permissions:Get", "Permissions:Clear"], "chrome://browser/content/PermissionsHelper.js"],
   ["FeedHandler", ["Feeds:Subscribe"], "chrome://browser/content/FeedHandler.js"],
   ["Feedback", ["Feedback:Show"], "chrome://browser/content/Feedback.js"],
   ["EmbedRT", ["GeckoView:ImportScript"], "chrome://browser/content/EmbedRT.js"],
   ["Reader", ["Reader:AddToCache", "Reader:RemoveFromCache"], "chrome://browser/content/Reader.js"],
   ["PrintHelper", ["Print:PDF"], "chrome://browser/content/PrintHelper.js"],
 ];
 
@@ -249,16 +248,19 @@ lazilyLoadedObserverScripts.forEach(func
   });
 });
 
 // Lazily-loaded JS subscripts that use global/window EventDispatcher.
 [
   ["ActionBarHandler", WindowEventDispatcher,
    ["TextSelection:Get", "TextSelection:Action", "TextSelection:End"],
    "chrome://browser/content/ActionBarHandler.js"],
+  ["FindHelper", GlobalEventDispatcher,
+   ["FindInPage:Opened", "FindInPage:Closed"],
+   "chrome://browser/content/FindHelper.js"],
 ].forEach(module => {
   let [name, dispatcher, events, script] = module;
   XPCOMUtils.defineLazyGetter(window, name, function() {
     let sandbox = {};
     Services.scriptloader.loadSubScript(script, sandbox);
     return sandbox[name];
   });
   let listener = (event, message, callback) => {