Bug 801573 - [Web Activities] Need to notify SystemMessageInternal when the app's registration restarts to avoid sending system messages to deprecated pages. r=fabrice
authorGene Lian <clian@mozilla.com>
Wed, 17 Oct 2012 12:30:43 +0800
changeset 110715 357778ffa80165c04d0b71ab284fa300c870df51
parent 110714 af98d67916ada9ff478f4f321a2a8460d31f2d7e
child 110716 d896a7f47e02184fa2693ad72641608bad716767
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersfabrice
bugs801573
milestone19.0a1
Bug 801573 - [Web Activities] Need to notify SystemMessageInternal when the app's registration restarts to avoid sending system messages to deprecated pages. r=fabrice
b2g/chrome/content/shell.js
dom/apps/src/Webapps.jsm
dom/messages/SystemMessageInternal.js
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -493,16 +493,20 @@ Services.obs.addObserver(function onSyst
   shell.sendSystemMessage(msg);
 }, 'system-messages-open-app', false);
 
 Services.obs.addObserver(function(aSubject, aTopic, aData) {
   shell.sendChromeEvent({ type: "fullscreenoriginchange",
                           fullscreenorigin: aData });
 }, "fullscreen-origin-change", false);
 
+Services.obs.addObserver(function onWebappsStart(subject, topic, data) {
+  shell.sendChromeEvent({ type: 'webapps-registry-start' });
+}, 'webapps-registry-start', false);
+
 Services.obs.addObserver(function onWebappsReady(subject, topic, data) {
   shell.sendChromeEvent({ type: 'webapps-registry-ready' });
 }, 'webapps-registry-ready', false);
 
 Services.obs.addObserver(function onBluetoothVolumeChange(subject, topic, data) {
   if (data == 'up') {
     shell.sendChromeEvent({ type: 'volume-up-button-press' });
     shell.sendChromeEvent({ type: 'volume-up-button-release' });
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -119,34 +119,39 @@ let DOMApplicationRegistry = {
         }
         aNext();
       }).bind(this));
     } else {
       aNext();
     }
   },
 
-  // We are done with loading and initializing. Notify and
-  // save a copy of the registry.
-  onInitDone: function onInitDone() {
+  // Notify we are starting with registering apps.
+  notifyAppsRegistryStart: function notifyAppsRegistryStart() {
+    Services.obs.notifyObservers(this, "webapps-registry-start", null);
+  },
+
+  // Notify we are done with registering apps and save a copy of the registry.
+  notifyAppsRegistryReady: function notifyAppsRegistryReady() {
     Services.obs.notifyObservers(this, "webapps-registry-ready", null);
     this._saveApps();
   },
 
-  // registers all the activities and system messages
+  // Registers all the activities and system messages.
   registerAppsHandlers: function registerAppsHandlers() {
+    this.notifyAppsRegistryStart();
 #ifdef MOZ_SYS_MSG
     let ids = [];
     for (let id in this.webapps) {
       ids.push({ id: id });
     }
     this._processManifestForIds(ids);
 #else
     // Nothing else to do but notifying we're ready.
-    this.onInitDone();
+    this.notifyAppsRegistryReady();
 #endif
   },
 
   updatePermissionsForApp: function updatePermissionsForApp(aId) {
     // Install the permissions for this app, as if we were updating
     // to cleanup the old ones if needed.
     this._readManifests([{ id: aId }], (function(aResult) {
       let data = aResult[0];
@@ -243,17 +248,16 @@ let DOMApplicationRegistry = {
       }
     }
     this.registerAppsHandlers();
 #endif
     }).bind(this));
   },
 
 #ifdef MOZ_SYS_MSG
-
   // aEntryPoint is either the entry_point name or the null, in which case we
   // use the root of the manifest.
   _registerSystemMessagesForEntryPoint: function(aManifest, aApp, aEntryPoint) {
     let root = aManifest;
     if (aEntryPoint && aManifest.entry_points[aEntryPoint]) {
       root = aManifest.entry_points[aEntryPoint];
     }
 
@@ -365,20 +369,24 @@ let DOMApplicationRegistry = {
       return;
     }
 
     for (let entryPoint in aManifest.entry_points) {
       this._unregisterActivitiesForEntryPoint(aManifest, aApp, entryPoint);
     }
   },
 
