|
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ |
|
3 |
|
4 "use strict"; |
|
5 |
|
6 this.EXPORTED_SYMBOLS = ["PhoneNumberUtils"]; |
|
7 |
|
8 const DEBUG = false; |
|
9 function debug(s) { if(DEBUG) dump("-*- PhoneNumberutils: " + s + "\n"); } |
|
10 |
|
11 const Cu = Components.utils; |
|
12 const Cc = Components.classes; |
|
13 const Ci = Components.interfaces; |
|
14 |
|
15 Cu.import("resource://gre/modules/Services.jsm"); |
|
16 Cu.import('resource://gre/modules/XPCOMUtils.jsm'); |
|
17 Cu.import("resource://gre/modules/PhoneNumberNormalizer.jsm"); |
|
18 Cu.import("resource://gre/modules/mcc_iso3166_table.jsm"); |
|
19 |
|
20 #ifdef MOZ_B2G_RIL |
|
21 XPCOMUtils.defineLazyServiceGetter(this, "mobileConnection", |
|
22 "@mozilla.org/ril/content-helper;1", |
|
23 "nsIMobileConnectionProvider"); |
|
24 XPCOMUtils.defineLazyServiceGetter(this, "icc", |
|
25 "@mozilla.org/ril/content-helper;1", |
|
26 "nsIIccProvider"); |
|
27 #endif |
|
28 |
|
29 this.PhoneNumberUtils = { |
|
30 init: function() { |
|
31 ppmm.addMessageListener(["PhoneNumberService:FuzzyMatch"], this); |
|
32 }, |
|
33 // 1. See whether we have a network mcc |
|
34 // 2. If we don't have that, look for the simcard mcc |
|
35 // 3. If we don't have that or its 0 (not activated), pick up the last used mcc |
|
36 // 4. If we don't have, default to some mcc |
|
37 |
|
38 // mcc for Brasil |
|
39 _mcc: '724', |
|
40 |
|
41 getCountryName: function getCountryName() { |
|
42 let mcc; |
|
43 let countryName; |
|
44 |
|
45 #ifdef MOZ_B2G_RIL |
|
46 // TODO: Bug 926740 - PhoneNumberUtils for multisim |
|
47 // In Multi-sim, there is more than one client in |
|
48 // iccProvider/mobileConnectionProvider. Each client represents a |
|
49 // icc/mobileConnection service. To maintain the backward compatibility with |
|
50 // single sim, we always use client 0 for now. Adding support for multiple |
|
51 // sim will be addressed in bug 926740, if needed. |
|
52 let clientId = 0; |
|
53 |
|
54 // Get network mcc |
|
55 let voice = mobileConnection.getVoiceConnectionInfo(clientId); |
|
56 if (voice && voice.network && voice.network.mcc) { |
|
57 mcc = voice.network.mcc; |
|
58 } |
|
59 |
|
60 // Get SIM mcc |
|
61 let iccInfo = icc.getIccInfo(clientId); |
|
62 if (!mcc && iccInfo && iccInfo.mcc) { |
|
63 mcc = iccInfo.mcc; |
|
64 } |
|
65 |
|
66 // Attempt to grab last known sim mcc from prefs |
|
67 if (!mcc) { |
|
68 try { |
|
69 mcc = Services.prefs.getCharPref("ril.lastKnownSimMcc"); |
|
70 } catch (e) {} |
|
71 } |
|
72 |
|
73 // Set to default mcc |
|
74 if (!mcc) { |
|
75 mcc = this._mcc; |
|
76 } |
|
77 #else |
|
78 |
|
79 // Attempt to grab last known sim mcc from prefs |
|
80 if (!mcc) { |
|
81 try { |
|
82 mcc = Services.prefs.getCharPref("ril.lastKnownSimMcc"); |
|
83 } catch (e) {} |
|
84 } |
|
85 |
|
86 if (!mcc) { |
|
87 mcc = this._mcc; |
|
88 } |
|
89 #endif |
|
90 |
|
91 countryName = MCC_ISO3166_TABLE[mcc]; |
|
92 if (DEBUG) debug("MCC: " + mcc + "countryName: " + countryName); |
|
93 return countryName; |
|
94 }, |
|
95 |
|
96 parse: function(aNumber) { |
|
97 if (DEBUG) debug("call parse: " + aNumber); |
|
98 let result = PhoneNumber.Parse(aNumber, this.getCountryName()); |
|
99 |
|
100 if (result) { |
|
101 let countryName = result.countryName || this.getCountryName(); |
|
102 let number = null; |
|
103 if (countryName) { |
|
104 if (Services.prefs.getPrefType("dom.phonenumber.substringmatching." + countryName) == Ci.nsIPrefBranch.PREF_INT) { |
|
105 let val = Services.prefs.getIntPref("dom.phonenumber.substringmatching." + countryName); |
|
106 if (val) { |
|
107 number = result.internationalNumber || result.nationalNumber; |
|
108 if (number && number.length > val) { |
|
109 number = number.slice(-val); |
|
110 } |
|
111 } |
|
112 } |
|
113 } |
|
114 Object.defineProperty(result, "nationalMatchingFormat", { value: number, enumerable: true }); |
|
115 if (DEBUG) { |
|
116 debug("InternationalFormat: " + result.internationalFormat); |
|
117 debug("InternationalNumber: " + result.internationalNumber); |
|
118 debug("NationalNumber: " + result.nationalNumber); |
|
119 debug("NationalFormat: " + result.nationalFormat); |
|
120 debug("CountryName: " + result.countryName); |
|
121 debug("NationalMatchingFormat: " + result.nationalMatchingFormat); |
|
122 } |
|
123 } else if (DEBUG) { |
|
124 debug("NO PARSING RESULT!"); |
|
125 } |
|
126 return result; |
|
127 }, |
|
128 |
|
129 parseWithMCC: function(aNumber, aMCC) { |
|
130 let countryName = MCC_ISO3166_TABLE[aMCC]; |
|
131 if (DEBUG) debug("found country name: " + countryName); |
|
132 return PhoneNumber.Parse(aNumber, countryName); |
|
133 }, |
|
134 |
|
135 parseWithCountryName: function(aNumber, countryName) { |
|
136 return PhoneNumber.Parse(aNumber, countryName); |
|
137 }, |
|
138 |
|
139 isPlainPhoneNumber: function isPlainPhoneNumber(aNumber) { |
|
140 var isPlain = PhoneNumber.IsPlain(aNumber); |
|
141 if (DEBUG) debug("isPlain(" + aNumber + ") " + isPlain); |
|
142 return isPlain; |
|
143 }, |
|
144 |
|
145 normalize: function Normalize(aNumber, aNumbersOnly) { |
|
146 let normalized = PhoneNumberNormalizer.Normalize(aNumber, aNumbersOnly); |
|
147 if (DEBUG) debug("normalize(" + aNumber + "): " + normalized + ", " + aNumbersOnly); |
|
148 return normalized; |
|
149 }, |
|
150 |
|
151 fuzzyMatch: function fuzzyMatch(aNumber1, aNumber2) { |
|
152 let normalized1 = this.normalize(aNumber1); |
|
153 let normalized2 = this.normalize(aNumber2); |
|
154 if (DEBUG) debug("Normalized Number1: " + normalized1 + ", Number2: " + normalized2); |
|
155 if (normalized1 === normalized2) { |
|
156 return true; |
|
157 } |
|
158 let parsed1 = this.parse(aNumber1); |
|
159 let parsed2 = this.parse(aNumber2); |
|
160 if (parsed1 && parsed2) { |
|
161 if ((parsed1.internationalNumber && parsed1.internationalNumber === parsed2.internationalNumber) |
|
162 || (parsed1.nationalNumber && parsed1.nationalNumber === parsed2.nationalNumber)) { |
|
163 return true; |
|
164 } |
|
165 } |
|
166 let countryName = this.getCountryName(); |
|
167 let ssPref = "dom.phonenumber.substringmatching." + countryName; |
|
168 if (Services.prefs.getPrefType(ssPref) == Ci.nsIPrefBranch.PREF_INT) { |
|
169 let val = Services.prefs.getIntPref(ssPref); |
|
170 if (normalized1.length > val && normalized2.length > val |
|
171 && normalized1.slice(-val) === normalized2.slice(-val)) { |
|
172 return true; |
|
173 } |
|
174 } |
|
175 return false; |
|
176 }, |
|
177 |
|
178 receiveMessage: function(aMessage) { |
|
179 if (DEBUG) debug("receiveMessage " + aMessage.name); |
|
180 let mm = aMessage.target; |
|
181 let msg = aMessage.data; |
|
182 |
|
183 switch (aMessage.name) { |
|
184 case "PhoneNumberService:FuzzyMatch": |
|
185 mm.sendAsyncMessage("PhoneNumberService:FuzzyMatch:Return:OK", { |
|
186 requestID: msg.requestID, |
|
187 result: this.fuzzyMatch(msg.options.number1, msg.options.number2) |
|
188 }); |
|
189 break; |
|
190 default: |
|
191 if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name); |
|
192 } |
|
193 } |
|
194 }; |
|
195 |
|
196 let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) |
|
197 .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; |
|
198 if (inParent) { |
|
199 Cu.import("resource://gre/modules/PhoneNumber.jsm"); |
|
200 XPCOMUtils.defineLazyServiceGetter(this, "ppmm", |
|
201 "@mozilla.org/parentprocessmessagemanager;1", |
|
202 "nsIMessageListenerManager"); |
|
203 PhoneNumberUtils.init(); |
|
204 } |
|
205 |