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 17 package com.android.dialer.compat.telephony; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.net.Uri; 22 import android.os.Build.VERSION; 23 import android.os.Build.VERSION_CODES; 24 import android.support.annotation.Nullable; 25 import android.support.v4.os.BuildCompat; 26 import android.telecom.PhoneAccountHandle; 27 import android.telephony.TelephonyManager; 28 import com.android.dialer.common.LogUtil; 29 import com.android.dialer.telecom.TelecomUtil; 30 import java.lang.reflect.InvocationTargetException; 31 32 /** Hidden APIs in {@link android.telephony.TelephonyManager}. */ 33 public class TelephonyManagerCompat { 34 35 // TODO(maxwelb): Use public API for these constants when available 36 public static final String EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE = 37 "android.telephony.event.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE"; 38 public static final String EVENT_HANDOVER_VIDEO_FROM_LTE_TO_WIFI = 39 "android.telephony.event.EVENT_HANDOVER_VIDEO_FROM_LTE_TO_WIFI"; 40 public static final String EVENT_HANDOVER_TO_WIFI_FAILED = 41 "android.telephony.event.EVENT_HANDOVER_TO_WIFI_FAILED"; 42 public static final String EVENT_CALL_REMOTELY_HELD = "android.telecom.event.CALL_REMOTELY_HELD"; 43 public static final String EVENT_CALL_REMOTELY_UNHELD = 44 "android.telecom.event.CALL_REMOTELY_UNHELD"; 45 public static final String EVENT_MERGE_START = "android.telecom.event.MERGE_START"; 46 public static final String EVENT_MERGE_COMPLETE = "android.telecom.event.MERGE_COMPLETE"; 47 48 public static final String EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC = 49 "android.telephony.event.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC"; 50 public static final String EVENT_CALL_FORWARDED = "android.telephony.event.EVENT_CALL_FORWARDED"; 51 52 public static final String TELEPHONY_MANAGER_CLASS = "android.telephony.TelephonyManager"; 53 54 private static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE"; 55 56 // TODO(erfanian): a bug Replace with the platform/telecom constant when available. 57 /** 58 * Indicates that the call being placed originated from a known contact. 59 * 60 * <p>This signals to the telephony platform that an outgoing call qualifies for assisted dialing. 61 */ 62 public static final String USE_ASSISTED_DIALING = "android.telecom.extra.USE_ASSISTED_DIALING"; 63 64 // TODO(erfanian): a bug Replace with the platform/telecom API when available. 65 /** Additional information relating to the assisted dialing transformation. */ 66 public static final String ASSISTED_DIALING_EXTRAS = 67 "android.telecom.extra.ASSISTED_DIALING_EXTRAS"; 68 69 /** Indicates the Connection/Call used assisted dialing. */ 70 public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9; 71 72 public static final String EXTRA_IS_REFRESH = 73 BuildCompat.isAtLeastOMR1() ? "android.telephony.extra.IS_REFRESH" : "is_refresh"; 74 75 /** 76 * Indicates the call underwent Assisted Dialing; typically set as a feature available from the 77 * CallLog. 78 */ 79 public static final Integer FEATURES_ASSISTED_DIALING = 1 << 4; 80 81 /** 82 * Flag specifying whether to show an alert dialog for video call charges. By default this value 83 * is {@code false}. TODO(a bug): Replace with public API for these constants when available. 84 */ 85 public static final String CARRIER_CONFIG_KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL = 86 "show_video_call_charges_alert_dialog_bool"; 87 88 /** 89 * Returns the number of phones available. Returns 1 for Single standby mode (Single SIM 90 * functionality) Returns 2 for Dual standby mode.(Dual SIM functionality) 91 * 92 * <p>Returns 1 if the method or telephonyManager is not available. 93 * 94 * @param telephonyManager The telephony manager instance to use for method calls. 95 */ getPhoneCount(@ullable TelephonyManager telephonyManager)96 public static int getPhoneCount(@Nullable TelephonyManager telephonyManager) { 97 if (telephonyManager == null) { 98 return 1; 99 } 100 return telephonyManager.getPhoneCount(); 101 } 102 103 /** 104 * Whether the phone supports TTY mode. 105 * 106 * @param telephonyManager The telephony manager instance to use for method calls. 107 * @return {@code true} if the device supports TTY mode, and {@code false} otherwise. 108 */ isTtyModeSupported(@ullable TelephonyManager telephonyManager)109 public static boolean isTtyModeSupported(@Nullable TelephonyManager telephonyManager) { 110 return telephonyManager != null && telephonyManager.isTtyModeSupported(); 111 } 112 113 /** 114 * Whether the phone supports hearing aid compatibility. 115 * 116 * @param telephonyManager The telephony manager instance to use for method calls. 117 * @return {@code true} if the device supports hearing aid compatibility, and {@code false} 118 * otherwise. 119 */ isHearingAidCompatibilitySupported( @ullable TelephonyManager telephonyManager)120 public static boolean isHearingAidCompatibilitySupported( 121 @Nullable TelephonyManager telephonyManager) { 122 return telephonyManager != null && telephonyManager.isHearingAidCompatibilitySupported(); 123 } 124 125 /** 126 * Returns the URI for the per-account voicemail ringtone set in Phone settings. 127 * 128 * @param telephonyManager The telephony manager instance to use for method calls. 129 * @param accountHandle The handle for the {@link android.telecom.PhoneAccount} for which to 130 * retrieve the voicemail ringtone. 131 * @return The URI for the ringtone to play when receiving a voicemail from a specific 132 * PhoneAccount. 133 */ 134 @Nullable getVoicemailRingtoneUri( TelephonyManager telephonyManager, PhoneAccountHandle accountHandle)135 public static Uri getVoicemailRingtoneUri( 136 TelephonyManager telephonyManager, PhoneAccountHandle accountHandle) { 137 return telephonyManager.getVoicemailRingtoneUri(accountHandle); 138 } 139 140 /** 141 * Returns whether vibration is set for voicemail notification in Phone settings. 142 * 143 * @param telephonyManager The telephony manager instance to use for method calls. 144 * @param accountHandle The handle for the {@link android.telecom.PhoneAccount} for which to 145 * retrieve the voicemail vibration setting. 146 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise. 147 */ isVoicemailVibrationEnabled( TelephonyManager telephonyManager, PhoneAccountHandle accountHandle)148 public static boolean isVoicemailVibrationEnabled( 149 TelephonyManager telephonyManager, PhoneAccountHandle accountHandle) { 150 return telephonyManager.isVoicemailVibrationEnabled(accountHandle); 151 } 152 153 /** 154 * This method uses a new system API to enable or disable visual voicemail. TODO(twyen): restrict 155 * to N MR1, not needed in future SDK. 156 */ setVisualVoicemailEnabled( TelephonyManager telephonyManager, PhoneAccountHandle handle, boolean enabled)157 public static void setVisualVoicemailEnabled( 158 TelephonyManager telephonyManager, PhoneAccountHandle handle, boolean enabled) { 159 try { 160 TelephonyManager.class 161 .getMethod("setVisualVoicemailEnabled", PhoneAccountHandle.class, boolean.class) 162 .invoke(telephonyManager, handle, enabled); 163 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 164 LogUtil.e("TelephonyManagerCompat.setVisualVoicemailEnabled", "failed", e); 165 } 166 } 167 168 /** 169 * This method uses a new system API to check if visual voicemail is enabled TODO(twyen): restrict 170 * to N MR1, not needed in future SDK. 171 */ isVisualVoicemailEnabled( TelephonyManager telephonyManager, PhoneAccountHandle handle)172 public static boolean isVisualVoicemailEnabled( 173 TelephonyManager telephonyManager, PhoneAccountHandle handle) { 174 try { 175 return (boolean) 176 TelephonyManager.class 177 .getMethod("isVisualVoicemailEnabled", PhoneAccountHandle.class) 178 .invoke(telephonyManager, handle); 179 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 180 LogUtil.e("TelephonyManagerCompat.setVisualVoicemailEnabled", "failed", e); 181 } 182 return false; 183 } 184 185 /** 186 * Handles secret codes to launch arbitrary activities. 187 * 188 * @param context the context to use 189 * @param secretCode the secret code without the "*#*#" prefix and "#*#*" suffix 190 */ handleSecretCode(Context context, String secretCode)191 public static void handleSecretCode(Context context, String secretCode) { 192 // Must use system service on O+ to avoid using broadcasts, which are not allowed on O+. 193 if (BuildCompat.isAtLeastO()) { 194 if (!TelecomUtil.isDefaultDialer(context)) { 195 LogUtil.e( 196 "TelephonyManagerCompat.handleSecretCode", 197 "not default dialer, cannot send special code"); 198 return; 199 } 200 context.getSystemService(TelephonyManager.class).sendDialerSpecialCode(secretCode); 201 } else { 202 // System service call is not supported pre-O, so must use a broadcast for N-. 203 Intent intent = 204 new Intent(SECRET_CODE_ACTION, Uri.parse("android_secret_code://" + secretCode)); 205 context.sendBroadcast(intent); 206 } 207 } 208 209 /** 210 * Returns network country iso for given {@code PhoneAccountHandle} for O+ devices and country iso 211 * for default sim for pre-O devices. 212 */ getNetworkCountryIsoForPhoneAccountHandle( Context context, @Nullable PhoneAccountHandle phoneAccountHandle)213 public static String getNetworkCountryIsoForPhoneAccountHandle( 214 Context context, @Nullable PhoneAccountHandle phoneAccountHandle) { 215 return getTelephonyManagerForPhoneAccountHandle(context, phoneAccountHandle) 216 .getNetworkCountryIso(); 217 } 218 219 /** 220 * Returns TelephonyManager for given {@code PhoneAccountHandle} for O+ devices and default {@code 221 * TelephonyManager} for pre-O devices. 222 */ getTelephonyManagerForPhoneAccountHandle( Context context, @Nullable PhoneAccountHandle phoneAccountHandle)223 public static TelephonyManager getTelephonyManagerForPhoneAccountHandle( 224 Context context, @Nullable PhoneAccountHandle phoneAccountHandle) { 225 TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); 226 if (phoneAccountHandle == null) { 227 return telephonyManager; 228 } 229 if (VERSION.SDK_INT >= VERSION_CODES.O) { 230 TelephonyManager telephonyManagerForPhoneAccount = 231 telephonyManager.createForPhoneAccountHandle(phoneAccountHandle); 232 if (telephonyManagerForPhoneAccount != null) { 233 return telephonyManagerForPhoneAccount; 234 } 235 } 236 return telephonyManager; 237 } 238 } 239