mobile/android/modules/ContactService.jsm

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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("-*- Android 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 = [];
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/PhoneNumberUtils.jsm");
michael@0 19
michael@0 20 XPCOMUtils.defineLazyServiceGetter(this, "ppmm", "@mozilla.org/parentprocessmessagemanager;1",
michael@0 21 "nsIMessageListenerManager");
michael@0 22
michael@0 23 let ContactService = {
michael@0 24 init: function() {
michael@0 25 if (DEBUG) debug("Init");
michael@0 26 this._requestMessages = {};
michael@0 27
michael@0 28 // Add listeners for all messages from ContactManager.js
michael@0 29 let messages = ["Contacts:Clear", "Contacts:Find", "Contacts:GetAll",
michael@0 30 "Contacts:GetAll:SendNow", "Contacts:GetCount", "Contacts:GetRevision",
michael@0 31 "Contact:Remove", "Contact:Save",];
michael@0 32 messages.forEach(function(msgName) {
michael@0 33 ppmm.addMessageListener(msgName, this);
michael@0 34 }.bind(this));
michael@0 35
michael@0 36 // Add listeners for all messages from ContactService.java
michael@0 37 let returnMessages = ["Android:Contacts:Count",
michael@0 38 "Android:Contacts:Clear:Return:OK", "Android:Contacts:Clear:Return:KO",
michael@0 39 "Android:Contacts:Find:Return:OK", "Android:Contacts:Find:Return:KO",
michael@0 40 "Android:Contacts:GetAll:Next", "Android:Contacts:RegisterForMessages",
michael@0 41 "Android:Contact:Remove:Return:OK", "Android:Contact:Remove:Return:KO",
michael@0 42 "Android:Contact:Save:Return:OK", "Android:Contact:Save:Return:KO",];
michael@0 43
michael@0 44 returnMessages.forEach(function(msgName) {
michael@0 45 Services.obs.addObserver(this, msgName, false);
michael@0 46 }.bind(this));
michael@0 47 },
michael@0 48
michael@0 49 _sendMessageToJava: function(aMsg) {
michael@0 50 Services.androidBridge.handleGeckoMessage(aMsg);
michael@0 51 },
michael@0 52
michael@0 53 _sendReturnMessage: function(aTopic, aRequestID, aResult) {
michael@0 54 this._requestMessages[aRequestID].target.sendAsyncMessage(aTopic, aResult);
michael@0 55 },
michael@0 56
michael@0 57 _sendAndDeleteReturnMessage: function(aTopic, aRequestID, aResult) {
michael@0 58 this._sendReturnMessage(aTopic, aRequestID, aResult)
michael@0 59 delete this._requestMessages[aRequestID];
michael@0 60 },
michael@0 61
michael@0 62 observe: function(aSubject, aTopic, aData) {
michael@0 63 if (DEBUG) {
michael@0 64 debug("observe: subject: " + aSubject + " topic: " + aTopic + " data: " + aData);
michael@0 65 }
michael@0 66
michael@0 67 let message = JSON.parse(aData, function date_reviver(k, v) {
michael@0 68 // The Java service sends dates as strings, so convert them to Dates before
michael@0 69 // sending them back to the child.
michael@0 70 if (v != null && v != "null" &&
michael@0 71 ["updated", "published", "anniversary", "bday"].indexOf(k) != -1) {
michael@0 72 return new Date(v);
michael@0 73 }
michael@0 74 return v;
michael@0 75 });
michael@0 76 let requestID = message.requestID;
michael@0 77
michael@0 78 // The return message topic is the same as the current topic, but without the "Android:" prefix
michael@0 79 let returnMessageTopic = aTopic.substring(8);
michael@0 80
michael@0 81 switch (aTopic) {
michael@0 82 case "Android:Contacts:Find:Return:OK":
michael@0 83 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID, contacts: message.contacts});
michael@0 84 break;
michael@0 85
michael@0 86 case "Android:Contacts:Find:Return:KO":
michael@0 87 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
michael@0 88 break;
michael@0 89
michael@0 90 case "Android:Contact:Save:Return:OK":
michael@0 91 this._sendReturnMessage(returnMessageTopic, requestID, {requestID: requestID, contactID: message.contactID});
michael@0 92 this._sendAndDeleteReturnMessage("Contact:Changed", requestID, {contactID: message.contactID, reason: message.reason});
michael@0 93 break;
michael@0 94
michael@0 95 case "Android:Contact:Save:Return:KO":
michael@0 96 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
michael@0 97 break;
michael@0 98
michael@0 99 case "Android:Contact:Remove:Return:OK":
michael@0 100 this._sendReturnMessage(returnMessageTopic, requestID, {requestID: requestID, contactID: message.contactID});
michael@0 101 this._sendAndDeleteReturnMessage("Contact:Changed", requestID, {contactID: message.contactID, reason: "remove"});
michael@0 102 break;
michael@0 103
michael@0 104 case "Android:Contact:Remove:Return:KO":
michael@0 105 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
michael@0 106 break;
michael@0 107
michael@0 108 case "Android:Contacts:Clear:Return:OK":
michael@0 109 this._sendReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
michael@0 110 this._sendAndDeleteReturnMessage("Contact:Changed", requestID, {reason: "remove"});
michael@0 111 break;
michael@0 112
michael@0 113 case "Android:Contact:Clear:Return:KO":
michael@0 114 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
michael@0 115 break;
michael@0 116
michael@0 117 case "Android:Contacts:GetAll:Next":
michael@0 118 // GetAll uses a cursor ID instead of a request ID. Translate the request ID back to the cursor ID
michael@0 119 this._sendReturnMessage(returnMessageTopic, requestID, {cursorId: requestID, contacts: message.contacts});
michael@0 120
michael@0 121 // Send a message with no contacts to denote the end of contacts returned by the query
michael@0 122 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {cursorId: requestID});
michael@0 123 break;
michael@0 124
michael@0 125 case "Android:Contacts:Count":
michael@0 126 this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID, count: message.count});
michael@0 127 break;
michael@0 128
michael@0 129 default:
michael@0 130 throw "Wrong message received: " + aTopic;
michael@0 131 }
michael@0 132 },
michael@0 133
michael@0 134 assertPermission: function(aMessage, aPerm) {
michael@0 135 if (!aMessage.target.assertPermission(aPerm)) {
michael@0 136 Cu.reportError("Contacts message " + aMessage.name +
michael@0 137 " from a content process with no" + aPerm + " privileges.");
michael@0 138 return false;
michael@0 139 }
michael@0 140 return true;
michael@0 141 },
michael@0 142
michael@0 143 receiveMessage: function(aMessage) {
michael@0 144 if (DEBUG) debug("receiveMessage " + aMessage.name);
michael@0 145
michael@0 146 // GetAll uses a cursor ID instead of a request ID, but they can be treated the same from here
michael@0 147 if (!aMessage.data.requestID && aMessage.data.cursorId) {
michael@0 148 aMessage.data.requestID = aMessage.data.cursorId;
michael@0 149 }
michael@0 150 let requestID = aMessage.data.requestID;
michael@0 151
michael@0 152 // Store the message so it the request callback can be called when the Java side is finished
michael@0 153 this._requestMessages[requestID] = aMessage;
michael@0 154
michael@0 155 switch (aMessage.name) {
michael@0 156 case "Contacts:Find":
michael@0 157 this.findContacts(aMessage);
michael@0 158 break;
michael@0 159
michael@0 160 case "Contacts:GetAll":
michael@0 161 this.getAllContacts(aMessage);
michael@0 162 break;
michael@0 163
michael@0 164 case "Contacts:GetAll:SendNow":
michael@0 165 // Send an empty message to denote there are no most contacts for the getAll query
michael@0 166 this._sendAndDeleteReturnMessage("Contacts:GetAll:Next", requestID, {cursorId: requestID});
michael@0 167 break;
michael@0 168
michael@0 169 case "Contact:Save":
michael@0 170 this.saveContact(aMessage);
michael@0 171 break;
michael@0 172
michael@0 173 case "Contact:Remove":
michael@0 174 this.removeContact(aMessage);
michael@0 175 break;
michael@0 176
michael@0 177 case "Contacts:Clear":
michael@0 178 this.clearContacts(aMessage);
michael@0 179 break;
michael@0 180
michael@0 181 case "Contacts:GetCount":
michael@0 182 this.getContactsCount(aMessage);
michael@0 183 break;
michael@0 184
michael@0 185 case "Contacts:GetRevision":
michael@0 186 // Android does not support the get revision function
michael@0 187 this._sendAndDeleteReturnMessage("Contacts:GetRevision:Return:KO", requestID, {requestID: requestID,
michael@0 188 errorMsg: "Android does not support the revision function."});
michael@0 189 break;
michael@0 190
michael@0 191 case "Contacts:RegisterForMessages":
michael@0 192 delete this._requestMessages[requestID];
michael@0 193 break;
michael@0 194
michael@0 195 default:
michael@0 196 delete this._requestMessages[requestID];
michael@0 197 throw "Wrong message received: " + aMessage.name;
michael@0 198 }
michael@0 199 },
michael@0 200
michael@0 201 findContacts: function(aMessage) {
michael@0 202 if (!this.assertPermission(aMessage, "contacts-read")) {
michael@0 203 return;
michael@0 204 }
michael@0 205
michael@0 206 let countryName = PhoneNumberUtils.getCountryName();
michael@0 207 let substringmatchingPref = "dom.phonenumber.substringmatching." + countryName;
michael@0 208 let substringmatchingValue = 0;
michael@0 209 if (Services.prefs.getPrefType(substringmatchingPref) == Ci.nsIPrefBranch.PREF_INT) {
michael@0 210 substringmatchingValue = Services.prefs.getIntPref(substringmatchingPref);
michael@0 211 }
michael@0 212
michael@0 213 // Add the substring matching value to the find options JSON
michael@0 214 aMessage.data.options.findOptions.substringMatching = substringmatchingValue;
michael@0 215
michael@0 216 this._sendMessageToJava({type: "Android:Contacts:Find", data: aMessage.data});
michael@0 217 },
michael@0 218
michael@0 219 getAllContacts: function(aMessage) {
michael@0 220 if (!this.assertPermission(aMessage, "contacts-read")) {
michael@0 221 return;
michael@0 222 }
michael@0 223
michael@0 224 this._sendMessageToJava({type: "Android:Contacts:GetAll", data: aMessage.data});
michael@0 225 },
michael@0 226
michael@0 227 saveContact: function(aMessage) {
michael@0 228 if ((aMessage.data.options.reason === "create" &&
michael@0 229 !this.assertPermission(aMessage, "contacts-create")) ||
michael@0 230 !this.assertPermission(aMessage, "contacts-write")) {
michael@0 231 return;
michael@0 232 }
michael@0 233
michael@0 234 this._sendMessageToJava({type: "Android:Contact:Save", data: aMessage.data});
michael@0 235 },
michael@0 236
michael@0 237 removeContact: function(aMessage) {
michael@0 238 if (!this.assertPermission(aMessage, "contacts-write")) {
michael@0 239 return;
michael@0 240 }
michael@0 241
michael@0 242 this._sendMessageToJava({type: "Android:Contact:Remove", data: aMessage.data});
michael@0 243 },
michael@0 244
michael@0 245 clearContacts: function(aMessage) {
michael@0 246 if (!this.assertPermission(aMessage, "contacts-write")) {
michael@0 247 return;
michael@0 248 }
michael@0 249
michael@0 250 this._sendMessageToJava({type: "Android:Contacts:Clear", data: aMessage.data});
michael@0 251 },
michael@0 252
michael@0 253 getContactsCount: function(aMessage) {
michael@0 254 if (!this.assertPermission(aMessage, "contacts-read")) {
michael@0 255 return;
michael@0 256 }
michael@0 257
michael@0 258 this._sendMessageToJava({type: "Android:Contacts:GetCount", data: aMessage.data});
michael@0 259 },
michael@0 260 }
michael@0 261
michael@0 262 ContactService.init();

mercurial