Bug 795209 - System Message API: Fail to fire 'icc-stkcommand' system messages. r=fabrice
authorGene Lian <clian@mozilla.com>
Tue, 02 Oct 2012 13:03:59 +0800
changeset 108980 97362b531a38ba6a134d70a567b499d5267d75fb
parent 108979 7f3d9233b236a347174bb6f917f288fd571609ea
child 108981 80f9522602c512e4308a44d7cddbe3147b8e24b4
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersfabrice
bugs795209
milestone18.0a1
Bug 795209 - System Message API: Fail to fire 'icc-stkcommand' system messages. r=fabrice
dom/messages/SystemMessageInternal.js
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -35,24 +35,40 @@ function debug(aMsg) {
 
 // Implementation of the component used by internal users.
 
 function SystemMessageInternal() {
   // The set of pages registered by installed apps. We keep the
   // list of pending messages for each page here also.
   this._pages = [];
   this._listeners = {};
+
+  this._webappsRegistryReady = false;
+  this._bufferedSysMsgs = [];
+
   Services.obs.addObserver(this, "xpcom-shutdown", false);
+  Services.obs.addObserver(this, "webapps-registry-ready", false);
   kMessages.forEach((function(aMsg) {
     ppmm.addMessageListener(aMsg, this);
   }).bind(this));
 }
 
 SystemMessageInternal.prototype = {
   sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) {
+    // Buffer system messages until the webapps' registration is ready,
+    // so that we can know the correct pages registered to be sent.
+    if (!this._webappsRegistryReady) {
+      this._bufferedSysMsgs.push({ how: "send",
+                                   type: aType,
+                                   msg: aMessage,
+                                   pageURI: aPageURI,
+                                   manifestURI: aManifestURI });
+      return;
+    }
+
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     if (this._listeners[aManifestURI.spec]) {
       this._listeners[aManifestURI.spec].forEach(function sendMsg(aListener) {
         aListener.sendAsyncMessage("SystemMessageManager:Message",
                                    { type: aType,
                                      msg: aMessage,
                                      manifest: aManifestURI.spec })
       });
@@ -65,16 +81,25 @@ SystemMessageInternal.prototype = {
         return;
       }
 
       this._processPage(aPage, aMessage);
     }.bind(this))
   },
 
   broadcastMessage: function broadcastMessage(aType, aMessage) {
+    // Buffer system messages until the webapps' registration is ready,
+    // so that we can know the correct pages registered to be broadcasted.
+    if (!this._webappsRegistryReady) {
+      this._bufferedSysMsgs.push({ how: "broadcast",
+                                   type: aType,
+                                   msg: aMessage });
+      return;
+    }
+
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     // Find pages that registered an handler for this type.
     this._pages.forEach(function(aPage) {
       if (aPage.type == aType) {
         if (this._listeners[aPage.manifest]) {
           this._listeners[aPage.manifest].forEach(function sendMsg(aListener) {
             aListener.sendAsyncMessage("SystemMessageManager:Message",
                                        { type: aType,
@@ -147,23 +172,44 @@ SystemMessageInternal.prototype = {
         page.pending = [];
 
         return pending;
         break;
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
-    if (aTopic == "xpcom-shutdown") {
-      kMessages.forEach((function(aMsg) {
-        ppmm.removeMessageListener(aMsg, this);
-      }).bind(this));
-      Services.obs.removeObserver(this, "xpcom-shutdown");
-      ppmm = null;
-      this._pages = null;
+    switch (aTopic) {
+      case "xpcom-shutdown":
+        kMessages.forEach((function(aMsg) {
+          ppmm.removeMessageListener(aMsg, this);
+        }).bind(this));
+        Services.obs.removeObserver(this, "xpcom-shutdown");
+        Services.obs.removeObserver(this, "webapps-registry-ready");
+        ppmm = null;
+        this._pages = null;
+        this._bufferedSysMsgs = null;
+        break;
+      case "webapps-registry-ready":
+        // After the webapps' registration has been done for sure,
+        // re-fire the buffered system messages if there is any.
+        this._webappsRegistryReady = true;
+        this._bufferedSysMsgs.forEach((function(aSysMsg) {
+          switch (aSysMsg.how) {
+            case "send":
+              this.sendMessage(
+                aSysMsg.type, aSysMsg.msg, aSysMsg.pageURI, aSysMsg.manifestURI);
+              break;
+            case "broadcast":
+              this.broadcastMessage(aSysMsg.type, aSysMsg.msg);
+              break;
+          }
+        }).bind(this));
+        this._bufferedSysMsgs = null;
+        break;
     }
   },
 
   _processPage: function _processPage(aPage, aMessage) {
     // Queue the message for the page.
     aPage.pending.push(aMessage);
     if (aPage.pending.length > kMaxPendingMessages) {
       aPage.pending.splice(0, 1);