mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 857730 - Part 3: Add contacts API Javascript to Android. r=cpeterson
This commit is contained in:
parent
506065e03d
commit
4152d66713
@ -541,6 +541,7 @@ function ContactManager()
|
||||
ContactManager.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
_oncontactchange: null,
|
||||
_cachedContacts: [] ,
|
||||
|
||||
set oncontactchange(aCallback) {
|
||||
if (DEBUG) debug("set oncontactchange");
|
||||
@ -630,6 +631,13 @@ ContactManager.prototype = {
|
||||
}
|
||||
break;
|
||||
case "Contact:Save:Return:OK":
|
||||
// If a cached contact was saved and a new contact ID was returned, update the contact's ID
|
||||
if (this._cachedContacts[msg.requestID]) {
|
||||
if (msg.contactID) {
|
||||
this._cachedContacts[msg.requestID].id = msg.contactID;
|
||||
}
|
||||
delete this._cachedContacts[msg.requestID];
|
||||
}
|
||||
case "Contacts:Clear:Return:OK":
|
||||
case "Contact:Remove:Return:OK":
|
||||
req = this.getRequest(msg.requestID);
|
||||
@ -643,8 +651,12 @@ ContactManager.prototype = {
|
||||
case "Contacts:GetRevision:Return:KO":
|
||||
case "Contacts:Count:Return:KO":
|
||||
req = this.getRequest(msg.requestID);
|
||||
if (req)
|
||||
Services.DOMRequest.fireError(req.request, msg.errorMsg);
|
||||
if (req) {
|
||||
if (req.request) {
|
||||
req = req.request;
|
||||
}
|
||||
Services.DOMRequest.fireError(req, msg.errorMsg);
|
||||
}
|
||||
break;
|
||||
case "PermissionPromptHelper:AskPermission:OK":
|
||||
if (DEBUG) debug("id: " + msg.requestID);
|
||||
@ -747,7 +759,6 @@ ContactManager.prototype = {
|
||||
},
|
||||
|
||||
save: function save(aContact) {
|
||||
let request;
|
||||
if (DEBUG) debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
|
||||
let newContact = {};
|
||||
newContact.properties = {
|
||||
@ -777,12 +788,16 @@ ContactManager.prototype = {
|
||||
for (let field in newContact.properties) {
|
||||
newContact.properties[field] = aContact[field];
|
||||
}
|
||||
let request = this.createRequest();
|
||||
let requestID = this.getRequestId({request: request, reason: reason});
|
||||
|
||||
let reason;
|
||||
if (aContact.id == "undefined") {
|
||||
// for example {25c00f01-90e5-c545-b4d4-21E2ddbab9e0} becomes
|
||||
// 25c00f0190e5c545b4d421E2ddbab9e0
|
||||
aContact.id = this._getRandomId().replace('-', '', 'g').replace('{', '').replace('}', '');
|
||||
// Cache the contact so that its ID may be updated later if necessary
|
||||
this._cachedContacts[requestID] = aContact;
|
||||
reason = "create";
|
||||
} else {
|
||||
reason = "update";
|
||||
@ -790,10 +805,9 @@ ContactManager.prototype = {
|
||||
|
||||
this._setMetaData(newContact, aContact);
|
||||
if (DEBUG) debug("send: " + JSON.stringify(newContact));
|
||||
request = this.createRequest();
|
||||
let options = { contact: newContact, reason: reason };
|
||||
let allowCallback = function() {
|
||||
cpmm.sendAsyncMessage("Contact:Save", {requestID: this.getRequestId({request: request, reason: reason}), options: options});
|
||||
cpmm.sendAsyncMessage("Contact:Save", {requestID: requestID, options: options});
|
||||
}.bind(this)
|
||||
this.askPermission(reason, request, allowCallback);
|
||||
return request;
|
||||
@ -920,8 +934,8 @@ ContactManager.prototype = {
|
||||
"Contact:Remove:Return:OK", "Contact:Remove:Return:KO",
|
||||
"Contact:Changed",
|
||||
"PermissionPromptHelper:AskPermission:OK",
|
||||
"Contacts:GetAll:Next", "Contacts:Revision",
|
||||
"Contacts:Count"]);
|
||||
"Contacts:GetAll:Next", "Contacts:Count",
|
||||
"Contacts:Revision", "Contacts:GetRevision:Return:KO",]);
|
||||
},
|
||||
|
||||
// Called from DOMRequestIpcHelper
|
||||
|
@ -757,6 +757,17 @@ pref("dom.payment.provider.0.type", "mozilla/payments/pay/v1");
|
||||
pref("dom.payment.provider.0.requestMethod", "GET");
|
||||
#endif
|
||||
|
||||
// Contacts API
|
||||
pref("dom.mozContacts.enabled", true);
|
||||
pref("dom.navigator-property.disable.mozContacts", false);
|
||||
pref("dom.global-constructor.disable.mozContact", false);
|
||||
|
||||
// Shortnumber matching needed for e.g. Brazil:
|
||||
// 01187654321 can be found with 87654321
|
||||
pref("dom.phonenumber.substringmatching.BR", 8);
|
||||
pref("dom.phonenumber.substringmatching.CO", 10);
|
||||
pref("dom.phonenumber.substringmatching.VE", 7);
|
||||
|
||||
// Support for the mozAudioChannel attribute on media elements is disabled in non-webapps
|
||||
pref("media.useAudioChannelService", false);
|
||||
|
||||
|
@ -17,6 +17,7 @@ Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/JNI.jsm");
|
||||
Cu.import('resource://gre/modules/Payment.jsm');
|
||||
Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
|
||||
Cu.import("resource://gre/modules/ContactService.jsm");
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
Cu.import("resource://gre/modules/accessibility/AccessFu.jsm");
|
||||
|
254
mobile/android/modules/ContactService.jsm
Normal file
254
mobile/android/modules/ContactService.jsm
Normal file
@ -0,0 +1,254 @@
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = false;
|
||||
function debug(s) { dump("-*- Android ContactService component: " + s + "\n"); }
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [];
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm", "@mozilla.org/parentprocessmessagemanager;1",
|
||||
"nsIMessageListenerManager");
|
||||
|
||||
let ContactService = {
|
||||
init: function() {
|
||||
if (DEBUG) debug("Init");
|
||||
this._requestMessages = {};
|
||||
|
||||
// Add listeners for all messages from ContactManager.js
|
||||
let messages = ["Contacts:Clear", "Contacts:Find", "Contacts:GetAll",
|
||||
"Contacts:GetAll:SendNow", "Contacts:GetCount", "Contacts:GetRevision",
|
||||
"Contact:Remove", "Contact:Save",];
|
||||
messages.forEach(function(msgName) {
|
||||
ppmm.addMessageListener(msgName, this);
|
||||
}.bind(this));
|
||||
|
||||
// Add listeners for all messages from ContactService.java
|
||||
let returnMessages = ["Android:Contacts:Count",
|
||||
"Android:Contacts:Clear:Return:OK", "Android:Contacts:Clear:Return:KO",
|
||||
"Android:Contacts:Find:Return:OK", "Android:Contacts:Find:Return:KO",
|
||||
"Android:Contacts:GetAll:Next", "Android:Contacts:RegisterForMessages",
|
||||
"Android:Contact:Remove:Return:OK", "Android:Contact:Remove:Return:KO",
|
||||
"Android:Contact:Save:Return:OK", "Android:Contact:Save:Return:KO",];
|
||||
|
||||
returnMessages.forEach(function(msgName) {
|
||||
Services.obs.addObserver(this, msgName, false);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_sendMessageToJava: function(aMsg) {
|
||||
Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge).handleGeckoMessage(JSON.stringify(aMsg));
|
||||
},
|
||||
|
||||
_sendReturnMessage: function(aTopic, aRequestID, aResult) {
|
||||
this._requestMessages[aRequestID].target.sendAsyncMessage(aTopic, aResult);
|
||||
},
|
||||
|
||||
_sendAndDeleteReturnMessage: function(aTopic, aRequestID, aResult) {
|
||||
this._sendReturnMessage(aTopic, aRequestID, aResult)
|
||||
delete this._requestMessages[aRequestID];
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (DEBUG) {
|
||||
debug("observe: subject: " + aSubject + " topic: " + aTopic + " data: " + aData);
|
||||
}
|
||||
|
||||
let message = JSON.parse(aData);
|
||||
let requestID = message.requestID;
|
||||
|
||||
// The return message topic is the same as the current topic, but without the "Android:" prefix
|
||||
let returnMessageTopic = aTopic.substring(8);
|
||||
|
||||
switch (aTopic) {
|
||||
case "Android:Contacts:Find:Return:OK":
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID, contacts: message.contacts});
|
||||
break;
|
||||
|
||||
case "Android:Contacts:Find:Return:KO":
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
|
||||
break;
|
||||
|
||||
case "Android:Contact:Save:Return:OK":
|
||||
this._sendReturnMessage(returnMessageTopic, requestID, {requestID: requestID, contactID: message.contactID});
|
||||
this._sendAndDeleteReturnMessage("Contact:Changed", requestID, {contactID: message.contactID, reason: message.reason});
|
||||
break;
|
||||
|
||||
case "Android:Contact:Save:Return:KO":
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
|
||||
break;
|
||||
|
||||
case "Android:Contact:Remove:Return:OK":
|
||||
this._sendReturnMessage(returnMessageTopic, requestID, {requestID: requestID, contactID: message.contactID});
|
||||
this._sendAndDeleteReturnMessage("Contact:Changed", requestID, {contactID: message.contactID, reason: "remove"});
|
||||
break;
|
||||
|
||||
case "Android:Contact:Remove:Return:KO":
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
|
||||
break;
|
||||
|
||||
case "Android:Contacts:Clear:Return:OK":
|
||||
this._sendReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
|
||||
this._sendAndDeleteReturnMessage("Contact:Changed", requestID, {reason: "remove"});
|
||||
break;
|
||||
|
||||
case "Android:Contact:Clear:Return:KO":
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID});
|
||||
break;
|
||||
|
||||
case "Android:Contacts:GetAll:Next":
|
||||
// GetAll uses a cursor ID instead of a request ID. Translate the request ID back to the cursor ID
|
||||
this._sendReturnMessage(returnMessageTopic, requestID, {cursorId: requestID, contacts: message.contacts});
|
||||
|
||||
// Send a message with no contacts to denote the end of contacts returned by the query
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {cursorId: requestID});
|
||||
break;
|
||||
|
||||
case "Android:Contacts:Count":
|
||||
this._sendAndDeleteReturnMessage(returnMessageTopic, requestID, {requestID: requestID, count: message.count});
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "Wrong message received: " + aTopic;
|
||||
}
|
||||
},
|
||||
|
||||
assertPermission: function(aMessage, aPerm) {
|
||||
if (!aMessage.target.assertPermission(aPerm)) {
|
||||
Cu.reportError("Contacts message " + aMessage.name +
|
||||
" from a content process with no" + aPerm + " privileges.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (DEBUG) debug("receiveMessage " + aMessage.name);
|
||||
|
||||
// GetAll uses a cursor ID instead of a request ID, but they can be treated the same from here
|
||||
if (!aMessage.data.requestID && aMessage.data.cursorId) {
|
||||
aMessage.data.requestID = aMessage.data.cursorId;
|
||||
}
|
||||
let requestID = aMessage.data.requestID;
|
||||
|
||||
// Store the message so it the request callback can be called when the Java side is finished
|
||||
this._requestMessages[requestID] = aMessage;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Contacts:Find":
|
||||
this.findContacts(aMessage);
|
||||
break;
|
||||
|
||||
case "Contacts:GetAll":
|
||||
this.getAllContacts(aMessage);
|
||||
break;
|
||||
|
||||
case "Contacts:GetAll:SendNow":
|
||||
// Send an empty message to denote there are no most contacts for the getAll query
|
||||
this._sendAndDeleteReturnMessage("Contacts:GetAll:Next", requestID, {cursorId: requestID});
|
||||
break;
|
||||
|
||||
case "Contact:Save":
|
||||
this.saveContact(aMessage);
|
||||
break;
|
||||
|
||||
case "Contact:Remove":
|
||||
this.removeContact(aMessage);
|
||||
break;
|
||||
|
||||
case "Contacts:Clear":
|
||||
this.clearContacts(aMessage);
|
||||
break;
|
||||
|
||||
case "Contacts:GetCount":
|
||||
this.getContactsCount(aMessage);
|
||||
break;
|
||||
|
||||
case "Contacts:GetRevision":
|
||||
// Android does not support the get revision function
|
||||
this._sendAndDeleteReturnMessage("Contacts:GetRevision:Return:KO", requestID, {requestID: requestID,
|
||||
errorMsg: "Android does not support the revision function."});
|
||||
break;
|
||||
|
||||
case "Contacts:RegisterForMessages":
|
||||
delete this._requestMessages[requestID];
|
||||
break;
|
||||
|
||||
default:
|
||||
delete this._requestMessages[requestID];
|
||||
throw "Wrong message received: " + aMessage.name;
|
||||
}
|
||||
},
|
||||
|
||||
findContacts: function(aMessage) {
|
||||
if (!this.assertPermission(aMessage, "contacts-read")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let countryName = PhoneNumberUtils.getCountryName();
|
||||
let substringmatchingPref = "dom.phonenumber.substringmatching." + countryName;
|
||||
let substringmatchingValue = 0;
|
||||
if (Services.prefs.getPrefType(substringmatchingPref) == Ci.nsIPrefBranch.PREF_INT) {
|
||||
substringmatchingValue = Services.prefs.getIntPref(substringmatchingPref);
|
||||
}
|
||||
|
||||
// Add the substring matching value to the find options JSON
|
||||
aMessage.data.options.findOptions.substringMatching = substringmatchingValue;
|
||||
|
||||
this._sendMessageToJava({type: "Android:Contacts:Find", data: aMessage.data});
|
||||
},
|
||||
|
||||
getAllContacts: function(aMessage) {
|
||||
if (!this.assertPermission(aMessage, "contacts-read")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToJava({type: "Android:Contacts:GetAll", data: aMessage.data});
|
||||
},
|
||||
|
||||
saveContact: function(aMessage) {
|
||||
if ((aMessage.data.options.reason === "create" &&
|
||||
!this.assertPermission(aMessage, "contacts-create")) ||
|
||||
!this.assertPermission(aMessage, "contacts-write")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToJava({type: "Android:Contact:Save", data: aMessage.data});
|
||||
},
|
||||
|
||||
removeContact: function(aMessage) {
|
||||
if (!this.assertPermission(aMessage, "contacts-write")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToJava({type: "Android:Contact:Remove", data: aMessage.data});
|
||||
},
|
||||
|
||||
clearContacts: function(aMessage) {
|
||||
if (!this.assertPermission(aMessage, "contacts-write")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToJava({type: "Android:Contacts:Clear", data: aMessage.data});
|
||||
},
|
||||
|
||||
getContactsCount: function(aMessage) {
|
||||
if (!this.assertPermission(aMessage, "contacts-read")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToJava({type: "Android:Contacts:GetCount", data: aMessage.data});
|
||||
},
|
||||
}
|
||||
|
||||
ContactService.init();
|
@ -5,6 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'ContactService.jsm',
|
||||
'JNI.jsm',
|
||||
'LightweightThemeConsumer.jsm',
|
||||
'OrderedBroadcast.jsm',
|
||||
|
Loading…
Reference in New Issue
Block a user