1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.telephony.cts;
17 
18 
19 import android.content.ContentResolver;
20 import android.content.ContentValues;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.os.RemoteException;
25 import android.provider.Contacts;
26 import android.provider.Contacts.People;
27 import android.telephony.PhoneNumberUtils;
28 import android.telephony.TelephonyManager;
29 import android.test.AndroidTestCase;
30 import android.text.Editable;
31 import android.text.Spannable;
32 import android.text.SpannableString;
33 import android.text.SpannableStringBuilder;
34 import android.text.style.TtsSpan;
35 
36 import java.util.Locale;
37 
38 public class PhoneNumberUtilsTest extends AndroidTestCase {
39     // mPhoneNumber ~ "+17005550020", length == 7.
40     private byte[] mPhoneNumber = { (byte) 0x91, (byte) 0x71, (byte) 0x00, (byte) 0x55,
41             (byte) 0x05, (byte) 0x20, (byte) 0xF0 };
42 
testExtractMethods()43     public void testExtractMethods() {
44 
45         // Test extractNetworkPortion
46         assertNull(PhoneNumberUtils.extractNetworkPortion(null));
47         assertEquals("+17005554141", PhoneNumberUtils.extractNetworkPortion("+17005554141"));
48         assertEquals("+17005554141*#N",
49                 PhoneNumberUtils.extractNetworkPortion("+1 (700).555-4141*#N"));
50         assertEquals("170055541", PhoneNumberUtils.extractNetworkPortion(
51                 String.format("1 (700).555-41%c1234", PhoneNumberUtils.PAUSE)));
52         assertEquals("**21**17005554141#",
53                 PhoneNumberUtils.extractNetworkPortion("**21**+17005554141#"));
54 
55         // Test extractPostDialPortion
56         assertNull(PhoneNumberUtils.extractPostDialPortion(null));
57         assertEquals("", PhoneNumberUtils.extractPostDialPortion("+17005554141"));
58         assertEquals(String.format("%c1234", PhoneNumberUtils.PAUSE),
59                 PhoneNumberUtils.extractPostDialPortion(
60                 String.format("+1 (700).555-41NN%c1234", PhoneNumberUtils.PAUSE)));
61         assertEquals(String.format("%c1234", PhoneNumberUtils.WAIT),
62                 PhoneNumberUtils.extractPostDialPortion(
63                 String.format("+1 (700).555-41NN%c1234", PhoneNumberUtils.WAIT)));
64         assertEquals(String.format("%c1234%c%cN", PhoneNumberUtils.WAIT, PhoneNumberUtils.PAUSE,
65                 PhoneNumberUtils.WAIT), PhoneNumberUtils
66                 .extractPostDialPortion(
67                         String.format("+1 (700).555-41NN%c1-2.34 %c%cN", PhoneNumberUtils.WAIT,
68                                 PhoneNumberUtils.PAUSE,
69                                 PhoneNumberUtils.WAIT)));
70     }
71 
testCallMethods()72     public void testCallMethods() {
73         // Test calledPartyBCDToString
74         assertEquals("+17005550020", PhoneNumberUtils.calledPartyBCDToString(mPhoneNumber, 0, 7));
75 
76         // Test toCallerIDMinMatch
77         assertNull(PhoneNumberUtils.toCallerIDMinMatch(null));
78 //        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
79 //        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
80 //        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
81 //        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
82 //        assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
83         assertEquals("", PhoneNumberUtils.toCallerIDMinMatch(""));
84         assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300"));
85         assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300"));
86         assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
87 
88         // Test networkPortionToCalledPartyBCD, calledPartyBCDToString
89         byte[] bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("+17005550020");
90         assertEquals(mPhoneNumber.length, bRet.length);
91         for (int i = 0; i < mPhoneNumber.length; i++) {
92             assertEquals(mPhoneNumber[i], bRet[i]);
93         }
94         bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020");
95         assertEquals("7005550020", PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length));
96 
97         // Test calledPartyBCDFragmentToString
98         assertEquals("1917005550020", PhoneNumberUtils.calledPartyBCDFragmentToString(mPhoneNumber,
99                 0, 7));
100 
101         // Test networkPortionToCalledPartyBCDWithLength
102         bRet = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength("+17005550020");
103         assertEquals(mPhoneNumber.length + 1, bRet.length);
104         for (int i = 0; i < mPhoneNumber.length; i++) {
105             assertEquals(mPhoneNumber[i], bRet[i + 1]);
106         }
107 
108         // Test numberToCalledPartyBCD
109         bRet = PhoneNumberUtils.numberToCalledPartyBCD("+17005550020");
110         assertEquals(mPhoneNumber.length, bRet.length);
111         for (int i = 0; i < mPhoneNumber.length; i++) {
112             assertEquals(mPhoneNumber[i], bRet[i]);
113         }
114     }
115 
testGetMethods()116     public void testGetMethods() throws RemoteException {
117         // Test getStrippedReversed
118         assertNull(PhoneNumberUtils.getStrippedReversed(null));
119         assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141"));
120         assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141,1234"));
121         assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141;1234"));
122         assertEquals("NN145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-41NN"));
123         assertEquals("", PhoneNumberUtils.getStrippedReversed(""));
124         assertEquals("#130#*+", PhoneNumberUtils.getStrippedReversed("+*#031#"));
125 
126         // Test getFormatTypeForLocale
127         int formatType = PhoneNumberUtils.getFormatTypeForLocale(Locale.CHINA);
128         assertEquals(PhoneNumberUtils.FORMAT_UNKNOWN, formatType);
129         formatType = PhoneNumberUtils.getFormatTypeForLocale(Locale.US);
130         assertEquals(PhoneNumberUtils.FORMAT_NANP, formatType);
131         formatType = PhoneNumberUtils.getFormatTypeForLocale(Locale.JAPAN);
132         assertEquals(PhoneNumberUtils.FORMAT_JAPAN, formatType);
133 
134         // Test getNumberFromIntent, query nothing, return null.
135         Intent intent = new Intent();
136         intent.setData(Contacts.People.CONTENT_URI);
137         Context context = getContext();
138         assertNull(PhoneNumberUtils.getNumberFromIntent(intent, context));
139 
140         intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+18005555555"));
141         assertEquals("+18005555555", PhoneNumberUtils.getNumberFromIntent(intent, getContext()));
142 
143         ContentResolver cr = getContext().getContentResolver();
144         Uri personRecord = null;
145         Uri phoneRecord = null;
146         try {
147             // insert a contact with phone number
148             ContentValues values = new ContentValues();
149             values.put(People.NAME, "CTS test contact");
150             personRecord = cr.insert(People.CONTENT_URI, values);
151             Uri phoneUri = Uri.withAppendedPath(personRecord, People.Phones.CONTENT_DIRECTORY);
152             values.clear();
153             values.put(People.Phones.TYPE, People.Phones.TYPE_HOME);
154             values.put(People.Phones.NUMBER, "+18005552871");
155             phoneRecord = cr.insert(phoneUri, values);
156 
157             intent = new Intent(Intent.ACTION_DIAL, phoneRecord);
158             assertEquals("+18005552871",
159                     PhoneNumberUtils.getNumberFromIntent(intent, getContext()));
160         } finally {
161             if (personRecord != null) {
162                 cr.delete(personRecord, null, null);
163             }
164             if (phoneRecord != null) {
165                 cr.delete(phoneRecord, null, null);
166             }
167         }
168     }
169 
testFormatMethods()170     public void testFormatMethods() {
171         // Test formatNanpNumber
172         SpannableStringBuilder builderNumber = new SpannableStringBuilder();
173         builderNumber.append("8005551212");
174         PhoneNumberUtils.formatNanpNumber(builderNumber);
175         assertEquals("800-555-1212", builderNumber.toString());
176         builderNumber.clear();
177         builderNumber.append("800555121");
178         PhoneNumberUtils.formatNanpNumber(builderNumber);
179         assertEquals("800-555-121", builderNumber.toString());
180         builderNumber.clear();
181         builderNumber.append("555-1212");
182         PhoneNumberUtils.formatNanpNumber(builderNumber);
183         assertEquals("555-1212", builderNumber.toString());
184         builderNumber.clear();
185         builderNumber.append("180055512");
186         PhoneNumberUtils.formatNanpNumber(builderNumber);
187         assertEquals("1-800-555-12", builderNumber.toString());
188         builderNumber.clear();
189         builderNumber.append("+180055512");
190         PhoneNumberUtils.formatNanpNumber(builderNumber);
191         assertEquals("+1-800-555-12", builderNumber.toString());
192 
193         // Test convertKeypadLettersToDigits
194         assertEquals("1-800-4664-411", PhoneNumberUtils
195                 .convertKeypadLettersToDigits("1-800-GOOG-411"));
196         assertEquals("1-800-466-4411", PhoneNumberUtils
197                 .convertKeypadLettersToDigits("1-800-466-4411"));
198         assertEquals("222-333-444-555-666-7777-888-9999", PhoneNumberUtils
199                 .convertKeypadLettersToDigits("ABC-DEF-GHI-JKL-MNO-PQRS-TUV-WXYZ"));
200         assertEquals("222-333-444-555-666-7777-888-9999", PhoneNumberUtils
201                 .convertKeypadLettersToDigits("abc-def-ghi-jkl-mno-pqrs-tuv-wxyz"));
202         assertEquals("(800) 222-3334", PhoneNumberUtils
203                 .convertKeypadLettersToDigits("(800) ABC-DEFG"));
204 
205         // Test stringFromStringAndTOA
206         assertNull(PhoneNumberUtils.stringFromStringAndTOA(null, 1));
207         assertEquals("+888888888", PhoneNumberUtils.stringFromStringAndTOA("888888888",
208                 PhoneNumberUtils.TOA_International));
209 
210         // Test formatJapaneseNumber
211         Editable jpEditNumber = Editable.Factory.getInstance().newEditable("0377777777");
212         PhoneNumberUtils.formatJapaneseNumber(jpEditNumber);
213         assertEquals("03-7777-7777", jpEditNumber.toString());
214         jpEditNumber = Editable.Factory.getInstance().newEditable("09077777777");
215         PhoneNumberUtils.formatJapaneseNumber(jpEditNumber);
216         assertEquals("090-7777-7777", jpEditNumber.toString());
217         jpEditNumber = Editable.Factory.getInstance().newEditable("0120777777");
218         PhoneNumberUtils.formatJapaneseNumber(jpEditNumber);
219         assertEquals("0120-777-777", jpEditNumber.toString());
220         jpEditNumber = Editable.Factory.getInstance().newEditable("+81377777777");
221         PhoneNumberUtils.formatJapaneseNumber(jpEditNumber);
222         assertEquals("+81-3-7777-7777", jpEditNumber.toString());
223         jpEditNumber = Editable.Factory.getInstance().newEditable("+819077777777");
224         PhoneNumberUtils.formatJapaneseNumber(jpEditNumber);
225         assertEquals("+81-90-7777-7777", jpEditNumber.toString());
226 
227         // Test formatNumber(String). Only numbers begin with +1 or +81 can be formatted.
228         assertEquals("+1-888-888-888", PhoneNumberUtils.formatNumber("+1888888888"));
229         // Test formatNumber(Editable, int)
230         Editable editNumber = Editable.Factory.getInstance().newEditable("0377777777");
231         PhoneNumberUtils.formatNumber(editNumber, PhoneNumberUtils.FORMAT_UNKNOWN);
232         assertEquals("0377777777", editNumber.toString());
233         editNumber = Editable.Factory.getInstance().newEditable("+177777777");
234         PhoneNumberUtils.formatNumber(editNumber, PhoneNumberUtils.FORMAT_UNKNOWN);
235         assertEquals("+1-777-777-77", editNumber.toString());
236         editNumber = Editable.Factory.getInstance().newEditable("+8177777777");
237         PhoneNumberUtils.formatNumber(editNumber, PhoneNumberUtils.FORMAT_UNKNOWN);
238         assertEquals("+81-77-777-777", editNumber.toString());
239 
240         // Test stripSeparators
241         assertEquals("+188888888", PhoneNumberUtils.stripSeparators("+188-888-888"));
242 
243         // Test toaFromString
244         assertEquals(PhoneNumberUtils.TOA_International, PhoneNumberUtils
245                 .toaFromString("+88888888"));
246         assertEquals(PhoneNumberUtils.TOA_Unknown, PhoneNumberUtils.toaFromString("88888888"));
247     }
248 
testJudgeMethods()249     public void testJudgeMethods() {
250         // Test is12Key, isDialable, isISODigit, isReallyDialable, isStartsPostDial
251         for (char c = '0'; c <= '9'; c++) {
252             assertTrue(PhoneNumberUtils.is12Key(c));
253             assertTrue(PhoneNumberUtils.isDialable(c));
254             assertTrue(PhoneNumberUtils.isISODigit(c));
255             assertTrue(PhoneNumberUtils.isNonSeparator(c));
256             assertTrue(PhoneNumberUtils.isReallyDialable(c));
257         }
258         char c = '*';
259         assertTrue(PhoneNumberUtils.is12Key(c));
260         assertTrue(PhoneNumberUtils.isDialable(c));
261         assertTrue(PhoneNumberUtils.isNonSeparator(c));
262         assertTrue(PhoneNumberUtils.isReallyDialable(c));
263         c = '#';
264         assertTrue(PhoneNumberUtils.is12Key(c));
265         assertTrue(PhoneNumberUtils.isDialable(c));
266         assertTrue(PhoneNumberUtils.isNonSeparator(c));
267         assertTrue(PhoneNumberUtils.isReallyDialable(c));
268         c = '$';
269         assertFalse(PhoneNumberUtils.is12Key(c));
270         assertFalse(PhoneNumberUtils.isDialable(c));
271         assertFalse(PhoneNumberUtils.isDialable(c));
272         c = '+';
273         assertTrue(PhoneNumberUtils.isDialable(c));
274         assertFalse(PhoneNumberUtils.isISODigit(c));
275         assertTrue(PhoneNumberUtils.isNonSeparator(c));
276         assertTrue(PhoneNumberUtils.isReallyDialable(c));
277         c = PhoneNumberUtils.WILD;
278         assertTrue(PhoneNumberUtils.isDialable(c));
279         assertTrue(PhoneNumberUtils.isNonSeparator(c));
280         assertFalse(PhoneNumberUtils.isReallyDialable(c));
281         c = PhoneNumberUtils.WAIT;
282         assertTrue(PhoneNumberUtils.isNonSeparator(c));
283         assertTrue(PhoneNumberUtils.isStartsPostDial(c));
284         c = PhoneNumberUtils.PAUSE;
285         assertTrue(PhoneNumberUtils.isNonSeparator(c));
286         assertTrue(PhoneNumberUtils.isStartsPostDial(c));
287         c = '8';
288         assertFalse(PhoneNumberUtils.isStartsPostDial(c));
289 
290         // Test isEmergencyNumber, now only know US emergency number
291         TelephonyManager tm = (TelephonyManager)getContext().getSystemService(
292                  Context.TELEPHONY_SERVICE);
293         // Test isEmergencyNumber, now only know US emergency number
294         if ("US".equals(tm.getSimCountryIso())) {
295             assertTrue(PhoneNumberUtils.isEmergencyNumber("911"));
296             assertFalse(PhoneNumberUtils.isEmergencyNumber("119"));
297         }
298 
299         // Test isGlobalPhoneNumber
300         assertTrue(PhoneNumberUtils.isGlobalPhoneNumber("+17005554141"));
301         assertFalse(PhoneNumberUtils.isGlobalPhoneNumber("android"));
302 
303         // Test isWellFormedSmsAddress
304         assertTrue(PhoneNumberUtils.isWellFormedSmsAddress("+17005554141"));
305         assertFalse(PhoneNumberUtils.isWellFormedSmsAddress("android"));
306     }
307 
testIsUriNumber()308     public void testIsUriNumber() {
309         assertTrue(PhoneNumberUtils.isUriNumber("foo@google.com"));
310         assertTrue(PhoneNumberUtils.isUriNumber("xyz@zzz.org"));
311         assertFalse(PhoneNumberUtils.isUriNumber("+15103331245"));
312         assertFalse(PhoneNumberUtils.isUriNumber("+659231235"));
313     }
314 
testGetUsernameFromUriNumber()315     public void testGetUsernameFromUriNumber() {
316         assertEquals("john", PhoneNumberUtils.getUsernameFromUriNumber("john@myorg.com"));
317         assertEquals("tim_123", PhoneNumberUtils.getUsernameFromUriNumber("tim_123@zzz.org"));
318         assertEquals("5103331245", PhoneNumberUtils.getUsernameFromUriNumber("5103331245"));
319     }
320 
testConvertAndStrip()321     public void testConvertAndStrip() {
322         // Untouched number.
323         assertEquals("123456789", PhoneNumberUtils.convertAndStrip("123456789"));
324         // Dashes should be stripped, legal separators (i.e. wild character remain untouched)
325         assertEquals("+15103331245*123", PhoneNumberUtils.convertAndStrip("+1-510-333-1245*123"));
326         // Arabic digits should be converted
327         assertEquals("5567861616", PhoneNumberUtils.convertAndStrip("٥‎٥‎٦‎٧‎٨‎٦‎١‎٦‎١‎٦‎"));
328         // Arabic digits converted and spaces stripped
329         assertEquals("5567861616", PhoneNumberUtils.convertAndStrip("٥‎ ٥‎٦‎ ٧‎ ٨‎ ٦‎ ١‎ ٦‎ ١‎ ٦‎"));
330 
331     }
332 
testGetPhoneTtsSpan()333     public void testGetPhoneTtsSpan() {
334         // Setup: phone number without a country code. Lets keep coverage minimal to avoid
335         // exercising the underlying PhoneNumberUtil or constraining localization changes.
336         String phoneNumber = "6512223333";
337         // Execute
338         TtsSpan ttsSpan = PhoneNumberUtils.createTtsSpan(phoneNumber);
339         // Verify: the created TtsSpan contains the phone number.
340         assertEquals("6512223333", ttsSpan.getArgs().get(TtsSpan.ARG_NUMBER_PARTS));
341     }
342 
testAddPhoneTtsSpan()343     public void testAddPhoneTtsSpan() {
344         // Setup: phone number without a country code. Lets keep coverage minimal to avoid
345         // exercising the underlying PhoneNumberUtil or constraining localization changes.
346         Spannable spannable = new SpannableString("Hello 6502223333");
347         // Execute
348         PhoneNumberUtils.addTtsSpan(spannable, 5, spannable.length());
349         // Verify: the Spannable is annotated with a TtsSpan in the correct location.
350         TtsSpan[] ttsSpans = spannable.getSpans(5, spannable.length() - 1, TtsSpan.class);
351         assertEquals(1, ttsSpans.length);
352         assertEquals("6502223333", ttsSpans[0].getArgs().get(TtsSpan.ARG_NUMBER_PARTS));
353     }
354 
testGetPhoneTtsSpannable()355     public void testGetPhoneTtsSpannable() {
356         // Setup: phone number without a country code. Lets keep coverage minimal to avoid
357         // exercising the underlying PhoneNumberUtil or constraining localization changes.
358         CharSequence phoneNumber = "6512223333";
359         // Execute
360         Spannable spannable = (Spannable) PhoneNumberUtils.createTtsSpannable(phoneNumber);
361         // Verify: returned char sequence contains a TtsSpan with the phone number in it
362         TtsSpan[] ttsSpans = spannable.getSpans(0, spannable.length() - 1, TtsSpan.class);
363         assertEquals(1, ttsSpans.length);
364         assertEquals("6512223333", ttsSpans[0].getArgs().get(TtsSpan.ARG_NUMBER_PARTS));
365     }
366 }
367