Bug 836423 - Contacts API: Fix oncontactchange function. r=bent
authorGregor Wagner <anygregor@gmail.com>
Fri, 01 Feb 2013 12:44:55 -0800
changeset 120617 4a93c9d94a3b6a0450dd021ae442267dd1e2bd93
parent 120616 ac2666f2a095cd05c7efb3ddfc4c84133e5dd343
child 120618 a874d2756f6530a8ee7c8dc6dbcb7102944d5127
push id22329
push usergwagner@mozilla.com
push dateFri, 01 Feb 2013 20:45:11 +0000
treeherdermozilla-inbound@4a93c9d94a3b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs836423
milestone21.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 836423 - Contacts API: Fix oncontactchange function. r=bent
dom/contacts/ContactManager.js
dom/contacts/fallback/ContactService.jsm
--- a/dom/contacts/ContactManager.js
+++ b/dom/contacts/ContactManager.js
@@ -155,19 +155,17 @@ ContactFindOptions.prototype = {
 }
 
 //Contact
 
 const CONTACT_CONTRACTID = "@mozilla.org/contact;1";
 const CONTACT_CID        = Components.ID("{da0f7040-388b-11e1-b86c-0800200c9a66}");
 const nsIDOMContact      = Components.interfaces.nsIDOMContact;
 
-function Contact() {
-  if (DEBUG) debug("Contact constr: ");
-};
+function Contact() { };
 
 Contact.prototype = {
   __exposedProps__: {
                       id: 'rw',
                       updated: 'rw',
                       published:  'rw',
                       name: 'rw',
                       honorificPrefix: 'rw',
@@ -329,16 +327,19 @@ function ContactManager()
 
 ContactManager.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
   _oncontactchange: null,
 
   set oncontactchange(aCallback) {
     if (DEBUG) debug("set oncontactchange");
     let allowCallback = function() {
+      if (!this._oncontactchange) {
+        cpmm.sendAsyncMessage("Contacts:RegisterForMessages");
+      }
       this._oncontactchange = aCallback;
     }.bind(this);
     let cancelCallback = function() {
       throw Components.results.NS_ERROR_FAILURE;
     }
     this.askPermission("listen", null, allowCallback, cancelCallback);
   },
 
@@ -394,25 +395,16 @@ ContactManager.prototype = {
         }
         break;
       case "Contact:Save:Return:OK":
       case "Contacts:Clear:Return:OK":
       case "Contact:Remove:Return:OK":
         req = this.getRequest(msg.requestID);
         if (req)
           Services.DOMRequest.fireSuccess(req.request, null);
-
-        // Fire oncontactchange event
-        if (this._oncontactchange) {
-          let event = new this._window.MozContactChangeEvent("contactchanged", {
-            contactID: msg.contactID,
-            reason: req.reason
-          });
-          this._oncontactchange.handleEvent(event);
-        }
         break;
       case "Contacts:Find:Return:KO":
       case "Contact:Save:Return:KO":
       case "Contact:Remove:Return:KO":
       case "Contacts:Clear:Return:KO":
       case "Contacts:GetSimContacts:Return:KO":
         req = this.getRequest(msg.requestID);
         if (req)
@@ -426,17 +418,28 @@ ContactManager.prototype = {
         }
 
         if (msg.result == Ci.nsIPermissionManager.ALLOW_ACTION) {
           req.allow();
         } else {
           req.cancel();
         }
         break;
-      default: 
+      case "Contact:Changed":
+        // Fire oncontactchange event
+        if (DEBUG) debug("Contacts:ContactChanged: " + msg.contactID + ", " + msg.reason);
+        if (this._oncontactchange) {
+          let event = new this._window.MozContactChangeEvent("contactchanged", {
+            contactID: msg.contactID,
+            reason: msg.reason
+          });
+          this._oncontactchange.handleEvent(event);
+        }
+        break;
+      default:
         if (DEBUG) debug("Wrong message: " + aMessage.name);
     }
     this.removeRequest(msg.requestID);
   },
 
   askPermission: function (aAccess, aRequest, aAllowCallback, aCancelCallback) {
     if (DEBUG) debug("askPermission for contacts");
     let access;
@@ -594,16 +597,17 @@ ContactManager.prototype = {
       return null;
 
     this.initHelper(aWindow, ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
                               "Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO",
                               "Contact:Save:Return:OK", "Contact:Save:Return:KO",
                               "Contact:Remove:Return:OK", "Contact:Remove:Return:KO",
                               "Contacts:GetSimContacts:Return:OK",
                               "Contacts:GetSimContacts:Return:KO",
+                              "Contact:Changed",
                               "PermissionPromptHelper:AskPermission:OK"]);
   },
 
   // Called from DOMRequestIpcHelper
   uninit: function uninit() {
     if (DEBUG) debug("uninit call");
     if (this._oncontactchange)
       this._oncontactchange = null;
--- a/dom/contacts/fallback/ContactService.jsm
+++ b/dom/contacts/fallback/ContactService.jsm
@@ -34,17 +34,20 @@ XPCOMUtils.defineLazyGetter(this, "mRIL"
   return telephony.getService(Ci.nsIRadioInterfaceLayer);
 });
 
 let myGlobal = this;
 
 this.DOMContactManager = {
   init: function() {
     if (DEBUG) debug("Init");
-    this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove", "Contacts:GetSimContacts"];
+    this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save",
+                      "Contact:Remove", "Contacts:GetSimContacts",
+                      "Contacts:RegisterForMessages", "child-process-shutdown"];
+    this._children = [];
     this._messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
     }).bind(this));
 
     var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
     idbManager.initWindowless(myGlobal);
     this._db = new ContactDB(myGlobal);
     this._db.init(myGlobal);
