1 /* 2 * Copyright (C) 2011 The Libphonenumber Authors 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 17 package com.android.i18n.phonenumbers; 18 19 import com.android.i18n.phonenumbers.Phonemetadata.PhoneMetadata; 20 21 import java.util.regex.Pattern; 22 23 /* 24 * Utility for international short phone numbers, such as short codes and emergency numbers. Note 25 * most commercial short numbers are not handled here, but by the PhoneNumberUtil. 26 * 27 * @author Shaopeng Jia 28 */ 29 public class ShortNumberUtil { 30 31 private final PhoneNumberUtil phoneUtil; 32 33 public ShortNumberUtil() { 34 phoneUtil = PhoneNumberUtil.getInstance(); 35 } 36 37 // @VisibleForTesting 38 ShortNumberUtil(PhoneNumberUtil util) { 39 phoneUtil = util; 40 } 41 42 /** 43 * Returns true if the number might be used to connect to an emergency service in the given 44 * region. 45 * 46 * This method takes into account cases where the number might contain formatting, or might have 47 * additional digits appended (when it is okay to do that in the region specified). 48 * 49 * @param number the phone number to test 50 * @param regionCode the region where the phone number is being dialed 51 * @return if the number might be used to connect to an emergency service in the given region. 52 */ 53 public boolean connectsToEmergencyNumber(String number, String regionCode) { 54 return matchesEmergencyNumberHelper(number, regionCode, true /* allows prefix match */); 55 } 56 57 /** 58 * Returns true if the number exactly matches an emergency service number in the given region. 59 * 60 * This method takes into account cases where the number might contain formatting, but doesn't 61 * allow additional digits to be appended. 62 * 63 * @param number the phone number to test 64 * @param regionCode the region where the phone number is being dialed 65 * @return if the number exactly matches an emergency services number in the given region. 66 */ 67 public boolean isEmergencyNumber(String number, String regionCode) { 68 return matchesEmergencyNumberHelper(number, regionCode, false /* doesn't allow prefix match */); 69 } 70 71 private boolean matchesEmergencyNumberHelper(String number, String regionCode, 72 boolean allowPrefixMatch) { 73 number = PhoneNumberUtil.extractPossibleNumber(number); 74 if (PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(number).lookingAt()) { 75 // Returns false if the number starts with a plus sign. We don't believe dialing the country 76 // code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can 77 // add additional logic here to handle it. 78 return false; 79 } 80 PhoneMetadata metadata = phoneUtil.getMetadataForRegion(regionCode); 81 if (metadata == null || !metadata.hasEmergency()) { 82 return false; 83 } 84 Pattern emergencyNumberPattern = 85 Pattern.compile(metadata.getEmergency().getNationalNumberPattern()); 86 String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number); 87 // In Brazil, emergency numbers don't work when additional digits are appended. 88 return (!allowPrefixMatch || regionCode.equals("BR")) 89 ? emergencyNumberPattern.matcher(normalizedNumber).matches() 90 : emergencyNumberPattern.matcher(normalizedNumber).lookingAt(); 91 } 92 } 93