1 /* 2 * Copyright (C) 2013 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 17 package com.android.dialer.util; 18 19 import android.content.Context; 20 import android.provider.CallLog; 21 import android.telecom.PhoneAccountHandle; 22 import android.text.TextUtils; 23 import android.util.Log; 24 import android.util.Pair; 25 26 import com.android.contacts.common.util.PhoneNumberHelper; 27 import com.android.contacts.common.util.TelephonyManagerUtils; 28 import com.google.common.collect.Sets; 29 import com.google.i18n.phonenumbers.NumberParseException; 30 import com.google.i18n.phonenumbers.Phonenumber; 31 import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; 32 33 import java.util.HashMap; 34 import java.util.Locale; 35 import java.util.Map; 36 import java.util.Set; 37 38 public class PhoneNumberUtil { 39 private static final String TAG = "PhoneNumberUtil"; 40 private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3"); 41 42 /** Returns true if it is possible to place a call to the given number. */ canPlaceCallsTo(CharSequence number, int presentation)43 public static boolean canPlaceCallsTo(CharSequence number, int presentation) { 44 return presentation == CallLog.Calls.PRESENTATION_ALLOWED 45 && !TextUtils.isEmpty(number) && !isLegacyUnknownNumbers(number); 46 } 47 48 /** 49 * Returns true if the given number is the number of the configured voicemail. To be able to 50 * mock-out this, it is not a static method. 51 */ isVoicemailNumber( Context context, PhoneAccountHandle accountHandle, CharSequence number)52 public static boolean isVoicemailNumber( 53 Context context, PhoneAccountHandle accountHandle, CharSequence number) { 54 if (TextUtils.isEmpty(number)) { 55 return false; 56 } 57 return TelecomUtil.isVoicemailNumber(context, accountHandle, number.toString()); 58 } 59 60 /** 61 * Returns true if the given number is a SIP address. To be able to mock-out this, it is not a 62 * static method. 63 */ isSipNumber(CharSequence number)64 public static boolean isSipNumber(CharSequence number) { 65 return number != null && PhoneNumberHelper.isUriNumber(number.toString()); 66 } 67 isUnknownNumberThatCanBeLookedUp( Context context, PhoneAccountHandle accountHandle, CharSequence number, int presentation)68 public static boolean isUnknownNumberThatCanBeLookedUp( 69 Context context, 70 PhoneAccountHandle accountHandle, 71 CharSequence number, 72 int presentation) { 73 if (presentation == CallLog.Calls.PRESENTATION_UNKNOWN) { 74 return false; 75 } 76 if (presentation == CallLog.Calls.PRESENTATION_RESTRICTED) { 77 return false; 78 } 79 if (presentation == CallLog.Calls.PRESENTATION_PAYPHONE) { 80 return false; 81 } 82 if (TextUtils.isEmpty(number)) { 83 return false; 84 } 85 if (isVoicemailNumber(context, accountHandle, number)) { 86 return false; 87 } 88 if (isLegacyUnknownNumbers(number)) { 89 return false; 90 } 91 return true; 92 } 93 isLegacyUnknownNumbers(CharSequence number)94 public static boolean isLegacyUnknownNumbers(CharSequence number) { 95 return number != null && LEGACY_UNKNOWN_NUMBERS.contains(number.toString()); 96 } 97 98 /** 99 * @return a geographical description string for the specified number. 100 * @see com.android.i18n.phonenumbers.PhoneNumberOfflineGeocoder 101 */ getGeoDescription(Context context, String number)102 public static String getGeoDescription(Context context, String number) { 103 Log.v(TAG, "getGeoDescription('" + pii(number) + "')..."); 104 105 if (TextUtils.isEmpty(number)) { 106 return null; 107 } 108 109 com.google.i18n.phonenumbers.PhoneNumberUtil util = 110 com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance(); 111 PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance(); 112 113 Locale locale = context.getResources().getConfiguration().locale; 114 String countryIso = TelephonyManagerUtils.getCurrentCountryIso(context, locale); 115 Phonenumber.PhoneNumber pn = null; 116 try { 117 Log.v(TAG, "parsing '" + pii(number) 118 + "' for countryIso '" + countryIso + "'..."); 119 pn = util.parse(number, countryIso); 120 Log.v(TAG, "- parsed number: " + pii(pn)); 121 } catch (NumberParseException e) { 122 Log.v(TAG, "getGeoDescription: NumberParseException for incoming number '" + 123 pii(number) + "'"); 124 } 125 126 if (pn != null) { 127 String description = geocoder.getDescriptionForNumber(pn, locale); 128 Log.v(TAG, "- got description: '" + description + "'"); 129 return description; 130 } 131 132 return null; 133 } 134 pii(Object pii)135 private static String pii(Object pii) { 136 return com.android.incallui.Log.pii(pii); 137 } 138 } 139