@@ -69,16 +72,22 @@ this.DOMContactManager = {
     if (!aMessage.target.assertPermission(aPerm)) {
       Cu.reportError("Contacts message " + msg.name +
                      " from a content process with no" + aPerm + " privileges.");
       return false;
     }
     return true;
   },
 
+  broadcastMessage: function broadcastMessage(aMsgName, aContent) {
+    this._children.forEach(function(msgMgr) {
+      msgMgr.sendAsyncMessage(aMsgName, aContent);
+    });
+  },
+
   receiveMessage: function(aMessage) {
     if (DEBUG) debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
     let mm = aMessage.target;
     let msg = aMessage.data;
 
     /*
      * Sorting the contacts by sortBy field. sortBy can either be familyName or givenName.
      * If 2 entries have the same sortyBy field or no sortBy field is present, we continue 
@@ -150,36 +159,45 @@ this.DOMContactManager = {
           }
         } else {
           if (!this.assertPermission(aMessage, "contacts-write")) {
             return null;
           }
         }
         this._db.saveContact(
           msg.options.contact,
-          function() { mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.options.contact.id }); }.bind(this),
+          function() {
+            mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.options.contact.id });
+            this.broadcastMessage("Contact:Changed", { contactID: msg.options.contact.id, reason: msg.options.reason });
+          }.bind(this),
           function(aErrorMsg) { mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
         );
         break;
       case "Contact:Remove":
         if (!this.assertPermission(aMessage, "contacts-write")) {
           return null;
         }
         this._db.removeContact(
           msg.options.id,
-          function() { mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.options.id }); }.bind(this),
+          function() {
+            mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.options.id });
+            this.broadcastMessage("Contact:Changed", { contactID: msg.options.id, reason: "remove" });
+          }.bind(this),
           function(aErrorMsg) { mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
         );
         break;
       case "Contacts:Clear":
         if (!this.assertPermission(aMessage, "contacts-write")) {
           return null;
         }
         this._db.clear(
-          function() { mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
+          function() {
+            mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID });
+            this.broadcastMessage("Contact:Changed", { reason: "remove" });
+          }.bind(this),
           function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
         );
         break;
       case "Contacts:GetSimContacts":
         if (!this.assertPermission(aMessage, "contacts-read")) {
           return null;
         }
         mRIL.getICCContacts(
@@ -191,15 +209,32 @@ this.DOMContactManager = {
                                    errorMsg: aErrorMsg});
             } else {
               mm.sendAsyncMessage("Contacts:GetSimContacts:Return:OK",
                                   {requestID: msg.requestID,
                                    contacts: aContacts});
             }
           }.bind(this));
         break;
+      case "Contacts:RegisterForMessages":
+        if (!aMessage.target.assertPermission("contacts-read")) {
+          return null;
+        }
+        if (DEBUG) debug("Register!");
+        if (this._children.indexOf(mm) == -1) {
+          this._children.push(mm);
+        }
+        break;
+      case "child-process-shutdown":
+        if (DEBUG) debug("Unregister");
+        let index = this._children.indexOf(mm);
+        if (index != -1) {
+          if (DEBUG) debug("Unregister index: " + index);
+          this._children.splice(index, 1);
+        }
+        break;
       default:
         if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);
     }
   }
 }
 
 DOMContactManager.init();