dom/contacts/fallback/ContactService.jsm

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 const DEBUG = false;
     8 function debug(s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
    10 const Cu = Components.utils;
    11 const Cc = Components.classes;
    12 const Ci = Components.interfaces;
    14 this.EXPORTED_SYMBOLS = ["ContactService"];
    16 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    17 Cu.import("resource://gre/modules/Services.jsm");
    18 Cu.import("resource://gre/modules/ContactDB.jsm");
    19 Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
    21 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
    22                                    "@mozilla.org/parentprocessmessagemanager;1",
    23                                    "nsIMessageListenerManager");
    26 /* all exported symbols need to be bound to this on B2G - Bug 961777 */
    27 let ContactService = this.ContactService = {
    28   init: function() {
    29     if (DEBUG) debug("Init");
    30     this._messages = ["Contacts:Find", "Contacts:GetAll", "Contacts:GetAll:SendNow",
    31                       "Contacts:Clear", "Contact:Save",
    32                       "Contact:Remove", "Contacts:RegisterForMessages",
    33                       "child-process-shutdown", "Contacts:GetRevision",
    34                       "Contacts:GetCount"];
    35     this._children = [];
    36     this._cursors = new Map();
    37     this._messages.forEach(function(msgName) {
    38       ppmm.addMessageListener(msgName, this);
    39     }.bind(this));
    41     this._db = new ContactDB();
    42     this._db.init();
    44     this.configureSubstringMatching();
    46     Services.obs.addObserver(this, "profile-before-change", false);
    47     Services.prefs.addObserver("ril.lastKnownSimMcc", this, false);
    48   },
    50   observe: function(aSubject, aTopic, aData) {
    51     if (aTopic === 'profile-before-change') {
    52       this._messages.forEach(function(msgName) {
    53         ppmm.removeMessageListener(msgName, this);
    54       }.bind(this));
    55       Services.obs.removeObserver(this, "profile-before-change");
    56       Services.prefs.removeObserver("dom.phonenumber.substringmatching", this);
    57       ppmm = null;
    58       this._messages = null;
    59       if (this._db)
    60         this._db.close();
    61       this._db = null;
    62       this._children = null;
    63       this._cursors = null;
    64     } else if (aTopic === 'nsPref:changed' && aData === "ril.lastKnownSimMcc") {
    65       this.configureSubstringMatching();
    66     }
    67   },
    69   configureSubstringMatching: function() {
    70     let countryName = PhoneNumberUtils.getCountryName();
    71     if (Services.prefs.getPrefType("dom.phonenumber.substringmatching." + countryName) == Ci.nsIPrefBranch.PREF_INT) {
    72       let val = Services.prefs.getIntPref("dom.phonenumber.substringmatching." + countryName);
    73       if (val) {
    74         this._db.enableSubstringMatching(val);
    75         return;
    76       }
    77     }
    78     // if we got here, we dont have a substring setting
    79     // for this country, so disable substring matching
    80     this._db.disableSubstringMatching();
    81   },
    83   assertPermission: function(aMessage, aPerm) {
    84     if (!aMessage.target.assertPermission(aPerm)) {
    85       Cu.reportError("Contacts message " + aMessage.name +
    86                      " from a content process with no" + aPerm + " privileges.");
    87       return false;
    88     }
    89     return true;
    90   },
    92   broadcastMessage: function broadcastMessage(aMsgName, aContent) {
    93     this._children.forEach(function(msgMgr) {
    94       msgMgr.sendAsyncMessage(aMsgName, aContent);
    95     });
    96   },
    98   receiveMessage: function(aMessage) {
    99     if (DEBUG) debug("receiveMessage " + aMessage.name);
   100     let mm = aMessage.target;
   101     let msg = aMessage.data;
   103     switch (aMessage.name) {
   104       case "Contacts:Find":
   105         if (!this.assertPermission(aMessage, "contacts-read")) {
   106           return null;
   107         }
   108         let result = [];
   109         this._db.find(
   110           function(contacts) {
   111             for (let i in contacts) {
   112               result.push(contacts[i]);
   113             }
   115             if (DEBUG) debug("result:" + JSON.stringify(result));
   116             mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
   117           }.bind(this),
   118           function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this),
   119           msg.options.findOptions);
   120         break;
   121       case "Contacts:GetAll":
   122         if (!this.assertPermission(aMessage, "contacts-read")) {
   123           return null;
   124         }
   125         let cursorList = this._cursors.get(mm);
   126         if (!cursorList) {
   127           cursorList = [];
   128           this._cursors.set(mm, cursorList);
   129         }
   130         cursorList.push(msg.cursorId);
   132         this._db.getAll(
   133           function(aContacts) {
   134             try {
   135               mm.sendAsyncMessage("Contacts:GetAll:Next", {cursorId: msg.cursorId, contacts: aContacts});
   136               if (aContacts === null) {
   137                 let cursorList = this._cursors.get(mm);
   138                 let index = cursorList.indexOf(msg.cursorId);
   139                 cursorList.splice(index, 1);
   140               }
   141             } catch (e) {
   142               if (DEBUG) debug("Child is dead, DB should stop sending contacts");
   143               throw e;
   144             }
   145           }.bind(this),
   146           function(aErrorMsg) { mm.sendAsyncMessage("Contacts:GetAll:Return:KO", { requestID: msg.cursorId, errorMsg: aErrorMsg }); },
   147           msg.findOptions, msg.cursorId);
   148         break;
   149       case "Contacts:GetAll:SendNow":
   150         // sendNow is a no op if there isn't an existing cursor in the DB, so we
   151         // don't need to assert the permission again.
   152         this._db.sendNow(msg.cursorId);
   153         break;
   154       case "Contact:Save":
   155         if (msg.options.reason === "create") {
   156           if (!this.assertPermission(aMessage, "contacts-create")) {
   157             return null;
   158           }
   159         } else {
   160           if (!this.assertPermission(aMessage, "contacts-write")) {
   161             return null;
   162           }
   163         }
   164         this._db.saveContact(
   165           msg.options.contact,
   166           function() {
   167             mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.options.contact.id });
   168             this.broadcastMessage("Contact:Changed", { contactID: msg.options.contact.id, reason: msg.options.reason });
   169           }.bind(this),
   170           function(aErrorMsg) { mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
   171         );
   172         break;
   173       case "Contact:Remove":
   174         if (!this.assertPermission(aMessage, "contacts-write")) {
   175           return null;
   176         }
   177         this._db.removeContact(
   178           msg.options.id,
   179           function() {
   180             mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.options.id });
   181             this.broadcastMessage("Contact:Changed", { contactID: msg.options.id, reason: "remove" });
   182           }.bind(this),
   183           function(aErrorMsg) { mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
   184         );
   185         break;
   186       case "Contacts:Clear":
   187         if (!this.assertPermission(aMessage, "contacts-write")) {
   188           return null;
   189         }
   190         this._db.clear(
   191           function() {
   192             mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID });
   193             this.broadcastMessage("Contact:Changed", { reason: "remove" });
   194           }.bind(this),
   195           function(aErrorMsg) {
   196             mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg });
   197           }.bind(this)
   198         );
   199         break;
   200       case "Contacts:GetRevision":
   201         if (!this.assertPermission(aMessage, "contacts-read")) {
   202           return null;
   203         }
   204         this._db.getRevision(
   205           function(revision) {
   206             mm.sendAsyncMessage("Contacts:Revision", {
   207               requestID: msg.requestID,
   208               revision: revision
   209             });
   210           },
   211           function(aErrorMsg) {
   212             mm.sendAsyncMessage("Contacts:GetRevision:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg });
   213           }.bind(this)
   214         );
   215         break;
   216       case "Contacts:GetCount":
   217         if (!this.assertPermission(aMessage, "contacts-read")) {
   218           return null;
   219         }
   220         this._db.getCount(
   221           function(count) {
   222             mm.sendAsyncMessage("Contacts:Count", {
   223               requestID: msg.requestID,
   224               count: count
   225             });
   226           },
   227           function(aErrorMsg) {
   228             mm.sendAsyncMessage("Contacts:Count:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg });
   229           }.bind(this)
   230         );
   231         break;
   232       case "Contacts:RegisterForMessages":
   233         if (!aMessage.target.assertPermission("contacts-read")) {
   234           return null;
   235         }
   236         if (DEBUG) debug("Register!");
   237         if (this._children.indexOf(mm) == -1) {
   238           this._children.push(mm);
   239         }
   240         break;
   241       case "child-process-shutdown":
   242         if (DEBUG) debug("Unregister");
   243         let index = this._children.indexOf(mm);
   244         if (index != -1) {
   245           if (DEBUG) debug("Unregister index: " + index);
   246           this._children.splice(index, 1);
   247         }
   248         cursorList = this._cursors.get(mm);
   249         if (cursorList) {
   250           for (let id of cursorList) {
   251             this._db.clearDispatcher(id);
   252           }
   253           this._cursors.delete(mm);
   254         }
   255         break;
   256       default:
   257         if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);
   258     }
   259   }
   260 }
   262 ContactService.init();

mercurial