1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/phonenumberutils/PhoneNumberUtils.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,205 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 1.6 + 1.7 +"use strict"; 1.8 + 1.9 +this.EXPORTED_SYMBOLS = ["PhoneNumberUtils"]; 1.10 + 1.11 +const DEBUG = false; 1.12 +function debug(s) { if(DEBUG) dump("-*- PhoneNumberutils: " + s + "\n"); } 1.13 + 1.14 +const Cu = Components.utils; 1.15 +const Cc = Components.classes; 1.16 +const Ci = Components.interfaces; 1.17 + 1.18 +Cu.import("resource://gre/modules/Services.jsm"); 1.19 +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); 1.20 +Cu.import("resource://gre/modules/PhoneNumberNormalizer.jsm"); 1.21 +Cu.import("resource://gre/modules/mcc_iso3166_table.jsm"); 1.22 + 1.23 +#ifdef MOZ_B2G_RIL 1.24 +XPCOMUtils.defineLazyServiceGetter(this, "mobileConnection", 1.25 + "@mozilla.org/ril/content-helper;1", 1.26 + "nsIMobileConnectionProvider"); 1.27 +XPCOMUtils.defineLazyServiceGetter(this, "icc", 1.28 + "@mozilla.org/ril/content-helper;1", 1.29 + "nsIIccProvider"); 1.30 +#endif 1.31 + 1.32 +this.PhoneNumberUtils = { 1.33 + init: function() { 1.34 + ppmm.addMessageListener(["PhoneNumberService:FuzzyMatch"], this); 1.35 + }, 1.36 + // 1. See whether we have a network mcc 1.37 + // 2. If we don't have that, look for the simcard mcc 1.38 + // 3. If we don't have that or its 0 (not activated), pick up the last used mcc 1.39 + // 4. If we don't have, default to some mcc 1.40 + 1.41 + // mcc for Brasil 1.42 + _mcc: '724', 1.43 + 1.44 + getCountryName: function getCountryName() { 1.45 + let mcc; 1.46 + let countryName; 1.47 + 1.48 +#ifdef MOZ_B2G_RIL 1.49 + // TODO: Bug 926740 - PhoneNumberUtils for multisim 1.50 + // In Multi-sim, there is more than one client in 1.51 + // iccProvider/mobileConnectionProvider. Each client represents a 1.52 + // icc/mobileConnection service. To maintain the backward compatibility with 1.53 + // single sim, we always use client 0 for now. Adding support for multiple 1.54 + // sim will be addressed in bug 926740, if needed. 1.55 + let clientId = 0; 1.56 + 1.57 + // Get network mcc 1.58 + let voice = mobileConnection.getVoiceConnectionInfo(clientId); 1.59 + if (voice && voice.network && voice.network.mcc) { 1.60 + mcc = voice.network.mcc; 1.61 + } 1.62 + 1.63 + // Get SIM mcc 1.64 + let iccInfo = icc.getIccInfo(clientId); 1.65 + if (!mcc && iccInfo && iccInfo.mcc) { 1.66 + mcc = iccInfo.mcc; 1.67 + } 1.68 + 1.69 + // Attempt to grab last known sim mcc from prefs 1.70 + if (!mcc) { 1.71 + try { 1.72 + mcc = Services.prefs.getCharPref("ril.lastKnownSimMcc"); 1.73 + } catch (e) {} 1.74 + } 1.75 + 1.76 + // Set to default mcc 1.77 + if (!mcc) { 1.78 + mcc = this._mcc; 1.79 + } 1.80 +#else 1.81 + 1.82 + // Attempt to grab last known sim mcc from prefs 1.83 + if (!mcc) { 1.84 + try { 1.85 + mcc = Services.prefs.getCharPref("ril.lastKnownSimMcc"); 1.86 + } catch (e) {} 1.87 + } 1.88 + 1.89 + if (!mcc) { 1.90 + mcc = this._mcc; 1.91 + } 1.92 +#endif 1.93 + 1.94 + countryName = MCC_ISO3166_TABLE[mcc]; 1.95 + if (DEBUG) debug("MCC: " + mcc + "countryName: " + countryName); 1.96 + return countryName; 1.97 + }, 1.98 + 1.99 + parse: function(aNumber) { 1.100 + if (DEBUG) debug("call parse: " + aNumber); 1.101 + let result = PhoneNumber.Parse(aNumber, this.getCountryName()); 1.102 + 1.103 + if (result) { 1.104 + let countryName = result.countryName || this.getCountryName(); 1.105 + let number = null; 1.106 + if (countryName) { 1.107 + if (Services.prefs.getPrefType("dom.phonenumber.substringmatching." + countryName) == Ci.nsIPrefBranch.PREF_INT) { 1.108 + let val = Services.prefs.getIntPref("dom.phonenumber.substringmatching." + countryName); 1.109 + if (val) { 1.110 + number = result.internationalNumber || result.nationalNumber; 1.111 + if (number && number.length > val) { 1.112 + number = number.slice(-val); 1.113 + } 1.114 + } 1.115 + } 1.116 + } 1.117 + Object.defineProperty(result, "nationalMatchingFormat", { value: number, enumerable: true }); 1.118 + if (DEBUG) { 1.119 + debug("InternationalFormat: " + result.internationalFormat); 1.120 + debug("InternationalNumber: " + result.internationalNumber); 1.121 + debug("NationalNumber: " + result.nationalNumber); 1.122 + debug("NationalFormat: " + result.nationalFormat); 1.123 + debug("CountryName: " + result.countryName); 1.124 + debug("NationalMatchingFormat: " + result.nationalMatchingFormat); 1.125 + } 1.126 + } else if (DEBUG) { 1.127 + debug("NO PARSING RESULT!"); 1.128 + } 1.129 + return result; 1.130 + }, 1.131 + 1.132 + parseWithMCC: function(aNumber, aMCC) { 1.133 + let countryName = MCC_ISO3166_TABLE[aMCC]; 1.134 + if (DEBUG) debug("found country name: " + countryName); 1.135 + return PhoneNumber.Parse(aNumber, countryName); 1.136 + }, 1.137 + 1.138 + parseWithCountryName: function(aNumber, countryName) { 1.139 + return PhoneNumber.Parse(aNumber, countryName); 1.140 + }, 1.141 + 1.142 + isPlainPhoneNumber: function isPlainPhoneNumber(aNumber) { 1.143 + var isPlain = PhoneNumber.IsPlain(aNumber); 1.144 + if (DEBUG) debug("isPlain(" + aNumber + ") " + isPlain); 1.145 + return isPlain; 1.146 + }, 1.147 + 1.148 + normalize: function Normalize(aNumber, aNumbersOnly) { 1.149 + let normalized = PhoneNumberNormalizer.Normalize(aNumber, aNumbersOnly); 1.150 + if (DEBUG) debug("normalize(" + aNumber + "): " + normalized + ", " + aNumbersOnly); 1.151 + return normalized; 1.152 + }, 1.153 + 1.154 + fuzzyMatch: function fuzzyMatch(aNumber1, aNumber2) { 1.155 + let normalized1 = this.normalize(aNumber1); 1.156 + let normalized2 = this.normalize(aNumber2); 1.157 + if (DEBUG) debug("Normalized Number1: " + normalized1 + ", Number2: " + normalized2); 1.158 + if (normalized1 === normalized2) { 1.159 + return true; 1.160 + } 1.161 + let parsed1 = this.parse(aNumber1); 1.162 + let parsed2 = this.parse(aNumber2); 1.163 + if (parsed1 && parsed2) { 1.164 + if ((parsed1.internationalNumber && parsed1.internationalNumber === parsed2.internationalNumber) 1.165 + || (parsed1.nationalNumber && parsed1.nationalNumber === parsed2.nationalNumber)) { 1.166 + return true; 1.167 + } 1.168 + } 1.169 + let countryName = this.getCountryName(); 1.170 + let ssPref = "dom.phonenumber.substringmatching." + countryName; 1.171 + if (Services.prefs.getPrefType(ssPref) == Ci.nsIPrefBranch.PREF_INT) { 1.172 + let val = Services.prefs.getIntPref(ssPref); 1.173 + if (normalized1.length > val && normalized2.length > val 1.174 + && normalized1.slice(-val) === normalized2.slice(-val)) { 1.175 + return true; 1.176 + } 1.177 + } 1.178 + return false; 1.179 + }, 1.180 + 1.181 + receiveMessage: function(aMessage) { 1.182 + if (DEBUG) debug("receiveMessage " + aMessage.name); 1.183 + let mm = aMessage.target; 1.184 + let msg = aMessage.data; 1.185 + 1.186 + switch (aMessage.name) { 1.187 + case "PhoneNumberService:FuzzyMatch": 1.188 + mm.sendAsyncMessage("PhoneNumberService:FuzzyMatch:Return:OK", { 1.189 + requestID: msg.requestID, 1.190 + result: this.fuzzyMatch(msg.options.number1, msg.options.number2) 1.191 + }); 1.192 + break; 1.193 + default: 1.194 + if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name); 1.195 + } 1.196 + } 1.197 +}; 1.198 + 1.199 +let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) 1.200 + .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; 1.201 +if (inParent) { 1.202 + Cu.import("resource://gre/modules/PhoneNumber.jsm"); 1.203 + XPCOMUtils.defineLazyServiceGetter(this, "ppmm", 1.204 + "@mozilla.org/parentprocessmessagemanager;1", 1.205 + "nsIMessageListenerManager"); 1.206 + PhoneNumberUtils.init(); 1.207 +} 1.208 +