Bug 993666 - Keep track of whether or not to send banner message to Java when a banner is added. r=bnicholson, a=bkerensa
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Tue, 15 Apr 2014 10:03:03 -0700
changeset 193065 d41c02af37a6c941a5896ed8f274152b6ac6cb83
parent 193064 684a7c304b762b89712dd48ab1c0c6b55d257afb
child 193066 4f4f58855f42debe08d901d10a435a36a53e881c
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson, bkerensa
bugs993666
milestone30.0a2
Bug 993666 - Keep track of whether or not to send banner message to Java when a banner is added. r=bnicholson, a=bkerensa
mobile/android/chrome/content/browser.js
mobile/android/modules/Home.jsm
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -126,17 +126,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
     Services.obs.addObserver(function(s, t, d) {
         window[name].observe(s, t, d)
     }, aNotification, false);
   });
 });
 
 // Lazily-loaded JS modules that use observer notifications
 [
-  ["Home", ["HomePanels:Get", "HomePanels:Installed", "HomePanels:Uninstalled"], "resource://gre/modules/Home.jsm"],
+  ["Home", ["HomeBanner:Get", "HomePanels:Get", "HomePanels:Installed", "HomePanels:Uninstalled"], "resource://gre/modules/Home.jsm"],
 ].forEach(module => {
   let [name, notifications, resource] = module;
   XPCOMUtils.defineLazyModuleGetter(this, name, resource);
   notifications.forEach(notification => {
     Services.obs.addObserver((s,t,d) => {
       this[name].observe(s,t,d)
     }, notification, false);
   });
--- a/mobile/android/modules/Home.jsm
+++ b/mobile/android/modules/Home.jsm
@@ -43,33 +43,53 @@ function BannerMessage(options) {
 
   if ("onclick" in options && typeof options.onclick === "function")
     this.onclick = options.onclick;
 
   if ("ondismiss" in options && typeof options.ondismiss === "function")
     this.ondismiss = options.ondismiss;
 }
 
+// We need this object to have access to the HomeBanner
+// private members without leaking it outside Home.jsm.
+let HomeBannerMessageHandlers;
+
 let HomeBanner = (function () {
+  // Whether there is a "HomeBanner:Get" request we couldn't fulfill.
+  let _pendingRequest = false;
+
+  // Functions used to handle messages sent from Java.
+  HomeBannerMessageHandlers = {
+    "HomeBanner:Get": function handleBannerGet(data) {
+      if (!_sendBannerData()) {
+        _pendingRequest = true;
+      }
+    }
+  };
+
   // Holds the messages that will rotate through the banner.
   let _messages = {};
 
+  let _sendBannerData = function() {
+    let keys = Object.keys(_messages);
+    if (!keys.length) {
+      return false;
+    }
 
-  let _handleGet = function() {
     // Choose a message at random.
-    let keys = Object.keys(_messages);
     let randomId = keys[Math.floor(Math.random() * keys.length)];
     let message = _messages[randomId];
 
     sendMessageToJava({
       type: "HomeBanner:Data",
       id: message.id,
       text: message.text,
       iconURI: message.iconURI
     });
+    return true;
   };
 
   let _handleShown = function(id) {
     let message = _messages[id];
     if (message.onshown)
       message.onshown();
   };
 
@@ -83,20 +103,16 @@ let HomeBanner = (function () {
     let message = _messages[id];
     if (message.ondismiss)
       message.ondismiss();
   };
 
   return Object.freeze({
     observe: function(subject, topic, data) {
       switch(topic) {
-        case "HomeBanner:Get":
-          _handleGet();
-          break;
-
         case "HomeBanner:Shown":
           _handleShown(data);
           break;
 
         case "HomeBanner:Click":
           _handleClick(data);
           break;
 
@@ -113,24 +129,25 @@ let HomeBanner = (function () {
      */
     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:Get", false);
         Services.obs.addObserver(this, "HomeBanner:Shown", false);
         Services.obs.addObserver(this, "HomeBanner:Click", false);
         Services.obs.addObserver(this, "HomeBanner:Dismiss", false);
 
-        // Send a message to Java, in case there's an active HomeBanner
-        // waiting for a response.
-        _handleGet();
+        // Send a message to Java if there's a pending "HomeBanner:Get" request.
+        if (_pendingRequest) {
+          _pendingRequest = false;
+          _sendBannerData();
+        }
       }
 
       return message.id;
     },
 
     /**
      * Removes a banner message from the rotation.
      *
@@ -140,17 +157,16 @@ let 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:Get");
         Services.obs.removeObserver(this, "HomeBanner:Shown");
         Services.obs.removeObserver(this, "HomeBanner:Click");
         Services.obs.removeObserver(this, "HomeBanner:Dismiss");
       }
     }
   });
 })();
 
@@ -370,15 +386,17 @@ let HomePanels = (function () {
 
 // Public API
 this.Home = Object.freeze({
   banner: HomeBanner,
   panels: HomePanels,
 
   // Lazy notification observer registered in browser.js
   observe: function(subject, topic, data) {
-    if (topic in HomePanelsMessageHandlers) {
+    if (topic in HomeBannerMessageHandlers) {
+      HomeBannerMessageHandlers[topic](data);
+    } else if (topic in HomePanelsMessageHandlers) {
       HomePanelsMessageHandlers[topic](data);
     } else {
       Cu.reportError("Home.observe: message handler not found for topic: " + topic);
     }
   }
 });