Home | History | Annotate | Download | only in phonenumbers
      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, it is impossible to append additional digits to an emergency number to dial the
     88     // number.
     89     return (!allowPrefixMatch || regionCode.equals("BR"))
     90         ? emergencyNumberPattern.matcher(normalizedNumber).matches()
     91         : emergencyNumberPattern.matcher(normalizedNumber).lookingAt();
     92   }
     93 }
     94