blob: ddde01c22b8dcbd1493d2844e924eff032c4ab60 [file] [log] [blame]
Chiao Chengcb5b2702012-09-05 16:10:50 -07001/*
Brian Attwell066bd682015-02-03 17:10:19 -08002 * Copyright (C) 2015 The Android Open Source Project
Chiao Chengcb5b2702012-09-05 16:10:50 -07003 *
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
Gary Mai0a49afa2016-12-05 15:53:58 -080017package com.android.contacts;
Brian Attwell066bd682015-02-03 17:10:19 -080018
Andrew Lee7e558dc2014-08-20 16:02:11 -070019import android.content.Context;
Chiao Chengcb5b2702012-09-05 16:10:50 -070020import android.content.Intent;
21import android.net.Uri;
Tyler Gunn5cf7f012014-09-10 15:20:21 -070022import android.telecom.PhoneAccount;
Vinit Deshpandeca6b31e2015-03-15 13:23:01 -070023import android.telecom.PhoneAccountHandle;
Tyler Gunn5cf7f012014-09-10 15:20:21 -070024import android.telecom.TelecomManager;
25import android.telecom.VideoProfile;
Brian Attwell066bd682015-02-03 17:10:19 -080026import android.text.TextUtils;
Chiao Chengcb5b2702012-09-05 16:10:50 -070027
Gary Mai0a49afa2016-12-05 15:53:58 -080028import com.android.contacts.compat.CompatUtils;
29import com.android.contacts.compat.PhoneAccountSdkCompat;
30import com.android.contacts.util.PermissionsUtil;
31import com.android.contacts.util.PhoneNumberHelper;
32import com.android.contactsbind.FeedbackHelper;
33import com.android.phone.common.PhoneConstants;
34
Yorke Lee9028db02015-03-19 17:01:54 +000035import java.util.List;
36
Chiao Chengcb5b2702012-09-05 16:10:50 -070037/**
Brian Attwell066bd682015-02-03 17:10:19 -080038 * Utilities related to calls that can be used by non system apps. These
39 * use {@link Intent#ACTION_CALL} instead of ACTION_CALL_PRIVILEGED.
40 *
41 * The privileged version of this util exists inside Dialer.
Chiao Chengcb5b2702012-09-05 16:10:50 -070042 */
43public class CallUtil {
44
Wenyi Wang7a27b852016-11-11 11:36:24 -080045 public static final String TAG = "CallUtil";
46
Chiao Chengcb5b2702012-09-05 16:10:50 -070047 /**
Tyler Gunn001d9742015-12-18 13:57:02 -080048 * Indicates that the video calling is not available.
49 */
50 public static final int VIDEO_CALLING_DISABLED = 0;
51
52 /**
53 * Indicates that video calling is enabled, regardless of presence status.
54 */
55 public static final int VIDEO_CALLING_ENABLED = 1;
56
57 /**
58 * Indicates that video calling is enabled, but the availability of video call affordances is
59 * determined by the presence status associated with contacts.
60 */
61 public static final int VIDEO_CALLING_PRESENCE = 2;
62
63 /**
Chiao Chengcb5b2702012-09-05 16:10:50 -070064 * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined
65 * automatically.
66 */
Tyler Gunn9e0c14e2015-08-04 13:33:49 -070067 public static Intent getCallWithSubjectIntent(String number,
68 PhoneAccountHandle phoneAccountHandle, String callSubject) {
69
70 final Intent intent = getCallIntent(getCallUri(number));
71 intent.putExtra(TelecomManager.EXTRA_CALL_SUBJECT, callSubject);
72 if (phoneAccountHandle != null) {
73 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
74 }
75 return intent;
76 }
77
78 /**
79 * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined
80 * automatically.
81 */
Chiao Chengcb5b2702012-09-05 16:10:50 -070082 public static Intent getCallIntent(String number) {
Brian Attwell066bd682015-02-03 17:10:19 -080083 return getCallIntent(getCallUri(number));
Chiao Chengcb5b2702012-09-05 16:10:50 -070084 }
85
86 /**
87 * Return an Intent for making a phone call. A given Uri will be used as is (without any
88 * sanity check).
89 */
90 public static Intent getCallIntent(Uri uri) {
Brian Attwell066bd682015-02-03 17:10:19 -080091 return new Intent(Intent.ACTION_CALL, uri);
Chiao Chengcb5b2702012-09-05 16:10:50 -070092 }
93
94 /**
Brian Attwell066bd682015-02-03 17:10:19 -080095 * A variant of {@link #getCallIntent} for starting a video call.
Andrew Leec18a7542014-07-08 16:02:30 -070096 */
Nancy Chenc095aee2014-07-09 10:29:41 -070097 public static Intent getVideoCallIntent(String number, String callOrigin) {
Brian Attwell066bd682015-02-03 17:10:19 -080098 final Intent intent = new Intent(Intent.ACTION_CALL, getCallUri(number));
99 intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
Yorke Leecb93d462015-05-12 16:23:06 -0700100 VideoProfile.STATE_BIDIRECTIONAL);
Brian Attwell066bd682015-02-03 17:10:19 -0800101 if (!TextUtils.isEmpty(callOrigin)) {
Chiao Chengcb5b2702012-09-05 16:10:50 -0700102 intent.putExtra(PhoneConstants.EXTRA_CALL_ORIGIN, callOrigin);
103 }
104 return intent;
105 }
106
107 /**
Jay Shraunered1a3b22014-09-05 15:37:27 -0700108 * Return Uri with an appropriate scheme, accepting both SIP and usual phone call
Chiao Chengcb5b2702012-09-05 16:10:50 -0700109 * numbers.
110 */
111 public static Uri getCallUri(String number) {
Yorke Lee9e8e7cb2014-03-17 13:04:45 -0700112 if (PhoneNumberHelper.isUriNumber(number)) {
Jay Shraunered1a3b22014-09-05 15:37:27 -0700113 return Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null);
Chiao Chengcb5b2702012-09-05 16:10:50 -0700114 }
Jay Shraunered1a3b22014-09-05 15:37:27 -0700115 return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null);
Yorke Lee9028db02015-03-19 17:01:54 +0000116 }
Paul Soulos56046082014-08-18 16:12:40 -0700117
Yorke Lee9028db02015-03-19 17:01:54 +0000118 /**
Tyler Gunn001d9742015-12-18 13:57:02 -0800119 * Determines if video calling is available, and if so whether presence checking is available
120 * as well.
121 *
122 * Returns a bitmask with {@link #VIDEO_CALLING_ENABLED} to indicate that video calling is
123 * available, and {@link #VIDEO_CALLING_PRESENCE} if presence indication is also available.
124 *
125 * @param context The context
126 * @return A bit-mask describing the current video capabilities.
127 */
128 public static int getVideoCallingAvailability(Context context) {
129 if (!PermissionsUtil.hasPermission(context, android.Manifest.permission.READ_PHONE_STATE)
130 || !CompatUtils.isVideoCompatible()) {
131 return VIDEO_CALLING_DISABLED;
132 }
133 TelecomManager telecommMgr = (TelecomManager)
134 context.getSystemService(Context.TELECOM_SERVICE);
135 if (telecommMgr == null) {
136 return VIDEO_CALLING_DISABLED;
137 }
138
Wenyi Wang7a27b852016-11-11 11:36:24 -0800139 try {
140 List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();
141 for (PhoneAccountHandle accountHandle : accountHandles) {
142 PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);
143 if (account != null) {
144 if (account.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)) {
145 // Builds prior to N do not have presence support.
146 if (!CompatUtils.isVideoPresenceCompatible()) {
147 return VIDEO_CALLING_ENABLED;
148 }
Tyler Gunn001d9742015-12-18 13:57:02 -0800149
Wenyi Wang7a27b852016-11-11 11:36:24 -0800150 int videoCapabilities = VIDEO_CALLING_ENABLED;
151 if (account.hasCapabilities(PhoneAccountSdkCompat
152 .CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) {
153 videoCapabilities |= VIDEO_CALLING_PRESENCE;
154 }
155 return videoCapabilities;
Tyler Gunn001d9742015-12-18 13:57:02 -0800156 }
Tyler Gunn001d9742015-12-18 13:57:02 -0800157 }
158 }
Wenyi Wang7a27b852016-11-11 11:36:24 -0800159 return VIDEO_CALLING_DISABLED;
160 } catch (SecurityException e) {
161 FeedbackHelper.sendFeedback(context, TAG,
Wenyi Wang969c5952016-12-20 14:31:18 -0800162 "Security exception when getting call capable phone accounts", e);
Wenyi Wang7a27b852016-11-11 11:36:24 -0800163 return VIDEO_CALLING_DISABLED;
Tyler Gunn001d9742015-12-18 13:57:02 -0800164 }
Tyler Gunn001d9742015-12-18 13:57:02 -0800165 }
166
167 /**
Tyler Gunna05f1532015-08-06 15:01:44 -0700168 * Determines if one of the call capable phone accounts defined supports calling with a subject
169 * specified.
170 *
171 * @param context The context.
172 * @return {@code true} if one of the call capable phone accounts supports calling with a
173 * subject specified, {@code false} otherwise.
174 */
175 public static boolean isCallWithSubjectSupported(Context context) {
Nancy Chen5fe647d2015-12-08 16:57:48 -0800176 if (!PermissionsUtil.hasPermission(context, android.Manifest.permission.READ_PHONE_STATE)
177 || !CompatUtils.isCallSubjectCompatible()) {
Yorke Leed2c96922015-09-18 12:59:16 -0700178 return false;
179 }
Tyler Gunna05f1532015-08-06 15:01:44 -0700180 TelecomManager telecommMgr = (TelecomManager)
181 context.getSystemService(Context.TELECOM_SERVICE);
182 if (telecommMgr == null) {
183 return false;
184 }
185
Wenyi Wang969c5952016-12-20 14:31:18 -0800186 try {
187 List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();
188 for (PhoneAccountHandle accountHandle : accountHandles) {
189 PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);
190 if (account != null && account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_SUBJECT)) {
191 return true;
192 }
Tyler Gunna05f1532015-08-06 15:01:44 -0700193 }
Wenyi Wang969c5952016-12-20 14:31:18 -0800194 return false;
195 } catch (SecurityException e) {
196 FeedbackHelper.sendFeedback(context, TAG,
197 "Security exception when getting call capable phone accounts", e);
198 return false;
Tyler Gunna05f1532015-08-06 15:01:44 -0700199 }
Wenyi Wang969c5952016-12-20 14:31:18 -0800200
Tyler Gunna05f1532015-08-06 15:01:44 -0700201 }
Chiao Chengcb5b2702012-09-05 16:10:50 -0700202}