2012-02-28 22:01:48 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2012-07-03 18:00:53 +00:00
|
|
|
"use strict";
|
2012-02-28 22:01:48 +00:00
|
|
|
|
2012-08-22 21:34:57 +00:00
|
|
|
const DEBUG = false;
|
|
|
|
function debug(s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
|
2012-02-28 22:01:48 +00:00
|
|
|
|
|
|
|
const Cu = Components.utils;
|
|
|
|
const Cc = Components.classes;
|
|
|
|
const Ci = Components.interfaces;
|
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
this.EXPORTED_SYMBOLS = ["DOMContactManager"];
|
2012-02-28 22:01:48 +00:00
|
|
|
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
|
|
Cu.import("resource://gre/modules/ContactDB.jsm");
|
|
|
|
|
2012-08-27 14:13:02 +00:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
|
|
"@mozilla.org/parentprocessmessagemanager;1",
|
|
|
|
"nsIMessageListenerManager");
|
2012-03-07 21:45:24 +00:00
|
|
|
|
2012-08-31 13:54:48 +00:00
|
|
|
XPCOMUtils.defineLazyGetter(this, "mRIL", function () {
|
2012-10-23 22:09:29 +00:00
|
|
|
let telephony = Cc["@mozilla.org/telephony/system-worker-manager;1"];
|
|
|
|
if (!telephony) {
|
|
|
|
// Return a mock RIL because B2G Desktop build does not support telephony.
|
|
|
|
return {
|
|
|
|
getICCContacts: function(aContactType, aCallback) {
|
|
|
|
aCallback("!telephony", null, null);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
return telephony.
|
|
|
|
getService(Ci.nsIInterfaceRequestor).
|
|
|
|
getInterface(Ci.nsIRadioInterfaceLayer);
|
2012-08-31 13:54:48 +00:00
|
|
|
});
|
|
|
|
|
2012-02-28 22:01:48 +00:00
|
|
|
let myGlobal = this;
|
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
this.DOMContactManager = {
|
2012-02-28 22:01:48 +00:00
|
|
|
init: function() {
|
2012-08-22 21:34:57 +00:00
|
|
|
if (DEBUG) debug("Init");
|
2012-08-31 13:54:48 +00:00
|
|
|
this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove", "Contacts:GetSimContacts"];
|
2012-02-28 22:01:48 +00:00
|
|
|
this._messages.forEach((function(msgName) {
|
2012-03-07 21:45:24 +00:00
|
|
|
ppmm.addMessageListener(msgName, this);
|
2012-02-28 22:01:48 +00:00
|
|
|
}).bind(this));
|
|
|
|
|
|
|
|
var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
|
|
|
|
idbManager.initWindowless(myGlobal);
|
|
|
|
this._db = new ContactDB(myGlobal);
|
2012-04-26 22:10:04 +00:00
|
|
|
this._db.init(myGlobal);
|
2012-02-28 22:01:48 +00:00
|
|
|
|
|
|
|
Services.obs.addObserver(this, "profile-before-change", false);
|
|
|
|
},
|
|
|
|
|
|
|
|
observe: function(aSubject, aTopic, aData) {
|
|
|
|
myGlobal = null;
|
|
|
|
this._messages.forEach((function(msgName) {
|
2012-03-07 21:45:24 +00:00
|
|
|
ppmm.removeMessageListener(msgName, this);
|
2012-02-28 22:01:48 +00:00
|
|
|
}).bind(this));
|
|
|
|
Services.obs.removeObserver(this, "profile-before-change");
|
2012-03-07 21:45:24 +00:00
|
|
|
ppmm = null;
|
2012-02-28 22:01:48 +00:00
|
|
|
this._messages = null;
|
|
|
|
if (this._db)
|
|
|
|
this._db.close();
|
2012-04-26 01:31:48 +00:00
|
|
|
this._db = null;
|
2012-02-28 22:01:48 +00:00
|
|
|
},
|
|
|
|
|
2012-11-01 00:26:05 +00:00
|
|
|
assertPermission: function(aMessage, aPerm) {
|
|
|
|
if (!aMessage.target.assertPermission(aPerm)) {
|
|
|
|
Cu.reportError("Contacts message " + msg.name +
|
|
|
|
" from a content process with no" + aPerm + " privileges.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2012-02-28 22:01:48 +00:00
|
|
|
receiveMessage: function(aMessage) {
|
2012-08-22 21:34:57 +00:00
|
|
|
if (DEBUG) debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
|
2012-08-27 14:13:02 +00:00
|
|
|
let mm = aMessage.target;
|
2012-08-09 18:34:57 +00:00
|
|
|
let msg = aMessage.data;
|
2012-05-23 23:58:47 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
* sorting with the other sortyBy field.
|
|
|
|
*/
|
2012-04-02 23:39:57 +00:00
|
|
|
function sortfunction(a, b){
|
|
|
|
let x, y;
|
2012-05-23 23:58:47 +00:00
|
|
|
let result = 0;
|
2012-08-09 18:34:57 +00:00
|
|
|
let findOptions = msg.options.findOptions;
|
|
|
|
let sortOrder = findOptions.sortOrder;
|
2012-10-28 21:48:24 +00:00
|
|
|
let sortBy = findOptions.sortBy === "familyName" ? [ "familyName", "givenName" ] : [ "givenName" , "familyName" ];
|
|
|
|
let xIndex = 0;
|
|
|
|
let yIndex = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
while (xIndex < sortBy.length && !x) {
|
|
|
|
x = a.properties[sortBy[xIndex]] ? a.properties[sortBy[xIndex]][0].toLowerCase() : null;
|
|
|
|
xIndex++;
|
2012-05-23 23:58:47 +00:00
|
|
|
}
|
2012-10-28 21:48:24 +00:00
|
|
|
if (!x) {
|
2012-05-23 23:58:47 +00:00
|
|
|
return sortOrder == 'ascending' ? 1 : -1;
|
|
|
|
}
|
2012-10-28 21:48:24 +00:00
|
|
|
while (yIndex < sortBy.length && !y) {
|
|
|
|
y = b.properties[sortBy[yIndex]] ? b.properties[sortBy[yIndex]][0].toLowerCase() : null;
|
|
|
|
yIndex++;
|
|
|
|
}
|
|
|
|
if (!y) {
|
2012-05-23 23:58:47 +00:00
|
|
|
return sortOrder == 'ascending' ? 1 : -1;
|
|
|
|
}
|
2012-10-28 21:48:24 +00:00
|
|
|
|
2012-05-23 23:58:47 +00:00
|
|
|
result = x.localeCompare(y);
|
2012-10-28 21:48:24 +00:00
|
|
|
x = null;
|
|
|
|
y = null;
|
|
|
|
} while (result === 0);
|
|
|
|
|
2012-05-23 23:58:47 +00:00
|
|
|
return sortOrder == 'ascending' ? result : -result;
|
2012-04-02 23:39:57 +00:00
|
|
|
}
|
2012-05-23 23:58:47 +00:00
|
|
|
|
2012-02-28 22:01:48 +00:00
|
|
|
switch (aMessage.name) {
|
|
|
|
case "Contacts:Find":
|
2012-11-01 00:26:05 +00:00
|
|
|
if (!this.assertPermission(aMessage, "contacts-read")) {
|
|
|
|
return null;
|
|
|
|
}
|
2012-02-28 22:01:48 +00:00
|
|
|
let result = new Array();
|
|
|
|
this._db.find(
|
|
|
|
function(contacts) {
|
|
|
|
for (let i in contacts)
|
|
|
|
result.push(contacts[i]);
|
2012-08-09 18:34:57 +00:00
|
|
|
if (msg.options && msg.options.findOptions) {
|
|
|
|
let findOptions = msg.options.findOptions;
|
|
|
|
if (findOptions.sortOrder !== 'undefined' && findOptions.sortBy !== 'undefined') {
|
2012-08-22 21:34:57 +00:00
|
|
|
if (DEBUG) debug('sortBy: ' + findOptions.sortBy + ', sortOrder: ' + findOptions.sortOrder );
|
2012-08-09 18:34:57 +00:00
|
|
|
result.sort(sortfunction);
|
|
|
|
if (findOptions.filterLimit)
|
|
|
|
result = result.slice(0, findOptions.filterLimit);
|
|
|
|
}
|
2012-04-02 23:39:57 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 21:34:57 +00:00
|
|
|
if (DEBUG) debug("result:" + JSON.stringify(result));
|
2012-07-25 17:27:27 +00:00
|
|
|
mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
|
2012-02-28 22:01:48 +00:00
|
|
|
}.bind(this),
|
2012-07-25 17:27:27 +00:00
|
|
|
function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
|
2012-08-09 18:34:57 +00:00
|
|
|
msg.options.findOptions);
|
2012-02-28 22:01:48 +00:00
|
|
|
break;
|
|
|
|
case "Contact:Save":
|
2012-11-01 00:26:05 +00:00
|
|
|
if (msg.options.reason === "create") {
|
|
|
|
if (!this.assertPermission(aMessage, "contacts-create")) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!this.assertPermission(aMessage, "contacts-write")) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2012-05-08 18:42:41 +00:00
|
|
|
this._db.saveContact(
|
2012-08-09 18:34:57 +00:00
|
|
|
msg.options.contact,
|
|
|
|
function() { mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.options.contact.id }); }.bind(this),
|
2012-07-25 17:27:27 +00:00
|
|
|
function(aErrorMsg) { mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
|
2012-05-08 18:42:41 +00:00
|
|
|
);
|
2012-02-28 22:01:48 +00:00
|
|
|
break;
|
|
|
|
case "Contact:Remove":
|
2012-11-01 00:26:05 +00:00
|
|
|
if (!this.assertPermission(aMessage, "contacts-write")) {
|
|
|
|
return null;
|
|
|
|
}
|
2012-05-08 18:42:41 +00:00
|
|
|
this._db.removeContact(
|
2012-08-09 18:34:57 +00:00
|
|
|
msg.options.id,
|
|
|
|
function() { mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.options.id }); }.bind(this),
|
2012-07-25 17:27:27 +00:00
|
|
|
function(aErrorMsg) { mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
|
2012-05-08 18:42:41 +00:00
|
|
|
);
|
2012-02-28 22:01:48 +00:00
|
|
|
break;
|
|
|
|
case "Contacts:Clear":
|
2012-11-01 00:26:05 +00:00
|
|
|
if (!this.assertPermission(aMessage, "contacts-write")) {
|
|
|
|
return null;
|
|
|
|
}
|
2012-05-08 18:42:41 +00:00
|
|
|
this._db.clear(
|
2012-07-25 17:27:27 +00:00
|
|
|
function() { mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
|
|
|
function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
|
2012-05-08 18:42:41 +00:00
|
|
|
);
|
2012-08-31 13:54:48 +00:00
|
|
|
break;
|
|
|
|
case "Contacts:GetSimContacts":
|
2012-11-01 00:26:05 +00:00
|
|
|
if (!this.assertPermission(aMessage, "contacts-read")) {
|
|
|
|
return null;
|
|
|
|
}
|
2012-09-07 04:31:20 +00:00
|
|
|
mRIL.getICCContacts(
|
|
|
|
msg.options.contactType,
|
|
|
|
function (aErrorMsg, aType, aContacts) {
|
2012-09-27 17:37:39 +00:00
|
|
|
if (aErrorMsg !== 'undefined') {
|
2012-09-07 04:31:20 +00:00
|
|
|
mm.sendAsyncMessage("Contacts:GetSimContacts:Return:KO",
|
|
|
|
{requestID: msg.requestID,
|
|
|
|
errorMsg: aErrorMsg});
|
|
|
|
} else {
|
|
|
|
mm.sendAsyncMessage("Contacts:GetSimContacts:Return:OK",
|
|
|
|
{requestID: msg.requestID,
|
|
|
|
contacts: aContacts});
|
|
|
|
}
|
|
|
|
}.bind(this));
|
2012-08-31 13:54:48 +00:00
|
|
|
break;
|
2012-08-09 18:34:57 +00:00
|
|
|
default:
|
2012-08-22 21:34:57 +00:00
|
|
|
if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);
|
2012-02-28 22:01:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DOMContactManager.init();
|