2014-06-25 05:12:07 +00:00
|
|
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
2012-11-08 22:53:44 +00:00
|
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
this.EXPORTED_SYMBOLS = ["PhoneNumberUtils"];
|
|
|
|
|
2012-11-29 22:50:19 +00:00
|
|
|
const DEBUG = false;
|
|
|
|
function debug(s) { if(DEBUG) dump("-*- PhoneNumberutils: " + s + "\n"); }
|
2012-11-08 22:53:44 +00:00
|
|
|
|
|
|
|
const Cu = Components.utils;
|
2013-08-01 04:04:59 +00:00
|
|
|
const Cc = Components.classes;
|
|
|
|
const Ci = Components.interfaces;
|
2012-11-08 22:53:44 +00:00
|
|
|
|
2012-11-29 22:50:19 +00:00
|
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
|
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
2014-05-07 22:53:16 +00:00
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "PhoneNumberNormalizer",
|
|
|
|
"resource://gre/modules/PhoneNumberNormalizer.jsm");
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "MCC_ISO3166_TABLE",
|
|
|
|
"resource://gre/modules/mcc_iso3166_table.jsm");
|
2012-11-08 22:53:44 +00:00
|
|
|
|
2012-11-29 22:50:19 +00:00
|
|
|
#ifdef MOZ_B2G_RIL
|
2013-03-06 09:53:12 +00:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "mobileConnection",
|
2014-07-02 10:10:30 +00:00
|
|
|
"@mozilla.org/mobileconnection/mobileconnectionservice;1",
|
|
|
|
"nsIMobileConnectionService");
|
2015-01-15 10:42:24 +00:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gIccService",
|
|
|
|
"@mozilla.org/icc/iccservice;1",
|
|
|
|
"nsIIccService");
|
2012-11-29 22:50:19 +00:00
|
|
|
#endif
|
2012-11-08 22:53:44 +00:00
|
|
|
|
|
|
|
this.PhoneNumberUtils = {
|
2015-03-31 21:56:05 +00:00
|
|
|
|
|
|
|
initParent: function() {
|
2013-08-01 04:04:59 +00:00
|
|
|
ppmm.addMessageListener(["PhoneNumberService:FuzzyMatch"], this);
|
2015-03-31 21:56:05 +00:00
|
|
|
this._countryNameCache = Object.create(null);
|
|
|
|
},
|
|
|
|
|
|
|
|
initChild: function () {
|
|
|
|
this._countryNameCache = Object.create(null);
|
2013-08-01 04:04:59 +00:00
|
|
|
},
|
2012-11-08 22:53:44 +00:00
|
|
|
// 1. See whether we have a network mcc
|
|
|
|
// 2. If we don't have that, look for the simcard mcc
|
2013-07-18 20:17:41 +00:00
|
|
|
// 3. If we don't have that or its 0 (not activated), pick up the last used mcc
|
2012-11-08 22:53:44 +00:00
|
|
|
// 4. If we don't have, default to some mcc
|
2012-11-29 22:50:19 +00:00
|
|
|
|
|
|
|
// mcc for Brasil
|
|
|
|
_mcc: '724',
|
|
|
|
|
2013-06-13 22:00:23 +00:00
|
|
|
getCountryName: function getCountryName() {
|
2012-11-08 22:53:44 +00:00
|
|
|
let mcc;
|
|
|
|
let countryName;
|
2012-11-29 22:50:19 +00:00
|
|
|
|
|
|
|
#ifdef MOZ_B2G_RIL
|
2013-10-30 04:03:54 +00:00
|
|
|
// TODO: Bug 926740 - PhoneNumberUtils for multisim
|
2015-01-15 10:42:24 +00:00
|
|
|
// In Multi-sim, there is more than one client in
|
|
|
|
// iccService/mobileConnectionService. Each client represents a
|
2013-10-16 10:15:55 +00:00
|
|
|
// icc/mobileConnection service. To maintain the backward compatibility with
|
|
|
|
// single sim, we always use client 0 for now. Adding support for multiple
|
|
|
|
// sim will be addressed in bug 926740, if needed.
|
|
|
|
let clientId = 0;
|
|
|
|
|
|
|
|
// Get network mcc
|
2014-09-21 07:24:43 +00:00
|
|
|
let connection = mobileConnection.getItemByServiceId(clientId);
|
|
|
|
let voice = connection && connection.voice;
|
2013-07-18 20:17:41 +00:00
|
|
|
if (voice && voice.network && voice.network.mcc) {
|
|
|
|
mcc = voice.network.mcc;
|
2012-12-20 07:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get SIM mcc
|
2015-01-15 10:42:24 +00:00
|
|
|
let icc = gIccService.getIccByServiceId(clientId);
|
|
|
|
let iccInfo = icc && icc.iccInfo;
|
2013-08-20 09:59:08 +00:00
|
|
|
if (!mcc && iccInfo && iccInfo.mcc) {
|
2013-07-18 20:17:41 +00:00
|
|
|
mcc = iccInfo.mcc;
|
2012-12-20 07:17:37 +00:00
|
|
|
}
|
2012-11-08 22:53:44 +00:00
|
|
|
|
2013-07-18 20:17:41 +00:00
|
|
|
// Attempt to grab last known sim mcc from prefs
|
|
|
|
if (!mcc) {
|
|
|
|
try {
|
|
|
|
mcc = Services.prefs.getCharPref("ril.lastKnownSimMcc");
|
|
|
|
} catch (e) {}
|
2012-12-20 07:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set to default mcc
|
|
|
|
if (!mcc) {
|
|
|
|
mcc = this._mcc;
|
|
|
|
}
|
2012-11-29 22:50:19 +00:00
|
|
|
#else
|
2013-08-29 14:56:19 +00:00
|
|
|
|
|
|
|
// Attempt to grab last known sim mcc from prefs
|
|
|
|
if (!mcc) {
|
|
|
|
try {
|
|
|
|
mcc = Services.prefs.getCharPref("ril.lastKnownSimMcc");
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mcc) {
|
|
|
|
mcc = this._mcc;
|
|
|
|
}
|
2012-11-29 22:50:19 +00:00
|
|
|
#endif
|
2012-11-08 22:53:44 +00:00
|
|
|
|
|
|
|
countryName = MCC_ISO3166_TABLE[mcc];
|
2012-12-20 07:17:37 +00:00
|
|
|
if (DEBUG) debug("MCC: " + mcc + "countryName: " + countryName);
|
2012-11-08 22:53:44 +00:00
|
|
|
return countryName;
|
|
|
|
},
|
|
|
|
|
|
|
|
parse: function(aNumber) {
|
2012-12-20 07:17:37 +00:00
|
|
|
if (DEBUG) debug("call parse: " + aNumber);
|
2013-06-13 22:00:23 +00:00
|
|
|
let result = PhoneNumber.Parse(aNumber, this.getCountryName());
|
2013-08-29 14:56:19 +00:00
|
|
|
|
|
|
|
if (result) {
|
|
|
|
let countryName = result.countryName || this.getCountryName();
|
|
|
|
let number = null;
|
|
|
|
if (countryName) {
|
|
|
|
if (Services.prefs.getPrefType("dom.phonenumber.substringmatching." + countryName) == Ci.nsIPrefBranch.PREF_INT) {
|
|
|
|
let val = Services.prefs.getIntPref("dom.phonenumber.substringmatching." + countryName);
|
|
|
|
if (val) {
|
|
|
|
number = result.internationalNumber || result.nationalNumber;
|
|
|
|
if (number && number.length > val) {
|
|
|
|
number = number.slice(-val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Object.defineProperty(result, "nationalMatchingFormat", { value: number, enumerable: true });
|
|
|
|
if (DEBUG) {
|
2012-11-29 22:50:19 +00:00
|
|
|
debug("InternationalFormat: " + result.internationalFormat);
|
|
|
|
debug("InternationalNumber: " + result.internationalNumber);
|
|
|
|
debug("NationalNumber: " + result.nationalNumber);
|
|
|
|
debug("NationalFormat: " + result.nationalFormat);
|
2013-08-29 14:56:19 +00:00
|
|
|
debug("CountryName: " + result.countryName);
|
|
|
|
debug("NationalMatchingFormat: " + result.nationalMatchingFormat);
|
2012-11-29 22:50:19 +00:00
|
|
|
}
|
2013-08-29 14:56:19 +00:00
|
|
|
} else if (DEBUG) {
|
|
|
|
debug("NO PARSING RESULT!");
|
2012-11-29 22:50:19 +00:00
|
|
|
}
|
2012-11-08 22:53:44 +00:00
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
|
|
|
parseWithMCC: function(aNumber, aMCC) {
|
2015-03-31 21:56:05 +00:00
|
|
|
if (DEBUG) debug("parseWithMCC " + aNumber + ", " + aMCC);
|
2012-11-08 22:53:44 +00:00
|
|
|
let countryName = MCC_ISO3166_TABLE[aMCC];
|
2012-12-20 07:17:37 +00:00
|
|
|
if (DEBUG) debug("found country name: " + countryName);
|
2012-11-08 22:53:44 +00:00
|
|
|
return PhoneNumber.Parse(aNumber, countryName);
|
2013-02-20 09:02:45 +00:00
|
|
|
},
|
|
|
|
|
2015-03-31 21:56:05 +00:00
|
|
|
parseWithCountryName: function(aNumber, aCountryName) {
|
|
|
|
if (this._countryNameCache[aCountryName]) {
|
|
|
|
return PhoneNumber.Parse(aNumber, aCountryName);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Object.keys(this._countryNameCache).length === 0) {
|
|
|
|
// populate the cache
|
|
|
|
let keys = Object.keys(MCC_ISO3166_TABLE);
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
|
|
|
this._countryNameCache[MCC_ISO3166_TABLE[keys[i]]] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this._countryNameCache[aCountryName]) {
|
|
|
|
dump("Couldn't find country name: " + aCountryName + "\n");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PhoneNumber.Parse(aNumber, aCountryName);
|
2013-10-31 09:20:00 +00:00
|
|
|
},
|
|
|
|
|
2013-03-08 15:08:55 +00:00
|
|
|
isPlainPhoneNumber: function isPlainPhoneNumber(aNumber) {
|
|
|
|
var isPlain = PhoneNumber.IsPlain(aNumber);
|
|
|
|
if (DEBUG) debug("isPlain(" + aNumber + ") " + isPlain);
|
|
|
|
return isPlain;
|
|
|
|
},
|
|
|
|
|
2013-06-13 21:52:40 +00:00
|
|
|
normalize: function Normalize(aNumber, aNumbersOnly) {
|
2013-08-01 04:04:59 +00:00
|
|
|
let normalized = PhoneNumberNormalizer.Normalize(aNumber, aNumbersOnly);
|
2013-06-13 21:52:40 +00:00
|
|
|
if (DEBUG) debug("normalize(" + aNumber + "): " + normalized + ", " + aNumbersOnly);
|
2013-03-08 15:08:55 +00:00
|
|
|
return normalized;
|
2013-08-01 04:04:59 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
fuzzyMatch: function fuzzyMatch(aNumber1, aNumber2) {
|
|
|
|
let normalized1 = this.normalize(aNumber1);
|
|
|
|
let normalized2 = this.normalize(aNumber2);
|
|
|
|
if (DEBUG) debug("Normalized Number1: " + normalized1 + ", Number2: " + normalized2);
|
|
|
|
if (normalized1 === normalized2) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
let parsed1 = this.parse(aNumber1);
|
|
|
|
let parsed2 = this.parse(aNumber2);
|
|
|
|
if (parsed1 && parsed2) {
|
2013-08-29 14:56:19 +00:00
|
|
|
if ((parsed1.internationalNumber && parsed1.internationalNumber === parsed2.internationalNumber)
|
|
|
|
|| (parsed1.nationalNumber && parsed1.nationalNumber === parsed2.nationalNumber)) {
|
2013-08-01 04:04:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let countryName = this.getCountryName();
|
|
|
|
let ssPref = "dom.phonenumber.substringmatching." + countryName;
|
|
|
|
if (Services.prefs.getPrefType(ssPref) == Ci.nsIPrefBranch.PREF_INT) {
|
|
|
|
let val = Services.prefs.getIntPref(ssPref);
|
2013-08-29 14:56:19 +00:00
|
|
|
if (normalized1.length > val && normalized2.length > val
|
|
|
|
&& normalized1.slice(-val) === normalized2.slice(-val)) {
|
2013-08-01 04:04:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
receiveMessage: function(aMessage) {
|
|
|
|
if (DEBUG) debug("receiveMessage " + aMessage.name);
|
|
|
|
let mm = aMessage.target;
|
|
|
|
let msg = aMessage.data;
|
|
|
|
|
|
|
|
switch (aMessage.name) {
|
|
|
|
case "PhoneNumberService:FuzzyMatch":
|
|
|
|
mm.sendAsyncMessage("PhoneNumberService:FuzzyMatch:Return:OK", {
|
|
|
|
requestID: msg.requestID,
|
|
|
|
result: this.fuzzyMatch(msg.options.number1, msg.options.number2)
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);
|
|
|
|
}
|
2012-11-29 22:50:19 +00:00
|
|
|
}
|
2012-11-08 22:53:44 +00:00
|
|
|
};
|
2013-08-01 04:04:59 +00:00
|
|
|
|
|
|
|
let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
|
|
|
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
|
|
|
if (inParent) {
|
2014-05-07 22:53:16 +00:00
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "PhoneNumber",
|
|
|
|
"resource://gre/modules/PhoneNumber.jsm");
|
2013-08-01 04:04:59 +00:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
|
|
"@mozilla.org/parentprocessmessagemanager;1",
|
|
|
|
"nsIMessageListenerManager");
|
2015-03-31 21:56:05 +00:00
|
|
|
PhoneNumberUtils.initParent();
|
|
|
|
} else {
|
|
|
|
PhoneNumberUtils.initChild();
|
2013-08-01 04:04:59 +00:00
|
|
|
}
|
|
|
|
|