1 /* 2 * Copyright (C) 2015 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 package com.android.contacts.common.compat.telecom; 17 18 import android.app.Activity; 19 import android.content.Intent; 20 import android.content.Context; 21 import android.net.Uri; 22 import android.support.annotation.Nullable; 23 import android.telecom.PhoneAccount; 24 import android.telecom.PhoneAccountHandle; 25 import android.telecom.TelecomManager; 26 import android.telephony.PhoneNumberUtils; 27 import android.telephony.TelephonyManager; 28 import android.text.TextUtils; 29 30 import com.android.contacts.common.compat.CompatUtils; 31 32 import java.lang.reflect.Method; 33 import java.util.ArrayList; 34 import java.util.List; 35 36 /** 37 * Compatibility class for {@link android.telecom.TelecomManager}. 38 */ 39 public class TelecomManagerCompat { 40 public static final String TELECOM_MANAGER_CLASS = "android.telecom.TelecomManager"; 41 /** 42 * Places a new outgoing call to the provided address using the system telecom service with 43 * the specified intent. 44 * 45 * @param activity {@link Activity} used to start another activity for the given intent 46 * @param telecomManager the {@link TelecomManager} used to place a call, if possible 47 * @param intent the intent for the call 48 */ placeCall(@ullable Activity activity, @Nullable TelecomManager telecomManager, @Nullable Intent intent)49 public static void placeCall(@Nullable Activity activity, 50 @Nullable TelecomManager telecomManager, @Nullable Intent intent) { 51 if (activity == null || telecomManager == null || intent == null) { 52 return; 53 } 54 if (CompatUtils.isMarshmallowCompatible()) { 55 telecomManager.placeCall(intent.getData(), intent.getExtras()); 56 return; 57 } 58 activity.startActivityForResult(intent, 0); 59 } 60 61 /** 62 * Get the URI for running an adn query. 63 * 64 * @param telecomManager the {@link TelecomManager} used for method calls, if possible. 65 * @param accountHandle The handle for the account to derive an adn query URI for or 66 * {@code null} to return a URI which will use the default account. 67 * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount} 68 * for the the content retrieve. 69 */ getAdnUriForPhoneAccount(@ullable TelecomManager telecomManager, PhoneAccountHandle accountHandle)70 public static Uri getAdnUriForPhoneAccount(@Nullable TelecomManager telecomManager, 71 PhoneAccountHandle accountHandle) { 72 if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() 73 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "getAdnUriForPhoneAccount", 74 PhoneAccountHandle.class))) { 75 return telecomManager.getAdnUriForPhoneAccount(accountHandle); 76 } 77 return Uri.parse("content://icc/adn"); 78 } 79 80 /** 81 * Returns a list of {@link PhoneAccountHandle}s which can be used to make and receive phone 82 * calls. The returned list includes only those accounts which have been explicitly enabled 83 * by the user. 84 * 85 * @param telecomManager the {@link TelecomManager} used for method calls, if possible. 86 * @return A list of PhoneAccountHandle objects. 87 */ getCallCapablePhoneAccounts( @ullable TelecomManager telecomManager)88 public static List<PhoneAccountHandle> getCallCapablePhoneAccounts( 89 @Nullable TelecomManager telecomManager) { 90 if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() 91 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, 92 "getCallCapablePhoneAccounts"))) { 93 return telecomManager.getCallCapablePhoneAccounts(); 94 } 95 return new ArrayList<>(); 96 } 97 98 /** 99 * Used to determine the currently selected default dialer package. 100 * 101 * @param telecomManager the {@link TelecomManager} used for method calls, if possible. 102 * @return package name for the default dialer package or null if no package has been 103 * selected as the default dialer. 104 */ 105 @Nullable getDefaultDialerPackage(@ullable TelecomManager telecomManager)106 public static String getDefaultDialerPackage(@Nullable TelecomManager telecomManager) { 107 if (telecomManager != null && CompatUtils.isDefaultDialerCompatible()) { 108 return telecomManager.getDefaultDialerPackage(); 109 } 110 return null; 111 } 112 113 /** 114 * Return the {@link PhoneAccount} which will be used to place outgoing calls to addresses with 115 * the specified {@code uriScheme}. This PhoneAccount will always be a member of the 116 * list which is returned from invoking {@link TelecomManager#getCallCapablePhoneAccounts()}. 117 * The specific account returned depends on the following priorities: 118 * 119 * 1. If the user-selected default PhoneAccount supports the specified scheme, it will 120 * be returned. 121 * 2. If there exists only one PhoneAccount that supports the specified scheme, it 122 * will be returned. 123 * 124 * If no PhoneAccount fits the criteria above, this method will return {@code null}. 125 * 126 * @param telecomManager the {@link TelecomManager} used for method calls, if possible. 127 * @param uriScheme The URI scheme. 128 * @return The {@link PhoneAccountHandle} corresponding to the account to be used. 129 */ 130 @Nullable getDefaultOutgoingPhoneAccount( @ullable TelecomManager telecomManager, @Nullable String uriScheme)131 public static PhoneAccountHandle getDefaultOutgoingPhoneAccount( 132 @Nullable TelecomManager telecomManager, @Nullable String uriScheme) { 133 if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() 134 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, 135 "getDefaultOutgoingPhoneAccount", String.class))) { 136 return telecomManager.getDefaultOutgoingPhoneAccount(uriScheme); 137 } 138 return null; 139 } 140 141 /** 142 * Return the line 1 phone number for given phone account. 143 * 144 * @param telecomManager the {@link TelecomManager} to use in the event that 145 * {@link TelecomManager#getLine1Number(PhoneAccountHandle)} is available 146 * @param telephonyManager the {@link TelephonyManager} to use if TelecomManager#getLine1Number 147 * is unavailable 148 * @param phoneAccountHandle the phoneAccountHandle upon which to check the line one number 149 * @return the line one number 150 */ 151 @Nullable getLine1Number(@ullable TelecomManager telecomManager, @Nullable TelephonyManager telephonyManager, @Nullable PhoneAccountHandle phoneAccountHandle)152 public static String getLine1Number(@Nullable TelecomManager telecomManager, 153 @Nullable TelephonyManager telephonyManager, 154 @Nullable PhoneAccountHandle phoneAccountHandle) { 155 if (telecomManager != null && CompatUtils.isMarshmallowCompatible()) { 156 return telecomManager.getLine1Number(phoneAccountHandle); 157 } 158 if (telephonyManager != null) { 159 return telephonyManager.getLine1Number(); 160 } 161 return null; 162 } 163 164 /** 165 * Return whether a given phone number is the configured voicemail number for a 166 * particular phone account. 167 * 168 * @param telecomManager the {@link TelecomManager} to use for checking the number. 169 * @param accountHandle The handle for the account to check the voicemail number against 170 * @param number The number to look up. 171 */ isVoiceMailNumber(@ullable TelecomManager telecomManager, @Nullable PhoneAccountHandle accountHandle, @Nullable String number)172 public static boolean isVoiceMailNumber(@Nullable TelecomManager telecomManager, 173 @Nullable PhoneAccountHandle accountHandle, @Nullable String number) { 174 if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() 175 || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "isVoiceMailNumber", 176 PhoneAccountHandle.class, String.class))) { 177 return telecomManager.isVoiceMailNumber(accountHandle, number); 178 } 179 return PhoneNumberUtils.isVoiceMailNumber(number); 180 } 181 182 /** 183 * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes 184 * resources which can be used in a user interface. 185 * 186 * @param telecomManager the {@link TelecomManager} used for method calls, if possible. 187 * @param account The {@link PhoneAccountHandle}. 188 * @return The {@link PhoneAccount} object or null if it doesn't exist. 189 */ 190 @Nullable getPhoneAccount(@ullable TelecomManager telecomManager, @Nullable PhoneAccountHandle accountHandle)191 public static PhoneAccount getPhoneAccount(@Nullable TelecomManager telecomManager, 192 @Nullable PhoneAccountHandle accountHandle) { 193 if (telecomManager != null && (CompatUtils.isMethodAvailable( 194 TELECOM_MANAGER_CLASS, "getPhoneAccount", PhoneAccountHandle.class))) { 195 return telecomManager.getPhoneAccount(accountHandle); 196 } 197 return null; 198 } 199 200 /** 201 * Return the voicemail number for a given phone account. 202 * 203 * @param telecomManager The {@link TelecomManager} object to use for retrieving the voicemail 204 * number if accountHandle is specified. 205 * @param telephonyManager The {@link TelephonyManager} object to use for retrieving the 206 * voicemail number if accountHandle is null. 207 * @param accountHandle The handle for the phone account. 208 * @return The voicemail number for the phone account, and {@code null} if one has not been 209 * configured. 210 */ 211 @Nullable getVoiceMailNumber(@ullable TelecomManager telecomManager, @Nullable TelephonyManager telephonyManager, @Nullable PhoneAccountHandle accountHandle)212 public static String getVoiceMailNumber(@Nullable TelecomManager telecomManager, 213 @Nullable TelephonyManager telephonyManager, 214 @Nullable PhoneAccountHandle accountHandle) { 215 if (telecomManager != null && (CompatUtils.isMethodAvailable( 216 TELECOM_MANAGER_CLASS, "getVoiceMailNumber", PhoneAccountHandle.class))) { 217 return telecomManager.getVoiceMailNumber(accountHandle); 218 } else if (telephonyManager != null){ 219 return telephonyManager.getVoiceMailNumber(); 220 } 221 return null; 222 } 223 224 /** 225 * Processes the specified dial string as an MMI code. 226 * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#". 227 * Some of these sequences launch special behavior through handled by Telephony. 228 * 229 * @param telecomManager The {@link TelecomManager} object to use for handling MMI. 230 * @param dialString The digits to dial. 231 * @return {@code true} if the digits were processed as an MMI code, {@code false} otherwise. 232 */ handleMmi(@ullable TelecomManager telecomManager, @Nullable String dialString, @Nullable PhoneAccountHandle accountHandle)233 public static boolean handleMmi(@Nullable TelecomManager telecomManager, 234 @Nullable String dialString, @Nullable PhoneAccountHandle accountHandle) { 235 if (telecomManager == null || TextUtils.isEmpty(dialString)) { 236 return false; 237 } 238 if (CompatUtils.isMarshmallowCompatible()) { 239 return telecomManager.handleMmi(dialString, accountHandle); 240 } 241 242 Object handleMmiResult = CompatUtils.invokeMethod( 243 telecomManager, 244 "handleMmi", 245 new Class<?>[] {PhoneAccountHandle.class, String.class}, 246 new Object[] {accountHandle, dialString}); 247 if (handleMmiResult != null) { 248 return (boolean) handleMmiResult; 249 } 250 251 return telecomManager.handleMmi(dialString); 252 } 253 254 /** 255 * Silences the ringer if a ringing call exists. Noop if {@link TelecomManager#silenceRinger()} 256 * is unavailable. 257 * 258 * @param telecomManager the TelecomManager to use to silence the ringer. 259 */ silenceRinger(@ullable TelecomManager telecomManager)260 public static void silenceRinger(@Nullable TelecomManager telecomManager) { 261 if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() || CompatUtils 262 .isMethodAvailable(TELECOM_MANAGER_CLASS, "silenceRinger"))) { 263 telecomManager.silenceRinger(); 264 } 265 } 266 267 /** 268 * Returns the current SIM call manager. Apps must be prepared for this method to return null, 269 * indicating that there currently exists no registered SIM call manager. 270 * 271 * @param telecomManager the {@link TelecomManager} to use to fetch the SIM call manager. 272 * @return The phone account handle of the current sim call manager. 273 */ 274 @Nullable getSimCallManager(TelecomManager telecomManager)275 public static PhoneAccountHandle getSimCallManager(TelecomManager telecomManager) { 276 if (telecomManager != null && (CompatUtils.isMarshmallowCompatible() || CompatUtils 277 .isMethodAvailable(TELECOM_MANAGER_CLASS, "getSimCallManager"))) { 278 return telecomManager.getSimCallManager(); 279 } 280 return null; 281 } 282 } 283