Bug 1330439 - 2. Convert HomeBanner events to bundle events; r=sebastian
authorJim Chen <nchen@mozilla.com>
Wed, 25 Jan 2017 18:53:58 -0500
changeset 466661 bf42119cf8af9501275c0ab54890c02b60115a22
parent 466660 d3c8b390c953ac092935591d83eaa20fe3b41a33
child 466662 904d17b3ff1e65af007e338f54c797ba0802103b
push id42948
push userbmo:gasolin@mozilla.com
push dateThu, 26 Jan 2017 07:49:21 +0000
reviewerssebastian
bugs1330439
milestone54.0a1
Bug 1330439 - 2. Convert HomeBanner events to bundle events; r=sebastian Convert the events in HomeBanner to bundle events. "HomeBanner:Shown" is removed in favor of using a callback.
mobile/android/base/java/org/mozilla/gecko/home/HomeBanner.java
mobile/android/modules/Home.jsm
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeBanner.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeBanner.java
@@ -1,42 +1,43 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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.home;
 
-import org.json.JSONObject;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.animation.PropertyAnimator;
 import org.mozilla.gecko.animation.PropertyAnimator.Property;
 import org.mozilla.gecko.animation.ViewHelper;
 import org.mozilla.gecko.util.FloatUtils;
 import org.mozilla.gecko.util.ResourceDrawableUtils;
-import org.mozilla.gecko.util.GeckoEventListener;
+import org.mozilla.gecko.util.BundleEventListener;
+import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.widget.EllipsisTextView;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.text.Html;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
 public class HomeBanner extends LinearLayout
-                        implements GeckoEventListener {
+                        implements BundleEventListener {
     private static final String LOGTAG = "GeckoHomeBanner";
 
     // Used for tracking scroll length
     private float mTouchY = -1;
 
     // Used to detect for upwards scroll to push banner all the way up
     private boolean mSnapBannerToTop;
 
@@ -95,38 +96,43 @@ public class HomeBanner extends LinearLa
         closeButton.getDrawable().setAlpha(127);
 
         closeButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 HomeBanner.this.dismiss();
 
                 // Send the current message id back to JS.
-                GeckoAppShell.notifyObservers("HomeBanner:Dismiss", (String) getTag());
+                final GeckoBundle data = new GeckoBundle(1);
+                data.putString("id", (String) getTag());
+                EventDispatcher.getInstance().dispatch("HomeBanner:Dismiss", data);
             }
         });
 
         setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 HomeBanner.this.dismiss();
 
                 // Send the current message id back to JS.
-                GeckoAppShell.notifyObservers("HomeBanner:Click", (String) getTag());
+                final GeckoBundle data = new GeckoBundle(1);
+                data.putString("id", (String) getTag());
+                EventDispatcher.getInstance().dispatch("HomeBanner:Click", data);
             }
         });
 
