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 110583 357778ffa80165c04d0b71ab284fa300c870df51
parent 110582 af98d67916ada9ff478f4f321a2a8460d31f2d7e
child 110584 d896a7f47e02184fa2693ad72641608bad716767
push id23700
push userryanvm@gmail.com
push dateThu, 18 Oct 2012 02:10:26 +0000
treeherdermozilla-central@5142bbd4da12 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs801573
milestone19.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 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 });