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.

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

mercurial