Bug 1081143 - datastore-update-* events should be dispatched as broadcast messages, r=fabrice
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 20 Oct 2014 20:47:12 +0100
changeset 235669 0660519a81b7d5c02096ed044d85c8f3a2487cd8
parent 235668 9a425c40daaeb7e00f540702715d2a022143ffee
child 235670 9cea2a5955d7a9757ee19dce3ffcfe9824286d3e
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs1081143
milestone36.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 1081143 - datastore-update-* events should be dispatched as broadcast messages, r=fabrice
dom/datastore/DataStoreChangeNotifier.jsm
dom/messages/SystemMessagePermissionsChecker.jsm
--- a/dom/datastore/DataStoreChangeNotifier.jsm
+++ b/dom/datastore/DataStoreChangeNotifier.jsm
@@ -100,30 +100,18 @@ this.DataStoreChangeNotifier = {
       delete this.sysMsgOnChangeShortTimers[storeKey];
     }
     var longTimer = this.sysMsgOnChangeLongTimers[storeKey];
     if (longTimer) {
       longTimer.cancel();
       delete this.sysMsgOnChangeLongTimers[storeKey];
     }
 
-    // Get all the manifest URLs of the apps which can access the datastore.
-    var manifestURLs = dataStoreService.getAppManifestURLsForDataStore(aStore);
-    var enumerate = manifestURLs.enumerate();
-    while (enumerate.hasMoreElements()) {
-      var manifestURL = enumerate.getNext().QueryInterface(Ci.nsISupportsString);
-      debug("Notify app " + manifestURL + " of datastore updates");
-      // Send the system message 'datastore-update-{store name}' to all the
-      // pages for these apps. With the manifest URL of the owner in the message
-      // payload, it notifies the consumer a sync operation should be performed.
-      systemMessenger.sendMessage("datastore-update-" + aStore,
-                                  { owner: aOwner },
-                                  null,
-                                  Services.io.newURI(manifestURL, null, null));
-    }
+    systemMessenger.broadcastMessage("datastore-update-" + aStore,
+                                     { owner: aOwner });
   },
 
   // Use the following logic to broadcast system messages in a moderate pattern.
   // 1. When an entry is changed, start a short timer and a long timer.
   // 2. If an entry is changed while the short timer is running, reset it.
   //    Do not reset the long timer.
   // 3. Once either fires, broadcast the system message and cancel both timers.
   setSystemMessageTimeout: function(aStore, aOwner) {
--- a/dom/messages/SystemMessagePermissionsChecker.jsm
+++ b/dom/messages/SystemMessagePermissionsChecker.jsm
@@ -9,19 +9,22 @@ const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
 Cu.import("resource://gre/modules/PermissionsTable.jsm");
 Cu.import("resource://gre/modules/PermissionSettings.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
+                                   "@mozilla.org/datastore-service;1",
+                                   "nsIDataStoreService");
+
 this.EXPORTED_SYMBOLS = ["SystemMessagePermissionsChecker",
-                         "SystemMessagePermissionsTable",
-                         "SystemMessagePrefixPermissionsTable"];
+                         "SystemMessagePermissionsTable"];
 
 function debug(aStr) {
   // dump("SystemMessagePermissionsChecker.jsm: " + aStr + "\n");
 }
 
 // This table maps system message to permission(s), indicating only
 // the system messages granted by the page's permissions are allowed
 // to be registered or sent to that page. Note the empty permission
@@ -124,27 +127,16 @@ this.SystemMessagePermissionsTable = {
     "settings": ["read", "write"]
   },
   "wifip2p-pairing-request": { },
   "first-run-with-sim": {
     "settings": ["read", "write"]
   }
 };
 
