blob: 52213d8c4fae9470f72a718d4bd2f798c8f43f0e [file] [log] [blame]
Ihab Awade63fadb2014-07-09 21:52:04 -07001/*
2 * Copyright (C) 2014 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
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Ihab Awade63fadb2014-07-09 21:52:04 -070018
Hall Liu95d55872017-01-25 17:12:49 -080019import android.annotation.IntDef;
Ravi Paluri404babb2020-01-23 19:02:44 +053020import android.annotation.NonNull;
Hall Liu95d55872017-01-25 17:12:49 -080021import android.annotation.Nullable;
Andrew Leeda80c872015-04-15 14:09:50 -070022import android.annotation.SystemApi;
Hall Liu6dfa2492019-10-01 17:20:39 -070023import android.annotation.TestApi;
Artur Satayev53ada2a2019-12-10 17:47:56 +000024import android.compat.annotation.UnsupportedAppUsage;
Ihab Awade63fadb2014-07-09 21:52:04 -070025import android.net.Uri;
Tyler Gunn6e3ecc42018-11-12 11:30:56 -080026import android.os.Build;
Nancy Chen10798dc2014-08-08 14:00:25 -070027import android.os.Bundle;
Andrew Lee011728f2015-04-23 15:47:06 -070028import android.os.Handler;
Hall Liu95d55872017-01-25 17:12:49 -080029import android.os.ParcelFileDescriptor;
Ihab Awade63fadb2014-07-09 21:52:04 -070030
Tyler Gunnd1fdf3a2019-11-05 15:47:58 -080031import com.android.internal.telecom.IVideoProvider;
32
Hall Liu95d55872017-01-25 17:12:49 -080033import java.io.IOException;
34import java.io.InputStreamReader;
35import java.io.OutputStreamWriter;
Hall Liu95d55872017-01-25 17:12:49 -080036import java.lang.annotation.Retention;
37import java.lang.annotation.RetentionPolicy;
38import java.nio.charset.StandardCharsets;
Ihab Awade63fadb2014-07-09 21:52:04 -070039import java.util.ArrayList;
Tyler Gunn071be6f2016-05-10 14:52:33 -070040import java.util.Arrays;
Ihab Awade63fadb2014-07-09 21:52:04 -070041import java.util.Collections;
42import java.util.List;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070043import java.util.Map;
Ihab Awade63fadb2014-07-09 21:52:04 -070044import java.util.Objects;
Jay Shrauner229e3822014-08-15 09:23:07 -070045import java.util.concurrent.CopyOnWriteArrayList;
Ihab Awade63fadb2014-07-09 21:52:04 -070046
47/**
48 * Represents an ongoing phone call that the in-call app should present to the user.
49 */
50public final class Call {
51 /**
52 * The state of a {@code Call} when newly created.
53 */
54 public static final int STATE_NEW = 0;
55
56 /**
57 * The state of an outgoing {@code Call} when dialing the remote number, but not yet connected.
58 */
59 public static final int STATE_DIALING = 1;
60
61 /**
62 * The state of an incoming {@code Call} when ringing locally, but not yet connected.
63 */
64 public static final int STATE_RINGING = 2;
65
66 /**
67 * The state of a {@code Call} when in a holding state.
68 */
69 public static final int STATE_HOLDING = 3;
70
71 /**
72 * The state of a {@code Call} when actively supporting conversation.
73 */
74 public static final int STATE_ACTIVE = 4;
75
76 /**
77 * The state of a {@code Call} when no further voice or other communication is being
78 * transmitted, the remote side has been or will inevitably be informed that the {@code Call}
79 * is no longer active, and the local data transport has or inevitably will release resources
80 * associated with this {@code Call}.
81 */
82 public static final int STATE_DISCONNECTED = 7;
83
Nancy Chen5da0fd52014-07-08 14:16:17 -070084 /**
Santos Cordone3c507b2015-04-23 14:44:19 -070085 * The state of an outgoing {@code Call} when waiting on user to select a
86 * {@link PhoneAccount} through which to place the call.
Nancy Chen5da0fd52014-07-08 14:16:17 -070087 */
Santos Cordone3c507b2015-04-23 14:44:19 -070088 public static final int STATE_SELECT_PHONE_ACCOUNT = 8;
89
90 /**
91 * @hide
92 * @deprecated use STATE_SELECT_PHONE_ACCOUNT.
93 */
94 @Deprecated
95 @SystemApi
96 public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT;
Nancy Chen5da0fd52014-07-08 14:16:17 -070097
Nancy Chene20930f2014-08-07 16:17:21 -070098 /**
Nancy Chene9b7a8e2014-08-08 14:26:27 -070099 * The initial state of an outgoing {@code Call}.
100 * Common transitions are to {@link #STATE_DIALING} state for a successful call or
101 * {@link #STATE_DISCONNECTED} if it failed.
Nancy Chene20930f2014-08-07 16:17:21 -0700102 */
103 public static final int STATE_CONNECTING = 9;
104
Nancy Chen513c8922014-09-17 14:47:20 -0700105 /**
Tyler Gunn4afc6af2014-10-07 10:14:55 -0700106 * The state of a {@code Call} when the user has initiated a disconnection of the call, but the
107 * call has not yet been disconnected by the underlying {@code ConnectionService}. The next
108 * state of the call is (potentially) {@link #STATE_DISCONNECTED}.
109 */
110 public static final int STATE_DISCONNECTING = 10;
111
112 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700113 * The state of an external call which is in the process of being pulled from a remote device to
114 * the local device.
115 * <p>
116 * A call can only be in this state if the {@link Details#PROPERTY_IS_EXTERNAL_CALL} property
117 * and {@link Details#CAPABILITY_CAN_PULL_CALL} capability are set on the call.
118 * <p>
119 * An {@link InCallService} will only see this state if it has the
120 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its
121 * manifest.
122 */
123 public static final int STATE_PULLING_CALL = 11;
124
125 /**
Hall Liu6dfa2492019-10-01 17:20:39 -0700126 * The state of a call that is active with the network, but the audio from the call is
127 * being intercepted by an app on the local device. Telecom does not hold audio focus in this
128 * state, and the call will be invisible to the user except for a persistent notification.
129 */
130 public static final int STATE_AUDIO_PROCESSING = 12;
131
132 /**
133 * The state of a call that is being presented to the user after being in
134 * {@link #STATE_AUDIO_PROCESSING}. The call is still active with the network in this case, and
135 * Telecom will hold audio focus and play a ringtone if appropriate.
136 */
137 public static final int STATE_SIMULATED_RINGING = 13;
138
139 /**
Nancy Chen513c8922014-09-17 14:47:20 -0700140 * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
141 * extras. Used to pass the phone accounts to display on the front end to the user in order to
142 * select phone accounts to (for example) place a call.
Hall Liu34d9e242018-11-21 17:05:58 -0800143 * @deprecated Use the list from {@link #EXTRA_SUGGESTED_PHONE_ACCOUNTS} instead.
Nancy Chen513c8922014-09-17 14:47:20 -0700144 */
Hall Liu34d9e242018-11-21 17:05:58 -0800145 @Deprecated
Nancy Chen513c8922014-09-17 14:47:20 -0700146 public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
147
mike dooley4af561f2016-12-20 08:55:17 -0800148 /**
Hall Liu34d9e242018-11-21 17:05:58 -0800149 * Key for extra used to pass along a list of {@link PhoneAccountSuggestion}s to the in-call
150 * UI when a call enters the {@link #STATE_SELECT_PHONE_ACCOUNT} state. The list included here
151 * will have the same length and be in the same order as the list passed with
152 * {@link #AVAILABLE_PHONE_ACCOUNTS}.
153 */
154 public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS =
155 "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
156
157 /**
mike dooley91217422017-03-09 12:58:42 -0800158 * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC)
159 * when the last outgoing emergency call was made. This is used to identify potential emergency
160 * callbacks.
mike dooley4af561f2016-12-20 08:55:17 -0800161 */
162 public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
163 "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
164
Usman Abdullahb0dc29a2019-03-06 15:54:56 -0800165
166 /**
167 * Extra key used to indicate whether a {@link CallScreeningService} has requested to silence
168 * the ringtone for a call. If the {@link InCallService} declares
169 * {@link TelecomManager#METADATA_IN_CALL_SERVICE_RINGING} in its manifest, it should not
170 * play a ringtone for an incoming call with this extra key set.
171 */
172 public static final String EXTRA_SILENT_RINGING_REQUESTED =
173 "android.telecom.extra.SILENT_RINGING_REQUESTED";
174
Tyler Gunn8bf76572017-04-06 15:30:08 -0700175 /**
176 * Call event sent from a {@link Call} via {@link #sendCallEvent(String, Bundle)} to inform
177 * Telecom that the user has requested that the current {@link Call} should be handed over
178 * to another {@link ConnectionService}.
179 * <p>
180 * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to
181 * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to.
182 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700183 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
184 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700185 */
186 public static final String EVENT_REQUEST_HANDOVER =
187 "android.telecom.event.REQUEST_HANDOVER";
188
189 /**
190 * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the
191 * {@link PhoneAccountHandle} to which a call should be handed over to.
192 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700193 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
194 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700195 */
196 public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE =
197 "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE";
198
199 /**
200 * Integer extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the
201 * video state of the call when it is handed over to the new {@link PhoneAccount}.
202 * <p>
203 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
204 * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and
205 * {@link VideoProfile#STATE_TX_ENABLED}.
206 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700207 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
208 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700209 */
210 public static final String EXTRA_HANDOVER_VIDEO_STATE =
211 "android.telecom.extra.HANDOVER_VIDEO_STATE";
212
213 /**
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700214 * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Used by the
215 * {@link InCallService} initiating a handover to provide a {@link Bundle} with extra
216 * information to the handover {@link ConnectionService} specified by
217 * {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE}.
218 * <p>
219 * This {@link Bundle} is not interpreted by Telecom, but passed as-is to the
220 * {@link ConnectionService} via the request extras when
221 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
222 * is called to initate the handover.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700223 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700224 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
225 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700226 */
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700227 public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS";
Tyler Gunn8bf76572017-04-06 15:30:08 -0700228
229 /**
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700230 * Call event sent from Telecom to the handover {@link ConnectionService} via
231 * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
232 * to the {@link ConnectionService} has completed successfully.
233 * <p>
234 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700235 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700236 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
237 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700238 */
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700239 public static final String EVENT_HANDOVER_COMPLETE =
240 "android.telecom.event.HANDOVER_COMPLETE";
Tyler Gunn34a2b312017-06-23 08:32:00 -0700241
242 /**
243 * Call event sent from Telecom to the handover destination {@link ConnectionService} via
244 * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the
245 * source connection has disconnected. The {@link Bundle} parameter for the call event will be
246 * {@code null}.
247 * <p>
248 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
249 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700250 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
251 * APIs instead.
Tyler Gunn34a2b312017-06-23 08:32:00 -0700252 */
253 public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
254 "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
255
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700256 /**
257 * Call event sent from Telecom to the handover {@link ConnectionService} via
258 * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
259 * to the {@link ConnectionService} has failed.
260 * <p>
261 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
262 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700263 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
264 * APIs instead.
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700265 */
266 public static final String EVENT_HANDOVER_FAILED =
267 "android.telecom.event.HANDOVER_FAILED";
Tyler Gunn8bf76572017-04-06 15:30:08 -0700268
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800269
270 /**
271 * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this
272 * call because they have declined to answer it. This typically means that they are unable
273 * to answer the call at this time and would prefer it be sent to voicemail.
274 */
275 public static final int REJECT_REASON_DECLINED = 1;
276
277 /**
278 * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this
279 * call because it is an unwanted call. This allows the user to indicate that they are
280 * rejecting a call because it is likely a nuisance call.
281 */
282 public static final int REJECT_REASON_UNWANTED = 2;
283
284 /**
285 * @hide
286 */
287 @IntDef(prefix = { "REJECT_REASON_" },
288 value = {REJECT_REASON_DECLINED, REJECT_REASON_UNWANTED})
289 @Retention(RetentionPolicy.SOURCE)
290 public @interface RejectReason {};
291
Ihab Awade63fadb2014-07-09 21:52:04 -0700292 public static class Details {
Tyler Gunn94f8f112018-12-17 09:56:11 -0800293 /** @hide */
294 @Retention(RetentionPolicy.SOURCE)
295 @IntDef(
296 prefix = { "DIRECTION_" },
297 value = {DIRECTION_UNKNOWN, DIRECTION_INCOMING, DIRECTION_OUTGOING})
298 public @interface CallDirection {}
299
300 /**
301 * Indicates that the call is neither and incoming nor an outgoing call. This can be the
302 * case for calls reported directly by a {@link ConnectionService} in special cases such as
303 * call handovers.
304 */
305 public static final int DIRECTION_UNKNOWN = -1;
306
307 /**
308 * Indicates that the call is an incoming call.
309 */
310 public static final int DIRECTION_INCOMING = 0;
311
312 /**
313 * Indicates that the call is an outgoing call.
314 */
315 public static final int DIRECTION_OUTGOING = 1;
316
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800317 /** Call can currently be put on hold or unheld. */
318 public static final int CAPABILITY_HOLD = 0x00000001;
319
320 /** Call supports the hold feature. */
321 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
322
323 /**
324 * Calls within a conference can be merged. A {@link ConnectionService} has the option to
325 * add a {@link Conference} call before the child {@link Connection}s are merged. This is how
326 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
327 * capability allows a merge button to be shown while the conference call is in the foreground
328 * of the in-call UI.
329 * <p>
330 * This is only intended for use by a {@link Conference}.
331 */
332 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
333
334 /**
335 * Calls within a conference can be swapped between foreground and background.
336 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
337 * <p>
338 * This is only intended for use by a {@link Conference}.
339 */
340 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
341
342 /**
343 * @hide
344 */
Andrew Lee2378ea72015-04-29 14:38:11 -0700345 public static final int CAPABILITY_UNUSED_1 = 0x00000010;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800346
347 /** Call supports responding via text option. */
348 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
349
350 /** Call can be muted. */
351 public static final int CAPABILITY_MUTE = 0x00000040;
352
353 /**
354 * Call supports conference call management. This capability only applies to {@link Conference}
355 * calls which can have {@link Connection}s as children.
356 */
357 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
358
359 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700360 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800361 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700362 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800363
364 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700365 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800366 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700367 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800368
369 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700370 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800371 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700372 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700373 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800374
375 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700376 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800377 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700378 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
379
380 /**
381 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700382 */
383 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
384
385 /**
386 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700387 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700388 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700389 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800390
391 /**
392 * Call is able to be separated from its parent {@code Conference}, if any.
393 */
394 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
395
396 /**
397 * Call is able to be individually disconnected when in a {@code Conference}.
398 */
399 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
400
401 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500402 * Speed up audio setup for MT call.
403 * @hide
404 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700405 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
406
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700407 /**
408 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700409 * @hide
Tyler Gunn6e3ecc42018-11-12 11:30:56 -0800410 * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
411 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call
412 * whether or not video calling is supported.
Rekha Kumar07366812015-03-24 16:42:31 -0700413 */
Tyler Gunn6e3ecc42018-11-12 11:30:56 -0800414 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590)
Rekha Kumar07366812015-03-24 16:42:31 -0700415 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
416
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700417 /**
418 * For video calls, indicates whether the outgoing video for the call can be paused using
Yorke Lee32f24732015-05-12 16:18:03 -0700419 * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700420 */
421 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
422
Bryce Lee81901682015-08-28 16:38:02 -0700423 /**
424 * Call sends responses through connection.
425 * @hide
426 */
Tyler Gunnf97a0092016-01-19 15:59:34 -0800427 public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00200000;
428
429 /**
430 * When set, prevents a video {@code Call} from being downgraded to an audio-only call.
431 * <p>
432 * Should be set when the VideoState has the {@link VideoProfile#STATE_TX_ENABLED} or
433 * {@link VideoProfile#STATE_RX_ENABLED} bits set to indicate that the connection cannot be
434 * downgraded from a video call back to a VideoState of
435 * {@link VideoProfile#STATE_AUDIO_ONLY}.
436 * <p>
437 * Intuitively, a call which can be downgraded to audio should also have local and remote
438 * video
439 * capabilities (see {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
440 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL}).
441 */
442 public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00400000;
Bryce Lee81901682015-08-28 16:38:02 -0700443
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700444 /**
445 * When set for an external call, indicates that this {@code Call} can be pulled from a
446 * remote device to the current device.
447 * <p>
448 * Should only be set on a {@code Call} where {@link #PROPERTY_IS_EXTERNAL_CALL} is set.
449 * <p>
450 * An {@link InCallService} will only see calls with this capability if it has the
451 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
452 * in its manifest.
453 * <p>
454 * See {@link Connection#CAPABILITY_CAN_PULL_CALL} and
Tyler Gunn720c6642016-03-22 09:02:47 -0700455 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700456 */
457 public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000;
458
Pooja Jaind34698d2017-12-28 14:15:31 +0530459 /** Call supports the deflect feature. */
460 public static final int CAPABILITY_SUPPORT_DEFLECT = 0x01000000;
461
Tyler Gunn0c62ef02020-02-11 14:39:43 -0800462 /**
463 * Call supports adding participants to the call via
464 * {@link #addConferenceParticipants(List)}.
465 * @hide
466 */
Ravi Paluri404babb2020-01-23 19:02:44 +0530467 public static final int CAPABILITY_ADD_PARTICIPANT = 0x02000000;
Tyler Gunnd11a3152015-03-18 13:09:14 -0700468 //******************************************************************************************
Ravi Paluri404babb2020-01-23 19:02:44 +0530469 // Next CAPABILITY value: 0x04000000
Andrew Lee2378ea72015-04-29 14:38:11 -0700470 //******************************************************************************************
471
472 /**
473 * Whether the call is currently a conference.
474 */
475 public static final int PROPERTY_CONFERENCE = 0x00000001;
476
477 /**
478 * Whether the call is a generic conference, where we do not know the precise state of
479 * participants in the conference (eg. on CDMA).
480 */
481 public static final int PROPERTY_GENERIC_CONFERENCE = 0x00000002;
482
483 /**
484 * Whether the call is made while the device is in emergency callback mode.
485 */
486 public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 0x00000004;
487
488 /**
489 * Connection is using WIFI.
490 */
491 public static final int PROPERTY_WIFI = 0x00000008;
492
493 /**
Tyler Gunn6b6ae552018-10-11 10:42:10 -0700494 * When set, the UI should indicate to the user that a call is using high definition
495 * audio.
496 * <p>
497 * The underlying {@link ConnectionService} is responsible for reporting this
498 * property. It is important to note that this property is not intended to report the
499 * actual audio codec being used for a Call, but whether the call should be indicated
500 * to the user as high definition.
501 * <p>
502 * The Android Telephony stack reports this property for calls based on a number
503 * of factors, including which audio codec is used and whether a call is using an HD
504 * codec end-to-end. Some mobile operators choose to suppress display of an HD indication,
505 * and in these cases this property will not be set for a call even if the underlying audio
506 * codec is in fact "high definition".
Andrew Lee2378ea72015-04-29 14:38:11 -0700507 */
508 public static final int PROPERTY_HIGH_DEF_AUDIO = 0x00000010;
509
Tony Maka68dcce2015-12-17 09:31:18 +0000510 /**
Tony Mak53b5df42016-05-19 13:40:38 +0100511 * Whether the call is associated with the work profile.
512 */
513 public static final int PROPERTY_ENTERPRISE_CALL = 0x00000020;
514
515 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700516 * When set, indicates that this {@code Call} does not actually exist locally for the
517 * {@link ConnectionService}.
518 * <p>
519 * Consider, for example, a scenario where a user has two phones with the same phone number.
520 * When a user places a call on one device, the telephony stack can represent that call on
521 * the other device by adding it to the {@link ConnectionService} with the
Tyler Gunn720c6642016-03-22 09:02:47 -0700522 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL} property set.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700523 * <p>
524 * An {@link InCallService} will only see calls with this property if it has the
525 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
526 * in its manifest.
527 * <p>
Tyler Gunn720c6642016-03-22 09:02:47 -0700528 * See {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700529 */
530 public static final int PROPERTY_IS_EXTERNAL_CALL = 0x00000040;
531
Brad Ebinger15847072016-05-18 11:08:36 -0700532 /**
533 * Indicates that the call has CDMA Enhanced Voice Privacy enabled.
534 */
535 public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 0x00000080;
536
Tyler Gunn24e18332017-02-10 09:42:49 -0800537 /**
538 * Indicates that the call is from a self-managed {@link ConnectionService}.
539 * <p>
540 * See also {@link Connection#PROPERTY_SELF_MANAGED}
541 */
542 public static final int PROPERTY_SELF_MANAGED = 0x00000100;
543
Eric Erfanianec881872017-12-06 16:27:53 -0800544 /**
545 * Indicates the call used Assisted Dialing.
Tyler Gunn5567d742019-10-31 13:04:37 -0700546 *
547 * @see TelecomManager#EXTRA_USE_ASSISTED_DIALING
Eric Erfanianec881872017-12-06 16:27:53 -0800548 */
Tyler Gunnc9503d62020-01-27 10:30:51 -0800549 public static final int PROPERTY_ASSISTED_DIALING = 0x00000200;
Eric Erfanianec881872017-12-06 16:27:53 -0800550
Hall Liue9041242018-02-09 16:40:03 -0800551 /**
552 * Indicates that the call is an RTT call. Use {@link #getRttCall()} to get the
553 * {@link RttCall} object that is used to send and receive text.
554 */
555 public static final int PROPERTY_RTT = 0x00000400;
556
Tyler Gunn5bd90852018-09-21 09:37:07 -0700557 /**
558 * Indicates that the call has been identified as the network as an emergency call. This
559 * property may be set for both incoming and outgoing calls which the network identifies as
560 * emergency calls.
561 */
562 public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 0x00000800;
563
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700564 /**
565 * Indicates that the call is using VoIP audio mode.
566 * <p>
567 * When this property is set, the {@link android.media.AudioManager} audio mode for this
568 * call will be {@link android.media.AudioManager#MODE_IN_COMMUNICATION}. When this
569 * property is not set, the audio mode for this call will be
570 * {@link android.media.AudioManager#MODE_IN_CALL}.
571 * <p>
572 * This property reflects changes made using {@link Connection#setAudioModeIsVoip(boolean)}.
573 * <p>
574 * You can use this property to determine whether an un-answered incoming call or a held
575 * call will use VoIP audio mode (if the call does not currently have focus, the system
576 * audio mode may not reflect the mode the call will use).
577 */
578 public static final int PROPERTY_VOIP_AUDIO_MODE = 0x00001000;
579
Ravi Paluri80aa2142019-12-02 11:57:37 +0530580 /**
581 * Indicates that the call is an adhoc conference call. This property can be set for both
582 * incoming and outgoing calls.
Tyler Gunna967af52020-02-10 15:19:07 -0800583 * @hide
Ravi Paluri80aa2142019-12-02 11:57:37 +0530584 */
585 public static final int PROPERTY_IS_ADHOC_CONFERENCE = 0x00002000;
586
Andrew Lee2378ea72015-04-29 14:38:11 -0700587 //******************************************************************************************
Ravi Paluri80aa2142019-12-02 11:57:37 +0530588 // Next PROPERTY value: 0x00004000
Tyler Gunnd11a3152015-03-18 13:09:14 -0700589 //******************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800590
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800591 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700592 private final Uri mHandle;
593 private final int mHandlePresentation;
594 private final String mCallerDisplayName;
595 private final int mCallerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700596 private final PhoneAccountHandle mAccountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700597 private final int mCallCapabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700598 private final int mCallProperties;
Christine Hallstrom4e22d6d2016-11-30 16:06:42 -0800599 private final int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700600 private final DisconnectCause mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700601 private final long mConnectTimeMillis;
602 private final GatewayInfo mGatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700603 private final int mVideoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700604 private final StatusHints mStatusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700605 private final Bundle mExtras;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700606 private final Bundle mIntentExtras;
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700607 private final long mCreationTimeMillis;
Hall Liuef98bf82020-01-09 15:22:44 -0800608 private final String mContactDisplayName;
Tyler Gunn94f8f112018-12-17 09:56:11 -0800609 private final @CallDirection int mCallDirection;
Tyler Gunnd57d76c2019-09-24 14:53:23 -0700610 private final @Connection.VerificationStatus int mCallerNumberVerificationStatus;
Ihab Awade63fadb2014-07-09 21:52:04 -0700611
612 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800613 * Whether the supplied capabilities supports the specified capability.
614 *
615 * @param capabilities A bit field of capabilities.
616 * @param capability The capability to check capabilities for.
617 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800618 */
619 public static boolean can(int capabilities, int capability) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800620 return (capabilities & capability) == capability;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800621 }
622
623 /**
624 * Whether the capabilities of this {@code Details} supports the specified capability.
625 *
626 * @param capability The capability to check capabilities for.
627 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800628 */
629 public boolean can(int capability) {
630 return can(mCallCapabilities, capability);
631 }
632
633 /**
634 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
635 *
636 * @param capabilities A capability bit field.
637 * @return A human readable string representation.
638 */
639 public static String capabilitiesToString(int capabilities) {
640 StringBuilder builder = new StringBuilder();
641 builder.append("[Capabilities:");
642 if (can(capabilities, CAPABILITY_HOLD)) {
643 builder.append(" CAPABILITY_HOLD");
644 }
645 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
646 builder.append(" CAPABILITY_SUPPORT_HOLD");
647 }
648 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
649 builder.append(" CAPABILITY_MERGE_CONFERENCE");
650 }
651 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
652 builder.append(" CAPABILITY_SWAP_CONFERENCE");
653 }
654 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
655 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
656 }
657 if (can(capabilities, CAPABILITY_MUTE)) {
658 builder.append(" CAPABILITY_MUTE");
659 }
660 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
661 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
662 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700663 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
664 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
665 }
666 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
667 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
668 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700669 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
670 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800671 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700672 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
673 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
674 }
675 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
676 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
677 }
Tyler Gunnf97a0092016-01-19 15:59:34 -0800678 if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
679 builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO");
680 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700681 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
682 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800683 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500684 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700685 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500686 }
Rekha Kumar07366812015-03-24 16:42:31 -0700687 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
688 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
689 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700690 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
691 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
692 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700693 if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
694 builder.append(" CAPABILITY_CAN_PULL_CALL");
695 }
Pooja Jaind34698d2017-12-28 14:15:31 +0530696 if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) {
697 builder.append(" CAPABILITY_SUPPORT_DEFLECT");
698 }
Ravi Paluri404babb2020-01-23 19:02:44 +0530699 if (can(capabilities, CAPABILITY_ADD_PARTICIPANT)) {
700 builder.append(" CAPABILITY_ADD_PARTICIPANT");
701 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800702 builder.append("]");
703 return builder.toString();
704 }
705
706 /**
Andrew Lee2378ea72015-04-29 14:38:11 -0700707 * Whether the supplied properties includes the specified property.
708 *
709 * @param properties A bit field of properties.
710 * @param property The property to check properties for.
711 * @return Whether the specified property is supported.
712 */
713 public static boolean hasProperty(int properties, int property) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800714 return (properties & property) == property;
Andrew Lee2378ea72015-04-29 14:38:11 -0700715 }
716
717 /**
718 * Whether the properties of this {@code Details} includes the specified property.
719 *
720 * @param property The property to check properties for.
721 * @return Whether the specified property is supported.
722 */
723 public boolean hasProperty(int property) {
724 return hasProperty(mCallProperties, property);
725 }
726
727 /**
728 * Render a set of property bits ({@code PROPERTY_*}) as a human readable string.
729 *
730 * @param properties A property bit field.
731 * @return A human readable string representation.
732 */
733 public static String propertiesToString(int properties) {
734 StringBuilder builder = new StringBuilder();
735 builder.append("[Properties:");
736 if (hasProperty(properties, PROPERTY_CONFERENCE)) {
737 builder.append(" PROPERTY_CONFERENCE");
738 }
739 if (hasProperty(properties, PROPERTY_GENERIC_CONFERENCE)) {
740 builder.append(" PROPERTY_GENERIC_CONFERENCE");
741 }
742 if (hasProperty(properties, PROPERTY_WIFI)) {
743 builder.append(" PROPERTY_WIFI");
744 }
745 if (hasProperty(properties, PROPERTY_HIGH_DEF_AUDIO)) {
746 builder.append(" PROPERTY_HIGH_DEF_AUDIO");
747 }
748 if (hasProperty(properties, PROPERTY_EMERGENCY_CALLBACK_MODE)) {
Yorke Leebe2a4a22015-06-12 10:10:55 -0700749 builder.append(" PROPERTY_EMERGENCY_CALLBACK_MODE");
Andrew Lee2378ea72015-04-29 14:38:11 -0700750 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700751 if (hasProperty(properties, PROPERTY_IS_EXTERNAL_CALL)) {
752 builder.append(" PROPERTY_IS_EXTERNAL_CALL");
753 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700754 if (hasProperty(properties, PROPERTY_HAS_CDMA_VOICE_PRIVACY)) {
Brad Ebinger15847072016-05-18 11:08:36 -0700755 builder.append(" PROPERTY_HAS_CDMA_VOICE_PRIVACY");
756 }
Tyler Gunnc9503d62020-01-27 10:30:51 -0800757 if (hasProperty(properties, PROPERTY_ASSISTED_DIALING)) {
Eric Erfanianec881872017-12-06 16:27:53 -0800758 builder.append(" PROPERTY_ASSISTED_DIALING_USED");
759 }
Tyler Gunn5bd90852018-09-21 09:37:07 -0700760 if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
761 builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL");
762 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700763 if (hasProperty(properties, PROPERTY_RTT)) {
764 builder.append(" PROPERTY_RTT");
765 }
766 if (hasProperty(properties, PROPERTY_VOIP_AUDIO_MODE)) {
767 builder.append(" PROPERTY_VOIP_AUDIO_MODE");
768 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530769 if (hasProperty(properties, PROPERTY_IS_ADHOC_CONFERENCE)) {
770 builder.append(" PROPERTY_IS_ADHOC_CONFERENCE");
771 }
Andrew Lee2378ea72015-04-29 14:38:11 -0700772 builder.append("]");
773 return builder.toString();
774 }
775
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800776 /** {@hide} */
Hall Liu31de23d2019-10-11 15:38:29 -0700777 @TestApi
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800778 public String getTelecomCallId() {
779 return mTelecomCallId;
780 }
781
Andrew Lee2378ea72015-04-29 14:38:11 -0700782 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700783 * @return The handle (e.g., phone number) to which the {@code Call} is currently
784 * connected.
785 */
786 public Uri getHandle() {
787 return mHandle;
788 }
789
790 /**
791 * @return The presentation requirements for the handle. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700792 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700793 */
794 public int getHandlePresentation() {
795 return mHandlePresentation;
796 }
797
798 /**
Tyler Gunnd081f042018-12-04 12:56:45 -0800799 * The display name for the caller.
800 * <p>
801 * This is the name as reported by the {@link ConnectionService} associated with this call.
Tyler Gunnd081f042018-12-04 12:56:45 -0800802 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700803 * @return The display name for the caller.
804 */
805 public String getCallerDisplayName() {
806 return mCallerDisplayName;
807 }
808
809 /**
810 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700811 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700812 */
813 public int getCallerDisplayNamePresentation() {
814 return mCallerDisplayNamePresentation;
815 }
816
817 /**
Evan Charlton6eb262c2014-07-19 18:18:19 -0700818 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being
819 * routed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700820 */
Evan Charlton8c8a0622014-07-20 12:31:00 -0700821 public PhoneAccountHandle getAccountHandle() {
822 return mAccountHandle;
Ihab Awade63fadb2014-07-09 21:52:04 -0700823 }
824
825 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800826 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various
827 * {@code CAPABILITY_*} constants in this class.
Ihab Awade63fadb2014-07-09 21:52:04 -0700828 */
Ihab Awad5d0410f2014-07-30 10:07:40 -0700829 public int getCallCapabilities() {
830 return mCallCapabilities;
Ihab Awade63fadb2014-07-09 21:52:04 -0700831 }
832
833 /**
Andrew Lee2378ea72015-04-29 14:38:11 -0700834 * @return A bitmask of the properties of the {@code Call}, as defined by the various
835 * {@code PROPERTY_*} constants in this class.
Andrew Lee223ad142014-08-27 16:33:08 -0700836 */
837 public int getCallProperties() {
838 return mCallProperties;
839 }
840
841 /**
Christine Hallstrom4e22d6d2016-11-30 16:06:42 -0800842 * @return a bitmask of the audio routes available for the call.
843 *
844 * @hide
845 */
846 public int getSupportedAudioRoutes() {
847 return mSupportedAudioRoutes;
848 }
849
850 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700851 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700852 * by {@link android.telecom.DisconnectCause}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700853 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700854 public DisconnectCause getDisconnectCause() {
855 return mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700856 }
857
858 /**
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700859 * Returns the time the {@link Call} connected (i.e. became active). This information is
860 * updated periodically, but user interfaces should not rely on this to display the "call
861 * time clock". For the time when the call was first added to Telecom, see
862 * {@link #getCreationTimeMillis()}.
863 *
864 * @return The time the {@link Call} connected in milliseconds since the epoch.
Ihab Awade63fadb2014-07-09 21:52:04 -0700865 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700866 public final long getConnectTimeMillis() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700867 return mConnectTimeMillis;
868 }
869
870 /**
871 * @return Information about any calling gateway the {@code Call} may be using.
872 */
873 public GatewayInfo getGatewayInfo() {
874 return mGatewayInfo;
875 }
876
Andrew Lee7a341382014-07-15 17:05:08 -0700877 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700878 * @return The video state of the {@code Call}.
Andrew Lee7a341382014-07-15 17:05:08 -0700879 */
880 public int getVideoState() {
881 return mVideoState;
882 }
883
Ihab Awad5d0410f2014-07-30 10:07:40 -0700884 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700885 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none
Ihab Awad5d0410f2014-07-30 10:07:40 -0700886 * have been set.
Evan Charlton5b49ade2014-07-15 17:03:20 -0700887 */
888 public StatusHints getStatusHints() {
889 return mStatusHints;
890 }
891
Nancy Chen10798dc2014-08-08 14:00:25 -0700892 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700893 * @return The extras associated with this call.
Nancy Chen10798dc2014-08-08 14:00:25 -0700894 */
895 public Bundle getExtras() {
896 return mExtras;
897 }
898
Santos Cordon6b7f9552015-05-27 17:21:45 -0700899 /**
900 * @return The extras used with the original intent to place this call.
901 */
902 public Bundle getIntentExtras() {
903 return mIntentExtras;
904 }
905
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700906 /**
907 * Returns the time when the call was first created and added to Telecom. This is the same
908 * time that is logged as the start time in the Call Log (see
909 * {@link android.provider.CallLog.Calls#DATE}). To determine when the call was connected
910 * (became active), see {@link #getConnectTimeMillis()}.
911 *
912 * @return The creation time of the call, in millis since the epoch.
913 */
914 public long getCreationTimeMillis() {
915 return mCreationTimeMillis;
916 }
917
Tyler Gunnd081f042018-12-04 12:56:45 -0800918 /**
Hall Liuef98bf82020-01-09 15:22:44 -0800919 * Returns the name of the caller on the remote end, as derived from a
920 * {@link android.provider.ContactsContract} lookup of the call's handle.
921 * @return The name of the caller, or {@code null} if the lookup is not yet complete, if
922 * there's no contacts entry for the caller, or if the {@link InCallService} does
923 * not hold the {@link android.Manifest.permission#READ_CONTACTS} permission.
924 */
925 public @Nullable String getContactDisplayName() {
926 return mContactDisplayName;
927 }
928
929 /**
Tyler Gunn94f8f112018-12-17 09:56:11 -0800930 * Indicates whether the call is an incoming or outgoing call.
931 * @return The call's direction.
932 */
933 public @CallDirection int getCallDirection() {
934 return mCallDirection;
935 }
936
Tyler Gunnd57d76c2019-09-24 14:53:23 -0700937 /**
938 * Gets the verification status for the phone number of an incoming call as identified in
939 * ATIS-1000082.
940 * @return the verification status.
941 */
942 public @Connection.VerificationStatus int getCallerNumberVerificationStatus() {
943 return mCallerNumberVerificationStatus;
944 }
945
Ihab Awade63fadb2014-07-09 21:52:04 -0700946 @Override
947 public boolean equals(Object o) {
948 if (o instanceof Details) {
949 Details d = (Details) o;
950 return
951 Objects.equals(mHandle, d.mHandle) &&
952 Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
953 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
954 Objects.equals(mCallerDisplayNamePresentation,
955 d.mCallerDisplayNamePresentation) &&
Evan Charlton8c8a0622014-07-20 12:31:00 -0700956 Objects.equals(mAccountHandle, d.mAccountHandle) &&
Ihab Awad5d0410f2014-07-30 10:07:40 -0700957 Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
Andrew Lee223ad142014-08-27 16:33:08 -0700958 Objects.equals(mCallProperties, d.mCallProperties) &&
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700959 Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
Ihab Awade63fadb2014-07-09 21:52:04 -0700960 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
Andrew Lee85f5d422014-07-11 17:22:03 -0700961 Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Evan Charlton5b49ade2014-07-15 17:03:20 -0700962 Objects.equals(mVideoState, d.mVideoState) &&
Nancy Chen10798dc2014-08-08 14:00:25 -0700963 Objects.equals(mStatusHints, d.mStatusHints) &&
Tyler Gunn1e9bfc62015-08-19 11:18:58 -0700964 areBundlesEqual(mExtras, d.mExtras) &&
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700965 areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
Tyler Gunnd081f042018-12-04 12:56:45 -0800966 Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
Hall Liuef98bf82020-01-09 15:22:44 -0800967 Objects.equals(mContactDisplayName, d.mContactDisplayName) &&
Tyler Gunnd57d76c2019-09-24 14:53:23 -0700968 Objects.equals(mCallDirection, d.mCallDirection) &&
969 Objects.equals(mCallerNumberVerificationStatus,
970 d.mCallerNumberVerificationStatus);
Ihab Awade63fadb2014-07-09 21:52:04 -0700971 }
972 return false;
973 }
974
975 @Override
976 public int hashCode() {
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700977 return Objects.hash(mHandle,
978 mHandlePresentation,
979 mCallerDisplayName,
980 mCallerDisplayNamePresentation,
981 mAccountHandle,
982 mCallCapabilities,
983 mCallProperties,
984 mDisconnectCause,
985 mConnectTimeMillis,
986 mGatewayInfo,
987 mVideoState,
988 mStatusHints,
989 mExtras,
990 mIntentExtras,
Tyler Gunnd081f042018-12-04 12:56:45 -0800991 mCreationTimeMillis,
Hall Liuef98bf82020-01-09 15:22:44 -0800992 mContactDisplayName,
Tyler Gunnd57d76c2019-09-24 14:53:23 -0700993 mCallDirection,
994 mCallerNumberVerificationStatus);
Ihab Awade63fadb2014-07-09 21:52:04 -0700995 }
996
997 /** {@hide} */
998 public Details(
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800999 String telecomCallId,
Ihab Awade63fadb2014-07-09 21:52:04 -07001000 Uri handle,
1001 int handlePresentation,
1002 String callerDisplayName,
1003 int callerDisplayNamePresentation,
Evan Charlton8c8a0622014-07-20 12:31:00 -07001004 PhoneAccountHandle accountHandle,
Ihab Awade63fadb2014-07-09 21:52:04 -07001005 int capabilities,
Andrew Lee223ad142014-08-27 16:33:08 -07001006 int properties,
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001007 DisconnectCause disconnectCause,
Ihab Awade63fadb2014-07-09 21:52:04 -07001008 long connectTimeMillis,
Andrew Lee85f5d422014-07-11 17:22:03 -07001009 GatewayInfo gatewayInfo,
Evan Charlton5b49ade2014-07-15 17:03:20 -07001010 int videoState,
Nancy Chen10798dc2014-08-08 14:00:25 -07001011 StatusHints statusHints,
Santos Cordon6b7f9552015-05-27 17:21:45 -07001012 Bundle extras,
Tyler Gunnc0bf6de2017-03-17 11:27:09 -07001013 Bundle intentExtras,
Tyler Gunnd081f042018-12-04 12:56:45 -08001014 long creationTimeMillis,
Hall Liuef98bf82020-01-09 15:22:44 -08001015 String contactDisplayName,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07001016 int callDirection,
1017 int callerNumberVerificationStatus) {
Sailesh Nepal1bef3392016-01-24 18:21:53 -08001018 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07001019 mHandle = handle;
1020 mHandlePresentation = handlePresentation;
1021 mCallerDisplayName = callerDisplayName;
1022 mCallerDisplayNamePresentation = callerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -07001023 mAccountHandle = accountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -07001024 mCallCapabilities = capabilities;
Andrew Lee223ad142014-08-27 16:33:08 -07001025 mCallProperties = properties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001026 mDisconnectCause = disconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -07001027 mConnectTimeMillis = connectTimeMillis;
1028 mGatewayInfo = gatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -07001029 mVideoState = videoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -07001030 mStatusHints = statusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -07001031 mExtras = extras;
Santos Cordon6b7f9552015-05-27 17:21:45 -07001032 mIntentExtras = intentExtras;
Tyler Gunnc0bf6de2017-03-17 11:27:09 -07001033 mCreationTimeMillis = creationTimeMillis;
Hall Liuef98bf82020-01-09 15:22:44 -08001034 mContactDisplayName = contactDisplayName;
Tyler Gunn94f8f112018-12-17 09:56:11 -08001035 mCallDirection = callDirection;
Tyler Gunnd57d76c2019-09-24 14:53:23 -07001036 mCallerNumberVerificationStatus = callerNumberVerificationStatus;
Ihab Awade63fadb2014-07-09 21:52:04 -07001037 }
Sailesh Nepal1bef3392016-01-24 18:21:53 -08001038
1039 /** {@hide} */
1040 public static Details createFromParcelableCall(ParcelableCall parcelableCall) {
1041 return new Details(
1042 parcelableCall.getId(),
1043 parcelableCall.getHandle(),
1044 parcelableCall.getHandlePresentation(),
1045 parcelableCall.getCallerDisplayName(),
1046 parcelableCall.getCallerDisplayNamePresentation(),
1047 parcelableCall.getAccountHandle(),
1048 parcelableCall.getCapabilities(),
1049 parcelableCall.getProperties(),
1050 parcelableCall.getDisconnectCause(),
1051 parcelableCall.getConnectTimeMillis(),
1052 parcelableCall.getGatewayInfo(),
1053 parcelableCall.getVideoState(),
1054 parcelableCall.getStatusHints(),
1055 parcelableCall.getExtras(),
Tyler Gunnc0bf6de2017-03-17 11:27:09 -07001056 parcelableCall.getIntentExtras(),
Tyler Gunnd081f042018-12-04 12:56:45 -08001057 parcelableCall.getCreationTimeMillis(),
Hall Liuef98bf82020-01-09 15:22:44 -08001058 parcelableCall.getContactDisplayName(),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07001059 parcelableCall.getCallDirection(),
1060 parcelableCall.getCallerNumberVerificationStatus());
Sailesh Nepal1bef3392016-01-24 18:21:53 -08001061 }
Santos Cordon3c20d632016-02-25 16:12:35 -08001062
1063 @Override
1064 public String toString() {
1065 StringBuilder sb = new StringBuilder();
Tyler Gunn3cd820f2018-11-30 14:21:18 -08001066 sb.append("[id: ");
1067 sb.append(mTelecomCallId);
1068 sb.append(", pa: ");
Santos Cordon3c20d632016-02-25 16:12:35 -08001069 sb.append(mAccountHandle);
1070 sb.append(", hdl: ");
Tyler Gunn3cd820f2018-11-30 14:21:18 -08001071 sb.append(Log.piiHandle(mHandle));
1072 sb.append(", hdlPres: ");
1073 sb.append(mHandlePresentation);
1074 sb.append(", videoState: ");
1075 sb.append(VideoProfile.videoStateToString(mVideoState));
Santos Cordon3c20d632016-02-25 16:12:35 -08001076 sb.append(", caps: ");
1077 sb.append(capabilitiesToString(mCallCapabilities));
1078 sb.append(", props: ");
Tyler Gunn720c6642016-03-22 09:02:47 -07001079 sb.append(propertiesToString(mCallProperties));
Santos Cordon3c20d632016-02-25 16:12:35 -08001080 sb.append("]");
1081 return sb.toString();
1082 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001083 }
1084
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001085 /**
1086 * Defines callbacks which inform the {@link InCallService} of changes to a {@link Call}.
1087 * These callbacks can originate from the Telecom framework, or a {@link ConnectionService}
1088 * implementation.
1089 * <p>
1090 * You can handle these callbacks by extending the {@link Callback} class and overriding the
1091 * callbacks that your {@link InCallService} is interested in. The callback methods include the
1092 * {@link Call} for which the callback applies, allowing reuse of a single instance of your
1093 * {@link Callback} implementation, if desired.
1094 * <p>
1095 * Use {@link Call#registerCallback(Callback)} to register your callback(s). Ensure
1096 * {@link Call#unregisterCallback(Callback)} is called when you no longer require callbacks
1097 * (typically in {@link InCallService#onCallRemoved(Call)}).
1098 * Note: Callbacks which occur before you call {@link Call#registerCallback(Callback)} will not
1099 * reach your implementation of {@link Callback}, so it is important to register your callback
1100 * as soon as your {@link InCallService} is notified of a new call via
1101 * {@link InCallService#onCallAdded(Call)}.
1102 */
Andrew Leeda80c872015-04-15 14:09:50 -07001103 public static abstract class Callback {
Ihab Awade63fadb2014-07-09 21:52:04 -07001104 /**
Sanket Padawea8eddd42017-11-03 11:07:35 -07001105 * @hide
1106 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001107 @IntDef(prefix = { "HANDOVER_" },
1108 value = {HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_NOT_SUPPORTED,
Tyler Gunn5c60d712018-03-16 09:53:44 -07001109 HANDOVER_FAILURE_USER_REJECTED, HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL,
Tyler Gunn9d127732018-03-02 15:45:51 -08001110 HANDOVER_FAILURE_UNKNOWN})
Sanket Padawea8eddd42017-11-03 11:07:35 -07001111 @Retention(RetentionPolicy.SOURCE)
1112 public @interface HandoverFailureErrors {}
1113
1114 /**
1115 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the app
Tyler Gunn9d127732018-03-02 15:45:51 -08001116 * to handover the call to rejects the handover request.
1117 * <p>
1118 * Will be returned when {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} is called
1119 * and the destination {@link PhoneAccountHandle}'s {@link ConnectionService} returns a
1120 * {@code null} {@link Connection} from
1121 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
1122 * ConnectionRequest)}.
1123 * <p>
1124 * For more information on call handovers, see
1125 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001126 */
1127 public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1;
1128
1129 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08001130 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
1131 * is initiated but the source or destination app does not support handover.
1132 * <p>
1133 * Will be returned when a handover is requested via
1134 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)} and the destination
1135 * {@link PhoneAccountHandle} does not declare
1136 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}. May also be returned when a handover is
1137 * requested at the {@link PhoneAccountHandle} for the current call (i.e. the source call's
1138 * {@link Details#getAccountHandle()}) does not declare
1139 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
1140 * <p>
1141 * For more information on call handovers, see
1142 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001143 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001144 public static final int HANDOVER_FAILURE_NOT_SUPPORTED = 2;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001145
1146 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08001147 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the remote
1148 * user rejects the handover request.
1149 * <p>
1150 * For more information on call handovers, see
1151 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001152 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001153 public static final int HANDOVER_FAILURE_USER_REJECTED = 3;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001154
Sanket Padawe85291f62017-12-01 13:59:27 -08001155 /**
1156 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there
1157 * is ongoing emergency call.
Tyler Gunn9d127732018-03-02 15:45:51 -08001158 * <p>
1159 * This error code is returned when {@link #handoverTo(PhoneAccountHandle, int, Bundle)} is
1160 * called on an emergency call, or if any other call is an emergency call.
1161 * <p>
1162 * Handovers are not permitted while there are ongoing emergency calls.
1163 * <p>
1164 * For more information on call handovers, see
1165 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawe85291f62017-12-01 13:59:27 -08001166 */
Tyler Gunn5c60d712018-03-16 09:53:44 -07001167 public static final int HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL = 4;
Sanket Padawe85291f62017-12-01 13:59:27 -08001168
Tyler Gunn9d127732018-03-02 15:45:51 -08001169 /**
1170 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
1171 * fails for an unknown reason.
1172 * <p>
1173 * For more information on call handovers, see
1174 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
1175 */
1176 public static final int HANDOVER_FAILURE_UNKNOWN = 5;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001177
1178 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001179 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
1180 *
Ihab Awade63fadb2014-07-09 21:52:04 -07001181 * @param call The {@code Call} invoking this method.
1182 * @param state The new state of the {@code Call}.
1183 */
1184 public void onStateChanged(Call call, int state) {}
1185
1186 /**
1187 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
1188 *
1189 * @param call The {@code Call} invoking this method.
1190 * @param parent The new parent of the {@code Call}.
1191 */
1192 public void onParentChanged(Call call, Call parent) {}
1193
1194 /**
1195 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}.
1196 *
1197 * @param call The {@code Call} invoking this method.
1198 * @param children The new children of the {@code Call}.
1199 */
1200 public void onChildrenChanged(Call call, List<Call> children) {}
1201
1202 /**
1203 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}.
1204 *
1205 * @param call The {@code Call} invoking this method.
1206 * @param details A {@code Details} object describing the {@code Call}.
1207 */
1208 public void onDetailsChanged(Call call, Details details) {}
1209
1210 /**
1211 * Invoked when the text messages that can be used as responses to the incoming
1212 * {@code Call} are loaded from the relevant database.
1213 * See {@link #getCannedTextResponses()}.
1214 *
1215 * @param call The {@code Call} invoking this method.
1216 * @param cannedTextResponses The text messages useable as responses.
1217 */
1218 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
1219
1220 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001221 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
1222 * character. This causes the post-dial signals to stop pending user confirmation. An
1223 * implementation should present this choice to the user and invoke
1224 * {@link #postDialContinue(boolean)} when the user makes the choice.
1225 *
1226 * @param call The {@code Call} invoking this method.
1227 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
1228 */
1229 public void onPostDialWait(Call call, String remainingPostDialSequence) {}
1230
1231 /**
Andrew Lee50aca232014-07-22 16:41:54 -07001232 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed.
Ihab Awade63fadb2014-07-09 21:52:04 -07001233 *
1234 * @param call The {@code Call} invoking this method.
Andrew Lee50aca232014-07-22 16:41:54 -07001235 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
Ihab Awade63fadb2014-07-09 21:52:04 -07001236 */
Andrew Lee50aca232014-07-22 16:41:54 -07001237 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
Ihab Awade63fadb2014-07-09 21:52:04 -07001238
1239 /**
1240 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning
1241 * up their UI for the {@code Call} in response to state transitions. Specifically,
1242 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of
1243 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather,
1244 * clients should wait for this method to be invoked.
1245 *
1246 * @param call The {@code Call} being destroyed.
1247 */
1248 public void onCallDestroyed(Call call) {}
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001249
1250 /**
1251 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
1252 * conferenced.
1253 *
1254 * @param call The {@code Call} being updated.
1255 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
1256 * conferenced.
1257 */
1258 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001259
1260 /**
Tyler Gunn5567d742019-10-31 13:04:37 -07001261 * Invoked when a {@link Call} receives an event from its associated {@link Connection} or
1262 * {@link Conference}.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001263 * <p>
1264 * Where possible, the Call should make an attempt to handle {@link Connection} events which
1265 * are part of the {@code android.telecom.*} namespace. The Call should ignore any events
1266 * it does not wish to handle. Unexpected events should be handled gracefully, as it is
1267 * possible that a {@link ConnectionService} has defined its own Connection events which a
1268 * Call is not aware of.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001269 * <p>
Tyler Gunn5567d742019-10-31 13:04:37 -07001270 * See {@link Connection#sendConnectionEvent(String, Bundle)},
1271 * {@link Conference#sendConferenceEvent(String, Bundle)}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001272 *
1273 * @param call The {@code Call} receiving the event.
1274 * @param event The event.
1275 * @param extras Extras associated with the connection event.
1276 */
1277 public void onConnectionEvent(Call call, String event, Bundle extras) {}
Hall Liu95d55872017-01-25 17:12:49 -08001278
1279 /**
1280 * Invoked when the RTT mode changes for this call.
1281 * @param call The call whose RTT mode has changed.
1282 * @param mode the new RTT mode, one of
1283 * {@link RttCall#RTT_MODE_FULL}, {@link RttCall#RTT_MODE_HCO},
1284 * or {@link RttCall#RTT_MODE_VCO}
1285 */
1286 public void onRttModeChanged(Call call, int mode) {}
1287
1288 /**
1289 * Invoked when the call's RTT status changes, either from off to on or from on to off.
1290 * @param call The call whose RTT status has changed.
1291 * @param enabled whether RTT is now enabled or disabled
1292 * @param rttCall the {@link RttCall} object to use for reading and writing if RTT is now
1293 * on, null otherwise.
1294 */
1295 public void onRttStatusChanged(Call call, boolean enabled, RttCall rttCall) {}
1296
1297 /**
1298 * Invoked when the remote end of the connection has requested that an RTT communication
1299 * channel be opened. A response to this should be sent via {@link #respondToRttRequest}
1300 * with the same ID that this method is invoked with.
1301 * @param call The call which the RTT request was placed on
1302 * @param id The ID of the request.
1303 */
1304 public void onRttRequest(Call call, int id) {}
Hall Liu57006aa2017-02-06 10:49:48 -08001305
1306 /**
1307 * Invoked when the RTT session failed to initiate for some reason, including rejection
1308 * by the remote party.
1309 * @param call The call which the RTT initiation failure occurred on.
1310 * @param reason One of the status codes defined in
1311 * {@link android.telecom.Connection.RttModifyStatus}, with the exception of
1312 * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
1313 */
1314 public void onRttInitiationFailure(Call call, int reason) {}
Sanket Padawea8eddd42017-11-03 11:07:35 -07001315
1316 /**
1317 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
1318 * has completed successfully.
Tyler Gunn9d127732018-03-02 15:45:51 -08001319 * <p>
1320 * For a full discussion of the handover process and the APIs involved, see
1321 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
1322 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07001323 * @param call The call which had initiated handover.
1324 */
1325 public void onHandoverComplete(Call call) {}
1326
1327 /**
1328 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
1329 * has failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08001330 * <p>
1331 * For a full discussion of the handover process and the APIs involved, see
1332 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
1333 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07001334 * @param call The call which had initiated handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08001335 * @param failureReason Error reason for failure.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001336 */
1337 public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {}
Hall Liu95d55872017-01-25 17:12:49 -08001338 }
1339
1340 /**
1341 * A class that holds the state that describes the state of the RTT channel to the remote
1342 * party, if it is active.
1343 */
1344 public static final class RttCall {
Hall Liu07094df2017-02-28 15:17:44 -08001345 /** @hide */
Hall Liu95d55872017-01-25 17:12:49 -08001346 @Retention(RetentionPolicy.SOURCE)
1347 @IntDef({RTT_MODE_INVALID, RTT_MODE_FULL, RTT_MODE_HCO, RTT_MODE_VCO})
1348 public @interface RttAudioMode {}
1349
1350 /**
1351 * For metrics use. Default value in the proto.
1352 * @hide
1353 */
1354 public static final int RTT_MODE_INVALID = 0;
1355
1356 /**
1357 * Indicates that there should be a bidirectional audio stream between the two parties
1358 * on the call.
1359 */
1360 public static final int RTT_MODE_FULL = 1;
1361
1362 /**
1363 * Indicates that the local user should be able to hear the audio stream from the remote
1364 * user, but not vice versa. Equivalent to muting the microphone.
1365 */
1366 public static final int RTT_MODE_HCO = 2;
1367
1368 /**
1369 * Indicates that the remote user should be able to hear the audio stream from the local
1370 * user, but not vice versa. Equivalent to setting the volume to zero.
1371 */
1372 public static final int RTT_MODE_VCO = 3;
1373
1374 private static final int READ_BUFFER_SIZE = 1000;
1375
1376 private InputStreamReader mReceiveStream;
1377 private OutputStreamWriter mTransmitStream;
1378 private int mRttMode;
1379 private final InCallAdapter mInCallAdapter;
Hall Liu57006aa2017-02-06 10:49:48 -08001380 private final String mTelecomCallId;
Hall Liu95d55872017-01-25 17:12:49 -08001381 private char[] mReadBuffer = new char[READ_BUFFER_SIZE];
1382
1383 /**
1384 * @hide
1385 */
Hall Liu57006aa2017-02-06 10:49:48 -08001386 public RttCall(String telecomCallId, InputStreamReader receiveStream,
1387 OutputStreamWriter transmitStream, int mode, InCallAdapter inCallAdapter) {
1388 mTelecomCallId = telecomCallId;
Hall Liu95d55872017-01-25 17:12:49 -08001389 mReceiveStream = receiveStream;
1390 mTransmitStream = transmitStream;
1391 mRttMode = mode;
1392 mInCallAdapter = inCallAdapter;
1393 }
1394
1395 /**
1396 * Returns the current RTT audio mode.
1397 * @return Current RTT audio mode. One of {@link #RTT_MODE_FULL}, {@link #RTT_MODE_VCO}, or
1398 * {@link #RTT_MODE_HCO}.
1399 */
1400 public int getRttAudioMode() {
1401 return mRttMode;
1402 }
1403
1404 /**
1405 * Sets the RTT audio mode. The requested mode change will be communicated through
1406 * {@link Callback#onRttModeChanged(Call, int)}.
1407 * @param mode The desired RTT audio mode, one of {@link #RTT_MODE_FULL},
1408 * {@link #RTT_MODE_VCO}, or {@link #RTT_MODE_HCO}.
1409 */
1410 public void setRttMode(@RttAudioMode int mode) {
Hall Liu57006aa2017-02-06 10:49:48 -08001411 mInCallAdapter.setRttMode(mTelecomCallId, mode);
Hall Liu95d55872017-01-25 17:12:49 -08001412 }
1413
1414 /**
1415 * Writes the string {@param input} into the outgoing text stream for this RTT call. Since
1416 * RTT transmits text in real-time, this method should be called once for each character
1417 * the user enters into the device.
1418 *
1419 * This method is not thread-safe -- calling it from multiple threads simultaneously may
1420 * lead to interleaved text.
1421 * @param input The message to send to the remote user.
1422 */
1423 public void write(String input) throws IOException {
1424 mTransmitStream.write(input);
1425 mTransmitStream.flush();
1426 }
1427
1428 /**
1429 * Reads a string from the remote user, blocking if there is no data available. Returns
1430 * {@code null} if the RTT conversation has been terminated and there is no further data
1431 * to read.
1432 *
1433 * This method is not thread-safe -- calling it from multiple threads simultaneously may
1434 * lead to interleaved text.
1435 * @return A string containing text sent by the remote user, or {@code null} if the
1436 * conversation has been terminated or if there was an error while reading.
1437 */
Hall Liub1c8a772017-07-17 17:04:41 -07001438 public String read() {
1439 try {
1440 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
1441 if (numRead < 0) {
1442 return null;
1443 }
1444 return new String(mReadBuffer, 0, numRead);
1445 } catch (IOException e) {
1446 Log.w(this, "Exception encountered when reading from InputStreamReader: %s", e);
Jeff Sharkey90396362017-06-12 16:26:53 -06001447 return null;
Hall Liuffa4a812017-03-02 16:11:00 -08001448 }
Hall Liuffa4a812017-03-02 16:11:00 -08001449 }
1450
1451 /**
1452 * Non-blocking version of {@link #read()}. Returns {@code null} if there is nothing to
1453 * be read.
1454 * @return A string containing text entered by the user, or {@code null} if the user has
1455 * not entered any new text yet.
1456 */
1457 public String readImmediately() throws IOException {
1458 if (mReceiveStream.ready()) {
Hall Liub1c8a772017-07-17 17:04:41 -07001459 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
1460 if (numRead < 0) {
1461 return null;
1462 }
1463 return new String(mReadBuffer, 0, numRead);
Hall Liuffa4a812017-03-02 16:11:00 -08001464 } else {
Hall Liu95d55872017-01-25 17:12:49 -08001465 return null;
1466 }
1467 }
Hall Liue9041242018-02-09 16:40:03 -08001468
1469 /**
1470 * Closes the underlying file descriptors
1471 * @hide
1472 */
1473 public void close() {
1474 try {
1475 mReceiveStream.close();
1476 } catch (IOException e) {
1477 // ignore
1478 }
1479 try {
1480 mTransmitStream.close();
1481 } catch (IOException e) {
1482 // ignore
1483 }
1484 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001485 }
1486
Andrew Leeda80c872015-04-15 14:09:50 -07001487 /**
1488 * @deprecated Use {@code Call.Callback} instead.
1489 * @hide
1490 */
1491 @Deprecated
1492 @SystemApi
1493 public static abstract class Listener extends Callback { }
1494
Ihab Awade63fadb2014-07-09 21:52:04 -07001495 private final Phone mPhone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001496 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07001497 private final InCallAdapter mInCallAdapter;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001498 private final List<String> mChildrenIds = new ArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -07001499 private final List<Call> mChildren = new ArrayList<>();
1500 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
Andrew Lee011728f2015-04-23 15:47:06 -07001501 private final List<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArrayList<>();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001502 private final List<Call> mConferenceableCalls = new ArrayList<>();
1503 private final List<Call> mUnmodifiableConferenceableCalls =
1504 Collections.unmodifiableList(mConferenceableCalls);
1505
Santos Cordon823fd3c2014-08-07 18:35:18 -07001506 private boolean mChildrenCached;
1507 private String mParentId = null;
Hall Liuef98bf82020-01-09 15:22:44 -08001508 private String mActiveGenericConferenceChild = null;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001509 private int mState;
Ihab Awade63fadb2014-07-09 21:52:04 -07001510 private List<String> mCannedTextResponses = null;
Tyler Gunnb88b3112016-11-09 10:19:23 -08001511 private String mCallingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08001512 private int mTargetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -07001513 private String mRemainingPostDialSequence;
Tyler Gunn584ba6c2015-12-08 10:53:41 -08001514 private VideoCallImpl mVideoCallImpl;
Hall Liu95d55872017-01-25 17:12:49 -08001515 private RttCall mRttCall;
Ihab Awade63fadb2014-07-09 21:52:04 -07001516 private Details mDetails;
Tyler Gunndee56a82016-03-23 16:06:34 -07001517 private Bundle mExtras;
Ihab Awade63fadb2014-07-09 21:52:04 -07001518
1519 /**
1520 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
1521 *
1522 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence
1523 * remaining or this {@code Call} is not in a post-dial state.
1524 */
1525 public String getRemainingPostDialSequence() {
1526 return mRemainingPostDialSequence;
1527 }
1528
1529 /**
1530 * Instructs this {@link #STATE_RINGING} {@code Call} to answer.
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001531 * @param videoState The video state in which to answer the call.
Ihab Awade63fadb2014-07-09 21:52:04 -07001532 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001533 public void answer(@VideoProfile.VideoState int videoState) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001534 mInCallAdapter.answerCall(mTelecomCallId, videoState);
Ihab Awade63fadb2014-07-09 21:52:04 -07001535 }
1536
1537 /**
Pooja Jaind34698d2017-12-28 14:15:31 +05301538 * Instructs this {@link #STATE_RINGING} {@code Call} to deflect.
1539 *
1540 * @param address The address to which the call will be deflected.
1541 */
1542 public void deflect(Uri address) {
1543 mInCallAdapter.deflectCall(mTelecomCallId, address);
1544 }
1545
1546 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001547 * Instructs this {@link #STATE_RINGING} {@code Call} to reject.
1548 *
1549 * @param rejectWithMessage Whether to reject with a text message.
1550 * @param textMessage An optional text message with which to respond.
1551 */
1552 public void reject(boolean rejectWithMessage, String textMessage) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001553 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
Ihab Awade63fadb2014-07-09 21:52:04 -07001554 }
1555
1556 /**
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001557 * Instructs the {@link ConnectionService} providing this {@link #STATE_RINGING} call that the
1558 * user has chosen to reject the call and has indicated a reason why the call is being rejected.
1559 *
1560 * @param rejectReason the reason the call is being rejected.
1561 */
1562 public void reject(@RejectReason int rejectReason) {
1563 mInCallAdapter.rejectCall(mTelecomCallId, rejectReason);
1564 }
1565
1566 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001567 * Instructs this {@code Call} to disconnect.
1568 */
1569 public void disconnect() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001570 mInCallAdapter.disconnectCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001571 }
1572
1573 /**
1574 * Instructs this {@code Call} to go on hold.
1575 */
1576 public void hold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001577 mInCallAdapter.holdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001578 }
1579
1580 /**
1581 * Instructs this {@link #STATE_HOLDING} call to release from hold.
1582 */
1583 public void unhold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001584 mInCallAdapter.unholdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001585 }
1586
1587 /**
Hall Liu6dfa2492019-10-01 17:20:39 -07001588 * Instructs Telecom to put the call into the background audio processing state.
1589 *
1590 * This method can be called either when the call is in {@link #STATE_RINGING} or
1591 * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to
1592 * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in
1593 * order to capture and play audio on the call stream.
1594 *
1595 * This method can only be called by the default dialer app.
1596 * @hide
1597 */
1598 @SystemApi
1599 @TestApi
Hall Liu6dfa2492019-10-01 17:20:39 -07001600 public void enterBackgroundAudioProcessing() {
1601 if (mState != STATE_ACTIVE && mState != STATE_RINGING) {
1602 throw new IllegalStateException("Call must be active or ringing");
1603 }
1604 mInCallAdapter.enterBackgroundAudioProcessing(mTelecomCallId);
1605 }
1606
1607 /**
1608 * Instructs Telecom to come out of the background audio processing state requested by
1609 * {@link #enterBackgroundAudioProcessing()} or from the call screening service.
1610 *
1611 * This method can only be called when the call is in {@link #STATE_AUDIO_PROCESSING}.
1612 *
1613 * @param shouldRing If true, Telecom will put the call into the
1614 * {@link #STATE_SIMULATED_RINGING} state and notify other apps that there is
1615 * a ringing call. Otherwise, the call will go into {@link #STATE_ACTIVE}
1616 * immediately.
1617 * @hide
1618 */
1619 @SystemApi
1620 @TestApi
Hall Liu6dfa2492019-10-01 17:20:39 -07001621 public void exitBackgroundAudioProcessing(boolean shouldRing) {
1622 if (mState != STATE_AUDIO_PROCESSING) {
1623 throw new IllegalStateException("Call must in the audio processing state");
1624 }
1625 mInCallAdapter.exitBackgroundAudioProcessing(mTelecomCallId, shouldRing);
1626 }
1627
1628 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001629 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
1630 *
1631 * Any other currently playing DTMF tone in the specified call is immediately stopped.
1632 *
1633 * @param digit A character representing the DTMF digit for which to play the tone. This
1634 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
1635 */
1636 public void playDtmfTone(char digit) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001637 mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
Ihab Awade63fadb2014-07-09 21:52:04 -07001638 }
1639
1640 /**
1641 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone
1642 * currently playing.
1643 *
1644 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
1645 * currently playing, this method will do nothing.
1646 */
1647 public void stopDtmfTone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001648 mInCallAdapter.stopDtmfTone(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001649 }
1650
1651 /**
1652 * Instructs this {@code Call} to continue playing a post-dial DTMF string.
1653 *
1654 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
1655 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
Ihab Awade63fadb2014-07-09 21:52:04 -07001656 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001657 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awade63fadb2014-07-09 21:52:04 -07001658 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
1659 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001660 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Leeda80c872015-04-15 14:09:50 -07001661 * {@code Call} will pause playing the tones and notify callbacks via
1662 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
Ihab Awade63fadb2014-07-09 21:52:04 -07001663 * should display to the user an indication of this state and an affordance to continue
1664 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
1665 * app should invoke the {@link #postDialContinue(boolean)} method.
1666 *
1667 * @param proceed Whether or not to continue with the post-dial sequence.
1668 */
1669 public void postDialContinue(boolean proceed) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001670 mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
Ihab Awade63fadb2014-07-09 21:52:04 -07001671 }
1672
1673 /**
Evan Charlton8c8a0622014-07-20 12:31:00 -07001674 * Notifies this {@code Call} that an account has been selected and to proceed with placing
Nancy Chen36c62f32014-10-21 18:36:39 -07001675 * an outgoing call. Optionally sets this account as the default account.
Nancy Chen5da0fd52014-07-08 14:16:17 -07001676 */
Nancy Chen36c62f32014-10-21 18:36:39 -07001677 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) {
1678 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);
Nancy Chen5da0fd52014-07-08 14:16:17 -07001679
1680 }
1681
1682 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001683 * Instructs this {@code Call} to enter a conference.
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001684 *
1685 * @param callToConferenceWith The other call with which to conference.
Ihab Awade63fadb2014-07-09 21:52:04 -07001686 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001687 public void conference(Call callToConferenceWith) {
1688 if (callToConferenceWith != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001689 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001690 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001691 }
1692
1693 /**
1694 * Instructs this {@code Call} to split from any conference call with which it may be
1695 * connected.
1696 */
1697 public void splitFromConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001698 mInCallAdapter.splitFromConference(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001699 }
1700
1701 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001702 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -07001703 */
1704 public void mergeConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001705 mInCallAdapter.mergeConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -07001706 }
1707
1708 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001709 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -07001710 */
1711 public void swapConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001712 mInCallAdapter.swapConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -07001713 }
1714
1715 /**
Ravi Paluri404babb2020-01-23 19:02:44 +05301716 * Pulls participants to existing call by forming a conference call.
1717 * See {@link Details#CAPABILITY_ADD_PARTICIPANT}.
1718 *
1719 * @param participants participants to be pulled to existing call.
Tyler Gunn0c62ef02020-02-11 14:39:43 -08001720 * @hide
Ravi Paluri404babb2020-01-23 19:02:44 +05301721 */
1722 public void addConferenceParticipants(@NonNull List<Uri> participants) {
1723 mInCallAdapter.addConferenceParticipants(mTelecomCallId, participants);
1724 }
1725
1726 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001727 * Initiates a request to the {@link ConnectionService} to pull an external call to the local
1728 * device.
1729 * <p>
1730 * Calls to this method are ignored if the call does not have the
1731 * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property set.
1732 * <p>
1733 * An {@link InCallService} will only see calls which support this method if it has the
1734 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
1735 * in its manifest.
1736 */
1737 public void pullExternalCall() {
1738 // If this isn't an external call, ignore the request.
1739 if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) {
1740 return;
1741 }
1742
1743 mInCallAdapter.pullExternalCall(mTelecomCallId);
1744 }
1745
1746 /**
1747 * Sends a {@code Call} event from this {@code Call} to the associated {@link Connection} in
1748 * the {@link ConnectionService}.
1749 * <p>
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001750 * Call events are used to communicate point in time information from an {@link InCallService}
1751 * to a {@link ConnectionService}. A {@link ConnectionService} implementation could define
1752 * events which enable the {@link InCallService}, for example, toggle a unique feature of the
1753 * {@link ConnectionService}.
1754 * <p>
1755 * A {@link ConnectionService} can communicate to the {@link InCallService} using
1756 * {@link Connection#sendConnectionEvent(String, Bundle)}.
1757 * <p>
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001758 * Events are exposed to {@link ConnectionService} implementations via
1759 * {@link android.telecom.Connection#onCallEvent(String, Bundle)}.
1760 * <p>
1761 * No assumptions should be made as to how a {@link ConnectionService} will handle these events.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001762 * The {@link InCallService} must assume that the {@link ConnectionService} could chose to
1763 * ignore some events altogether.
1764 * <p>
1765 * Events should be fully qualified (e.g., {@code com.example.event.MY_EVENT}) to avoid
1766 * conflicts between {@link InCallService} implementations. Further, {@link InCallService}
1767 * implementations shall not re-purpose events in the {@code android.*} namespace, nor shall
1768 * they define their own event types in this namespace. When defining a custom event type,
1769 * ensure the contents of the extras {@link Bundle} is clearly defined. Extra keys for this
1770 * bundle should be named similar to the event type (e.g. {@code com.example.extra.MY_EXTRA}).
1771 * <p>
1772 * When defining events and the associated extras, it is important to keep their behavior
1773 * consistent when the associated {@link InCallService} is updated. Support for deprecated
1774 * events/extras should me maintained to ensure backwards compatibility with older
1775 * {@link ConnectionService} implementations which were built to support the older behavior.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001776 *
1777 * @param event The connection event.
1778 * @param extras Bundle containing extra information associated with the event.
1779 */
1780 public void sendCallEvent(String event, Bundle extras) {
Sanket Padawef6a9e5b2018-01-05 14:26:16 -08001781 mInCallAdapter.sendCallEvent(mTelecomCallId, event, mTargetSdkVersion, extras);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001782 }
1783
1784 /**
Hall Liu95d55872017-01-25 17:12:49 -08001785 * Sends an RTT upgrade request to the remote end of the connection. Success is not
1786 * guaranteed, and notification of success will be via the
1787 * {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
1788 */
1789 public void sendRttRequest() {
Hall Liu57006aa2017-02-06 10:49:48 -08001790 mInCallAdapter.sendRttRequest(mTelecomCallId);
Hall Liu95d55872017-01-25 17:12:49 -08001791 }
1792
1793 /**
1794 * Responds to an RTT request received via the {@link Callback#onRttRequest(Call, int)} )}
1795 * callback.
1796 * The ID used here should be the same as the ID that was received via the callback.
1797 * @param id The request ID received via {@link Callback#onRttRequest(Call, int)}
1798 * @param accept {@code true} if the RTT request should be accepted, {@code false} otherwise.
1799 */
1800 public void respondToRttRequest(int id, boolean accept) {
Hall Liu57006aa2017-02-06 10:49:48 -08001801 mInCallAdapter.respondToRttRequest(mTelecomCallId, id, accept);
Hall Liu95d55872017-01-25 17:12:49 -08001802 }
1803
1804 /**
Sanket Padawea8eddd42017-11-03 11:07:35 -07001805 * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified
1806 * by {@code toHandle}. The videoState specified indicates the desired video state after the
1807 * handover.
1808 * <p>
Tyler Gunn9d127732018-03-02 15:45:51 -08001809 * A call handover is the process where an ongoing call is transferred from one app (i.e.
1810 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
1811 * mobile network call in a video calling app. The mobile network call via the Telephony stack
1812 * is referred to as the source of the handover, and the video calling app is referred to as the
1813 * destination.
1814 * <p>
1815 * When considering a handover scenario the device this method is called on is considered the
1816 * <em>initiating</em> device (since the user initiates the handover from this device), and the
1817 * other device is considered the <em>receiving</em> device.
1818 * <p>
1819 * When this method is called on the <em>initiating</em> device, the Telecom framework will bind
1820 * to the {@link ConnectionService} defined by the {@code toHandle} {@link PhoneAccountHandle}
1821 * and invoke
1822 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
1823 * ConnectionRequest)} to inform the destination app that a request has been made to handover a
1824 * call to it. The app returns an instance of {@link Connection} to represent the handover call
1825 * At this point the app should display UI to indicate to the user that a call
1826 * handover is in process.
1827 * <p>
1828 * The destination app is responsible for communicating the handover request from the
1829 * <em>initiating</em> device to the <em>receiving</em> device.
1830 * <p>
1831 * When the app on the <em>receiving</em> device receives the handover request, it calls
1832 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to continue the handover
1833 * process from the <em>initiating</em> device to the <em>receiving</em> device. At this point
1834 * the destination app on the <em>receiving</em> device should show UI to allow the user to
1835 * choose whether they want to continue their call in the destination app.
1836 * <p>
1837 * When the destination app on the <em>receiving</em> device calls
1838 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)}, Telecom will bind to its
1839 * {@link ConnectionService} and call
1840 * {@link ConnectionService#onCreateIncomingHandoverConnection(PhoneAccountHandle,
1841 * ConnectionRequest)} to inform it of the handover request. The app returns an instance of
1842 * {@link Connection} to represent the handover call.
1843 * <p>
1844 * If the user of the <em>receiving</em> device accepts the handover, the app calls
1845 * {@link Connection#setActive()} to complete the handover process; Telecom will disconnect the
1846 * original call. If the user rejects the handover, the app calls
1847 * {@link Connection#setDisconnected(DisconnectCause)} and specifies a {@link DisconnectCause}
1848 * of {@link DisconnectCause#CANCELED} to indicate that the handover has been cancelled.
1849 * <p>
1850 * Telecom will only allow handovers from {@link PhoneAccount}s which declare
1851 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}. Similarly, the {@link PhoneAccount}
1852 * specified by {@code toHandle} must declare {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}.
1853 * <p>
1854 * Errors in the handover process are reported to the {@link InCallService} via
1855 * {@link Callback#onHandoverFailed(Call, int)}. Errors in the handover process are reported to
1856 * the involved {@link ConnectionService}s via
1857 * {@link ConnectionService#onHandoverFailed(ConnectionRequest, int)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001858 *
1859 * @param toHandle {@link PhoneAccountHandle} of the {@link ConnectionService} to handover
1860 * this call to.
Tyler Gunn9d127732018-03-02 15:45:51 -08001861 * @param videoState Indicates the video state desired after the handover (see the
1862 * {@code STATE_*} constants defined in {@link VideoProfile}).
Sanket Padawea8eddd42017-11-03 11:07:35 -07001863 * @param extras Bundle containing extra information to be passed to the
1864 * {@link ConnectionService}
1865 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001866 public void handoverTo(PhoneAccountHandle toHandle, @VideoProfile.VideoState int videoState,
1867 Bundle extras) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07001868 mInCallAdapter.handoverTo(mTelecomCallId, toHandle, videoState, extras);
1869 }
1870
1871 /**
Hall Liu95d55872017-01-25 17:12:49 -08001872 * Terminate the RTT session on this call. The resulting state change will be notified via
1873 * the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
1874 */
1875 public void stopRtt() {
Hall Liu57006aa2017-02-06 10:49:48 -08001876 mInCallAdapter.stopRtt(mTelecomCallId);
Hall Liu95d55872017-01-25 17:12:49 -08001877 }
1878
1879 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07001880 * Adds some extras to this {@link Call}. Existing keys are replaced and new ones are
1881 * added.
1882 * <p>
1883 * No assumptions should be made as to how an In-Call UI or service will handle these
1884 * extras. Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
1885 *
1886 * @param extras The extras to add.
1887 */
1888 public final void putExtras(Bundle extras) {
1889 if (extras == null) {
1890 return;
1891 }
1892
1893 if (mExtras == null) {
1894 mExtras = new Bundle();
1895 }
1896 mExtras.putAll(extras);
1897 mInCallAdapter.putExtras(mTelecomCallId, extras);
1898 }
1899
1900 /**
1901 * Adds a boolean extra to this {@link Call}.
1902 *
1903 * @param key The extra key.
1904 * @param value The value.
1905 * @hide
1906 */
1907 public final void putExtra(String key, boolean value) {
1908 if (mExtras == null) {
1909 mExtras = new Bundle();
1910 }
1911 mExtras.putBoolean(key, value);
1912 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1913 }
1914
1915 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001916 * Adds an integer extra to this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001917 *
1918 * @param key The extra key.
1919 * @param value The value.
1920 * @hide
1921 */
1922 public final void putExtra(String key, int value) {
1923 if (mExtras == null) {
1924 mExtras = new Bundle();
1925 }
1926 mExtras.putInt(key, value);
1927 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1928 }
1929
1930 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001931 * Adds a string extra to this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001932 *
1933 * @param key The extra key.
1934 * @param value The value.
1935 * @hide
1936 */
1937 public final void putExtra(String key, String value) {
1938 if (mExtras == null) {
1939 mExtras = new Bundle();
1940 }
1941 mExtras.putString(key, value);
1942 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1943 }
1944
1945 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001946 * Removes extras from this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001947 *
1948 * @param keys The keys of the extras to remove.
1949 */
1950 public final void removeExtras(List<String> keys) {
1951 if (mExtras != null) {
1952 for (String key : keys) {
1953 mExtras.remove(key);
1954 }
1955 if (mExtras.size() == 0) {
1956 mExtras = null;
1957 }
1958 }
1959 mInCallAdapter.removeExtras(mTelecomCallId, keys);
1960 }
1961
1962 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001963 * Removes extras from this {@link Call}.
1964 *
1965 * @param keys The keys of the extras to remove.
1966 */
1967 public final void removeExtras(String ... keys) {
1968 removeExtras(Arrays.asList(keys));
1969 }
1970
1971 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001972 * Obtains the parent of this {@code Call} in a conference, if any.
1973 *
1974 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
1975 * child of any conference {@code Call}s.
1976 */
1977 public Call getParent() {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001978 if (mParentId != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001979 return mPhone.internalGetCallByTelecomId(mParentId);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001980 }
1981 return null;
Ihab Awade63fadb2014-07-09 21:52:04 -07001982 }
1983
1984 /**
1985 * Obtains the children of this conference {@code Call}, if any.
1986 *
1987 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty
1988 * {@code List} otherwise.
1989 */
1990 public List<Call> getChildren() {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001991 if (!mChildrenCached) {
1992 mChildrenCached = true;
1993 mChildren.clear();
1994
1995 for(String id : mChildrenIds) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001996 Call call = mPhone.internalGetCallByTelecomId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001997 if (call == null) {
1998 // At least one child was still not found, so do not save true for "cached"
1999 mChildrenCached = false;
2000 } else {
2001 mChildren.add(call);
2002 }
2003 }
2004 }
2005
Ihab Awade63fadb2014-07-09 21:52:04 -07002006 return mUnmodifiableChildren;
2007 }
2008
2009 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002010 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
2011 *
2012 * @return The list of conferenceable {@code Call}s.
2013 */
2014 public List<Call> getConferenceableCalls() {
2015 return mUnmodifiableConferenceableCalls;
2016 }
2017
2018 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07002019 * Obtains the state of this {@code Call}.
2020 *
2021 * @return A state value, chosen from the {@code STATE_*} constants.
2022 */
2023 public int getState() {
2024 return mState;
2025 }
2026
2027 /**
Hall Liuef98bf82020-01-09 15:22:44 -08002028 * Returns the child {@link Call} in a generic conference that is currently active.
2029 * For calls that are not generic conferences, or when the generic conference has more than
2030 * 2 children, returns {@code null}.
2031 * @see Details#PROPERTY_GENERIC_CONFERENCE
2032 * @return The active child call.
2033 */
2034 public @Nullable Call getGenericConferenceActiveChildCall() {
2035 if (mActiveGenericConferenceChild != null) {
2036 return mPhone.internalGetCallByTelecomId(mActiveGenericConferenceChild);
2037 }
2038 return null;
2039 }
2040
2041 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07002042 * Obtains a list of canned, pre-configured message responses to present to the user as
2043 * ways of rejecting this {@code Call} using via a text message.
2044 *
2045 * @see #reject(boolean, String)
2046 *
2047 * @return A list of canned text message responses.
2048 */
2049 public List<String> getCannedTextResponses() {
2050 return mCannedTextResponses;
2051 }
2052
2053 /**
2054 * Obtains an object that can be used to display video from this {@code Call}.
2055 *
Andrew Lee50aca232014-07-22 16:41:54 -07002056 * @return An {@code Call.VideoCall}.
Ihab Awade63fadb2014-07-09 21:52:04 -07002057 */
Andrew Lee50aca232014-07-22 16:41:54 -07002058 public InCallService.VideoCall getVideoCall() {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002059 return mVideoCallImpl;
Ihab Awade63fadb2014-07-09 21:52:04 -07002060 }
2061
2062 /**
2063 * Obtains an object containing call details.
2064 *
2065 * @return A {@link Details} object. Depending on the state of the {@code Call}, the
2066 * result may be {@code null}.
2067 */
2068 public Details getDetails() {
2069 return mDetails;
2070 }
2071
2072 /**
Hall Liu95d55872017-01-25 17:12:49 -08002073 * Returns this call's RttCall object. The {@link RttCall} instance is used to send and
2074 * receive RTT text data, as well as to change the RTT mode.
2075 * @return A {@link Call.RttCall}. {@code null} if there is no active RTT connection.
2076 */
2077 public @Nullable RttCall getRttCall() {
2078 return mRttCall;
2079 }
2080
2081 /**
2082 * Returns whether this call has an active RTT connection.
2083 * @return true if there is a connection, false otherwise.
2084 */
2085 public boolean isRttActive() {
Hall Liue9041242018-02-09 16:40:03 -08002086 return mRttCall != null && mDetails.hasProperty(Details.PROPERTY_RTT);
Hall Liu95d55872017-01-25 17:12:49 -08002087 }
2088
2089 /**
Andrew Leeda80c872015-04-15 14:09:50 -07002090 * Registers a callback to this {@code Call}.
2091 *
2092 * @param callback A {@code Callback}.
2093 */
2094 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -07002095 registerCallback(callback, new Handler());
2096 }
2097
2098 /**
2099 * Registers a callback to this {@code Call}.
2100 *
2101 * @param callback A {@code Callback}.
2102 * @param handler A handler which command and status changes will be delivered to.
2103 */
2104 public void registerCallback(Callback callback, Handler handler) {
2105 unregisterCallback(callback);
Roshan Pius1ca62072015-07-07 17:34:51 -07002106 // Don't allow new callback registration if the call is already being destroyed.
2107 if (callback != null && handler != null && mState != STATE_DISCONNECTED) {
Andrew Lee011728f2015-04-23 15:47:06 -07002108 mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler));
2109 }
Andrew Leeda80c872015-04-15 14:09:50 -07002110 }
2111
2112 /**
2113 * Unregisters a callback from this {@code Call}.
2114 *
2115 * @param callback A {@code Callback}.
2116 */
2117 public void unregisterCallback(Callback callback) {
Roshan Pius1ca62072015-07-07 17:34:51 -07002118 // Don't allow callback deregistration if the call is already being destroyed.
2119 if (callback != null && mState != STATE_DISCONNECTED) {
Andrew Lee011728f2015-04-23 15:47:06 -07002120 for (CallbackRecord<Callback> record : mCallbackRecords) {
2121 if (record.getCallback() == callback) {
2122 mCallbackRecords.remove(record);
2123 break;
2124 }
2125 }
Andrew Leeda80c872015-04-15 14:09:50 -07002126 }
2127 }
2128
Santos Cordon3c20d632016-02-25 16:12:35 -08002129 @Override
2130 public String toString() {
2131 return new StringBuilder().
2132 append("Call [id: ").
2133 append(mTelecomCallId).
2134 append(", state: ").
2135 append(stateToString(mState)).
2136 append(", details: ").
2137 append(mDetails).
2138 append("]").toString();
2139 }
2140
2141 /**
2142 * @param state An integer value of a {@code STATE_*} constant.
2143 * @return A string representation of the value.
2144 */
2145 private static String stateToString(int state) {
2146 switch (state) {
2147 case STATE_NEW:
2148 return "NEW";
2149 case STATE_RINGING:
2150 return "RINGING";
2151 case STATE_DIALING:
2152 return "DIALING";
2153 case STATE_ACTIVE:
2154 return "ACTIVE";
2155 case STATE_HOLDING:
2156 return "HOLDING";
2157 case STATE_DISCONNECTED:
2158 return "DISCONNECTED";
2159 case STATE_CONNECTING:
2160 return "CONNECTING";
2161 case STATE_DISCONNECTING:
2162 return "DISCONNECTING";
2163 case STATE_SELECT_PHONE_ACCOUNT:
2164 return "SELECT_PHONE_ACCOUNT";
Hall Liu4e35b642019-10-14 17:50:45 -07002165 case STATE_SIMULATED_RINGING:
2166 return "SIMULATED_RINGING";
2167 case STATE_AUDIO_PROCESSING:
2168 return "AUDIO_PROCESSING";
Santos Cordon3c20d632016-02-25 16:12:35 -08002169 default:
2170 Log.w(Call.class, "Unknown state %d", state);
2171 return "UNKNOWN";
2172 }
2173 }
2174
Andrew Leeda80c872015-04-15 14:09:50 -07002175 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07002176 * Adds a listener to this {@code Call}.
2177 *
2178 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -07002179 * @deprecated Use {@link #registerCallback} instead.
2180 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -07002181 */
Andrew Leeda80c872015-04-15 14:09:50 -07002182 @Deprecated
2183 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -07002184 public void addListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -07002185 registerCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -07002186 }
2187
2188 /**
2189 * Removes a listener from this {@code Call}.
2190 *
2191 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -07002192 * @deprecated Use {@link #unregisterCallback} instead.
2193 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -07002194 */
Andrew Leeda80c872015-04-15 14:09:50 -07002195 @Deprecated
2196 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -07002197 public void removeListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -07002198 unregisterCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -07002199 }
2200
2201 /** {@hide} */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002202 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage,
2203 int targetSdkVersion) {
Ihab Awade63fadb2014-07-09 21:52:04 -07002204 mPhone = phone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002205 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002206 mInCallAdapter = inCallAdapter;
2207 mState = STATE_NEW;
Tyler Gunnb88b3112016-11-09 10:19:23 -08002208 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08002209 mTargetSdkVersion = targetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -07002210 }
2211
2212 /** {@hide} */
Tyler Gunnb88b3112016-11-09 10:19:23 -08002213 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state,
Tyler Gunn159f35c2017-03-02 09:28:37 -08002214 String callingPackage, int targetSdkVersion) {
Shriram Ganeshddf570e2015-05-31 09:18:48 -07002215 mPhone = phone;
2216 mTelecomCallId = telecomCallId;
2217 mInCallAdapter = inCallAdapter;
2218 mState = state;
Tyler Gunnb88b3112016-11-09 10:19:23 -08002219 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08002220 mTargetSdkVersion = targetSdkVersion;
Shriram Ganeshddf570e2015-05-31 09:18:48 -07002221 }
2222
2223 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07002224 final String internalGetCallId() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002225 return mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002226 }
2227
2228 /** {@hide} */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002229 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
Tyler Gunnb88b3112016-11-09 10:19:23 -08002230
Ihab Awade63fadb2014-07-09 21:52:04 -07002231 // First, we update the internal state as far as possible before firing any updates.
Sailesh Nepal1bef3392016-01-24 18:21:53 -08002232 Details details = Details.createFromParcelableCall(parcelableCall);
Ihab Awade63fadb2014-07-09 21:52:04 -07002233 boolean detailsChanged = !Objects.equals(mDetails, details);
2234 if (detailsChanged) {
2235 mDetails = details;
2236 }
2237
2238 boolean cannedTextResponsesChanged = false;
Santos Cordon88b771d2014-07-19 13:10:40 -07002239 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
2240 && !parcelableCall.getCannedSmsResponses().isEmpty()) {
2241 mCannedTextResponses =
2242 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
Yorke Leee886f632015-08-04 13:43:31 -07002243 cannedTextResponsesChanged = true;
Ihab Awade63fadb2014-07-09 21:52:04 -07002244 }
2245
Tyler Gunnd1fdf3a2019-11-05 15:47:58 -08002246 IVideoProvider previousVideoProvider = mVideoCallImpl == null ? null :
2247 mVideoCallImpl.getVideoProvider();
2248 IVideoProvider newVideoProvider = parcelableCall.getVideoProvider();
2249
2250 // parcelableCall.isVideoCallProviderChanged is only true when we have a video provider
2251 // specified; so we should check if the actual IVideoProvider changes as well.
2252 boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged()
2253 && !Objects.equals(previousVideoProvider, newVideoProvider);
Andrew Lee50aca232014-07-22 16:41:54 -07002254 if (videoCallChanged) {
Tyler Gunnd1fdf3a2019-11-05 15:47:58 -08002255 if (mVideoCallImpl != null) {
2256 mVideoCallImpl.destroy();
2257 }
2258 mVideoCallImpl = parcelableCall.isVideoCallProviderChanged() ?
2259 parcelableCall.getVideoCallImpl(mCallingPackage, mTargetSdkVersion) : null;
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002260 }
Tyler Gunnd1fdf3a2019-11-05 15:47:58 -08002261
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002262 if (mVideoCallImpl != null) {
2263 mVideoCallImpl.setVideoState(getDetails().getVideoState());
Ihab Awade63fadb2014-07-09 21:52:04 -07002264 }
2265
Santos Cordone3c507b2015-04-23 14:44:19 -07002266 int state = parcelableCall.getState();
Hall Liu31de23d2019-10-11 15:38:29 -07002267 if (mTargetSdkVersion < Phone.SDK_VERSION_R && state == Call.STATE_SIMULATED_RINGING) {
2268 state = Call.STATE_RINGING;
2269 }
Ihab Awade63fadb2014-07-09 21:52:04 -07002270 boolean stateChanged = mState != state;
2271 if (stateChanged) {
2272 mState = state;
2273 }
2274
Santos Cordon823fd3c2014-08-07 18:35:18 -07002275 String parentId = parcelableCall.getParentCallId();
2276 boolean parentChanged = !Objects.equals(mParentId, parentId);
2277 if (parentChanged) {
2278 mParentId = parentId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002279 }
2280
Santos Cordon823fd3c2014-08-07 18:35:18 -07002281 List<String> childCallIds = parcelableCall.getChildCallIds();
2282 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
2283 if (childrenChanged) {
2284 mChildrenIds.clear();
2285 mChildrenIds.addAll(parcelableCall.getChildCallIds());
2286 mChildrenCached = false;
Ihab Awade63fadb2014-07-09 21:52:04 -07002287 }
2288
Hall Liuef98bf82020-01-09 15:22:44 -08002289 String activeChildCallId = parcelableCall.getActiveChildCallId();
2290 boolean activeChildChanged = !Objects.equals(activeChildCallId,
2291 mActiveGenericConferenceChild);
2292 if (activeChildChanged) {
2293 mActiveGenericConferenceChild = activeChildCallId;
2294 }
2295
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002296 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
2297 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
2298 for (String otherId : conferenceableCallIds) {
2299 if (callIdMap.containsKey(otherId)) {
2300 conferenceableCalls.add(callIdMap.get(otherId));
2301 }
2302 }
2303
2304 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
2305 mConferenceableCalls.clear();
2306 mConferenceableCalls.addAll(conferenceableCalls);
2307 fireConferenceableCallsChanged();
2308 }
2309
Hall Liu95d55872017-01-25 17:12:49 -08002310 boolean isRttChanged = false;
2311 boolean rttModeChanged = false;
Hall Liue9041242018-02-09 16:40:03 -08002312 if (parcelableCall.getIsRttCallChanged()
2313 && mDetails.hasProperty(Details.PROPERTY_RTT)) {
Hall Liu95d55872017-01-25 17:12:49 -08002314 ParcelableRttCall parcelableRttCall = parcelableCall.getParcelableRttCall();
2315 InputStreamReader receiveStream = new InputStreamReader(
2316 new ParcelFileDescriptor.AutoCloseInputStream(
2317 parcelableRttCall.getReceiveStream()),
2318 StandardCharsets.UTF_8);
2319 OutputStreamWriter transmitStream = new OutputStreamWriter(
2320 new ParcelFileDescriptor.AutoCloseOutputStream(
2321 parcelableRttCall.getTransmitStream()),
2322 StandardCharsets.UTF_8);
Hall Liu57006aa2017-02-06 10:49:48 -08002323 RttCall newRttCall = new Call.RttCall(mTelecomCallId,
Hall Liu95d55872017-01-25 17:12:49 -08002324 receiveStream, transmitStream, parcelableRttCall.getRttMode(), mInCallAdapter);
2325 if (mRttCall == null) {
2326 isRttChanged = true;
2327 } else if (mRttCall.getRttAudioMode() != newRttCall.getRttAudioMode()) {
2328 rttModeChanged = true;
2329 }
2330 mRttCall = newRttCall;
2331 } else if (mRttCall != null && parcelableCall.getParcelableRttCall() == null
2332 && parcelableCall.getIsRttCallChanged()) {
2333 isRttChanged = true;
2334 mRttCall = null;
2335 }
2336
Ihab Awade63fadb2014-07-09 21:52:04 -07002337 // Now we fire updates, ensuring that any client who listens to any of these notifications
2338 // gets the most up-to-date state.
2339
2340 if (stateChanged) {
2341 fireStateChanged(mState);
2342 }
2343 if (detailsChanged) {
2344 fireDetailsChanged(mDetails);
2345 }
2346 if (cannedTextResponsesChanged) {
2347 fireCannedTextResponsesLoaded(mCannedTextResponses);
2348 }
Andrew Lee50aca232014-07-22 16:41:54 -07002349 if (videoCallChanged) {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002350 fireVideoCallChanged(mVideoCallImpl);
Ihab Awade63fadb2014-07-09 21:52:04 -07002351 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002352 if (parentChanged) {
2353 fireParentChanged(getParent());
2354 }
Hall Liuef98bf82020-01-09 15:22:44 -08002355 if (childrenChanged || activeChildChanged) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07002356 fireChildrenChanged(getChildren());
2357 }
Hall Liu95d55872017-01-25 17:12:49 -08002358 if (isRttChanged) {
2359 fireOnIsRttChanged(mRttCall != null, mRttCall);
2360 }
2361 if (rttModeChanged) {
2362 fireOnRttModeChanged(mRttCall.getRttAudioMode());
2363 }
Ihab Awade63fadb2014-07-09 21:52:04 -07002364
2365 // If we have transitioned to DISCONNECTED, that means we need to notify clients and
2366 // remove ourselves from the Phone. Note that we do this after completing all state updates
2367 // so a client can cleanly transition all their UI to the state appropriate for a
2368 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
2369 if (mState == STATE_DISCONNECTED) {
2370 fireCallDestroyed();
Ihab Awade63fadb2014-07-09 21:52:04 -07002371 }
2372 }
2373
2374 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07002375 final void internalSetPostDialWait(String remaining) {
2376 mRemainingPostDialSequence = remaining;
2377 firePostDialWait(mRemainingPostDialSequence);
2378 }
2379
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07002380 /** {@hide} */
Santos Cordonf30d7e92014-08-26 09:54:33 -07002381 final void internalSetDisconnected() {
2382 if (mState != Call.STATE_DISCONNECTED) {
2383 mState = Call.STATE_DISCONNECTED;
2384 fireStateChanged(mState);
2385 fireCallDestroyed();
Santos Cordonf30d7e92014-08-26 09:54:33 -07002386 }
2387 }
2388
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002389 /** {@hide} */
2390 final void internalOnConnectionEvent(String event, Bundle extras) {
2391 fireOnConnectionEvent(event, extras);
2392 }
2393
Hall Liu95d55872017-01-25 17:12:49 -08002394 /** {@hide} */
2395 final void internalOnRttUpgradeRequest(final int requestId) {
2396 for (CallbackRecord<Callback> record : mCallbackRecords) {
2397 final Call call = this;
2398 final Callback callback = record.getCallback();
2399 record.getHandler().post(() -> callback.onRttRequest(call, requestId));
2400 }
2401 }
2402
Hall Liu57006aa2017-02-06 10:49:48 -08002403 /** @hide */
2404 final void internalOnRttInitiationFailure(int reason) {
2405 for (CallbackRecord<Callback> record : mCallbackRecords) {
2406 final Call call = this;
2407 final Callback callback = record.getCallback();
2408 record.getHandler().post(() -> callback.onRttInitiationFailure(call, reason));
2409 }
2410 }
2411
Sanket Padawe85291f62017-12-01 13:59:27 -08002412 /** {@hide} */
2413 final void internalOnHandoverFailed(int error) {
2414 for (CallbackRecord<Callback> record : mCallbackRecords) {
2415 final Call call = this;
2416 final Callback callback = record.getCallback();
2417 record.getHandler().post(() -> callback.onHandoverFailed(call, error));
2418 }
2419 }
2420
Tyler Gunn858bfaf2018-01-22 15:17:54 -08002421 /** {@hide} */
2422 final void internalOnHandoverComplete() {
2423 for (CallbackRecord<Callback> record : mCallbackRecords) {
2424 final Call call = this;
2425 final Callback callback = record.getCallback();
2426 record.getHandler().post(() -> callback.onHandoverComplete(call));
2427 }
2428 }
2429
Andrew Lee011728f2015-04-23 15:47:06 -07002430 private void fireStateChanged(final int newState) {
2431 for (CallbackRecord<Callback> record : mCallbackRecords) {
2432 final Call call = this;
2433 final Callback callback = record.getCallback();
2434 record.getHandler().post(new Runnable() {
2435 @Override
2436 public void run() {
2437 callback.onStateChanged(call, newState);
2438 }
2439 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002440 }
2441 }
2442
Andrew Lee011728f2015-04-23 15:47:06 -07002443 private void fireParentChanged(final Call newParent) {
2444 for (CallbackRecord<Callback> record : mCallbackRecords) {
2445 final Call call = this;
2446 final Callback callback = record.getCallback();
2447 record.getHandler().post(new Runnable() {
2448 @Override
2449 public void run() {
2450 callback.onParentChanged(call, newParent);
2451 }
2452 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002453 }
2454 }
2455
Andrew Lee011728f2015-04-23 15:47:06 -07002456 private void fireChildrenChanged(final List<Call> children) {
2457 for (CallbackRecord<Callback> record : mCallbackRecords) {
2458 final Call call = this;
2459 final Callback callback = record.getCallback();
2460 record.getHandler().post(new Runnable() {
2461 @Override
2462 public void run() {
2463 callback.onChildrenChanged(call, children);
2464 }
2465 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002466 }
2467 }
2468
Andrew Lee011728f2015-04-23 15:47:06 -07002469 private void fireDetailsChanged(final Details details) {
2470 for (CallbackRecord<Callback> record : mCallbackRecords) {
2471 final Call call = this;
2472 final Callback callback = record.getCallback();
2473 record.getHandler().post(new Runnable() {
2474 @Override
2475 public void run() {
2476 callback.onDetailsChanged(call, details);
2477 }
2478 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002479 }
2480 }
2481
Andrew Lee011728f2015-04-23 15:47:06 -07002482 private void fireCannedTextResponsesLoaded(final List<String> cannedTextResponses) {
2483 for (CallbackRecord<Callback> record : mCallbackRecords) {
2484 final Call call = this;
2485 final Callback callback = record.getCallback();
2486 record.getHandler().post(new Runnable() {
2487 @Override
2488 public void run() {
2489 callback.onCannedTextResponsesLoaded(call, cannedTextResponses);
2490 }
2491 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002492 }
2493 }
2494
Andrew Lee011728f2015-04-23 15:47:06 -07002495 private void fireVideoCallChanged(final InCallService.VideoCall videoCall) {
2496 for (CallbackRecord<Callback> record : mCallbackRecords) {
2497 final Call call = this;
2498 final Callback callback = record.getCallback();
2499 record.getHandler().post(new Runnable() {
2500 @Override
2501 public void run() {
2502 callback.onVideoCallChanged(call, videoCall);
2503 }
2504 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002505 }
2506 }
2507
Andrew Lee011728f2015-04-23 15:47:06 -07002508 private void firePostDialWait(final String remainingPostDialSequence) {
2509 for (CallbackRecord<Callback> record : mCallbackRecords) {
2510 final Call call = this;
2511 final Callback callback = record.getCallback();
2512 record.getHandler().post(new Runnable() {
2513 @Override
2514 public void run() {
2515 callback.onPostDialWait(call, remainingPostDialSequence);
2516 }
2517 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002518 }
2519 }
2520
2521 private void fireCallDestroyed() {
Roshan Pius1ca62072015-07-07 17:34:51 -07002522 /**
2523 * To preserve the ordering of the Call's onCallDestroyed callback and Phone's
2524 * onCallRemoved callback, we remove this call from the Phone's record
2525 * only once all of the registered onCallDestroyed callbacks are executed.
2526 * All the callbacks get removed from our records as a part of this operation
2527 * since onCallDestroyed is the final callback.
2528 */
2529 final Call call = this;
2530 if (mCallbackRecords.isEmpty()) {
2531 // No callbacks registered, remove the call from Phone's record.
2532 mPhone.internalRemoveCall(call);
2533 }
2534 for (final CallbackRecord<Callback> record : mCallbackRecords) {
Andrew Lee011728f2015-04-23 15:47:06 -07002535 final Callback callback = record.getCallback();
2536 record.getHandler().post(new Runnable() {
2537 @Override
2538 public void run() {
Roshan Pius1ca62072015-07-07 17:34:51 -07002539 boolean isFinalRemoval = false;
2540 RuntimeException toThrow = null;
2541 try {
2542 callback.onCallDestroyed(call);
2543 } catch (RuntimeException e) {
2544 toThrow = e;
2545 }
2546 synchronized(Call.this) {
2547 mCallbackRecords.remove(record);
2548 if (mCallbackRecords.isEmpty()) {
2549 isFinalRemoval = true;
2550 }
2551 }
2552 if (isFinalRemoval) {
2553 mPhone.internalRemoveCall(call);
2554 }
2555 if (toThrow != null) {
2556 throw toThrow;
2557 }
Andrew Lee011728f2015-04-23 15:47:06 -07002558 }
2559 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002560 }
2561 }
2562
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002563 private void fireConferenceableCallsChanged() {
Andrew Lee011728f2015-04-23 15:47:06 -07002564 for (CallbackRecord<Callback> record : mCallbackRecords) {
2565 final Call call = this;
2566 final Callback callback = record.getCallback();
2567 record.getHandler().post(new Runnable() {
2568 @Override
2569 public void run() {
2570 callback.onConferenceableCallsChanged(call, mUnmodifiableConferenceableCalls);
2571 }
2572 });
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002573 }
2574 }
Tyler Gunn1e9bfc62015-08-19 11:18:58 -07002575
2576 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002577 * Notifies listeners of an incoming connection event.
2578 * <p>
2579 * Connection events are issued via {@link Connection#sendConnectionEvent(String, Bundle)}.
2580 *
2581 * @param event
2582 * @param extras
2583 */
2584 private void fireOnConnectionEvent(final String event, final Bundle extras) {
2585 for (CallbackRecord<Callback> record : mCallbackRecords) {
2586 final Call call = this;
2587 final Callback callback = record.getCallback();
2588 record.getHandler().post(new Runnable() {
2589 @Override
2590 public void run() {
2591 callback.onConnectionEvent(call, event, extras);
2592 }
2593 });
2594 }
2595 }
2596
2597 /**
Hall Liu95d55872017-01-25 17:12:49 -08002598 * Notifies listeners of an RTT on/off change
2599 *
2600 * @param enabled True if RTT is now enabled, false otherwise
2601 */
2602 private void fireOnIsRttChanged(final boolean enabled, final RttCall rttCall) {
2603 for (CallbackRecord<Callback> record : mCallbackRecords) {
2604 final Call call = this;
2605 final Callback callback = record.getCallback();
2606 record.getHandler().post(() -> callback.onRttStatusChanged(call, enabled, rttCall));
2607 }
2608 }
2609
2610 /**
2611 * Notifies listeners of a RTT mode change
2612 *
2613 * @param mode The new RTT mode
2614 */
2615 private void fireOnRttModeChanged(final int mode) {
2616 for (CallbackRecord<Callback> record : mCallbackRecords) {
2617 final Call call = this;
2618 final Callback callback = record.getCallback();
2619 record.getHandler().post(() -> callback.onRttModeChanged(call, mode));
2620 }
2621 }
2622
2623 /**
Tyler Gunn1e9bfc62015-08-19 11:18:58 -07002624 * Determines if two bundles are equal.
2625 *
2626 * @param bundle The original bundle.
2627 * @param newBundle The bundle to compare with.
2628 * @retrun {@code true} if the bundles are equal, {@code false} otherwise.
2629 */
2630 private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) {
2631 if (bundle == null || newBundle == null) {
2632 return bundle == newBundle;
2633 }
2634
2635 if (bundle.size() != newBundle.size()) {
2636 return false;
2637 }
2638
2639 for(String key : bundle.keySet()) {
2640 if (key != null) {
2641 final Object value = bundle.get(key);
2642 final Object newValue = newBundle.get(key);
2643 if (!Objects.equals(value, newValue)) {
2644 return false;
2645 }
2646 }
2647 }
2648 return true;
2649 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002650}