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 import static androidx.test.InstrumentationRegistry.getContext; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 25 import android.content.ContentResolver; 26 import android.content.ContentValues; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.net.Uri; 30 import android.os.RemoteException; 31 import android.provider.Contacts; 32 import android.provider.Contacts.People; 33 import android.telephony.PhoneNumberUtils; 34 import android.telephony.SubscriptionManager; 35 import android.telephony.TelephonyManager; 36 import android.text.Editable; 37 import android.text.Spannable; 38 import android.text.SpannableString; 39 import android.text.SpannableStringBuilder; 40 import android.text.style.TtsSpan; 41 42 import org.junit.After; 43 import org.junit.Before; 44 import org.junit.Test; 45 46 import java.util.Locale; 47 48 public class PhoneNumberUtilsTest { 49 private static final int MIN_MATCH = 7; 50 51 // mPhoneNumber ~ "+17005550020", length == 7. 52 private byte[] mPhoneNumber = { (byte) 0x91, (byte) 0x71, (byte) 0x00, (byte) 0x55, 53 (byte) 0x05, (byte) 0x20, (byte) 0xF0 }; 54 55 private int mOldMinMatch; 56 57 @Before setUp()58 public void setUp() throws Exception { 59 mOldMinMatch = PhoneNumberUtils.getMinMatchForTest(); 60 PhoneNumberUtils.setMinMatchForTest(MIN_MATCH); 61 } 62 63 @After tearDown()64 public void tearDown() throws Exception { 65 PhoneNumberUtils.setMinMatchForTest(mOldMinMatch); 66 } 67 68 @Test testExtractMethods()69 public void testExtractMethods() { 70 71 // Test extractNetworkPortion 72 assertNull(PhoneNumberUtils.extractNetworkPortion(null)); 73 assertEquals("+17005554141", PhoneNumberUtils.extractNetworkPortion("+17005554141")); 74 assertEquals("+17005554141*#N", 75 PhoneNumberUtils.extractNetworkPortion("+1 (700).555-4141*#N")); 76 assertEquals("170055541", PhoneNumberUtils.extractNetworkPortion( 77 String.format("1 (700).555-41%c1234", PhoneNumberUtils.PAUSE))); 78 assertEquals("**21**17005554141#", 79 PhoneNumberUtils.extractNetworkPortion("**21**+17005554141#")); 80 81 // Test extractPostDialPortion 82 assertNull(PhoneNumberUtils.extractPostDialPortion(null)); 83 assertEquals("", PhoneNumberUtils.extractPostDialPortion("+17005554141")); 84 assertEquals(String.format("%c1234", PhoneNumberUtils.PAUSE), 85 PhoneNumberUtils.extractPostDialPortion( 86 String.format("+1 (700).555-41NN%c1234", PhoneNumberUtils.PAUSE))); 87 assertEquals(String.format("%c1234", PhoneNumberUtils.WAIT), 88 PhoneNumberUtils.extractPostDialPortion( 89 String.format("+1 (700).555-41NN%c1234", PhoneNumberUtils.WAIT))); 90 assertEquals(String.format("%c1234%c%cN", PhoneNumberUtils.WAIT, PhoneNumberUtils.PAUSE, 91 PhoneNumberUtils.WAIT), PhoneNumberUtils 92 .extractPostDialPortion( 93 String.format("+1 (700).555-41NN%c1-2.34 %c%cN", PhoneNumberUtils.WAIT, 94 PhoneNumberUtils.PAUSE, 95 PhoneNumberUtils.WAIT))); 96 assertEquals("example", PhoneNumberUtils.getUsernameFromUriNumber("example@example.com")); 97 } 98 99 @Test testCallMethods()100 public void testCallMethods() { 101 // Test calledPartyBCDToString 102 assertEquals("+17005550020", PhoneNumberUtils.calledPartyBCDToString(mPhoneNumber, 0, 7)); 103 104 // Test toCallerIDMinMatch 105 assertNull(PhoneNumberUtils.toCallerIDMinMatch(null)); 106 // assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141")); 107 // assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141")); 108 // assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234")); 109 // assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234")); 110 // assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN")); 111 assertEquals("", PhoneNumberUtils.toCallerIDMinMatch("")); 112 assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300")); 113 assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300")); 114 assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#")); 115 116 // Test networkPortionToCalledPartyBCD, calledPartyBCDToString 117 byte[] bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("+17005550020"); 118 assertEquals(mPhoneNumber.length, bRet.length); 119 for (int i = 0; i < mPhoneNumber.length; i++) { 120 assertEquals(mPhoneNumber[i], bRet[i]); 121 } 122 bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020"); 123 assertEquals("7005550020", PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length)); 124 125 // Test calledPartyBCDFragmentToString 126 assertEquals("1917005550020", PhoneNumberUtils.calledPartyBCDFragmentToString(mPhoneNumber, 127 0, 7)); 128 129 // Test networkPortionToCalledPartyBCDWithLength 130 bRet = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength("+17005550020"); 131 assertEquals(mPhoneNumber.length + 1, bRet.length); 132 for (int i = 0; i < mPhoneNumber.length; i++) { 133 assertEquals(mPhoneNumber[i], bRet[i + 1]); 134 } 135 136 // Test numberToCalledPartyBCD 137 bRet = PhoneNumberUtils.numberToCalledPartyBCD("+17005550020"); 138 assertEquals(mPhoneNumber.length, bRet.length); 139 for (int i = 0; i < mPhoneNumber.length; i++) { 140 assertEquals(mPhoneNumber[i], bRet[i]); 141 } 142 } 143 144 @Test testGetMethods()145 public void testGetMethods() throws RemoteException { 146 // Test getStrippedReversed 147 assertNull(PhoneNumberUtils.getStrippedReversed(null)); 148 assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141")); 149 assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141,1234")); 150 assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141;1234")); 151 assertEquals("NN145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-41NN")); 152 assertEquals("", PhoneNumberUtils.getStrippedReversed("")); 153 assertEquals("#130#*+", PhoneNumberUtils.getStrippedReversed("+*#031#")); 154 155 // Test getFormatTypeForLocale 156 int formatType = PhoneNumberUtils.getFormatTypeForLocale(Locale.CHINA); 157 assertEquals(PhoneNumberUtils.FORMAT_UNKNOWN, formatType); 158 formatType = PhoneNumberUtils.getFormatTypeForLocale(Locale.US); 159 assertEquals(PhoneNumberUtils.FORMAT_NANP, formatType); 160 formatType = PhoneNumberUtils.getFormatTypeForLocale(Locale.JAPAN); 161 assertEquals(PhoneNumberUtils.FORMAT_JAPAN, formatType); 162 163 // Test getNumberFromIntent, query nothing, return null. 164 Intent intent = new Intent(); 165 intent.setData(Contacts.People.CONTENT_URI); 166 Context context = getContext(); 167 assertNull(PhoneNumberUtils.getNumberFromIntent(intent, context)); 168 169 intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+18005555555")); 170 assertEquals("+18005555555", PhoneNumberUtils.getNumberFromIntent(intent, getContext())); 171 172 ContentResolver cr = getContext().getContentResolver(); 173 Uri personRecord = null; 174 Uri phoneRecord = null; 175 try { 176 // insert a contact with phone number 177 ContentValues values = new ContentValues(); 178 values.put(People.NAME, "CTS test contact"); 179 personRecord = cr.insert(People.CONTENT_URI, values); 180 Uri phoneUri = Uri.withAppendedPath(personRecord, People.Phones.CONTENT_DIRECTORY); 181 values.clear(); 182 values.put(People.Phones.TYPE, People.Phones.TYPE_HOME); 183 values.put(People.Phones.NUMBER, "+18005552871"); 184 phoneRecord = cr.insert(phoneUri, values); 185 186 intent = new Intent(Intent.ACTION_DIAL, phoneRecord); 187 assertEquals("+18005552871", 188 PhoneNumberUtils.getNumberFromIntent(intent, getContext())); 189 } finally { 190 if (personRecord != null) { 191 cr.delete(personRecord, null, null); 192 } 193 if (phoneRecord != null) { 194 cr.delete(phoneRecord, null, null); 195 } 196 } 197 } 198 199 @Test testFormatMethods()200 public void testFormatMethods() { 201 // Test formatNanpNumber 202 SpannableStringBuilder builderNumber = new SpannableStringBuilder(); 203 builderNumber.append("8005551212"); 204 PhoneNumberUtils.formatNanpNumber(builderNumber); 205 assertEquals("800-555-1212", builderNumber.toString()); 206 builderNumber.clear(); 207 builderNumber.append("800555121"); 208 PhoneNumberUtils.formatNanpNumber(builderNumber); 209 assertEquals("800-555-121", builderNumber.toString()); 210 builderNumber.clear(); 211 builderNumber.append("555-1212"); 212 PhoneNumberUtils.formatNanpNumber(builderNumber); 213 assertEquals("555-1212", builderNumber.toString()); 214 builderNumber.clear(); 215 builderNumber.append("180055512"); 216 PhoneNumberUtils.formatNanpNumber(builderNumber); 217 assertEquals("1-800-555-12", builderNumber.toString()); 218 builderNumber.clear(); 219 builderNumber.append("+180055512"); 220 PhoneNumberUtils.formatNanpNumber(builderNumber); 221 assertEquals("+1-800-555-12", builderNumber.toString()); 222 223 // Test convertKeypadLettersToDigits 224 assertEquals("1-800-4664-411", PhoneNumberUtils 225 .convertKeypadLettersToDigits("1-800-GOOG-411")); 226 assertEquals("1-800-466-4411", PhoneNumberUtils 227 .convertKeypadLettersToDigits("1-800-466-4411")); 228 assertEquals("222-333-444-555-666-7777-888-9999", PhoneNumberUtils 229 .convertKeypadLettersToDigits("ABC-DEF-GHI-JKL-MNO-PQRS-TUV-WXYZ")); 230 assertEquals("222-333-444-555-666-7777-888-9999", PhoneNumberUtils 231 .convertKeypadLettersToDigits("abc-def-ghi-jkl-mno-pqrs-tuv-wxyz")); 232 assertEquals("(800) 222-3334", PhoneNumberUtils 233 .convertKeypadLettersToDigits("(800) ABC-DEFG")); 234 235 // Test stringFromStringAndTOA 236 assertNull(PhoneNumberUtils.stringFromStringAndTOA(null, 1)); 237 assertEquals("+888888888", PhoneNumberUtils.stringFromStringAndTOA("888888888", 238 PhoneNumberUtils.TOA_International)); 239 240 // Test formatJapaneseNumber 241 Editable jpEditNumber = Editable.Factory.getInstance().newEditable("0377777777"); 242 PhoneNumberUtils.formatJapaneseNumber(jpEditNumber); 243 assertEquals("03-7777-7777", jpEditNumber.toString()); 244 jpEditNumber = Editable.Factory.getInstance().newEditable("09077777777"); 245 PhoneNumberUtils.formatJapaneseNumber(jpEditNumber); 246 assertEquals("090-7777-7777", jpEditNumber.toString()); 247 jpEditNumber = Editable.Factory.getInstance().newEditable("0120777777"); 248 PhoneNumberUtils.formatJapaneseNumber(jpEditNumber); 249 assertEquals("0120-777-777", jpEditNumber.toString()); 250 jpEditNumber = Editable.Factory.getInstance().newEditable("+81377777777"); 251 PhoneNumberUtils.formatJapaneseNumber(jpEditNumber); 252 assertEquals("+81-3-7777-7777", jpEditNumber.toString()); 253 jpEditNumber = Editable.Factory.getInstance().newEditable("+819077777777"); 254 PhoneNumberUtils.formatJapaneseNumber(jpEditNumber); 255 assertEquals("+81-90-7777-7777", jpEditNumber.toString()); 256 257 // Test formatNumber(String). Only numbers begin with +1 or +81 can be formatted. 258 assertEquals("+1-888-888-888", PhoneNumberUtils.formatNumber("+1888888888")); 259 // Test formatNumber(Editable, int) 260 Editable editNumber = Editable.Factory.getInstance().newEditable("0377777777"); 261 PhoneNumberUtils.formatNumber(editNumber, PhoneNumberUtils.FORMAT_UNKNOWN); 262 assertEquals("0377777777", editNumber.toString()); 263 editNumber = Editable.Factory.getInstance().newEditable("+177777777"); 264 PhoneNumberUtils.formatNumber(editNumber, PhoneNumberUtils.FORMAT_UNKNOWN); 265 assertEquals("+1-777-777-77", editNumber.toString()); 266 editNumber = Editable.Factory.getInstance().newEditable("+8177777777"); 267 PhoneNumberUtils.formatNumber(editNumber, PhoneNumberUtils.FORMAT_UNKNOWN); 268 assertEquals("+81-77-777-777", editNumber.toString()); 269 270 // Test stripSeparators 271 assertEquals("+188888888", PhoneNumberUtils.stripSeparators("+188-888-888")); 272 273 // Test toaFromString 274 assertEquals(PhoneNumberUtils.TOA_International, PhoneNumberUtils 275 .toaFromString("+88888888")); 276 assertEquals(PhoneNumberUtils.TOA_Unknown, PhoneNumberUtils.toaFromString("88888888")); 277 } 278 279 @Test testJudgeMethods()280 public void testJudgeMethods() { 281 // Test is12Key, isDialable, isISODigit, isReallyDialable, isStartsPostDial 282 for (char c = '0'; c <= '9'; c++) { 283 assertTrue(PhoneNumberUtils.is12Key(c)); 284 assertTrue(PhoneNumberUtils.isDialable(c)); 285 assertTrue(PhoneNumberUtils.isISODigit(c)); 286 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 287 assertTrue(PhoneNumberUtils.isReallyDialable(c)); 288 } 289 char c = '*'; 290 assertTrue(PhoneNumberUtils.is12Key(c)); 291 assertTrue(PhoneNumberUtils.isDialable(c)); 292 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 293 assertTrue(PhoneNumberUtils.isReallyDialable(c)); 294 c = '#'; 295 assertTrue(PhoneNumberUtils.is12Key(c)); 296 assertTrue(PhoneNumberUtils.isDialable(c)); 297 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 298 assertTrue(PhoneNumberUtils.isReallyDialable(c)); 299 c = '$'; 300 assertFalse(PhoneNumberUtils.is12Key(c)); 301 assertFalse(PhoneNumberUtils.isDialable(c)); 302 assertFalse(PhoneNumberUtils.isDialable(c)); 303 c = '+'; 304 assertTrue(PhoneNumberUtils.isDialable(c)); 305 assertFalse(PhoneNumberUtils.isISODigit(c)); 306 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 307 assertTrue(PhoneNumberUtils.isReallyDialable(c)); 308 c = PhoneNumberUtils.WILD; 309 assertTrue(PhoneNumberUtils.isDialable(c)); 310 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 311 assertFalse(PhoneNumberUtils.isReallyDialable(c)); 312 c = PhoneNumberUtils.WAIT; 313 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 314 assertTrue(PhoneNumberUtils.isStartsPostDial(c)); 315 c = PhoneNumberUtils.PAUSE; 316 assertTrue(PhoneNumberUtils.isNonSeparator(c)); 317 assertTrue(PhoneNumberUtils.isStartsPostDial(c)); 318 c = '8'; 319 assertFalse(PhoneNumberUtils.isStartsPostDial(c)); 320 321 // Test isEmergencyNumber, now only know US emergency number 322 TelephonyManager tm = (TelephonyManager)getContext().getSystemService( 323 Context.TELEPHONY_SERVICE); 324 // Test isEmergencyNumber, now only know US emergency number 325 if ("US".equals(tm.getSimCountryIso())) { 326 assertTrue(PhoneNumberUtils.isEmergencyNumber("911")); 327 assertFalse(PhoneNumberUtils.isEmergencyNumber("119")); 328 } 329 330 // Test isGlobalPhoneNumber 331 assertTrue(PhoneNumberUtils.isGlobalPhoneNumber("+17005554141")); 332 assertFalse(PhoneNumberUtils.isGlobalPhoneNumber("android")); 333 334 // Test isWellFormedSmsAddress 335 assertTrue(PhoneNumberUtils.isWellFormedSmsAddress("+17005554141")); 336 assertFalse(PhoneNumberUtils.isWellFormedSmsAddress("android")); 337 338 // Test isUriNumber 339 assertTrue(PhoneNumberUtils.isUriNumber("example@example.com")); 340 assertFalse(PhoneNumberUtils.isUriNumber("+18005555555")); 341 342 // Test isVoicemailNumber -- this is closely tied to the SIM so we'll just test some basic 343 // cases 344 assertFalse(PhoneNumberUtils.isVoiceMailNumber(getContext(), 345 SubscriptionManager.getDefaultSubscriptionId(), null)); 346 assertFalse(PhoneNumberUtils.isVoiceMailNumber(getContext(), 347 SubscriptionManager.getDefaultSubscriptionId(), "")); 348 349 } 350 351 @Test testGetPhoneTtsSpan()352 public void testGetPhoneTtsSpan() { 353 // Setup: phone number without a country code. Lets keep coverage minimal to avoid 354 // exercising the underlying PhoneNumberUtil or constraining localization changes. 355 String phoneNumber = "6512223333"; 356 // Execute 357 TtsSpan ttsSpan = PhoneNumberUtils.createTtsSpan(phoneNumber); 358 // Verify: the created TtsSpan contains the phone number. 359 assertEquals("6512223333", ttsSpan.getArgs().get(TtsSpan.ARG_NUMBER_PARTS)); 360 } 361 362 @Test testAddPhoneTtsSpan()363 public void testAddPhoneTtsSpan() { 364 // Setup: phone number without a country code. Lets keep coverage minimal to avoid 365 // exercising the underlying PhoneNumberUtil or constraining localization changes. 366 Spannable spannable = new SpannableString("Hello 6502223333"); 367 // Execute 368 PhoneNumberUtils.addTtsSpan(spannable, 5, spannable.length()); 369 // Verify: the Spannable is annotated with a TtsSpan in the correct location. 370 TtsSpan[] ttsSpans = spannable.getSpans(5, spannable.length() - 1, TtsSpan.class); 371 assertEquals(1, ttsSpans.length); 372 assertEquals("6502223333", ttsSpans[0].getArgs().get(TtsSpan.ARG_NUMBER_PARTS)); 373 } 374 375 @Test testGetPhoneTtsSpannable()376 public void testGetPhoneTtsSpannable() { 377 // Setup: phone number without a country code. Lets keep coverage minimal to avoid 378 // exercising the underlying PhoneNumberUtil or constraining localization changes. 379 CharSequence phoneNumber = "6512223333"; 380 // Execute 381 Spannable spannable = (Spannable) PhoneNumberUtils.createTtsSpannable(phoneNumber); 382 // Verify: returned char sequence contains a TtsSpan with the phone number in it 383 TtsSpan[] ttsSpans = spannable.getSpans(0, spannable.length() - 1, TtsSpan.class); 384 assertEquals(1, ttsSpans.length); 385 assertEquals("6512223333", ttsSpans[0].getArgs().get(TtsSpan.ARG_NUMBER_PARTS)); 386 } 387 388 @Test testFormatNumberToE164()389 public void testFormatNumberToE164() { 390 assertNull(PhoneNumberUtils.formatNumber("invalid#", "US")); 391 assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "US")); 392 393 assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "US")); 394 assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "US")); 395 assertEquals("+12023458246", PhoneNumberUtils.formatNumberToE164("(202)345-8246", "US")); 396 assertEquals("+812023458246", PhoneNumberUtils.formatNumberToE164("202-345-8246", "JP")); 397 } 398 } 399