-// This table maps system message prefix to permission(s), indicating only
-// the system messages with specified prefixes granted by the page's permissions
-// are allowed to be registered or sent to that page. Note the empty permission
-// set means this type of system message is always permitted.
-//
-// Note that this table is only used when the permission checker can't find a
-// match in SystemMessagePermissionsTable listed above.
-
-this.SystemMessagePrefixPermissionsTable = {
-  "datastore-update-": { },
-};
 
 this.SystemMessagePermissionsChecker = {
   /**
    * Return all the needed permission names for the given system message.
    * @param string aSysMsgName
    *        The system messsage name.
    * @returns object
    *        Format: { permName (string): permNamesWithAccess (string array), ... }
@@ -154,29 +146,19 @@ this.SystemMessagePermissionsChecker = {
    *        Return and report error when any unexpected error is ecountered.
    *        Ex, when the system message we want to search is not included.
    **/
   getSystemMessagePermissions: function getSystemMessagePermissions(aSysMsgName) {
     debug("getSystemMessagePermissions(): aSysMsgName: " + aSysMsgName);
 
     let permNames = SystemMessagePermissionsTable[aSysMsgName];
     if (permNames === undefined) {
-      // Try to look up in the prefix table.
-      for (let sysMsgPrefix in SystemMessagePrefixPermissionsTable) {
-        if (aSysMsgName.indexOf(sysMsgPrefix) === 0) {
-          permNames = SystemMessagePrefixPermissionsTable[sysMsgPrefix];
-          break;
-        }
-      }
-
-      if (permNames === undefined) {
-        debug("'" + aSysMsgName + "' is not associated with permissions. " +
-              "Please add them to the SystemMessage[Prefix]PermissionsTable.");
-        return null;
-      }
+      debug("'" + aSysMsgName + "' is not associated with permissions. " +
+            "Please add them to the SystemMessage[Prefix]PermissionsTable.");
+      return null;
     }
 
     let object = { };
     for (let permName in permNames) {
       if (PermissionsTable[permName] === undefined) {
         debug("'" + permName + "' for '" + aSysMsgName + "' is invalid. " +
               "Please correct it in the SystemMessage[Prefix]PermissionsTable.");
         return null;
@@ -190,16 +172,44 @@ this.SystemMessagePermissionsChecker = {
         return null;
       }
       object[permName] = appendAccessToPermName(permName, access);
     }
     return object
   },
 
   /**
+   * Check if the message is a datastore-update message
+   * @param string aSysMsgName
+   *        The system messsage name.
+   */
+  isDataStoreSystemMessage: function(aSysMsgName) {
+    return aSysMsgName.indexOf('datastore-update-') === 0;
+  },
+
+  /**
+   * Check if this manifest can deliver this particular datastore message.
+   */
+  canDeliverDataStoreSystemMessage: function(aSysMsgName, aManifestURL) {
+    let store = aSysMsgName.substr('datastore-update-'.length);
+
+    // Get all the manifest URLs of the apps which can access the datastore.
+    let manifestURLs = dataStoreService.getAppManifestURLsForDataStore(store);
+    let enumerate = manifestURLs.enumerate();
+    while (enumerate.hasMoreElements()) {
+      let manifestURL = enumerate.getNext().QueryInterface(Ci.nsISupportsString);
+      if (manifestURL == aManifestURL) {
+        return true;
+      }
+    }
+
+    return false;
+  },
+
+  /**
    * Check if the system message is permitted to be registered for the given
    * app at start-up based on the permissions claimed in the app's manifest.
    * @param string aSysMsgName
    *        The system messsage name.
    * @param string aManifestURL
    *        The app's manifest URL.
    * @param object aManifest
    *        The app's manifest.
@@ -210,16 +220,21 @@ this.SystemMessagePermissionsChecker = {
     function isSystemMessagePermittedToRegister(aSysMsgName,
                                                 aManifestURL,
                                                 aManifest) {
     debug("isSystemMessagePermittedToRegister(): " +
           "aSysMsgName: " + aSysMsgName + ", " +
           "aManifestURL: " + aManifestURL + ", " +
           "aManifest: " + JSON.stringify(aManifest));
 
+    if (this.isDataStoreSystemMessage(aSysMsgName) &&
+        this.canDeliverDataStoreSystemMessage(aSysMsgName, aManifestURL)) {
+      return true;
+    }
+
     let permNames = this.getSystemMessagePermissions(aSysMsgName);
     if (permNames === null) {
       return false;
     }
 
     // Check to see if the 'webapp' is app/privileged/certified.
     let appStatus;
     switch (AppsUtils.getAppManifestStatus(aManifest)) {
@@ -297,16 +312,21 @@ this.SystemMessagePermissionsChecker = {
    **/
   isSystemMessagePermittedToSend:
     function isSystemMessagePermittedToSend(aSysMsgName, aPageURL, aManifestURL) {
     debug("isSystemMessagePermittedToSend(): " +
           "aSysMsgName: " + aSysMsgName + ", " +
           "aPageURL: " + aPageURL + ", " +
           "aManifestURL: " + aManifestURL);
 
+    if (this.isDataStoreSystemMessage(aSysMsgName) &&
+        this.canDeliverDataStoreSystemMessage(aSysMsgName, aManifestURL)) {
+      return true;
+    }
+
     let permNames = this.getSystemMessagePermissions(aSysMsgName);
     if (permNames === null) {
       return false;
     }
 
     let pageURI = Services.io.newURI(aPageURL, null, null);
     for (let permName in permNames) {
       let permNamesWithAccess = permNames[permName];