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.contacts.common; 18 19 import com.android.contacts.common.compat.CompatUtils; 20 import com.android.contacts.common.compat.PhoneAccountSdkCompat; 21 import com.android.contacts.common.util.PermissionsUtil; 22 import com.android.contacts.common.util.PhoneNumberHelper; 23 import com.android.phone.common.PhoneConstants; 24 25 import android.content.Context; 26 import android.content.Intent; 27 import android.net.Uri; 28 import android.telecom.PhoneAccount; 29 import android.telecom.PhoneAccountHandle; 30 import android.telecom.TelecomManager; 31 import android.telecom.VideoProfile; 32 import android.text.TextUtils; 33 34 import java.util.List; 35 36 /** 37 * Utilities related to calls that can be used by non system apps. These 38 * use {@link Intent#ACTION_CALL} instead of ACTION_CALL_PRIVILEGED. 39 * 40 * The privileged version of this util exists inside Dialer. 41 */ 42 public class CallUtil { 43 44 /** 45 * Indicates that the video calling is not available. 46 */ 47 public static final int VIDEO_CALLING_DISABLED = 0; 48 49 /** 50 * Indicates that video calling is enabled, regardless of presence status. 51 */ 52 public static final int VIDEO_CALLING_ENABLED = 1; 53 54 /** 55 * Indicates that video calling is enabled, but the availability of video call affordances is 56 * determined by the presence status associated with contacts. 57 */ 58 public static final int VIDEO_CALLING_PRESENCE = 2; 59 60 /** 61 * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined 62 * automatically. 63 */ getCallWithSubjectIntent(String number, PhoneAccountHandle phoneAccountHandle, String callSubject)64 public static Intent getCallWithSubjectIntent(String number, 65 PhoneAccountHandle phoneAccountHandle, String callSubject) { 66 67 final Intent intent = getCallIntent(getCallUri(number)); 68 intent.putExtra(TelecomManager.EXTRA_CALL_SUBJECT, callSubject); 69 if (phoneAccountHandle != null) { 70 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); 71 } 72 return intent; 73 } 74 75 /** 76 * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined 77 * automatically. 78 */ getCallIntent(String number)79 public static Intent getCallIntent(String number) { 80 return getCallIntent(getCallUri(number)); 81 } 82 83 /** 84 * Return an Intent for making a phone call. A given Uri will be used as is (without any 85 * sanity check). 86 */ getCallIntent(Uri uri)87 public static Intent getCallIntent(Uri uri) { 88 return new Intent(Intent.ACTION_CALL, uri); 89 } 90 91 /** 92 * A variant of {@link #getCallIntent} for starting a video call. 93 */ getVideoCallIntent(String number, String callOrigin)94 public static Intent getVideoCallIntent(String number, String callOrigin) { 95 final Intent intent = new Intent(Intent.ACTION_CALL, getCallUri(number)); 96 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, 97 VideoProfile.STATE_BIDIRECTIONAL); 98 if (!TextUtils.isEmpty(callOrigin)) { 99 intent.putExtra(PhoneConstants.EXTRA_CALL_ORIGIN, callOrigin); 100 } 101 return intent; 102 } 103 104 /** 105 * Return Uri with an appropriate scheme, accepting both SIP and usual phone call 106 * numbers. 107 */ getCallUri(String number)108 public static Uri getCallUri(String number) { 109 if (PhoneNumberHelper.isUriNumber(number)) { 110 return Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null); 111 } 112 return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null); 113 } 114 115 /** 116 * @return Uri that directly dials a user's voicemail inbox. 117 */ getVoicemailUri()118 public static Uri getVoicemailUri() { 119 return Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null); 120 } 121 122 /** 123 * Determines if video calling is available, and if so whether presence checking is available 124 * as well. 125 * 126 * Returns a bitmask with {@link #VIDEO_CALLING_ENABLED} to indicate that video calling is 127 * available, and {@link #VIDEO_CALLING_PRESENCE} if presence indication is also available. 128 * 129 * @param context The context 130 * @return A bit-mask describing the current video capabilities. 131 */ getVideoCallingAvailability(Context context)132 public static int getVideoCallingAvailability(Context context) { 133 if (!PermissionsUtil.hasPermission(context, android.Manifest.permission.READ_PHONE_STATE) 134 || !CompatUtils.isVideoCompatible()) { 135 return VIDEO_CALLING_DISABLED; 136 } 137 TelecomManager telecommMgr = (TelecomManager) 138 context.getSystemService(Context.TELECOM_SERVICE); 139 if (telecommMgr == null) { 140 return VIDEO_CALLING_DISABLED; 141 } 142 143 List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts(); 144 for (PhoneAccountHandle accountHandle : accountHandles) { 145 PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle); 146 if (account != null) { 147 if (account.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)) { 148 // Builds prior to N do not have presence support. 149 if (!CompatUtils.isVideoPresenceCompatible()) { 150 return VIDEO_CALLING_ENABLED; 151 } 152 153 int videoCapabilities = VIDEO_CALLING_ENABLED; 154 if (account.hasCapabilities( 155 PhoneAccountSdkCompat.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) { 156 videoCapabilities |= VIDEO_CALLING_PRESENCE; 157 } 158 return videoCapabilities; 159 } 160 } 161 } 162 return VIDEO_CALLING_DISABLED; 163 } 164 165 /** 166 * Determines if one of the call capable phone accounts defined supports video calling. 167 * 168 * @param context The context. 169 * @return {@code true} if one of the call capable phone accounts supports video calling, 170 * {@code false} otherwise. 171 */ isVideoEnabled(Context context)172 public static boolean isVideoEnabled(Context context) { 173 return (getVideoCallingAvailability(context) & VIDEO_CALLING_ENABLED) != 0; 174 } 175 176 /** 177 * Determines if one of the call capable phone accounts defined supports calling with a subject 178 * specified. 179 * 180 * @param context The context. 181 * @return {@code true} if one of the call capable phone accounts supports calling with a 182 * subject specified, {@code false} otherwise. 183 */ isCallWithSubjectSupported(Context context)184 public static boolean isCallWithSubjectSupported(Context context) { 185 if (!PermissionsUtil.hasPermission(context, android.Manifest.permission.READ_PHONE_STATE) 186 || !CompatUtils.isCallSubjectCompatible()) { 187 return false; 188 } 189 TelecomManager telecommMgr = (TelecomManager) 190 context.getSystemService(Context.TELECOM_SERVICE); 191 if (telecommMgr == null) { 192 return false; 193 } 194 195 List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts(); 196 for (PhoneAccountHandle accountHandle : accountHandles) { 197 PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle); 198 if (account != null && account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_SUBJECT)) { 199 return true; 200 } 201 } 202 return false; 203 } 204 } 205