• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ShortNumberUtil()33   public ShortNumberUtil() {
34     phoneUtil = PhoneNumberUtil.getInstance();
35   }
36 
37   // @VisibleForTesting
ShortNumberUtil(PhoneNumberUtil util)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    */
connectsToEmergencyNumber(String number, String regionCode)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    */
isEmergencyNumber(String number, String regionCode)67   public boolean isEmergencyNumber(String number, String regionCode) {
68     return matchesEmergencyNumberHelper(number, regionCode, false /* doesn't allow prefix match */);
69   }
70 
matchesEmergencyNumberHelper(String number, String regionCode, boolean allowPrefixMatch)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