1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.util; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentResolver; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.pm.ApplicationInfo; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.pm.PackageManager; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.pm.PackageManager.NameNotFoundException; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.Cursor; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.ConnectivityManager; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.Settings; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.Telephony; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.util.ArrayMap; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.PhoneNumberUtils; 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.SmsManager; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.SubscriptionInfo; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.SubscriptionManager; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.TelephonyManager; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.Factory; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ParticipantData; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsSmsUtils; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.google.i18n.phonenumbers.NumberParseException; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.google.i18n.phonenumbers.PhoneNumberUtil; 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.lang.reflect.Method; 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList; 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.HashSet; 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.List; 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.Locale; 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This class abstracts away platform dependency of calling telephony related 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * platform APIs, mostly involving TelephonyManager, SubscriptionManager and 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * a bit of SmsManager. 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The class instance can only be obtained via the get(int subId) method parameterized 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * by a SIM subscription ID. On pre-L_MR1, the subId is not used and it has to be 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the default subId (-1). 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A convenient getDefault() method is provided for default subId (-1) on any platform 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic abstract class PhoneUtils { 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String TAG = LogUtil.BUGLE_TAG; 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int MINIMUM_PHONE_NUMBER_LENGTH_TO_FORMAT = 6; 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final List<SubscriptionInfo> EMPTY_SUBSCRIPTION_LIST = new ArrayList<>(); 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // The canonical phone number cache 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Each country gets its own cache. The following maps from ISO country code to 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // the country's cache. Each cache maps from original phone number to canonicalized phone 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final ArrayMap<String, ArrayMap<String, String>> sCanonicalPhoneNumberCache = 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new ArrayMap<>(); 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected final Context mContext; 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected final TelephonyManager mTelephonyManager; 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected final int mSubId; 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public PhoneUtils(int subId) { 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mSubId = subId; 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mContext = Factory.get().getApplicationContext(); 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTelephonyManager = 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the SIM's country code 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the country code on the SIM 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract String getSimCountry(); 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get number of SIM slots 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the SIM slot count 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int getSimSlotCount(); 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get SIM's carrier name 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the carrier name of the SIM 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract String getCarrierName(); 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if there is SIM inserted on the device 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if there is SIM inserted, false otherwise 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract boolean hasSim(); 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if the SIM is roaming 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the SIM is in romaing state, false otherwise 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract boolean isRoaming(); 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the MCC and MNC in integer of the SIM's provider 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an array of two ints, [0] is the MCC code and [1] is the MNC code 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int[] getMccMnc(); 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the mcc/mnc string 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the text of mccmnc string 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract String getSimOperatorNumeric(); 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the SIM's self raw number, i.e. not canonicalized 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param allowOverride Whether to use the app's setting to override the self number 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the original self number 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws IllegalStateException if no active subscription on L-MR1+ 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract String getSelfRawNumber(final boolean allowOverride); 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the "effective" subId, or the subId used in the context of actual messages, 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * conversations and subscription-specific settings, for the given "nominal" sub id. 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * For pre-L-MR1 platform, this should always be 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@value com.android.messaging.datamodel.data.ParticipantData#DEFAULT_SELF_SUB_ID}; 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * On the other hand, for L-MR1 and above, DEFAULT_SELF_SUB_ID will be mapped to the system 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * default subscription id for SMS. 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId The input subId 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the real subId if we can convert 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int getEffectiveSubId(int subId); 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the number of active subscriptions in the device. 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int getActiveSubscriptionCount(); 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get {@link SmsManager} instance 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the relevant SmsManager instance based on OS version and subId 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract SmsManager getSmsManager(); 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the default SMS subscription id 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the default sub ID 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int getDefaultSmsSubscriptionId(); 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns if there's currently a system default SIM selected for sending SMS. 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract boolean getHasPreferredSmsSim(); 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * For L_MR1, system may return a negative subId. Convert this into our own 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * subId, so that we consistently use -1 for invalid or default. 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * see b/18629526 and b/18670346 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param intent The push intent from system 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param extraName The name of the sub id extra 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the subId that is valid and meaningful for the app 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int getEffectiveIncomingSubIdFromSystem(Intent intent, String extraName); 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the subscription_id column value from a telephony provider cursor 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param cursor The database query cursor 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subIdIndex The index of the subId column in the cursor 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the subscription_id column value from the cursor 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract int getSubIdFromTelephony(Cursor cursor, int subIdIndex); 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if data roaming is enabled 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if data roaming is enabled, false otherwise 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract boolean isDataRoamingEnabled(); 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if mobile data is enabled 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if mobile data is enabled, false otherwise 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract boolean isMobileDataEnabled(); 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the set of self phone numbers, all normalized 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the set of normalized self phone numbers 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract HashSet<String> getNormalizedSelfNumbers(); 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This interface packages methods should only compile on L_MR1. 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This is needed to make unit tests happy when mockito tries to 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * mock these methods. Calling on these methods on L_MR1 requires 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * an extra invocation of toMr1(). 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public interface LMr1 { 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get this SIM's information. Only applies to L_MR1 above 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the subscription info of the SIM 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract SubscriptionInfo getActiveSubscriptionInfo(); 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the list of active SIMs in system. Only applies to L_MR1 above 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the list of subscription info for all inserted SIMs 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract List<SubscriptionInfo> getActiveSubscriptionInfoList(); 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Register subscription change listener. Only applies to L_MR1 above 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param listener The listener to register 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public abstract void registerOnSubscriptionsChangedListener( 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SubscriptionManager.OnSubscriptionsChangedListener listener); 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The PhoneUtils class for pre L_MR1 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static class PhoneUtilsPreLMR1 extends PhoneUtils { 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final ConnectivityManager mConnectivityManager; 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public PhoneUtilsPreLMR1() { 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super(ParticipantData.DEFAULT_SELF_SUB_ID); 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mConnectivityManager = 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSimCountry() { 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String country = mTelephonyManager.getSimCountryIso(); 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(country)) { 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return country.toUpperCase(); 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getSimSlotCount() { 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Don't support MSIM pre-L_MR1 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 1; 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getCarrierName() { 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.getNetworkOperatorName(); 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean hasSim() { 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT; 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isRoaming() { 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.isNetworkRoaming(); 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int[] getMccMnc() { 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String mccmnc = mTelephonyManager.getSimOperator(); 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mcc = 0; 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mnc = 0; 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mcc = Integer.parseInt(mccmnc.substring(0, 3)); 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mnc = Integer.parseInt(mccmnc.substring(3)); 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (Exception e) { 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(TAG, "PhoneUtils.getMccMnc: invalid string " + mccmnc, e); 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new int[]{mcc, mnc}; 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSimOperatorNumeric() { 314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.getSimOperator(); 315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSelfRawNumber(final boolean allowOverride) { 319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (allowOverride) { 320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String userDefinedNumber = getNumberFromPrefs(mContext, 321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ParticipantData.DEFAULT_SELF_SUB_ID); 322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!TextUtils.isEmpty(userDefinedNumber)) { 323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return userDefinedNumber; 324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.getLine1Number(); 327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getEffectiveSubId(int subId) { 331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.equals(ParticipantData.DEFAULT_SELF_SUB_ID, subId); 332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ParticipantData.DEFAULT_SELF_SUB_ID; 333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public SmsManager getSmsManager() { 337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return SmsManager.getDefault(); 338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getDefaultSmsSubscriptionId() { 342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.fail("PhoneUtils.getDefaultSmsSubscriptionId(): not supported before L MR1"); 343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ParticipantData.DEFAULT_SELF_SUB_ID; 344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean getHasPreferredSmsSim() { 348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // SIM selection is not supported pre-L_MR1. 349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getActiveSubscriptionCount() { 354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return hasSim() ? 1 : 0; 355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getEffectiveIncomingSubIdFromSystem(Intent intent, String extraName) { 359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Pre-L_MR1 always returns the default id 360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ParticipantData.DEFAULT_SELF_SUB_ID; 361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getSubIdFromTelephony(Cursor cursor, int subIdIndex) { 365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // No subscription_id column before L_MR1 366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ParticipantData.DEFAULT_SELF_SUB_ID; 367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @SuppressWarnings("deprecation") 371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isDataRoamingEnabled() { 372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean dataRoamingEnabled = false; 373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ContentResolver cr = mContext.getContentResolver(); 374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastJB_MR1()) { 375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd dataRoamingEnabled = 376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (Settings.Global.getInt(cr, Settings.Global.DATA_ROAMING, 0) != 0); 377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd dataRoamingEnabled = 379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (Settings.System.getInt(cr, Settings.System.DATA_ROAMING, 0) != 0); 380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return dataRoamingEnabled; 382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isMobileDataEnabled() { 386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean mobileDataEnabled = false; 387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Class cmClass = mConnectivityManager.getClass(); 389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Method method = cmClass.getDeclaredMethod("getMobileDataEnabled"); 390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd method.setAccessible(true); // Make the method callable 391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // get the setting for "mobile data" 392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mobileDataEnabled = (Boolean) method.invoke(mConnectivityManager); 393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final Exception e) { 394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtil.isMobileDataEnabled: system api not found", e); 395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mobileDataEnabled; 397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public HashSet<String> getNormalizedSelfNumbers() { 401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final HashSet<String> numbers = new HashSet<>(); 402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd numbers.add(getCanonicalForSelf(true/*allowOverride*/)); 403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return numbers; 404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The PhoneUtils class for L_MR1 409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static class PhoneUtilsLMR1 extends PhoneUtils implements LMr1 { 411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final SubscriptionManager mSubscriptionManager; 412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public PhoneUtilsLMR1(final int subId) { 414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super(subId); 415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mSubscriptionManager = SubscriptionManager.from(Factory.get().getApplicationContext()); 416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSimCountry() { 420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SubscriptionInfo subInfo = getActiveSubscriptionInfo(); 421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subInfo != null) { 422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String country = subInfo.getCountryIso(); 423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(country)) { 424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return country.toUpperCase(); 427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getSimSlotCount() { 433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mSubscriptionManager.getActiveSubscriptionInfoCountMax(); 434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getCarrierName() { 438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SubscriptionInfo subInfo = getActiveSubscriptionInfo(); 439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subInfo != null) { 440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final CharSequence displayName = subInfo.getDisplayName(); 441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!TextUtils.isEmpty(displayName)) { 442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return displayName.toString(); 443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final CharSequence carrierName = subInfo.getCarrierName(); 445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (carrierName != null) { 446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return carrierName.toString(); 447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean hasSim() { 454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mSubscriptionManager.getActiveSubscriptionInfoCount() > 0; 455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isRoaming() { 459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mSubscriptionManager.isNetworkRoaming(mSubId); 460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int[] getMccMnc() { 464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mcc = 0; 465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mnc = 0; 466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SubscriptionInfo subInfo = getActiveSubscriptionInfo(); 467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subInfo != null) { 468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mcc = subInfo.getMcc(); 469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mnc = subInfo.getMnc(); 470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new int[]{mcc, mnc}; 472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSimOperatorNumeric() { 476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // For L_MR1 we return the canonicalized (xxxxxx) string 477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getMccMncString(getMccMnc()); 478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSelfRawNumber(final boolean allowOverride) { 482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (allowOverride) { 483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String userDefinedNumber = getNumberFromPrefs(mContext, mSubId); 484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!TextUtils.isEmpty(userDefinedNumber)) { 485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return userDefinedNumber; 486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SubscriptionInfo subInfo = getActiveSubscriptionInfo(); 490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subInfo != null) { 491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String phoneNumber = subInfo.getNumber(); 492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(phoneNumber) && LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { 493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(TAG, "SubscriptionInfo phone number for self is empty!"); 494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return phoneNumber; 496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(TAG, "PhoneUtils.getSelfRawNumber: subInfo is null for " + mSubId); 498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalStateException("No active subscription"); 499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public SubscriptionInfo getActiveSubscriptionInfo() { 503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SubscriptionInfo subInfo = 505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mSubscriptionManager.getActiveSubscriptionInfo(mSubId); 506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subInfo == null) { 507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { 508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // This is possible if the sub id is no longer available. 509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(TAG, "PhoneUtils.getActiveSubscriptionInfo(): empty sub info for " 510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + mSubId); 511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return subInfo; 514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (Exception e) { 515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtils.getActiveSubscriptionInfo: system exception for " 516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + mSubId, e); 517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public List<SubscriptionInfo> getActiveSubscriptionInfoList() { 523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final List<SubscriptionInfo> subscriptionInfos = 524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mSubscriptionManager.getActiveSubscriptionInfoList(); 525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subscriptionInfos != null) { 526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return subscriptionInfos; 527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return EMPTY_SUBSCRIPTION_LIST; 529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getEffectiveSubId(int subId) { 533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subId == ParticipantData.DEFAULT_SELF_SUB_ID) { 534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getDefaultSmsSubscriptionId(); 535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return subId; 537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void registerOnSubscriptionsChangedListener( 541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SubscriptionManager.OnSubscriptionsChangedListener listener) { 542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mSubscriptionManager.addOnSubscriptionsChangedListener(listener); 543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public SmsManager getSmsManager() { 547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return SmsManager.getSmsManagerForSubscriptionId(mSubId); 548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getDefaultSmsSubscriptionId() { 552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int systemDefaultSubId = SmsManager.getDefaultSmsSubscriptionId(); 553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (systemDefaultSubId < 0) { 554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Always use -1 for any negative subId from system 555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ParticipantData.DEFAULT_SELF_SUB_ID; 556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return systemDefaultSubId; 558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean getHasPreferredSmsSim() { 562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getDefaultSmsSubscriptionId() != ParticipantData.DEFAULT_SELF_SUB_ID; 563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getActiveSubscriptionCount() { 567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mSubscriptionManager.getActiveSubscriptionInfoCount(); 568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getEffectiveIncomingSubIdFromSystem(Intent intent, String extraName) { 572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getEffectiveIncomingSubIdFromSystem(intent.getIntExtra(extraName, 573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ParticipantData.DEFAULT_SELF_SUB_ID)); 574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private int getEffectiveIncomingSubIdFromSystem(int subId) { 577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subId < 0) { 578d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mSubscriptionManager.getActiveSubscriptionInfoCount() > 1) { 579d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // For multi-SIM device, we can not decide which SIM to use if system 580d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // does not know either. So just make it the invalid sub id. 581d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ParticipantData.DEFAULT_SELF_SUB_ID; 582d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 583d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // For single-SIM device, it must come from the only SIM we have 584d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getDefaultSmsSubscriptionId(); 585d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 586d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return subId; 587d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 588d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 589d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 590d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getSubIdFromTelephony(Cursor cursor, int subIdIndex) { 591d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getEffectiveIncomingSubIdFromSystem(cursor.getInt(subIdIndex)); 592d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 593d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 594d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 595d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isDataRoamingEnabled() { 596d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SubscriptionInfo subInfo = getActiveSubscriptionInfo(); 597d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (subInfo == null) { 598d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // There is nothing we can do if system give us empty sub info 599d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtils.isDataRoamingEnabled: system return empty sub info for " 600d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + mSubId); 601d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 602d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 603d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return subInfo.getDataRoaming() != SubscriptionManager.DATA_ROAMING_DISABLE; 604d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 605d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 606d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 607d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isMobileDataEnabled() { 608d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean mobileDataEnabled = false; 609d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 610d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Class cmClass = mTelephonyManager.getClass(); 611d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Method method = cmClass.getDeclaredMethod("getDataEnabled", Integer.TYPE); 612d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd method.setAccessible(true); // Make the method callable 613d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // get the setting for "mobile data" 614d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mobileDataEnabled = (Boolean) method.invoke( 615d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTelephonyManager, Integer.valueOf(mSubId)); 616d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final Exception e) { 617d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtil.isMobileDataEnabled: system api not found", e); 618d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 619d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mobileDataEnabled; 620d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 621d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 622d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 623d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 624d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public HashSet<String> getNormalizedSelfNumbers() { 625d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final HashSet<String> numbers = new HashSet<>(); 626d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (SubscriptionInfo info : getActiveSubscriptionInfoList()) { 627d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd numbers.add(PhoneUtils.get(info.getSubscriptionId()).getCanonicalForSelf( 628d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd true/*allowOverride*/)); 629d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 630d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return numbers; 631d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 632d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 633d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 634d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 635d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A convenient get() method that uses the default SIM. Use this when SIM is 636d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * not relevant, e.g. isDefaultSmsApp 637d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 638d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an instance of PhoneUtils for default SIM 639d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 640d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static PhoneUtils getDefault() { 641d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Factory.get().getPhoneUtils(ParticipantData.DEFAULT_SELF_SUB_ID); 642d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 643d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 644d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 645d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get an instance of PhoneUtils associated with a specific SIM, which is also platform 646d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * specific. 647d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 648d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId The SIM's subscription ID 649d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the instance 650d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 651d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static PhoneUtils get(int subId) { 652d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Factory.get().getPhoneUtils(subId); 653d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 654d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 655d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public LMr1 toLMr1() { 656d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastL_MR1()) { 657d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (LMr1) this; 658d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 659d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.fail("PhoneUtils.toLMr1(): invalid OS version"); 660d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 661d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 662d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 663d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 664d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 665d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if this device supports SMS 666d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 667d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if SMS is supported, false otherwise 668d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 669d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isSmsCapable() { 670d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.isSmsCapable(); 671d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 672d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 673d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 674d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if this device supports voice calling 675d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 676d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if voice calling is supported, false otherwise 677d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 678d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isVoiceCapable() { 679d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTelephonyManager.isVoiceCapable(); 680d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 681d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 682d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 683d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the ISO country code from system locale setting 684d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 685d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the ISO country code from system locale 686d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 687d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String getLocaleCountry() { 688d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String country = Locale.getDefault().getCountry(); 689d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(country)) { 690d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 691d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 692d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return country.toUpperCase(); 693d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 694d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 695d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 696d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get ISO country code from the SIM, if not available, fall back to locale 697d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 698d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return SIM or locale ISO country code 699d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 700d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSimOrDefaultLocaleCountry() { 701d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String country = getSimCountry(); 702d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (country == null) { 703d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd country = getLocaleCountry(); 704d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 705d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return country; 706d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 707d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 708d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Get or set the cache of canonicalized phone numbers for a specific country 709d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static ArrayMap<String, String> getOrAddCountryMapInCacheLocked(String country) { 710d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (country == null) { 711d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd country = ""; 712d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 713d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ArrayMap<String, String> countryMap = sCanonicalPhoneNumberCache.get(country); 714d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (countryMap == null) { 715d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd countryMap = new ArrayMap<>(); 716d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sCanonicalPhoneNumberCache.put(country, countryMap); 717d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 718d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return countryMap; 719d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 720d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 721d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Get canonicalized phone number from cache 722d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String getCanonicalFromCache(final String phoneText, String country) { 723d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (sCanonicalPhoneNumberCache) { 724d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ArrayMap<String, String> countryMap = getOrAddCountryMapInCacheLocked(country); 725d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return countryMap.get(phoneText); 726d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 727d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 728d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 729d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Put canonicalized phone number into cache 730d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static void putCanonicalToCache(final String phoneText, String country, 731d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String canonical) { 732d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (sCanonicalPhoneNumberCache) { 733d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ArrayMap<String, String> countryMap = getOrAddCountryMapInCacheLocked(country); 734d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd countryMap.put(phoneText, canonical); 735d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 736d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 737d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 738d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 739d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Utility method to parse user input number into standard E164 number. 740d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 741d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param phoneText Phone number text as input by user. 742d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param country ISO country code based on which to parse the number. 743d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return E164 phone number. Returns null in case parsing failed. 744d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 745d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String getValidE164Number(final String phoneText, final String country) { 746d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); 747d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 748d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumber phoneNumber = phoneNumberUtil.parse(phoneText, country); 749d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (phoneNumber != null && phoneNumberUtil.isValidNumber(phoneNumber)) { 750d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return phoneNumberUtil.format(phoneNumber, PhoneNumberFormat.E164); 751d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 752d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final NumberParseException e) { 753d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtils.getValidE164Number(): Not able to parse phone number " 754d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + LogUtil.sanitizePII(phoneText) + " for country " + country); 755d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 756d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 757d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 758d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 759d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 760d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Canonicalize phone number using system locale country 761d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 762d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param phoneText The phone number to canonicalize 763d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the canonicalized number 764d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 765d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getCanonicalBySystemLocale(final String phoneText) { 766d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getCanonicalByCountry(phoneText, getLocaleCountry()); 767d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 768d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 769d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 770d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Canonicalize phone number using SIM's country, may fall back to system locale country 771d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * if SIM country can not be obtained 772d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 773d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param phoneText The phone number to canonicalize 774d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the canonicalized number 775d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 776d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getCanonicalBySimLocale(final String phoneText) { 777d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getCanonicalByCountry(phoneText, getSimOrDefaultLocaleCountry()); 778d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 779d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 780d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 781d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Canonicalize phone number using a country code. 782d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This uses an internal cache per country to speed up. 783d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 784d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param phoneText The phone number to canonicalize 785d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param country The ISO country code to use 786d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the canonicalized number, or the original number if can't be parsed 787d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 788d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private String getCanonicalByCountry(final String phoneText, final String country) { 789d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.notNull(phoneText); 790d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 791d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String canonicalNumber = getCanonicalFromCache(phoneText, country); 792d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (canonicalNumber != null) { 793d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return canonicalNumber; 794d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 795d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canonicalNumber = getValidE164Number(phoneText, country); 796d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (canonicalNumber == null) { 797d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // If we can't normalize this number, we just use the display string number. 798d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // This is possible for short codes and other non-localizable numbers. 799d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canonicalNumber = phoneText; 800d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 801d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd putCanonicalToCache(phoneText, country, canonicalNumber); 802d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return canonicalNumber; 803d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 804d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 805d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 806d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Canonicalize the self (per SIM) phone number 807d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 808d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param allowOverride whether to use the override number in app settings 809d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the canonicalized self phone number 810d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 811d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getCanonicalForSelf(final boolean allowOverride) { 812d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String selfNumber = null; 813d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 814d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selfNumber = getSelfRawNumber(allowOverride); 815d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IllegalStateException e) { 816d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // continue; 817d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 818d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (selfNumber == null) { 819d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ""; 820d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 821d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getCanonicalBySimLocale(selfNumber); 822d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 823d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 824d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 825d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the SIM's phone number in NATIONAL format with only digits, used in sending 826d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * as LINE1NOCOUNTRYCODE macro in mms_config 827d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 828d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return all digits national format number of the SIM 829d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 830d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getSimNumberNoCountryCode() { 831d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String selfNumber = null; 832d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 833d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selfNumber = getSelfRawNumber(false/*allowOverride*/); 834d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IllegalStateException e) { 835d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // continue 836d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 837d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (selfNumber == null) { 838d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selfNumber = ""; 839d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 840d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String country = getSimCountry(); 841d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); 842d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 843d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumber phoneNumber = phoneNumberUtil.parse(selfNumber, country); 844d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (phoneNumber != null && phoneNumberUtil.isValidNumber(phoneNumber)) { 845d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return phoneNumberUtil 846d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .format(phoneNumber, PhoneNumberFormat.NATIONAL) 847d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .replaceAll("\\D", ""); 848d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 849d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final NumberParseException e) { 850d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtils.getSimNumberNoCountryCode(): Not able to parse phone number " 851d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + LogUtil.sanitizePII(selfNumber) + " for country " + country); 852d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 853d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return selfNumber; 854d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 855d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 856d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 857d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 858d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Format a phone number for displaying, using system locale country. 859d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * If the country code matches between the system locale and the input phone number, 860d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * it will be formatted into NATIONAL format, otherwise, the INTERNATIONAL format 861d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 862d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param phoneText The original phone text 863d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return formatted number 864d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 865d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String formatForDisplay(final String phoneText) { 866d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Only format a valid number which length >=6 867d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(phoneText) || 868d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd phoneText.replaceAll("\\D", "").length() < MINIMUM_PHONE_NUMBER_LENGTH_TO_FORMAT) { 869d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return phoneText; 870d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 871d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); 872d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String systemCountry = getLocaleCountry(); 873d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int systemCountryCode = phoneNumberUtil.getCountryCodeForRegion(systemCountry); 874d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 875d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumber parsedNumber = phoneNumberUtil.parse(phoneText, systemCountry); 876d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PhoneNumberFormat phoneNumberFormat = 877d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (systemCountryCode > 0 && parsedNumber.getCountryCode() == systemCountryCode) ? 878d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PhoneNumberFormat.NATIONAL : PhoneNumberFormat.INTERNATIONAL; 879d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return phoneNumberUtil.format(parsedNumber, phoneNumberFormat); 880d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (NumberParseException e) { 881d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "PhoneUtils.formatForDisplay: invalid phone number " 882d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + LogUtil.sanitizePII(phoneText) + " with country " + systemCountry); 883d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return phoneText; 884d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 885d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 886d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 887d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 888d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Is Messaging the default SMS app? 889d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * - On KLP+ this checks the system setting. 890d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * - On JB (and below) this always returns true, since the setting was added in KLP. 891d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 892d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isDefaultSmsApp() { 893d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastKLP()) { 894d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String configuredApplication = Telephony.Sms.getDefaultSmsPackage(mContext); 895d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mContext.getPackageName().equals(configuredApplication); 896d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 897d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 898d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 899d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 900d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 901d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get default SMS app package name 902d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 903d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the package name of default SMS app 904d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 905d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getDefaultSmsApp() { 906d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastKLP()) { 907d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Telephony.Sms.getDefaultSmsPackage(mContext); 908d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 909d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 910d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 911d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 912d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 913d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Determines if SMS is currently enabled on this device. 914d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * - Device must support SMS 915d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * - On KLP+ we must be set as the default SMS app 916d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 917d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isSmsEnabled() { 918d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return isSmsCapable() && isDefaultSmsApp(); 919d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 920d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 921d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 922d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the name of the default SMS app, or the empty string if there is 923d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * an error or there is no default app (e.g. JB and below). 924d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 925d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getDefaultSmsAppLabel() { 926d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastKLP()) { 927d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String packageName = Telephony.Sms.getDefaultSmsPackage(mContext); 928d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final PackageManager pm = mContext.getPackageManager(); 929d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 930d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); 931d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return pm.getApplicationLabel(appInfo).toString(); 932d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (NameNotFoundException e) { 933d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Fall through and return empty string 934d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 935d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 936d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ""; 937d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 938d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 939d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 940d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the state of Airplane Mode. 941d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 942d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if enabled. 943d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 944d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @SuppressWarnings("deprecation") 945d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isAirplaneModeOn() { 946d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastJB_MR1()) { 947d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Settings.Global.getInt(mContext.getContentResolver(), 948d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Settings.Global.AIRPLANE_MODE_ON, 0) != 0; 949d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 950d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Settings.System.getInt(mContext.getContentResolver(), 951d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Settings.System.AIRPLANE_MODE_ON, 0) != 0; 952d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 953d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 954d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 955d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static String getMccMncString(int[] mccmnc) { 956d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mccmnc == null || mccmnc.length != 2) { 957d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return "000000"; 958d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 959d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return String.format("%03d%03d", mccmnc[0], mccmnc[1]); 960d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 961d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 962d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static String canonicalizeMccMnc(final String mcc, final String mnc) { 963d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 964d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return String.format("%03d%03d", Integer.parseInt(mcc), Integer.parseInt(mnc)); 965d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final NumberFormatException e) { 966d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Return invalid as is 967d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(TAG, "canonicalizeMccMnc: invalid mccmnc:" + mcc + " ," + mnc); 968d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 969d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mcc + mnc; 970d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 971d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 972d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 973d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns whether the given destination is valid for sending SMS/MMS message. 974d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 975d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static boolean isValidSmsMmsDestination(final String destination) { 976d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return PhoneNumberUtils.isWellFormedSmsAddress(destination) || 977d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsSmsUtils.isEmailAddress(destination); 978d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 979d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 980d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public interface SubscriptionRunnable { 981d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd void runForSubscription(int subId); 982d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 983d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 984d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 985d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A convenience method for iterating through all active subscriptions 986d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 987d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param runnable a {@link SubscriptionRunnable} for performing work on each subscription. 988d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 989d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static void forEachActiveSubscription(final SubscriptionRunnable runnable) { 990d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastL_MR1()) { 991d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final List<SubscriptionInfo> subscriptionList = 992d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd getDefault().toLMr1().getActiveSubscriptionInfoList(); 993d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (final SubscriptionInfo subscriptionInfo : subscriptionList) { 994d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd runnable.runForSubscription(subscriptionInfo.getSubscriptionId()); 995d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 996d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 997d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd runnable.runForSubscription(ParticipantData.DEFAULT_SELF_SUB_ID); 998d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 999d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1000d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1001d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String getNumberFromPrefs(final Context context, final int subId) { 1002d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final BuglePrefs prefs = BuglePrefs.getSubscriptionPrefs(subId); 1003d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String mmsPhoneNumberPrefKey = 1004d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd context.getString(R.string.mms_phone_number_pref_key); 1005d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String userDefinedNumber = prefs.getString(mmsPhoneNumberPrefKey, null); 1006d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!TextUtils.isEmpty(userDefinedNumber)) { 1007d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return userDefinedNumber; 1008d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1009d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1010d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1011d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 1012