-  _processManifestForIds: function(aIds) {
+  _initRegisterActivities: function() {
     this.activitiesToRegister = 0;
     this.activitiesRegistered = 0;
     this.allActivitiesSent = false;
+  },
+
+  _processManifestForIds: function(aIds) {
+    this._initRegisterActivities();
     this._readManifests(aIds, (function registerManifests(aResults) {
       aResults.forEach(function registerManifest(aResult) {
         let app = this.webapps[aResult.id];
         let manifest = aResult.manifest;
         app.name = manifest.name;
         this._registerSystemMessages(manifest, app);
         this._registerActivities(manifest, app);
       }, this);
@@ -535,17 +543,17 @@ let DOMApplicationRegistry = {
         break;
       case "Webapps::ApplyDownload":
         this.ApplyDownload(msg.manifestURL);
         break;
       case "Activities:Register:OK":
         this.activitiesRegistered++;
         if (this.allActivitiesSent &&
             this.activitiesRegistered === this.activitiesToRegister) {
-          this.onInitDone();
+          this.notifyAppsRegistryReady();
         }
         break;
       case "child-process-shutdown":
         this.removeMessageListener(mm);
         break;
     }
   },
 
@@ -770,23 +778,29 @@ let DOMApplicationRegistry = {
         aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:OK", aData);
       });
     }
 
     function updateHostedApp(aManifest) {
       debug("updateHostedApp");
       let id = this._appId(app.origin);
 
+      // Update the web apps' registration.
+      this.notifyAppsRegistryStart();
 #ifdef MOZ_SYS_MSG
-      // Update the Web Activities
+      this._initRegisterActivities();
       this._readManifests([{ id: id }], (function unregisterManifest(aResult) {
         this._unregisterActivities(aResult[0].manifest, app);
         this._registerSystemMessages(aManifest, app);
         this._registerActivities(aManifest, app);
+        this.allActivitiesSent = true;
       }).bind(this));
+#else
+      // Nothing else to do but notifying we're ready.
+      this.notifyAppsRegistryReady();
 #endif
 
       // Store the new manifest.
       let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
       let manFile = dir.clone();
       manFile.append("manifest.webapp");
       this._writeFile(manFile, JSON.stringify(aManifest), function() { });
 
@@ -977,22 +991,28 @@ let DOMApplicationRegistry = {
 
     if (!aFromSync)
       this._saveApps((function() {
         this.broadcastMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
         this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
       }).bind(this));
 
+    if (!aData.isPackage) {
+      this.notifyAppsRegistryStart();
 #ifdef MOZ_SYS_MSG
-    if (!aData.isPackage) {
+      this._initRegisterActivities();
       this._registerSystemMessages(app.manifest, app);
       this._registerActivities(app.manifest, app);
+      this.allActivitiesSent = true;
+#else
+      // Nothing else to do but notifying we're ready.
+      this.notifyAppsRegistryReady();
+#endif
     }
-#endif
 
     this.startOfflineCacheDownload(manifest, appObject, aProfileDir, aOfflineCacheObserver);
     if (manifest.package_path) {
       // origin for install apps is meaningless here, since it's app:// and this
       // can't be used to resolve package paths.
       manifest = new ManifestHelper(jsonManifest, app.manifestURL);
       this.downloadPackage(manifest, appObject, false, function(aId, aManifest) {
         // Success! Move the zip out of TmpD.
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -46,16 +46,17 @@ function SystemMessageInternal() {
   // 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-start", false);
   Services.obs.addObserver(this, "webapps-registry-ready", false);
   kMessages.forEach(function(aMsg) {
     ppmm.addMessageListener(aMsg, this);
   }, this);
 
   Services.obs.notifyObservers(this, "system-message-internal-ready", null);
 }
 
@@ -231,37 +232,41 @@ SystemMessageInternal.prototype = {
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "xpcom-shutdown":
         kMessages.forEach(function(aMsg) {
           ppmm.removeMessageListener(aMsg, this);
         }, this);
         Services.obs.removeObserver(this, "xpcom-shutdown");
+        Services.obs.removeObserver(this, "webapps-registry-start");
         Services.obs.removeObserver(this, "webapps-registry-ready");
         ppmm = null;
         this._pages = null;
         this._bufferedSysMsgs = null;
         break;
+      case "webapps-registry-start":
+        this._webappsRegistryReady = false;
+        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;
           }
         }, this);
-        this._bufferedSysMsgs = null;
+        this._bufferedSysMsgs.length = 0;
         break;
     }
   },
 
   _openAppPage: function _openAppPage(aPage, aMessage, aMessageID) {
     // Queue the message for this page because we've never known if an app is
     // opened or not. We'll clean it up when the app has already received it.
     aPage.pendingMessages.push({ msg: aMessage, msgID: aMessageID });