-        EventDispatcher.getInstance().registerGeckoThreadListener(this, "HomeBanner:Data");
+        // Update the banner message on the UI thread.
+        EventDispatcher.getInstance().registerUiThreadListener(this, "HomeBanner:Data");
     }
 
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
-        EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "HomeBanner:Data");
+        EventDispatcher.getInstance().unregisterUiThreadListener(this, "HomeBanner:Data");
     }
 
     public void setScrollingPages(boolean scrollingPages) {
         mScrollingPages = scrollingPages;
     }
 
     public void setOnDismissListener(OnDismissListener listener) {
         mOnDismissListener = listener;
@@ -146,59 +152,54 @@ public class HomeBanner extends LinearLa
 
     /**
      * Sends a message to gecko to request a new banner message. UI is updated in handleMessage.
      */
     public void update() {
         GeckoAppShell.notifyObservers("HomeBanner:Get", null);
     }
 
-    @Override
-    public void handleMessage(String event, JSONObject message) {
-        final String id = message.optString("id");
-        final String text = message.optString("text");
-        final String iconURI = message.optString("iconURI");
+    @Override // BundleEventListener
+    public void handleMessage(final String event, final GeckoBundle message,
+                              final EventCallback callback) {
+        final String id = message.getString("id");
+        final String text = message.getString("text");
+        final String iconURI = message.getString("iconURI");
 
         // Don't update the banner if the message doesn't have valid id and text.
         if (TextUtils.isEmpty(id) || TextUtils.isEmpty(text)) {
             return;
         }
 
-        // Update the banner message on the UI thread.
-        ThreadUtils.postToUiThread(new Runnable() {
-            @Override
-            public void run() {
-                // Store the current message id to pass back to JS in the view's OnClickListener.
-                setTag(id);
-                mTextView.setOriginalText(Html.fromHtml(text));
+        // Store the current message id to pass back to JS in the view's OnClickListener.
+        setTag(id);
+        mTextView.setOriginalText(Html.fromHtml(text));
 
-                ResourceDrawableUtils.getDrawable(getContext(), iconURI, new ResourceDrawableUtils.BitmapLoader() {
-                    @Override
-                    public void onBitmapFound(final Drawable d) {
-                        // Hide the image view if we don't have an icon to show.
-                        if (d == null) {
-                            mIconView.setVisibility(View.GONE);
-                        } else {
-                            mIconView.setImageDrawable(d);
-                            mIconView.setVisibility(View.VISIBLE);
-                        }
-                    }
-                });
-
-                GeckoAppShell.notifyObservers("HomeBanner:Shown", id);
-
-                // Enable the banner after a message is set.
-                setEnabled(true);
-
-                // Animate the banner if it is currently active.
-                if (mActive) {
-                    animateUp();
+        ResourceDrawableUtils.getDrawable(getContext(), iconURI, new ResourceDrawableUtils.BitmapLoader() {
+            @Override
+            public void onBitmapFound(final Drawable d) {
+                // Hide the image view if we don't have an icon to show.
+                if (d == null) {
+                    mIconView.setVisibility(View.GONE);
+                } else {
+                    mIconView.setImageDrawable(d);
+                    mIconView.setVisibility(View.VISIBLE);
                 }
             }
         });
+
+        callback.sendSuccess(id);
+
+        // Enable the banner after a message is set.
+        setEnabled(true);
+
+        // Animate the banner if it is currently active.
+        if (mActive) {
+            animateUp();
+        }
     }
 
     public void setActive(boolean active) {
         // No need to animate if not changing
         if (mActive == active) {
             return;
         }
 
--- a/mobile/android/modules/Home.jsm
+++ b/mobile/android/modules/Home.jsm
@@ -89,22 +89,22 @@ var HomeBanner = (function () {
       totalWeight += message.weight;
       message.totalWeight = totalWeight;
     }
 
     let threshold = Math.random() * totalWeight;
     for (let key in _messages) {
       let message = _messages[key];
       if (threshold < message.totalWeight) {
-        Messaging.sendRequest({
+        EventDispatcher.instance.sendRequestForResult({
           type: "HomeBanner:Data",
           id: message.id,
           text: message.text,
           iconURI: message.iconURI
-        });
+        }).then(id => _handleShown(id));
         return;
       }
     }
   };
 
   let _handleShown = function(id) {
     let message = _messages[id];
     if (message.onshown)
@@ -119,47 +119,44 @@ var HomeBanner = (function () {
 
   let _handleDismiss = function(id) {
     let message = _messages[id];
     if (message.ondismiss)
       message.ondismiss();
   };
 
   return Object.freeze({
-    observe: function(subject, topic, data) {
+    onEvent: function(event, message, callback) {
       switch(topic) {
-        case "HomeBanner:Shown":
-          _handleShown(data);
-          break;
-
         case "HomeBanner:Click":
-          _handleClick(data);
+          _handleClick(message.id);
           break;
 
         case "HomeBanner:Dismiss":
-          _handleDismiss(data);
+          _handleDismiss(message.id);
           break;
       }
     },
 
     /**
      * Adds a new banner message to the rotation.
      *
      * @return id Unique identifer for the message.
      */
     add: function(options) {
       let message = new BannerMessage(options);
       _messages[message.id] = message;
 
       // If this is the first message we're adding, add
       // observers to listen for requests from the Java UI.
       if (Object.keys(_messages).length == 1) {
-        Services.obs.addObserver(this, "HomeBanner:Shown", false);
-        Services.obs.addObserver(this, "HomeBanner:Click", false);
-        Services.obs.addObserver(this, "HomeBanner:Dismiss", false);
+        EventDispatcher.instance.registerListener(this, [
+          "HomeBanner:Click",
+          "HomeBanner:Dismiss",
+        ]);
 
         // Send a message to Java if there's a pending "HomeBanner:Get" request.
         if (_pendingRequest) {
           _pendingRequest = false;
           _sendBannerData();
         }
       }
 
@@ -175,19 +172,20 @@ var HomeBanner = (function () {
       if (!(id in _messages)) {
         throw "Home.banner: Can't remove message that doesn't exist: id = " + id;
       }
 
       delete _messages[id];
 
       // If there are no more messages, remove the observers.
       if (Object.keys(_messages).length == 0) {
-        Services.obs.removeObserver(this, "HomeBanner:Shown");
-        Services.obs.removeObserver(this, "HomeBanner:Click");
-        Services.obs.removeObserver(this, "HomeBanner:Dismiss");
+        EventDispatcher.instance.unregisterListener(this, [
+          "HomeBanner:Click",
+          "HomeBanner:Dismiss",
+        ]);
       }
     }
   });
 })();
 
 // We need this object to have access to the HomePanels
 // private members without leaking it outside Home.jsm.
 var HomePanelsMessageHandlers;