blob: dcaa49996d0b32b49c62c2b39a3b67e7d0acae81 [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;
20import android.annotation.Nullable;
Andrew Leeda80c872015-04-15 14:09:50 -070021import android.annotation.SystemApi;
Mathew Inwood42346d12018-08-01 11:33:05 +010022import android.annotation.UnsupportedAppUsage;
Ihab Awade63fadb2014-07-09 21:52:04 -070023import android.net.Uri;
Tyler Gunn6e3ecc42018-11-12 11:30:56 -080024import android.os.Build;
Nancy Chen10798dc2014-08-08 14:00:25 -070025import android.os.Bundle;
Andrew Lee011728f2015-04-23 15:47:06 -070026import android.os.Handler;
Hall Liu95d55872017-01-25 17:12:49 -080027import android.os.ParcelFileDescriptor;
Ihab Awade63fadb2014-07-09 21:52:04 -070028
Hall Liu95d55872017-01-25 17:12:49 -080029import java.io.IOException;
30import java.io.InputStreamReader;
31import java.io.OutputStreamWriter;
Hall Liu95d55872017-01-25 17:12:49 -080032import java.lang.annotation.Retention;
33import java.lang.annotation.RetentionPolicy;
34import java.nio.charset.StandardCharsets;
Ihab Awade63fadb2014-07-09 21:52:04 -070035import java.util.ArrayList;
Tyler Gunn071be6f2016-05-10 14:52:33 -070036import java.util.Arrays;
Ihab Awade63fadb2014-07-09 21:52:04 -070037import java.util.Collections;
38import java.util.List;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070039import java.util.Map;
Ihab Awade63fadb2014-07-09 21:52:04 -070040import java.util.Objects;
Jay Shrauner229e3822014-08-15 09:23:07 -070041import java.util.concurrent.CopyOnWriteArrayList;
Ihab Awade63fadb2014-07-09 21:52:04 -070042
43/**
44 * Represents an ongoing phone call that the in-call app should present to the user.
45 */
46public final class Call {
47 /**
48 * The state of a {@code Call} when newly created.
49 */
50 public static final int STATE_NEW = 0;
51
52 /**
53 * The state of an outgoing {@code Call} when dialing the remote number, but not yet connected.
54 */
55 public static final int STATE_DIALING = 1;
56
57 /**
58 * The state of an incoming {@code Call} when ringing locally, but not yet connected.
59 */
60 public static final int STATE_RINGING = 2;
61
62 /**
63 * The state of a {@code Call} when in a holding state.
64 */
65 public static final int STATE_HOLDING = 3;
66
67 /**
68 * The state of a {@code Call} when actively supporting conversation.
69 */
70 public static final int STATE_ACTIVE = 4;
71
72 /**
73 * The state of a {@code Call} when no further voice or other communication is being
74 * transmitted, the remote side has been or will inevitably be informed that the {@code Call}
75 * is no longer active, and the local data transport has or inevitably will release resources
76 * associated with this {@code Call}.
77 */
78 public static final int STATE_DISCONNECTED = 7;
79
Nancy Chen5da0fd52014-07-08 14:16:17 -070080 /**
Santos Cordone3c507b2015-04-23 14:44:19 -070081 * The state of an outgoing {@code Call} when waiting on user to select a
82 * {@link PhoneAccount} through which to place the call.
Nancy Chen5da0fd52014-07-08 14:16:17 -070083 */
Santos Cordone3c507b2015-04-23 14:44:19 -070084 public static final int STATE_SELECT_PHONE_ACCOUNT = 8;
85
86 /**
87 * @hide
88 * @deprecated use STATE_SELECT_PHONE_ACCOUNT.
89 */
90 @Deprecated
91 @SystemApi
92 public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT;
Nancy Chen5da0fd52014-07-08 14:16:17 -070093
Nancy Chene20930f2014-08-07 16:17:21 -070094 /**
Nancy Chene9b7a8e2014-08-08 14:26:27 -070095 * The initial state of an outgoing {@code Call}.
96 * Common transitions are to {@link #STATE_DIALING} state for a successful call or
97 * {@link #STATE_DISCONNECTED} if it failed.
Nancy Chene20930f2014-08-07 16:17:21 -070098 */
99 public static final int STATE_CONNECTING = 9;
100
Nancy Chen513c8922014-09-17 14:47:20 -0700101 /**
Tyler Gunn4afc6af2014-10-07 10:14:55 -0700102 * The state of a {@code Call} when the user has initiated a disconnection of the call, but the
103 * call has not yet been disconnected by the underlying {@code ConnectionService}. The next
104 * state of the call is (potentially) {@link #STATE_DISCONNECTED}.
105 */
106 public static final int STATE_DISCONNECTING = 10;
107
108 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700109 * The state of an external call which is in the process of being pulled from a remote device to
110 * the local device.
111 * <p>
112 * A call can only be in this state if the {@link Details#PROPERTY_IS_EXTERNAL_CALL} property
113 * and {@link Details#CAPABILITY_CAN_PULL_CALL} capability are set on the call.
114 * <p>
115 * An {@link InCallService} will only see this state if it has the
116 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its
117 * manifest.
118 */
119 public static final int STATE_PULLING_CALL = 11;
120
121 /**
Nancy Chen513c8922014-09-17 14:47:20 -0700122 * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
123 * extras. Used to pass the phone accounts to display on the front end to the user in order to
124 * select phone accounts to (for example) place a call.
Hall Liu34d9e242018-11-21 17:05:58 -0800125 * @deprecated Use the list from {@link #EXTRA_SUGGESTED_PHONE_ACCOUNTS} instead.
Nancy Chen513c8922014-09-17 14:47:20 -0700126 */
Hall Liu34d9e242018-11-21 17:05:58 -0800127 @Deprecated
Nancy Chen513c8922014-09-17 14:47:20 -0700128 public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
129
mike dooley4af561f2016-12-20 08:55:17 -0800130 /**
Hall Liu34d9e242018-11-21 17:05:58 -0800131 * Key for extra used to pass along a list of {@link PhoneAccountSuggestion}s to the in-call
132 * UI when a call enters the {@link #STATE_SELECT_PHONE_ACCOUNT} state. The list included here
133 * will have the same length and be in the same order as the list passed with
134 * {@link #AVAILABLE_PHONE_ACCOUNTS}.
135 */
136 public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS =
137 "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
138
139 /**
mike dooley91217422017-03-09 12:58:42 -0800140 * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC)
141 * when the last outgoing emergency call was made. This is used to identify potential emergency
142 * callbacks.
mike dooley4af561f2016-12-20 08:55:17 -0800143 */
144 public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
145 "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
146
Tyler Gunn8bf76572017-04-06 15:30:08 -0700147 /**
148 * Call event sent from a {@link Call} via {@link #sendCallEvent(String, Bundle)} to inform
149 * Telecom that the user has requested that the current {@link Call} should be handed over
150 * to another {@link ConnectionService}.
151 * <p>
152 * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to
153 * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to.
154 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700155 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
156 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700157 */
158 public static final String EVENT_REQUEST_HANDOVER =
159 "android.telecom.event.REQUEST_HANDOVER";
160
161 /**
162 * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the
163 * {@link PhoneAccountHandle} to which a call should be handed over to.
164 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700165 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
166 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700167 */
168 public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE =
169 "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE";
170
171 /**
172 * Integer extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the
173 * video state of the call when it is handed over to the new {@link PhoneAccount}.
174 * <p>
175 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
176 * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and
177 * {@link VideoProfile#STATE_TX_ENABLED}.
178 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700179 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
180 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700181 */
182 public static final String EXTRA_HANDOVER_VIDEO_STATE =
183 "android.telecom.extra.HANDOVER_VIDEO_STATE";
184
185 /**
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700186 * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Used by the
187 * {@link InCallService} initiating a handover to provide a {@link Bundle} with extra
188 * information to the handover {@link ConnectionService} specified by
189 * {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE}.
190 * <p>
191 * This {@link Bundle} is not interpreted by Telecom, but passed as-is to the
192 * {@link ConnectionService} via the request extras when
193 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
194 * is called to initate the handover.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700195 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700196 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
197 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700198 */
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700199 public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS";
Tyler Gunn8bf76572017-04-06 15:30:08 -0700200
201 /**
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700202 * Call event sent from Telecom to the handover {@link ConnectionService} via
203 * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
204 * to the {@link ConnectionService} has completed successfully.
205 * <p>
206 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700207 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700208 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
209 * APIs instead.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700210 */
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700211 public static final String EVENT_HANDOVER_COMPLETE =
212 "android.telecom.event.HANDOVER_COMPLETE";
Tyler Gunn34a2b312017-06-23 08:32:00 -0700213
214 /**
215 * Call event sent from Telecom to the handover destination {@link ConnectionService} via
216 * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the
217 * source connection has disconnected. The {@link Bundle} parameter for the call event will be
218 * {@code null}.
219 * <p>
220 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
221 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700222 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
223 * APIs instead.
Tyler Gunn34a2b312017-06-23 08:32:00 -0700224 */
225 public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
226 "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
227
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700228 /**
229 * Call event sent from Telecom to the handover {@link ConnectionService} via
230 * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
231 * to the {@link ConnectionService} has failed.
232 * <p>
233 * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
234 * @hide
Tyler Gunn1a505fa2018-09-14 13:36:38 -0700235 * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
236 * APIs instead.
Tyler Gunn9f6f0472017-04-17 18:25:22 -0700237 */
238 public static final String EVENT_HANDOVER_FAILED =
239 "android.telecom.event.HANDOVER_FAILED";
Tyler Gunn8bf76572017-04-06 15:30:08 -0700240
Ihab Awade63fadb2014-07-09 21:52:04 -0700241 public static class Details {
Tyler Gunn94f8f112018-12-17 09:56:11 -0800242 /** @hide */
243 @Retention(RetentionPolicy.SOURCE)
244 @IntDef(
245 prefix = { "DIRECTION_" },
246 value = {DIRECTION_UNKNOWN, DIRECTION_INCOMING, DIRECTION_OUTGOING})
247 public @interface CallDirection {}
248
249 /**
250 * Indicates that the call is neither and incoming nor an outgoing call. This can be the
251 * case for calls reported directly by a {@link ConnectionService} in special cases such as
252 * call handovers.
253 */
254 public static final int DIRECTION_UNKNOWN = -1;
255
256 /**
257 * Indicates that the call is an incoming call.
258 */
259 public static final int DIRECTION_INCOMING = 0;
260
261 /**
262 * Indicates that the call is an outgoing call.
263 */
264 public static final int DIRECTION_OUTGOING = 1;
265
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800266
267 /** Call can currently be put on hold or unheld. */
268 public static final int CAPABILITY_HOLD = 0x00000001;
269
270 /** Call supports the hold feature. */
271 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
272
273 /**
274 * Calls within a conference can be merged. A {@link ConnectionService} has the option to
275 * add a {@link Conference} call before the child {@link Connection}s are merged. This is how
276 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
277 * capability allows a merge button to be shown while the conference call is in the foreground
278 * of the in-call UI.
279 * <p>
280 * This is only intended for use by a {@link Conference}.
281 */
282 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
283
284 /**
285 * Calls within a conference can be swapped between foreground and background.
286 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
287 * <p>
288 * This is only intended for use by a {@link Conference}.
289 */
290 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
291
292 /**
293 * @hide
294 */
Andrew Lee2378ea72015-04-29 14:38:11 -0700295 public static final int CAPABILITY_UNUSED_1 = 0x00000010;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800296
297 /** Call supports responding via text option. */
298 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
299
300 /** Call can be muted. */
301 public static final int CAPABILITY_MUTE = 0x00000040;
302
303 /**
304 * Call supports conference call management. This capability only applies to {@link Conference}
305 * calls which can have {@link Connection}s as children.
306 */
307 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
308
309 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700310 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800311 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700312 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800313
314 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700315 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800316 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700317 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800318
319 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700320 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800321 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700322 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700323 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800324
325 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700326 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800327 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700328 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
329
330 /**
331 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700332 */
333 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
334
335 /**
336 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700337 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700338 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700339 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800340
341 /**
342 * Call is able to be separated from its parent {@code Conference}, if any.
343 */
344 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
345
346 /**
347 * Call is able to be individually disconnected when in a {@code Conference}.
348 */
349 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
350
351 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500352 * Speed up audio setup for MT call.
353 * @hide
354 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700355 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
356
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700357 /**
358 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700359 * @hide
Tyler Gunn6e3ecc42018-11-12 11:30:56 -0800360 * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
361 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call
362 * whether or not video calling is supported.
Rekha Kumar07366812015-03-24 16:42:31 -0700363 */
Tyler Gunn6e3ecc42018-11-12 11:30:56 -0800364 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590)
Rekha Kumar07366812015-03-24 16:42:31 -0700365 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
366
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700367 /**
368 * For video calls, indicates whether the outgoing video for the call can be paused using
Yorke Lee32f24732015-05-12 16:18:03 -0700369 * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700370 */
371 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
372
Bryce Lee81901682015-08-28 16:38:02 -0700373 /**
374 * Call sends responses through connection.
375 * @hide
376 */
Tyler Gunnf97a0092016-01-19 15:59:34 -0800377 public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00200000;
378
379 /**
380 * When set, prevents a video {@code Call} from being downgraded to an audio-only call.
381 * <p>
382 * Should be set when the VideoState has the {@link VideoProfile#STATE_TX_ENABLED} or
383 * {@link VideoProfile#STATE_RX_ENABLED} bits set to indicate that the connection cannot be
384 * downgraded from a video call back to a VideoState of
385 * {@link VideoProfile#STATE_AUDIO_ONLY}.
386 * <p>
387 * Intuitively, a call which can be downgraded to audio should also have local and remote
388 * video
389 * capabilities (see {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
390 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL}).
391 */
392 public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00400000;
Bryce Lee81901682015-08-28 16:38:02 -0700393
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700394 /**
395 * When set for an external call, indicates that this {@code Call} can be pulled from a
396 * remote device to the current device.
397 * <p>
398 * Should only be set on a {@code Call} where {@link #PROPERTY_IS_EXTERNAL_CALL} is set.
399 * <p>
400 * An {@link InCallService} will only see calls with this capability if it has the
401 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
402 * in its manifest.
403 * <p>
404 * See {@link Connection#CAPABILITY_CAN_PULL_CALL} and
Tyler Gunn720c6642016-03-22 09:02:47 -0700405 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700406 */
407 public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000;
408
Pooja Jaind34698d2017-12-28 14:15:31 +0530409 /** Call supports the deflect feature. */
410 public static final int CAPABILITY_SUPPORT_DEFLECT = 0x01000000;
411
Tyler Gunnd11a3152015-03-18 13:09:14 -0700412 //******************************************************************************************
Pooja Jaind34698d2017-12-28 14:15:31 +0530413 // Next CAPABILITY value: 0x02000000
Andrew Lee2378ea72015-04-29 14:38:11 -0700414 //******************************************************************************************
415
416 /**
417 * Whether the call is currently a conference.
418 */
419 public static final int PROPERTY_CONFERENCE = 0x00000001;
420
421 /**
422 * Whether the call is a generic conference, where we do not know the precise state of
423 * participants in the conference (eg. on CDMA).
424 */
425 public static final int PROPERTY_GENERIC_CONFERENCE = 0x00000002;
426
427 /**
428 * Whether the call is made while the device is in emergency callback mode.
429 */
430 public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 0x00000004;
431
432 /**
433 * Connection is using WIFI.
434 */
435 public static final int PROPERTY_WIFI = 0x00000008;
436
437 /**
Tyler Gunn6b6ae552018-10-11 10:42:10 -0700438 * When set, the UI should indicate to the user that a call is using high definition
439 * audio.
440 * <p>
441 * The underlying {@link ConnectionService} is responsible for reporting this
442 * property. It is important to note that this property is not intended to report the
443 * actual audio codec being used for a Call, but whether the call should be indicated
444 * to the user as high definition.
445 * <p>
446 * The Android Telephony stack reports this property for calls based on a number
447 * of factors, including which audio codec is used and whether a call is using an HD
448 * codec end-to-end. Some mobile operators choose to suppress display of an HD indication,
449 * and in these cases this property will not be set for a call even if the underlying audio
450 * codec is in fact "high definition".
Andrew Lee2378ea72015-04-29 14:38:11 -0700451 */
452 public static final int PROPERTY_HIGH_DEF_AUDIO = 0x00000010;
453
Tony Maka68dcce2015-12-17 09:31:18 +0000454 /**
Tony Mak53b5df42016-05-19 13:40:38 +0100455 * Whether the call is associated with the work profile.
456 */
457 public static final int PROPERTY_ENTERPRISE_CALL = 0x00000020;
458
459 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700460 * When set, indicates that this {@code Call} does not actually exist locally for the
461 * {@link ConnectionService}.
462 * <p>
463 * Consider, for example, a scenario where a user has two phones with the same phone number.
464 * When a user places a call on one device, the telephony stack can represent that call on
465 * the other device by adding it to the {@link ConnectionService} with the
Tyler Gunn720c6642016-03-22 09:02:47 -0700466 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL} property set.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700467 * <p>
468 * An {@link InCallService} will only see calls with this property if it has the
469 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
470 * in its manifest.
471 * <p>
Tyler Gunn720c6642016-03-22 09:02:47 -0700472 * See {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700473 */
474 public static final int PROPERTY_IS_EXTERNAL_CALL = 0x00000040;
475
Brad Ebinger15847072016-05-18 11:08:36 -0700476 /**
477 * Indicates that the call has CDMA Enhanced Voice Privacy enabled.
478 */
479 public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 0x00000080;
480
Tyler Gunn24e18332017-02-10 09:42:49 -0800481 /**
482 * Indicates that the call is from a self-managed {@link ConnectionService}.
483 * <p>
484 * See also {@link Connection#PROPERTY_SELF_MANAGED}
485 */
486 public static final int PROPERTY_SELF_MANAGED = 0x00000100;
487
Eric Erfanianec881872017-12-06 16:27:53 -0800488 /**
489 * Indicates the call used Assisted Dialing.
490 * See also {@link Connection#PROPERTY_ASSISTED_DIALING_USED}
491 * @hide
492 */
493 public static final int PROPERTY_ASSISTED_DIALING_USED = 0x00000200;
494
Hall Liue9041242018-02-09 16:40:03 -0800495 /**
496 * Indicates that the call is an RTT call. Use {@link #getRttCall()} to get the
497 * {@link RttCall} object that is used to send and receive text.
498 */
499 public static final int PROPERTY_RTT = 0x00000400;
500
Tyler Gunn5bd90852018-09-21 09:37:07 -0700501 /**
502 * Indicates that the call has been identified as the network as an emergency call. This
503 * property may be set for both incoming and outgoing calls which the network identifies as
504 * emergency calls.
505 */
506 public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 0x00000800;
507
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700508 /**
509 * Indicates that the call is using VoIP audio mode.
510 * <p>
511 * When this property is set, the {@link android.media.AudioManager} audio mode for this
512 * call will be {@link android.media.AudioManager#MODE_IN_COMMUNICATION}. When this
513 * property is not set, the audio mode for this call will be
514 * {@link android.media.AudioManager#MODE_IN_CALL}.
515 * <p>
516 * This property reflects changes made using {@link Connection#setAudioModeIsVoip(boolean)}.
517 * <p>
518 * You can use this property to determine whether an un-answered incoming call or a held
519 * call will use VoIP audio mode (if the call does not currently have focus, the system
520 * audio mode may not reflect the mode the call will use).
521 */
522 public static final int PROPERTY_VOIP_AUDIO_MODE = 0x00001000;
523
Andrew Lee2378ea72015-04-29 14:38:11 -0700524 //******************************************************************************************
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700525 // Next PROPERTY value: 0x00002000
Tyler Gunnd11a3152015-03-18 13:09:14 -0700526 //******************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800527
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800528 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700529 private final Uri mHandle;
530 private final int mHandlePresentation;
531 private final String mCallerDisplayName;
532 private final int mCallerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700533 private final PhoneAccountHandle mAccountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700534 private final int mCallCapabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700535 private final int mCallProperties;
Christine Hallstrom4e22d6d2016-11-30 16:06:42 -0800536 private final int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700537 private final DisconnectCause mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700538 private final long mConnectTimeMillis;
539 private final GatewayInfo mGatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700540 private final int mVideoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700541 private final StatusHints mStatusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700542 private final Bundle mExtras;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700543 private final Bundle mIntentExtras;
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700544 private final long mCreationTimeMillis;
Tyler Gunnd081f042018-12-04 12:56:45 -0800545 private final CallIdentification mCallIdentification;
Tyler Gunn94f8f112018-12-17 09:56:11 -0800546 private final @CallDirection int mCallDirection;
Ihab Awade63fadb2014-07-09 21:52:04 -0700547
548 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800549 * Whether the supplied capabilities supports the specified capability.
550 *
551 * @param capabilities A bit field of capabilities.
552 * @param capability The capability to check capabilities for.
553 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800554 */
555 public static boolean can(int capabilities, int capability) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800556 return (capabilities & capability) == capability;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800557 }
558
559 /**
560 * Whether the capabilities of this {@code Details} supports the specified capability.
561 *
562 * @param capability The capability to check capabilities for.
563 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800564 */
565 public boolean can(int capability) {
566 return can(mCallCapabilities, capability);
567 }
568
569 /**
570 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
571 *
572 * @param capabilities A capability bit field.
573 * @return A human readable string representation.
574 */
575 public static String capabilitiesToString(int capabilities) {
576 StringBuilder builder = new StringBuilder();
577 builder.append("[Capabilities:");
578 if (can(capabilities, CAPABILITY_HOLD)) {
579 builder.append(" CAPABILITY_HOLD");
580 }
581 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
582 builder.append(" CAPABILITY_SUPPORT_HOLD");
583 }
584 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
585 builder.append(" CAPABILITY_MERGE_CONFERENCE");
586 }
587 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
588 builder.append(" CAPABILITY_SWAP_CONFERENCE");
589 }
590 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
591 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
592 }
593 if (can(capabilities, CAPABILITY_MUTE)) {
594 builder.append(" CAPABILITY_MUTE");
595 }
596 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
597 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
598 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700599 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
600 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
601 }
602 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
603 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
604 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700605 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
606 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800607 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700608 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
609 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
610 }
611 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
612 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
613 }
Tyler Gunnf97a0092016-01-19 15:59:34 -0800614 if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
615 builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO");
616 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700617 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
618 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800619 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500620 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700621 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500622 }
Rekha Kumar07366812015-03-24 16:42:31 -0700623 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
624 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
625 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700626 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
627 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
628 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700629 if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
630 builder.append(" CAPABILITY_CAN_PULL_CALL");
631 }
Pooja Jaind34698d2017-12-28 14:15:31 +0530632 if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) {
633 builder.append(" CAPABILITY_SUPPORT_DEFLECT");
634 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800635 builder.append("]");
636 return builder.toString();
637 }
638
639 /**
Andrew Lee2378ea72015-04-29 14:38:11 -0700640 * Whether the supplied properties includes the specified property.
641 *
642 * @param properties A bit field of properties.
643 * @param property The property to check properties for.
644 * @return Whether the specified property is supported.
645 */
646 public static boolean hasProperty(int properties, int property) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800647 return (properties & property) == property;
Andrew Lee2378ea72015-04-29 14:38:11 -0700648 }
649
650 /**
651 * Whether the properties of this {@code Details} includes the specified property.
652 *
653 * @param property The property to check properties for.
654 * @return Whether the specified property is supported.
655 */
656 public boolean hasProperty(int property) {
657 return hasProperty(mCallProperties, property);
658 }
659
660 /**
661 * Render a set of property bits ({@code PROPERTY_*}) as a human readable string.
662 *
663 * @param properties A property bit field.
664 * @return A human readable string representation.
665 */
666 public static String propertiesToString(int properties) {
667 StringBuilder builder = new StringBuilder();
668 builder.append("[Properties:");
669 if (hasProperty(properties, PROPERTY_CONFERENCE)) {
670 builder.append(" PROPERTY_CONFERENCE");
671 }
672 if (hasProperty(properties, PROPERTY_GENERIC_CONFERENCE)) {
673 builder.append(" PROPERTY_GENERIC_CONFERENCE");
674 }
675 if (hasProperty(properties, PROPERTY_WIFI)) {
676 builder.append(" PROPERTY_WIFI");
677 }
678 if (hasProperty(properties, PROPERTY_HIGH_DEF_AUDIO)) {
679 builder.append(" PROPERTY_HIGH_DEF_AUDIO");
680 }
681 if (hasProperty(properties, PROPERTY_EMERGENCY_CALLBACK_MODE)) {
Yorke Leebe2a4a22015-06-12 10:10:55 -0700682 builder.append(" PROPERTY_EMERGENCY_CALLBACK_MODE");
Andrew Lee2378ea72015-04-29 14:38:11 -0700683 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700684 if (hasProperty(properties, PROPERTY_IS_EXTERNAL_CALL)) {
685 builder.append(" PROPERTY_IS_EXTERNAL_CALL");
686 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700687 if (hasProperty(properties, PROPERTY_HAS_CDMA_VOICE_PRIVACY)) {
Brad Ebinger15847072016-05-18 11:08:36 -0700688 builder.append(" PROPERTY_HAS_CDMA_VOICE_PRIVACY");
689 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700690 if (hasProperty(properties, PROPERTY_ASSISTED_DIALING_USED)) {
Eric Erfanianec881872017-12-06 16:27:53 -0800691 builder.append(" PROPERTY_ASSISTED_DIALING_USED");
692 }
Tyler Gunn5bd90852018-09-21 09:37:07 -0700693 if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
694 builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL");
695 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700696 if (hasProperty(properties, PROPERTY_RTT)) {
697 builder.append(" PROPERTY_RTT");
698 }
699 if (hasProperty(properties, PROPERTY_VOIP_AUDIO_MODE)) {
700 builder.append(" PROPERTY_VOIP_AUDIO_MODE");
701 }
Andrew Lee2378ea72015-04-29 14:38:11 -0700702 builder.append("]");
703 return builder.toString();
704 }
705
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800706 /** {@hide} */
707 public String getTelecomCallId() {
708 return mTelecomCallId;
709 }
710
Andrew Lee2378ea72015-04-29 14:38:11 -0700711 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700712 * @return The handle (e.g., phone number) to which the {@code Call} is currently
713 * connected.
714 */
715 public Uri getHandle() {
716 return mHandle;
717 }
718
719 /**
720 * @return The presentation requirements for the handle. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700721 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700722 */
723 public int getHandlePresentation() {
724 return mHandlePresentation;
725 }
726
727 /**
Tyler Gunnd081f042018-12-04 12:56:45 -0800728 * The display name for the caller.
729 * <p>
730 * This is the name as reported by the {@link ConnectionService} associated with this call.
731 * The name reported by a {@link CallScreeningService} can be retrieved using
732 * {@link CallIdentification#getName()}.
733 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700734 * @return The display name for the caller.
735 */
736 public String getCallerDisplayName() {
737 return mCallerDisplayName;
738 }
739
740 /**
741 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700742 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700743 */
744 public int getCallerDisplayNamePresentation() {
745 return mCallerDisplayNamePresentation;
746 }
747
748 /**
Evan Charlton6eb262c2014-07-19 18:18:19 -0700749 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being
750 * routed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700751 */
Evan Charlton8c8a0622014-07-20 12:31:00 -0700752 public PhoneAccountHandle getAccountHandle() {
753 return mAccountHandle;
Ihab Awade63fadb2014-07-09 21:52:04 -0700754 }
755
756 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800757 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various
758 * {@code CAPABILITY_*} constants in this class.
Ihab Awade63fadb2014-07-09 21:52:04 -0700759 */
Ihab Awad5d0410f2014-07-30 10:07:40 -0700760 public int getCallCapabilities() {
761 return mCallCapabilities;
Ihab Awade63fadb2014-07-09 21:52:04 -0700762 }
763
764 /**
Andrew Lee2378ea72015-04-29 14:38:11 -0700765 * @return A bitmask of the properties of the {@code Call}, as defined by the various
766 * {@code PROPERTY_*} constants in this class.
Andrew Lee223ad142014-08-27 16:33:08 -0700767 */
768 public int getCallProperties() {
769 return mCallProperties;
770 }
771
772 /**
Christine Hallstrom4e22d6d2016-11-30 16:06:42 -0800773 * @return a bitmask of the audio routes available for the call.
774 *
775 * @hide
776 */
777 public int getSupportedAudioRoutes() {
778 return mSupportedAudioRoutes;
779 }
780
781 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700782 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700783 * by {@link android.telecom.DisconnectCause}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700784 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700785 public DisconnectCause getDisconnectCause() {
786 return mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700787 }
788
789 /**
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700790 * Returns the time the {@link Call} connected (i.e. became active). This information is
791 * updated periodically, but user interfaces should not rely on this to display the "call
792 * time clock". For the time when the call was first added to Telecom, see
793 * {@link #getCreationTimeMillis()}.
794 *
795 * @return The time the {@link Call} connected in milliseconds since the epoch.
Ihab Awade63fadb2014-07-09 21:52:04 -0700796 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700797 public final long getConnectTimeMillis() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700798 return mConnectTimeMillis;
799 }
800
801 /**
802 * @return Information about any calling gateway the {@code Call} may be using.
803 */
804 public GatewayInfo getGatewayInfo() {
805 return mGatewayInfo;
806 }
807
Andrew Lee7a341382014-07-15 17:05:08 -0700808 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700809 * @return The video state of the {@code Call}.
Andrew Lee7a341382014-07-15 17:05:08 -0700810 */
811 public int getVideoState() {
812 return mVideoState;
813 }
814
Ihab Awad5d0410f2014-07-30 10:07:40 -0700815 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700816 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none
Ihab Awad5d0410f2014-07-30 10:07:40 -0700817 * have been set.
Evan Charlton5b49ade2014-07-15 17:03:20 -0700818 */
819 public StatusHints getStatusHints() {
820 return mStatusHints;
821 }
822
Nancy Chen10798dc2014-08-08 14:00:25 -0700823 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700824 * @return The extras associated with this call.
Nancy Chen10798dc2014-08-08 14:00:25 -0700825 */
826 public Bundle getExtras() {
827 return mExtras;
828 }
829
Santos Cordon6b7f9552015-05-27 17:21:45 -0700830 /**
831 * @return The extras used with the original intent to place this call.
832 */
833 public Bundle getIntentExtras() {
834 return mIntentExtras;
835 }
836
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700837 /**
838 * Returns the time when the call was first created and added to Telecom. This is the same
839 * time that is logged as the start time in the Call Log (see
840 * {@link android.provider.CallLog.Calls#DATE}). To determine when the call was connected
841 * (became active), see {@link #getConnectTimeMillis()}.
842 *
843 * @return The creation time of the call, in millis since the epoch.
844 */
845 public long getCreationTimeMillis() {
846 return mCreationTimeMillis;
847 }
848
Tyler Gunnd081f042018-12-04 12:56:45 -0800849 /**
850 * Returns {@link CallIdentification} information provided by a
851 * {@link CallScreeningService} for this call.
852 * <p>
853 * {@link InCallService} implementations should display the {@link CallIdentification} for
854 * calls. The name of the call screening service is provided in
855 * {@link CallIdentification#getCallScreeningAppName()} and should be used to attribute the
856 * call identification information.
857 *
858 * @return The {@link CallIdentification} if it was provided by a
859 * {@link CallScreeningService}, or {@code null} if no {@link CallScreeningService} has
860 * provided {@link CallIdentification} information for the call.
861 */
862 public @Nullable CallIdentification getCallIdentification() {
863 return mCallIdentification;
864 }
865
Tyler Gunn94f8f112018-12-17 09:56:11 -0800866 /**
867 * Indicates whether the call is an incoming or outgoing call.
868 * @return The call's direction.
869 */
870 public @CallDirection int getCallDirection() {
871 return mCallDirection;
872 }
873
Ihab Awade63fadb2014-07-09 21:52:04 -0700874 @Override
875 public boolean equals(Object o) {
876 if (o instanceof Details) {
877 Details d = (Details) o;
878 return
879 Objects.equals(mHandle, d.mHandle) &&
880 Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
881 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
882 Objects.equals(mCallerDisplayNamePresentation,
883 d.mCallerDisplayNamePresentation) &&
Evan Charlton8c8a0622014-07-20 12:31:00 -0700884 Objects.equals(mAccountHandle, d.mAccountHandle) &&
Ihab Awad5d0410f2014-07-30 10:07:40 -0700885 Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
Andrew Lee223ad142014-08-27 16:33:08 -0700886 Objects.equals(mCallProperties, d.mCallProperties) &&
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700887 Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
Ihab Awade63fadb2014-07-09 21:52:04 -0700888 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
Andrew Lee85f5d422014-07-11 17:22:03 -0700889 Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Evan Charlton5b49ade2014-07-15 17:03:20 -0700890 Objects.equals(mVideoState, d.mVideoState) &&
Nancy Chen10798dc2014-08-08 14:00:25 -0700891 Objects.equals(mStatusHints, d.mStatusHints) &&
Tyler Gunn1e9bfc62015-08-19 11:18:58 -0700892 areBundlesEqual(mExtras, d.mExtras) &&
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700893 areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
Tyler Gunnd081f042018-12-04 12:56:45 -0800894 Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
Tyler Gunn94f8f112018-12-17 09:56:11 -0800895 Objects.equals(mCallIdentification, d.mCallIdentification) &&
896 Objects.equals(mCallDirection, d.mCallDirection);
Ihab Awade63fadb2014-07-09 21:52:04 -0700897 }
898 return false;
899 }
900
901 @Override
902 public int hashCode() {
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700903 return Objects.hash(mHandle,
904 mHandlePresentation,
905 mCallerDisplayName,
906 mCallerDisplayNamePresentation,
907 mAccountHandle,
908 mCallCapabilities,
909 mCallProperties,
910 mDisconnectCause,
911 mConnectTimeMillis,
912 mGatewayInfo,
913 mVideoState,
914 mStatusHints,
915 mExtras,
916 mIntentExtras,
Tyler Gunnd081f042018-12-04 12:56:45 -0800917 mCreationTimeMillis,
Tyler Gunn94f8f112018-12-17 09:56:11 -0800918 mCallIdentification,
919 mCallDirection);
Ihab Awade63fadb2014-07-09 21:52:04 -0700920 }
921
922 /** {@hide} */
923 public Details(
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800924 String telecomCallId,
Ihab Awade63fadb2014-07-09 21:52:04 -0700925 Uri handle,
926 int handlePresentation,
927 String callerDisplayName,
928 int callerDisplayNamePresentation,
Evan Charlton8c8a0622014-07-20 12:31:00 -0700929 PhoneAccountHandle accountHandle,
Ihab Awade63fadb2014-07-09 21:52:04 -0700930 int capabilities,
Andrew Lee223ad142014-08-27 16:33:08 -0700931 int properties,
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700932 DisconnectCause disconnectCause,
Ihab Awade63fadb2014-07-09 21:52:04 -0700933 long connectTimeMillis,
Andrew Lee85f5d422014-07-11 17:22:03 -0700934 GatewayInfo gatewayInfo,
Evan Charlton5b49ade2014-07-15 17:03:20 -0700935 int videoState,
Nancy Chen10798dc2014-08-08 14:00:25 -0700936 StatusHints statusHints,
Santos Cordon6b7f9552015-05-27 17:21:45 -0700937 Bundle extras,
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700938 Bundle intentExtras,
Tyler Gunnd081f042018-12-04 12:56:45 -0800939 long creationTimeMillis,
Tyler Gunn94f8f112018-12-17 09:56:11 -0800940 CallIdentification callIdentification,
941 int callDirection) {
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800942 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700943 mHandle = handle;
944 mHandlePresentation = handlePresentation;
945 mCallerDisplayName = callerDisplayName;
946 mCallerDisplayNamePresentation = callerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700947 mAccountHandle = accountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700948 mCallCapabilities = capabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700949 mCallProperties = properties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700950 mDisconnectCause = disconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700951 mConnectTimeMillis = connectTimeMillis;
952 mGatewayInfo = gatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700953 mVideoState = videoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700954 mStatusHints = statusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700955 mExtras = extras;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700956 mIntentExtras = intentExtras;
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700957 mCreationTimeMillis = creationTimeMillis;
Tyler Gunnd081f042018-12-04 12:56:45 -0800958 mCallIdentification = callIdentification;
Tyler Gunn94f8f112018-12-17 09:56:11 -0800959 mCallDirection = callDirection;
Ihab Awade63fadb2014-07-09 21:52:04 -0700960 }
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800961
962 /** {@hide} */
963 public static Details createFromParcelableCall(ParcelableCall parcelableCall) {
964 return new Details(
965 parcelableCall.getId(),
966 parcelableCall.getHandle(),
967 parcelableCall.getHandlePresentation(),
968 parcelableCall.getCallerDisplayName(),
969 parcelableCall.getCallerDisplayNamePresentation(),
970 parcelableCall.getAccountHandle(),
971 parcelableCall.getCapabilities(),
972 parcelableCall.getProperties(),
973 parcelableCall.getDisconnectCause(),
974 parcelableCall.getConnectTimeMillis(),
975 parcelableCall.getGatewayInfo(),
976 parcelableCall.getVideoState(),
977 parcelableCall.getStatusHints(),
978 parcelableCall.getExtras(),
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700979 parcelableCall.getIntentExtras(),
Tyler Gunnd081f042018-12-04 12:56:45 -0800980 parcelableCall.getCreationTimeMillis(),
Tyler Gunn94f8f112018-12-17 09:56:11 -0800981 parcelableCall.getCallIdentification(),
982 parcelableCall.getCallDirection());
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800983 }
Santos Cordon3c20d632016-02-25 16:12:35 -0800984
985 @Override
986 public String toString() {
987 StringBuilder sb = new StringBuilder();
Tyler Gunn3cd820f2018-11-30 14:21:18 -0800988 sb.append("[id: ");
989 sb.append(mTelecomCallId);
990 sb.append(", pa: ");
Santos Cordon3c20d632016-02-25 16:12:35 -0800991 sb.append(mAccountHandle);
992 sb.append(", hdl: ");
Tyler Gunn3cd820f2018-11-30 14:21:18 -0800993 sb.append(Log.piiHandle(mHandle));
994 sb.append(", hdlPres: ");
995 sb.append(mHandlePresentation);
996 sb.append(", videoState: ");
997 sb.append(VideoProfile.videoStateToString(mVideoState));
Santos Cordon3c20d632016-02-25 16:12:35 -0800998 sb.append(", caps: ");
999 sb.append(capabilitiesToString(mCallCapabilities));
1000 sb.append(", props: ");
Tyler Gunn720c6642016-03-22 09:02:47 -07001001 sb.append(propertiesToString(mCallProperties));
Santos Cordon3c20d632016-02-25 16:12:35 -08001002 sb.append("]");
1003 return sb.toString();
1004 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001005 }
1006
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001007 /**
1008 * Defines callbacks which inform the {@link InCallService} of changes to a {@link Call}.
1009 * These callbacks can originate from the Telecom framework, or a {@link ConnectionService}
1010 * implementation.
1011 * <p>
1012 * You can handle these callbacks by extending the {@link Callback} class and overriding the
1013 * callbacks that your {@link InCallService} is interested in. The callback methods include the
1014 * {@link Call} for which the callback applies, allowing reuse of a single instance of your
1015 * {@link Callback} implementation, if desired.
1016 * <p>
1017 * Use {@link Call#registerCallback(Callback)} to register your callback(s). Ensure
1018 * {@link Call#unregisterCallback(Callback)} is called when you no longer require callbacks
1019 * (typically in {@link InCallService#onCallRemoved(Call)}).
1020 * Note: Callbacks which occur before you call {@link Call#registerCallback(Callback)} will not
1021 * reach your implementation of {@link Callback}, so it is important to register your callback
1022 * as soon as your {@link InCallService} is notified of a new call via
1023 * {@link InCallService#onCallAdded(Call)}.
1024 */
Andrew Leeda80c872015-04-15 14:09:50 -07001025 public static abstract class Callback {
Ihab Awade63fadb2014-07-09 21:52:04 -07001026 /**
Sanket Padawea8eddd42017-11-03 11:07:35 -07001027 * @hide
1028 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001029 @IntDef(prefix = { "HANDOVER_" },
1030 value = {HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_NOT_SUPPORTED,
Tyler Gunn5c60d712018-03-16 09:53:44 -07001031 HANDOVER_FAILURE_USER_REJECTED, HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL,
Tyler Gunn9d127732018-03-02 15:45:51 -08001032 HANDOVER_FAILURE_UNKNOWN})
Sanket Padawea8eddd42017-11-03 11:07:35 -07001033 @Retention(RetentionPolicy.SOURCE)
1034 public @interface HandoverFailureErrors {}
1035
1036 /**
1037 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the app
Tyler Gunn9d127732018-03-02 15:45:51 -08001038 * to handover the call to rejects the handover request.
1039 * <p>
1040 * Will be returned when {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} is called
1041 * and the destination {@link PhoneAccountHandle}'s {@link ConnectionService} returns a
1042 * {@code null} {@link Connection} from
1043 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
1044 * ConnectionRequest)}.
1045 * <p>
1046 * For more information on call handovers, see
1047 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001048 */
1049 public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1;
1050
1051 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08001052 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
1053 * is initiated but the source or destination app does not support handover.
1054 * <p>
1055 * Will be returned when a handover is requested via
1056 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)} and the destination
1057 * {@link PhoneAccountHandle} does not declare
1058 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}. May also be returned when a handover is
1059 * requested at the {@link PhoneAccountHandle} for the current call (i.e. the source call's
1060 * {@link Details#getAccountHandle()}) does not declare
1061 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
1062 * <p>
1063 * For more information on call handovers, see
1064 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001065 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001066 public static final int HANDOVER_FAILURE_NOT_SUPPORTED = 2;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001067
1068 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08001069 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the remote
1070 * user rejects the handover request.
1071 * <p>
1072 * For more information on call handovers, see
1073 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001074 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001075 public static final int HANDOVER_FAILURE_USER_REJECTED = 3;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001076
Sanket Padawe85291f62017-12-01 13:59:27 -08001077 /**
1078 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there
1079 * is ongoing emergency call.
Tyler Gunn9d127732018-03-02 15:45:51 -08001080 * <p>
1081 * This error code is returned when {@link #handoverTo(PhoneAccountHandle, int, Bundle)} is
1082 * called on an emergency call, or if any other call is an emergency call.
1083 * <p>
1084 * Handovers are not permitted while there are ongoing emergency calls.
1085 * <p>
1086 * For more information on call handovers, see
1087 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawe85291f62017-12-01 13:59:27 -08001088 */
Tyler Gunn5c60d712018-03-16 09:53:44 -07001089 public static final int HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL = 4;
Sanket Padawe85291f62017-12-01 13:59:27 -08001090
Tyler Gunn9d127732018-03-02 15:45:51 -08001091 /**
1092 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
1093 * fails for an unknown reason.
1094 * <p>
1095 * For more information on call handovers, see
1096 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
1097 */
1098 public static final int HANDOVER_FAILURE_UNKNOWN = 5;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001099
1100 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001101 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
1102 *
Ihab Awade63fadb2014-07-09 21:52:04 -07001103 * @param call The {@code Call} invoking this method.
1104 * @param state The new state of the {@code Call}.
1105 */
1106 public void onStateChanged(Call call, int state) {}
1107
1108 /**
1109 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
1110 *
1111 * @param call The {@code Call} invoking this method.
1112 * @param parent The new parent of the {@code Call}.
1113 */
1114 public void onParentChanged(Call call, Call parent) {}
1115
1116 /**
1117 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}.
1118 *
1119 * @param call The {@code Call} invoking this method.
1120 * @param children The new children of the {@code Call}.
1121 */
1122 public void onChildrenChanged(Call call, List<Call> children) {}
1123
1124 /**
1125 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}.
1126 *
1127 * @param call The {@code Call} invoking this method.
1128 * @param details A {@code Details} object describing the {@code Call}.
1129 */
1130 public void onDetailsChanged(Call call, Details details) {}
1131
1132 /**
1133 * Invoked when the text messages that can be used as responses to the incoming
1134 * {@code Call} are loaded from the relevant database.
1135 * See {@link #getCannedTextResponses()}.
1136 *
1137 * @param call The {@code Call} invoking this method.
1138 * @param cannedTextResponses The text messages useable as responses.
1139 */
1140 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
1141
1142 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001143 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
1144 * character. This causes the post-dial signals to stop pending user confirmation. An
1145 * implementation should present this choice to the user and invoke
1146 * {@link #postDialContinue(boolean)} when the user makes the choice.
1147 *
1148 * @param call The {@code Call} invoking this method.
1149 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
1150 */
1151 public void onPostDialWait(Call call, String remainingPostDialSequence) {}
1152
1153 /**
Andrew Lee50aca232014-07-22 16:41:54 -07001154 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed.
Ihab Awade63fadb2014-07-09 21:52:04 -07001155 *
1156 * @param call The {@code Call} invoking this method.
Andrew Lee50aca232014-07-22 16:41:54 -07001157 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
Ihab Awade63fadb2014-07-09 21:52:04 -07001158 */
Andrew Lee50aca232014-07-22 16:41:54 -07001159 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
Ihab Awade63fadb2014-07-09 21:52:04 -07001160
1161 /**
1162 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning
1163 * up their UI for the {@code Call} in response to state transitions. Specifically,
1164 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of
1165 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather,
1166 * clients should wait for this method to be invoked.
1167 *
1168 * @param call The {@code Call} being destroyed.
1169 */
1170 public void onCallDestroyed(Call call) {}
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001171
1172 /**
1173 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
1174 * conferenced.
1175 *
1176 * @param call The {@code Call} being updated.
1177 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
1178 * conferenced.
1179 */
1180 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001181
1182 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001183 * Invoked when a {@link Call} receives an event from its associated {@link Connection}.
1184 * <p>
1185 * Where possible, the Call should make an attempt to handle {@link Connection} events which
1186 * are part of the {@code android.telecom.*} namespace. The Call should ignore any events
1187 * it does not wish to handle. Unexpected events should be handled gracefully, as it is
1188 * possible that a {@link ConnectionService} has defined its own Connection events which a
1189 * Call is not aware of.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001190 * <p>
1191 * See {@link Connection#sendConnectionEvent(String, Bundle)}.
1192 *
1193 * @param call The {@code Call} receiving the event.
1194 * @param event The event.
1195 * @param extras Extras associated with the connection event.
1196 */
1197 public void onConnectionEvent(Call call, String event, Bundle extras) {}
Hall Liu95d55872017-01-25 17:12:49 -08001198
1199 /**
1200 * Invoked when the RTT mode changes for this call.
1201 * @param call The call whose RTT mode has changed.
1202 * @param mode the new RTT mode, one of
1203 * {@link RttCall#RTT_MODE_FULL}, {@link RttCall#RTT_MODE_HCO},
1204 * or {@link RttCall#RTT_MODE_VCO}
1205 */
1206 public void onRttModeChanged(Call call, int mode) {}
1207
1208 /**
1209 * Invoked when the call's RTT status changes, either from off to on or from on to off.
1210 * @param call The call whose RTT status has changed.
1211 * @param enabled whether RTT is now enabled or disabled
1212 * @param rttCall the {@link RttCall} object to use for reading and writing if RTT is now
1213 * on, null otherwise.
1214 */
1215 public void onRttStatusChanged(Call call, boolean enabled, RttCall rttCall) {}
1216
1217 /**
1218 * Invoked when the remote end of the connection has requested that an RTT communication
1219 * channel be opened. A response to this should be sent via {@link #respondToRttRequest}
1220 * with the same ID that this method is invoked with.
1221 * @param call The call which the RTT request was placed on
1222 * @param id The ID of the request.
1223 */
1224 public void onRttRequest(Call call, int id) {}
Hall Liu57006aa2017-02-06 10:49:48 -08001225
1226 /**
1227 * Invoked when the RTT session failed to initiate for some reason, including rejection
1228 * by the remote party.
1229 * @param call The call which the RTT initiation failure occurred on.
1230 * @param reason One of the status codes defined in
1231 * {@link android.telecom.Connection.RttModifyStatus}, with the exception of
1232 * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
1233 */
1234 public void onRttInitiationFailure(Call call, int reason) {}
Sanket Padawea8eddd42017-11-03 11:07:35 -07001235
1236 /**
1237 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
1238 * has completed successfully.
Tyler Gunn9d127732018-03-02 15:45:51 -08001239 * <p>
1240 * For a full discussion of the handover process and the APIs involved, see
1241 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
1242 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07001243 * @param call The call which had initiated handover.
1244 */
1245 public void onHandoverComplete(Call call) {}
1246
1247 /**
1248 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
1249 * has failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08001250 * <p>
1251 * For a full discussion of the handover process and the APIs involved, see
1252 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
1253 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07001254 * @param call The call which had initiated handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08001255 * @param failureReason Error reason for failure.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001256 */
1257 public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {}
Hall Liu95d55872017-01-25 17:12:49 -08001258 }
1259
1260 /**
1261 * A class that holds the state that describes the state of the RTT channel to the remote
1262 * party, if it is active.
1263 */
1264 public static final class RttCall {
Hall Liu07094df2017-02-28 15:17:44 -08001265 /** @hide */
Hall Liu95d55872017-01-25 17:12:49 -08001266 @Retention(RetentionPolicy.SOURCE)
1267 @IntDef({RTT_MODE_INVALID, RTT_MODE_FULL, RTT_MODE_HCO, RTT_MODE_VCO})
1268 public @interface RttAudioMode {}
1269
1270 /**
1271 * For metrics use. Default value in the proto.
1272 * @hide
1273 */
1274 public static final int RTT_MODE_INVALID = 0;
1275
1276 /**
1277 * Indicates that there should be a bidirectional audio stream between the two parties
1278 * on the call.
1279 */
1280 public static final int RTT_MODE_FULL = 1;
1281
1282 /**
1283 * Indicates that the local user should be able to hear the audio stream from the remote
1284 * user, but not vice versa. Equivalent to muting the microphone.
1285 */
1286 public static final int RTT_MODE_HCO = 2;
1287
1288 /**
1289 * Indicates that the remote user should be able to hear the audio stream from the local
1290 * user, but not vice versa. Equivalent to setting the volume to zero.
1291 */
1292 public static final int RTT_MODE_VCO = 3;
1293
1294 private static final int READ_BUFFER_SIZE = 1000;
1295
1296 private InputStreamReader mReceiveStream;
1297 private OutputStreamWriter mTransmitStream;
1298 private int mRttMode;
1299 private final InCallAdapter mInCallAdapter;
Hall Liu57006aa2017-02-06 10:49:48 -08001300 private final String mTelecomCallId;
Hall Liu95d55872017-01-25 17:12:49 -08001301 private char[] mReadBuffer = new char[READ_BUFFER_SIZE];
1302
1303 /**
1304 * @hide
1305 */
Hall Liu57006aa2017-02-06 10:49:48 -08001306 public RttCall(String telecomCallId, InputStreamReader receiveStream,
1307 OutputStreamWriter transmitStream, int mode, InCallAdapter inCallAdapter) {
1308 mTelecomCallId = telecomCallId;
Hall Liu95d55872017-01-25 17:12:49 -08001309 mReceiveStream = receiveStream;
1310 mTransmitStream = transmitStream;
1311 mRttMode = mode;
1312 mInCallAdapter = inCallAdapter;
1313 }
1314
1315 /**
1316 * Returns the current RTT audio mode.
1317 * @return Current RTT audio mode. One of {@link #RTT_MODE_FULL}, {@link #RTT_MODE_VCO}, or
1318 * {@link #RTT_MODE_HCO}.
1319 */
1320 public int getRttAudioMode() {
1321 return mRttMode;
1322 }
1323
1324 /**
1325 * Sets the RTT audio mode. The requested mode change will be communicated through
1326 * {@link Callback#onRttModeChanged(Call, int)}.
1327 * @param mode The desired RTT audio mode, one of {@link #RTT_MODE_FULL},
1328 * {@link #RTT_MODE_VCO}, or {@link #RTT_MODE_HCO}.
1329 */
1330 public void setRttMode(@RttAudioMode int mode) {
Hall Liu57006aa2017-02-06 10:49:48 -08001331 mInCallAdapter.setRttMode(mTelecomCallId, mode);
Hall Liu95d55872017-01-25 17:12:49 -08001332 }
1333
1334 /**
1335 * Writes the string {@param input} into the outgoing text stream for this RTT call. Since
1336 * RTT transmits text in real-time, this method should be called once for each character
1337 * the user enters into the device.
1338 *
1339 * This method is not thread-safe -- calling it from multiple threads simultaneously may
1340 * lead to interleaved text.
1341 * @param input The message to send to the remote user.
1342 */
1343 public void write(String input) throws IOException {
1344 mTransmitStream.write(input);
1345 mTransmitStream.flush();
1346 }
1347
1348 /**
1349 * Reads a string from the remote user, blocking if there is no data available. Returns
1350 * {@code null} if the RTT conversation has been terminated and there is no further data
1351 * to read.
1352 *
1353 * This method is not thread-safe -- calling it from multiple threads simultaneously may
1354 * lead to interleaved text.
1355 * @return A string containing text sent by the remote user, or {@code null} if the
1356 * conversation has been terminated or if there was an error while reading.
1357 */
Hall Liub1c8a772017-07-17 17:04:41 -07001358 public String read() {
1359 try {
1360 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
1361 if (numRead < 0) {
1362 return null;
1363 }
1364 return new String(mReadBuffer, 0, numRead);
1365 } catch (IOException e) {
1366 Log.w(this, "Exception encountered when reading from InputStreamReader: %s", e);
Jeff Sharkey90396362017-06-12 16:26:53 -06001367 return null;
Hall Liuffa4a812017-03-02 16:11:00 -08001368 }
Hall Liuffa4a812017-03-02 16:11:00 -08001369 }
1370
1371 /**
1372 * Non-blocking version of {@link #read()}. Returns {@code null} if there is nothing to
1373 * be read.
1374 * @return A string containing text entered by the user, or {@code null} if the user has
1375 * not entered any new text yet.
1376 */
1377 public String readImmediately() throws IOException {
1378 if (mReceiveStream.ready()) {
Hall Liub1c8a772017-07-17 17:04:41 -07001379 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
1380 if (numRead < 0) {
1381 return null;
1382 }
1383 return new String(mReadBuffer, 0, numRead);
Hall Liuffa4a812017-03-02 16:11:00 -08001384 } else {
Hall Liu95d55872017-01-25 17:12:49 -08001385 return null;
1386 }
1387 }
Hall Liue9041242018-02-09 16:40:03 -08001388
1389 /**
1390 * Closes the underlying file descriptors
1391 * @hide
1392 */
1393 public void close() {
1394 try {
1395 mReceiveStream.close();
1396 } catch (IOException e) {
1397 // ignore
1398 }
1399 try {
1400 mTransmitStream.close();
1401 } catch (IOException e) {
1402 // ignore
1403 }
1404 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001405 }
1406
Andrew Leeda80c872015-04-15 14:09:50 -07001407 /**
1408 * @deprecated Use {@code Call.Callback} instead.
1409 * @hide
1410 */
1411 @Deprecated
1412 @SystemApi
1413 public static abstract class Listener extends Callback { }
1414
Ihab Awade63fadb2014-07-09 21:52:04 -07001415 private final Phone mPhone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001416 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07001417 private final InCallAdapter mInCallAdapter;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001418 private final List<String> mChildrenIds = new ArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -07001419 private final List<Call> mChildren = new ArrayList<>();
1420 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
Andrew Lee011728f2015-04-23 15:47:06 -07001421 private final List<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArrayList<>();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001422 private final List<Call> mConferenceableCalls = new ArrayList<>();
1423 private final List<Call> mUnmodifiableConferenceableCalls =
1424 Collections.unmodifiableList(mConferenceableCalls);
1425
Santos Cordon823fd3c2014-08-07 18:35:18 -07001426 private boolean mChildrenCached;
1427 private String mParentId = null;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001428 private int mState;
Ihab Awade63fadb2014-07-09 21:52:04 -07001429 private List<String> mCannedTextResponses = null;
Tyler Gunnb88b3112016-11-09 10:19:23 -08001430 private String mCallingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08001431 private int mTargetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -07001432 private String mRemainingPostDialSequence;
Tyler Gunn584ba6c2015-12-08 10:53:41 -08001433 private VideoCallImpl mVideoCallImpl;
Hall Liu95d55872017-01-25 17:12:49 -08001434 private RttCall mRttCall;
Ihab Awade63fadb2014-07-09 21:52:04 -07001435 private Details mDetails;
Tyler Gunndee56a82016-03-23 16:06:34 -07001436 private Bundle mExtras;
Ihab Awade63fadb2014-07-09 21:52:04 -07001437
1438 /**
1439 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
1440 *
1441 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence
1442 * remaining or this {@code Call} is not in a post-dial state.
1443 */
1444 public String getRemainingPostDialSequence() {
1445 return mRemainingPostDialSequence;
1446 }
1447
1448 /**
1449 * Instructs this {@link #STATE_RINGING} {@code Call} to answer.
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001450 * @param videoState The video state in which to answer the call.
Ihab Awade63fadb2014-07-09 21:52:04 -07001451 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001452 public void answer(@VideoProfile.VideoState int videoState) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001453 mInCallAdapter.answerCall(mTelecomCallId, videoState);
Ihab Awade63fadb2014-07-09 21:52:04 -07001454 }
1455
1456 /**
Pooja Jaind34698d2017-12-28 14:15:31 +05301457 * Instructs this {@link #STATE_RINGING} {@code Call} to deflect.
1458 *
1459 * @param address The address to which the call will be deflected.
1460 */
1461 public void deflect(Uri address) {
1462 mInCallAdapter.deflectCall(mTelecomCallId, address);
1463 }
1464
1465 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001466 * Instructs this {@link #STATE_RINGING} {@code Call} to reject.
1467 *
1468 * @param rejectWithMessage Whether to reject with a text message.
1469 * @param textMessage An optional text message with which to respond.
1470 */
1471 public void reject(boolean rejectWithMessage, String textMessage) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001472 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
Ihab Awade63fadb2014-07-09 21:52:04 -07001473 }
1474
1475 /**
1476 * Instructs this {@code Call} to disconnect.
1477 */
1478 public void disconnect() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001479 mInCallAdapter.disconnectCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001480 }
1481
1482 /**
1483 * Instructs this {@code Call} to go on hold.
1484 */
1485 public void hold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001486 mInCallAdapter.holdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001487 }
1488
1489 /**
1490 * Instructs this {@link #STATE_HOLDING} call to release from hold.
1491 */
1492 public void unhold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001493 mInCallAdapter.unholdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001494 }
1495
1496 /**
1497 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
1498 *
1499 * Any other currently playing DTMF tone in the specified call is immediately stopped.
1500 *
1501 * @param digit A character representing the DTMF digit for which to play the tone. This
1502 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
1503 */
1504 public void playDtmfTone(char digit) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001505 mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
Ihab Awade63fadb2014-07-09 21:52:04 -07001506 }
1507
1508 /**
1509 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone
1510 * currently playing.
1511 *
1512 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
1513 * currently playing, this method will do nothing.
1514 */
1515 public void stopDtmfTone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001516 mInCallAdapter.stopDtmfTone(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001517 }
1518
1519 /**
1520 * Instructs this {@code Call} to continue playing a post-dial DTMF string.
1521 *
1522 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
1523 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
Ihab Awade63fadb2014-07-09 21:52:04 -07001524 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001525 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awade63fadb2014-07-09 21:52:04 -07001526 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
1527 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001528 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Leeda80c872015-04-15 14:09:50 -07001529 * {@code Call} will pause playing the tones and notify callbacks via
1530 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
Ihab Awade63fadb2014-07-09 21:52:04 -07001531 * should display to the user an indication of this state and an affordance to continue
1532 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
1533 * app should invoke the {@link #postDialContinue(boolean)} method.
1534 *
1535 * @param proceed Whether or not to continue with the post-dial sequence.
1536 */
1537 public void postDialContinue(boolean proceed) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001538 mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
Ihab Awade63fadb2014-07-09 21:52:04 -07001539 }
1540
1541 /**
Evan Charlton8c8a0622014-07-20 12:31:00 -07001542 * Notifies this {@code Call} that an account has been selected and to proceed with placing
Nancy Chen36c62f32014-10-21 18:36:39 -07001543 * an outgoing call. Optionally sets this account as the default account.
Nancy Chen5da0fd52014-07-08 14:16:17 -07001544 */
Nancy Chen36c62f32014-10-21 18:36:39 -07001545 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) {
1546 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);
Nancy Chen5da0fd52014-07-08 14:16:17 -07001547
1548 }
1549
1550 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001551 * Instructs this {@code Call} to enter a conference.
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001552 *
1553 * @param callToConferenceWith The other call with which to conference.
Ihab Awade63fadb2014-07-09 21:52:04 -07001554 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001555 public void conference(Call callToConferenceWith) {
1556 if (callToConferenceWith != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001557 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001558 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001559 }
1560
1561 /**
1562 * Instructs this {@code Call} to split from any conference call with which it may be
1563 * connected.
1564 */
1565 public void splitFromConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001566 mInCallAdapter.splitFromConference(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001567 }
1568
1569 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001570 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -07001571 */
1572 public void mergeConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001573 mInCallAdapter.mergeConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -07001574 }
1575
1576 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001577 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -07001578 */
1579 public void swapConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001580 mInCallAdapter.swapConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -07001581 }
1582
1583 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001584 * Initiates a request to the {@link ConnectionService} to pull an external call to the local
1585 * device.
1586 * <p>
1587 * Calls to this method are ignored if the call does not have the
1588 * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property set.
1589 * <p>
1590 * An {@link InCallService} will only see calls which support this method if it has the
1591 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
1592 * in its manifest.
1593 */
1594 public void pullExternalCall() {
1595 // If this isn't an external call, ignore the request.
1596 if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) {
1597 return;
1598 }
1599
1600 mInCallAdapter.pullExternalCall(mTelecomCallId);
1601 }
1602
1603 /**
1604 * Sends a {@code Call} event from this {@code Call} to the associated {@link Connection} in
1605 * the {@link ConnectionService}.
1606 * <p>
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001607 * Call events are used to communicate point in time information from an {@link InCallService}
1608 * to a {@link ConnectionService}. A {@link ConnectionService} implementation could define
1609 * events which enable the {@link InCallService}, for example, toggle a unique feature of the
1610 * {@link ConnectionService}.
1611 * <p>
1612 * A {@link ConnectionService} can communicate to the {@link InCallService} using
1613 * {@link Connection#sendConnectionEvent(String, Bundle)}.
1614 * <p>
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001615 * Events are exposed to {@link ConnectionService} implementations via
1616 * {@link android.telecom.Connection#onCallEvent(String, Bundle)}.
1617 * <p>
1618 * No assumptions should be made as to how a {@link ConnectionService} will handle these events.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001619 * The {@link InCallService} must assume that the {@link ConnectionService} could chose to
1620 * ignore some events altogether.
1621 * <p>
1622 * Events should be fully qualified (e.g., {@code com.example.event.MY_EVENT}) to avoid
1623 * conflicts between {@link InCallService} implementations. Further, {@link InCallService}
1624 * implementations shall not re-purpose events in the {@code android.*} namespace, nor shall
1625 * they define their own event types in this namespace. When defining a custom event type,
1626 * ensure the contents of the extras {@link Bundle} is clearly defined. Extra keys for this
1627 * bundle should be named similar to the event type (e.g. {@code com.example.extra.MY_EXTRA}).
1628 * <p>
1629 * When defining events and the associated extras, it is important to keep their behavior
1630 * consistent when the associated {@link InCallService} is updated. Support for deprecated
1631 * events/extras should me maintained to ensure backwards compatibility with older
1632 * {@link ConnectionService} implementations which were built to support the older behavior.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001633 *
1634 * @param event The connection event.
1635 * @param extras Bundle containing extra information associated with the event.
1636 */
1637 public void sendCallEvent(String event, Bundle extras) {
Sanket Padawef6a9e5b2018-01-05 14:26:16 -08001638 mInCallAdapter.sendCallEvent(mTelecomCallId, event, mTargetSdkVersion, extras);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001639 }
1640
1641 /**
Hall Liu95d55872017-01-25 17:12:49 -08001642 * Sends an RTT upgrade request to the remote end of the connection. Success is not
1643 * guaranteed, and notification of success will be via the
1644 * {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
1645 */
1646 public void sendRttRequest() {
Hall Liu57006aa2017-02-06 10:49:48 -08001647 mInCallAdapter.sendRttRequest(mTelecomCallId);
Hall Liu95d55872017-01-25 17:12:49 -08001648 }
1649
1650 /**
1651 * Responds to an RTT request received via the {@link Callback#onRttRequest(Call, int)} )}
1652 * callback.
1653 * The ID used here should be the same as the ID that was received via the callback.
1654 * @param id The request ID received via {@link Callback#onRttRequest(Call, int)}
1655 * @param accept {@code true} if the RTT request should be accepted, {@code false} otherwise.
1656 */
1657 public void respondToRttRequest(int id, boolean accept) {
Hall Liu57006aa2017-02-06 10:49:48 -08001658 mInCallAdapter.respondToRttRequest(mTelecomCallId, id, accept);
Hall Liu95d55872017-01-25 17:12:49 -08001659 }
1660
1661 /**
Sanket Padawea8eddd42017-11-03 11:07:35 -07001662 * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified
1663 * by {@code toHandle}. The videoState specified indicates the desired video state after the
1664 * handover.
1665 * <p>
Tyler Gunn9d127732018-03-02 15:45:51 -08001666 * A call handover is the process where an ongoing call is transferred from one app (i.e.
1667 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
1668 * mobile network call in a video calling app. The mobile network call via the Telephony stack
1669 * is referred to as the source of the handover, and the video calling app is referred to as the
1670 * destination.
1671 * <p>
1672 * When considering a handover scenario the device this method is called on is considered the
1673 * <em>initiating</em> device (since the user initiates the handover from this device), and the
1674 * other device is considered the <em>receiving</em> device.
1675 * <p>
1676 * When this method is called on the <em>initiating</em> device, the Telecom framework will bind
1677 * to the {@link ConnectionService} defined by the {@code toHandle} {@link PhoneAccountHandle}
1678 * and invoke
1679 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
1680 * ConnectionRequest)} to inform the destination app that a request has been made to handover a
1681 * call to it. The app returns an instance of {@link Connection} to represent the handover call
1682 * At this point the app should display UI to indicate to the user that a call
1683 * handover is in process.
1684 * <p>
1685 * The destination app is responsible for communicating the handover request from the
1686 * <em>initiating</em> device to the <em>receiving</em> device.
1687 * <p>
1688 * When the app on the <em>receiving</em> device receives the handover request, it calls
1689 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to continue the handover
1690 * process from the <em>initiating</em> device to the <em>receiving</em> device. At this point
1691 * the destination app on the <em>receiving</em> device should show UI to allow the user to
1692 * choose whether they want to continue their call in the destination app.
1693 * <p>
1694 * When the destination app on the <em>receiving</em> device calls
1695 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)}, Telecom will bind to its
1696 * {@link ConnectionService} and call
1697 * {@link ConnectionService#onCreateIncomingHandoverConnection(PhoneAccountHandle,
1698 * ConnectionRequest)} to inform it of the handover request. The app returns an instance of
1699 * {@link Connection} to represent the handover call.
1700 * <p>
1701 * If the user of the <em>receiving</em> device accepts the handover, the app calls
1702 * {@link Connection#setActive()} to complete the handover process; Telecom will disconnect the
1703 * original call. If the user rejects the handover, the app calls
1704 * {@link Connection#setDisconnected(DisconnectCause)} and specifies a {@link DisconnectCause}
1705 * of {@link DisconnectCause#CANCELED} to indicate that the handover has been cancelled.
1706 * <p>
1707 * Telecom will only allow handovers from {@link PhoneAccount}s which declare
1708 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}. Similarly, the {@link PhoneAccount}
1709 * specified by {@code toHandle} must declare {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}.
1710 * <p>
1711 * Errors in the handover process are reported to the {@link InCallService} via
1712 * {@link Callback#onHandoverFailed(Call, int)}. Errors in the handover process are reported to
1713 * the involved {@link ConnectionService}s via
1714 * {@link ConnectionService#onHandoverFailed(ConnectionRequest, int)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001715 *
1716 * @param toHandle {@link PhoneAccountHandle} of the {@link ConnectionService} to handover
1717 * this call to.
Tyler Gunn9d127732018-03-02 15:45:51 -08001718 * @param videoState Indicates the video state desired after the handover (see the
1719 * {@code STATE_*} constants defined in {@link VideoProfile}).
Sanket Padawea8eddd42017-11-03 11:07:35 -07001720 * @param extras Bundle containing extra information to be passed to the
1721 * {@link ConnectionService}
1722 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001723 public void handoverTo(PhoneAccountHandle toHandle, @VideoProfile.VideoState int videoState,
1724 Bundle extras) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07001725 mInCallAdapter.handoverTo(mTelecomCallId, toHandle, videoState, extras);
1726 }
1727
1728 /**
Hall Liu95d55872017-01-25 17:12:49 -08001729 * Terminate the RTT session on this call. The resulting state change will be notified via
1730 * the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
1731 */
1732 public void stopRtt() {
Hall Liu57006aa2017-02-06 10:49:48 -08001733 mInCallAdapter.stopRtt(mTelecomCallId);
Hall Liu95d55872017-01-25 17:12:49 -08001734 }
1735
1736 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07001737 * Adds some extras to this {@link Call}. Existing keys are replaced and new ones are
1738 * added.
1739 * <p>
1740 * No assumptions should be made as to how an In-Call UI or service will handle these
1741 * extras. Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
1742 *
1743 * @param extras The extras to add.
1744 */
1745 public final void putExtras(Bundle extras) {
1746 if (extras == null) {
1747 return;
1748 }
1749
1750 if (mExtras == null) {
1751 mExtras = new Bundle();
1752 }
1753 mExtras.putAll(extras);
1754 mInCallAdapter.putExtras(mTelecomCallId, extras);
1755 }
1756
1757 /**
1758 * Adds a boolean extra to this {@link Call}.
1759 *
1760 * @param key The extra key.
1761 * @param value The value.
1762 * @hide
1763 */
1764 public final void putExtra(String key, boolean value) {
1765 if (mExtras == null) {
1766 mExtras = new Bundle();
1767 }
1768 mExtras.putBoolean(key, value);
1769 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1770 }
1771
1772 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001773 * Adds an integer extra to this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001774 *
1775 * @param key The extra key.
1776 * @param value The value.
1777 * @hide
1778 */
1779 public final void putExtra(String key, int value) {
1780 if (mExtras == null) {
1781 mExtras = new Bundle();
1782 }
1783 mExtras.putInt(key, value);
1784 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1785 }
1786
1787 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001788 * Adds a string extra to this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001789 *
1790 * @param key The extra key.
1791 * @param value The value.
1792 * @hide
1793 */
1794 public final void putExtra(String key, String value) {
1795 if (mExtras == null) {
1796 mExtras = new Bundle();
1797 }
1798 mExtras.putString(key, value);
1799 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1800 }
1801
1802 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001803 * Removes extras from this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001804 *
1805 * @param keys The keys of the extras to remove.
1806 */
1807 public final void removeExtras(List<String> keys) {
1808 if (mExtras != null) {
1809 for (String key : keys) {
1810 mExtras.remove(key);
1811 }
1812 if (mExtras.size() == 0) {
1813 mExtras = null;
1814 }
1815 }
1816 mInCallAdapter.removeExtras(mTelecomCallId, keys);
1817 }
1818
1819 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001820 * Removes extras from this {@link Call}.
1821 *
1822 * @param keys The keys of the extras to remove.
1823 */
1824 public final void removeExtras(String ... keys) {
1825 removeExtras(Arrays.asList(keys));
1826 }
1827
1828 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001829 * Obtains the parent of this {@code Call} in a conference, if any.
1830 *
1831 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
1832 * child of any conference {@code Call}s.
1833 */
1834 public Call getParent() {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001835 if (mParentId != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001836 return mPhone.internalGetCallByTelecomId(mParentId);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001837 }
1838 return null;
Ihab Awade63fadb2014-07-09 21:52:04 -07001839 }
1840
1841 /**
1842 * Obtains the children of this conference {@code Call}, if any.
1843 *
1844 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty
1845 * {@code List} otherwise.
1846 */
1847 public List<Call> getChildren() {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001848 if (!mChildrenCached) {
1849 mChildrenCached = true;
1850 mChildren.clear();
1851
1852 for(String id : mChildrenIds) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001853 Call call = mPhone.internalGetCallByTelecomId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001854 if (call == null) {
1855 // At least one child was still not found, so do not save true for "cached"
1856 mChildrenCached = false;
1857 } else {
1858 mChildren.add(call);
1859 }
1860 }
1861 }
1862
Ihab Awade63fadb2014-07-09 21:52:04 -07001863 return mUnmodifiableChildren;
1864 }
1865
1866 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001867 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
1868 *
1869 * @return The list of conferenceable {@code Call}s.
1870 */
1871 public List<Call> getConferenceableCalls() {
1872 return mUnmodifiableConferenceableCalls;
1873 }
1874
1875 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001876 * Obtains the state of this {@code Call}.
1877 *
1878 * @return A state value, chosen from the {@code STATE_*} constants.
1879 */
1880 public int getState() {
1881 return mState;
1882 }
1883
1884 /**
1885 * Obtains a list of canned, pre-configured message responses to present to the user as
1886 * ways of rejecting this {@code Call} using via a text message.
1887 *
1888 * @see #reject(boolean, String)
1889 *
1890 * @return A list of canned text message responses.
1891 */
1892 public List<String> getCannedTextResponses() {
1893 return mCannedTextResponses;
1894 }
1895
1896 /**
1897 * Obtains an object that can be used to display video from this {@code Call}.
1898 *
Andrew Lee50aca232014-07-22 16:41:54 -07001899 * @return An {@code Call.VideoCall}.
Ihab Awade63fadb2014-07-09 21:52:04 -07001900 */
Andrew Lee50aca232014-07-22 16:41:54 -07001901 public InCallService.VideoCall getVideoCall() {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08001902 return mVideoCallImpl;
Ihab Awade63fadb2014-07-09 21:52:04 -07001903 }
1904
1905 /**
1906 * Obtains an object containing call details.
1907 *
1908 * @return A {@link Details} object. Depending on the state of the {@code Call}, the
1909 * result may be {@code null}.
1910 */
1911 public Details getDetails() {
1912 return mDetails;
1913 }
1914
1915 /**
Hall Liu95d55872017-01-25 17:12:49 -08001916 * Returns this call's RttCall object. The {@link RttCall} instance is used to send and
1917 * receive RTT text data, as well as to change the RTT mode.
1918 * @return A {@link Call.RttCall}. {@code null} if there is no active RTT connection.
1919 */
1920 public @Nullable RttCall getRttCall() {
1921 return mRttCall;
1922 }
1923
1924 /**
1925 * Returns whether this call has an active RTT connection.
1926 * @return true if there is a connection, false otherwise.
1927 */
1928 public boolean isRttActive() {
Hall Liue9041242018-02-09 16:40:03 -08001929 return mRttCall != null && mDetails.hasProperty(Details.PROPERTY_RTT);
Hall Liu95d55872017-01-25 17:12:49 -08001930 }
1931
1932 /**
Andrew Leeda80c872015-04-15 14:09:50 -07001933 * Registers a callback to this {@code Call}.
1934 *
1935 * @param callback A {@code Callback}.
1936 */
1937 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -07001938 registerCallback(callback, new Handler());
1939 }
1940
1941 /**
1942 * Registers a callback to this {@code Call}.
1943 *
1944 * @param callback A {@code Callback}.
1945 * @param handler A handler which command and status changes will be delivered to.
1946 */
1947 public void registerCallback(Callback callback, Handler handler) {
1948 unregisterCallback(callback);
Roshan Pius1ca62072015-07-07 17:34:51 -07001949 // Don't allow new callback registration if the call is already being destroyed.
1950 if (callback != null && handler != null && mState != STATE_DISCONNECTED) {
Andrew Lee011728f2015-04-23 15:47:06 -07001951 mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler));
1952 }
Andrew Leeda80c872015-04-15 14:09:50 -07001953 }
1954
1955 /**
1956 * Unregisters a callback from this {@code Call}.
1957 *
1958 * @param callback A {@code Callback}.
1959 */
1960 public void unregisterCallback(Callback callback) {
Roshan Pius1ca62072015-07-07 17:34:51 -07001961 // Don't allow callback deregistration if the call is already being destroyed.
1962 if (callback != null && mState != STATE_DISCONNECTED) {
Andrew Lee011728f2015-04-23 15:47:06 -07001963 for (CallbackRecord<Callback> record : mCallbackRecords) {
1964 if (record.getCallback() == callback) {
1965 mCallbackRecords.remove(record);
1966 break;
1967 }
1968 }
Andrew Leeda80c872015-04-15 14:09:50 -07001969 }
1970 }
1971
Santos Cordon3c20d632016-02-25 16:12:35 -08001972 @Override
1973 public String toString() {
1974 return new StringBuilder().
1975 append("Call [id: ").
1976 append(mTelecomCallId).
1977 append(", state: ").
1978 append(stateToString(mState)).
1979 append(", details: ").
1980 append(mDetails).
1981 append("]").toString();
1982 }
1983
1984 /**
1985 * @param state An integer value of a {@code STATE_*} constant.
1986 * @return A string representation of the value.
1987 */
1988 private static String stateToString(int state) {
1989 switch (state) {
1990 case STATE_NEW:
1991 return "NEW";
1992 case STATE_RINGING:
1993 return "RINGING";
1994 case STATE_DIALING:
1995 return "DIALING";
1996 case STATE_ACTIVE:
1997 return "ACTIVE";
1998 case STATE_HOLDING:
1999 return "HOLDING";
2000 case STATE_DISCONNECTED:
2001 return "DISCONNECTED";
2002 case STATE_CONNECTING:
2003 return "CONNECTING";
2004 case STATE_DISCONNECTING:
2005 return "DISCONNECTING";
2006 case STATE_SELECT_PHONE_ACCOUNT:
2007 return "SELECT_PHONE_ACCOUNT";
2008 default:
2009 Log.w(Call.class, "Unknown state %d", state);
2010 return "UNKNOWN";
2011 }
2012 }
2013
Andrew Leeda80c872015-04-15 14:09:50 -07002014 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07002015 * Adds a listener to this {@code Call}.
2016 *
2017 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -07002018 * @deprecated Use {@link #registerCallback} instead.
2019 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -07002020 */
Andrew Leeda80c872015-04-15 14:09:50 -07002021 @Deprecated
2022 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -07002023 public void addListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -07002024 registerCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -07002025 }
2026
2027 /**
2028 * Removes a listener from this {@code Call}.
2029 *
2030 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -07002031 * @deprecated Use {@link #unregisterCallback} instead.
2032 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -07002033 */
Andrew Leeda80c872015-04-15 14:09:50 -07002034 @Deprecated
2035 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -07002036 public void removeListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -07002037 unregisterCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -07002038 }
2039
2040 /** {@hide} */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002041 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage,
2042 int targetSdkVersion) {
Ihab Awade63fadb2014-07-09 21:52:04 -07002043 mPhone = phone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002044 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002045 mInCallAdapter = inCallAdapter;
2046 mState = STATE_NEW;
Tyler Gunnb88b3112016-11-09 10:19:23 -08002047 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08002048 mTargetSdkVersion = targetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -07002049 }
2050
2051 /** {@hide} */
Tyler Gunnb88b3112016-11-09 10:19:23 -08002052 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state,
Tyler Gunn159f35c2017-03-02 09:28:37 -08002053 String callingPackage, int targetSdkVersion) {
Shriram Ganeshddf570e2015-05-31 09:18:48 -07002054 mPhone = phone;
2055 mTelecomCallId = telecomCallId;
2056 mInCallAdapter = inCallAdapter;
2057 mState = state;
Tyler Gunnb88b3112016-11-09 10:19:23 -08002058 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08002059 mTargetSdkVersion = targetSdkVersion;
Shriram Ganeshddf570e2015-05-31 09:18:48 -07002060 }
2061
2062 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07002063 final String internalGetCallId() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002064 return mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002065 }
2066
2067 /** {@hide} */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002068 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
Tyler Gunnb88b3112016-11-09 10:19:23 -08002069
Ihab Awade63fadb2014-07-09 21:52:04 -07002070 // First, we update the internal state as far as possible before firing any updates.
Sailesh Nepal1bef3392016-01-24 18:21:53 -08002071 Details details = Details.createFromParcelableCall(parcelableCall);
Ihab Awade63fadb2014-07-09 21:52:04 -07002072 boolean detailsChanged = !Objects.equals(mDetails, details);
2073 if (detailsChanged) {
2074 mDetails = details;
2075 }
2076
2077 boolean cannedTextResponsesChanged = false;
Santos Cordon88b771d2014-07-19 13:10:40 -07002078 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
2079 && !parcelableCall.getCannedSmsResponses().isEmpty()) {
2080 mCannedTextResponses =
2081 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
Yorke Leee886f632015-08-04 13:43:31 -07002082 cannedTextResponsesChanged = true;
Ihab Awade63fadb2014-07-09 21:52:04 -07002083 }
2084
Tyler Gunn159f35c2017-03-02 09:28:37 -08002085 VideoCallImpl newVideoCallImpl = parcelableCall.getVideoCallImpl(mCallingPackage,
2086 mTargetSdkVersion);
Tyler Gunn75958422015-04-15 14:23:42 -07002087 boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002088 !Objects.equals(mVideoCallImpl, newVideoCallImpl);
Andrew Lee50aca232014-07-22 16:41:54 -07002089 if (videoCallChanged) {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002090 mVideoCallImpl = newVideoCallImpl;
2091 }
2092 if (mVideoCallImpl != null) {
2093 mVideoCallImpl.setVideoState(getDetails().getVideoState());
Ihab Awade63fadb2014-07-09 21:52:04 -07002094 }
2095
Santos Cordone3c507b2015-04-23 14:44:19 -07002096 int state = parcelableCall.getState();
Ihab Awade63fadb2014-07-09 21:52:04 -07002097 boolean stateChanged = mState != state;
2098 if (stateChanged) {
2099 mState = state;
2100 }
2101
Santos Cordon823fd3c2014-08-07 18:35:18 -07002102 String parentId = parcelableCall.getParentCallId();
2103 boolean parentChanged = !Objects.equals(mParentId, parentId);
2104 if (parentChanged) {
2105 mParentId = parentId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002106 }
2107
Santos Cordon823fd3c2014-08-07 18:35:18 -07002108 List<String> childCallIds = parcelableCall.getChildCallIds();
2109 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
2110 if (childrenChanged) {
2111 mChildrenIds.clear();
2112 mChildrenIds.addAll(parcelableCall.getChildCallIds());
2113 mChildrenCached = false;
Ihab Awade63fadb2014-07-09 21:52:04 -07002114 }
2115
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002116 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
2117 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
2118 for (String otherId : conferenceableCallIds) {
2119 if (callIdMap.containsKey(otherId)) {
2120 conferenceableCalls.add(callIdMap.get(otherId));
2121 }
2122 }
2123
2124 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
2125 mConferenceableCalls.clear();
2126 mConferenceableCalls.addAll(conferenceableCalls);
2127 fireConferenceableCallsChanged();
2128 }
2129
Hall Liu95d55872017-01-25 17:12:49 -08002130 boolean isRttChanged = false;
2131 boolean rttModeChanged = false;
Hall Liue9041242018-02-09 16:40:03 -08002132 if (parcelableCall.getIsRttCallChanged()
2133 && mDetails.hasProperty(Details.PROPERTY_RTT)) {
Hall Liu95d55872017-01-25 17:12:49 -08002134 ParcelableRttCall parcelableRttCall = parcelableCall.getParcelableRttCall();
2135 InputStreamReader receiveStream = new InputStreamReader(
2136 new ParcelFileDescriptor.AutoCloseInputStream(
2137 parcelableRttCall.getReceiveStream()),
2138 StandardCharsets.UTF_8);
2139 OutputStreamWriter transmitStream = new OutputStreamWriter(
2140 new ParcelFileDescriptor.AutoCloseOutputStream(
2141 parcelableRttCall.getTransmitStream()),
2142 StandardCharsets.UTF_8);
Hall Liu57006aa2017-02-06 10:49:48 -08002143 RttCall newRttCall = new Call.RttCall(mTelecomCallId,
Hall Liu95d55872017-01-25 17:12:49 -08002144 receiveStream, transmitStream, parcelableRttCall.getRttMode(), mInCallAdapter);
2145 if (mRttCall == null) {
2146 isRttChanged = true;
2147 } else if (mRttCall.getRttAudioMode() != newRttCall.getRttAudioMode()) {
2148 rttModeChanged = true;
2149 }
2150 mRttCall = newRttCall;
2151 } else if (mRttCall != null && parcelableCall.getParcelableRttCall() == null
2152 && parcelableCall.getIsRttCallChanged()) {
2153 isRttChanged = true;
2154 mRttCall = null;
2155 }
2156
Ihab Awade63fadb2014-07-09 21:52:04 -07002157 // Now we fire updates, ensuring that any client who listens to any of these notifications
2158 // gets the most up-to-date state.
2159
2160 if (stateChanged) {
2161 fireStateChanged(mState);
2162 }
2163 if (detailsChanged) {
2164 fireDetailsChanged(mDetails);
2165 }
2166 if (cannedTextResponsesChanged) {
2167 fireCannedTextResponsesLoaded(mCannedTextResponses);
2168 }
Andrew Lee50aca232014-07-22 16:41:54 -07002169 if (videoCallChanged) {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002170 fireVideoCallChanged(mVideoCallImpl);
Ihab Awade63fadb2014-07-09 21:52:04 -07002171 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002172 if (parentChanged) {
2173 fireParentChanged(getParent());
2174 }
2175 if (childrenChanged) {
2176 fireChildrenChanged(getChildren());
2177 }
Hall Liu95d55872017-01-25 17:12:49 -08002178 if (isRttChanged) {
2179 fireOnIsRttChanged(mRttCall != null, mRttCall);
2180 }
2181 if (rttModeChanged) {
2182 fireOnRttModeChanged(mRttCall.getRttAudioMode());
2183 }
Ihab Awade63fadb2014-07-09 21:52:04 -07002184
2185 // If we have transitioned to DISCONNECTED, that means we need to notify clients and
2186 // remove ourselves from the Phone. Note that we do this after completing all state updates
2187 // so a client can cleanly transition all their UI to the state appropriate for a
2188 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
2189 if (mState == STATE_DISCONNECTED) {
2190 fireCallDestroyed();
Ihab Awade63fadb2014-07-09 21:52:04 -07002191 }
2192 }
2193
2194 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07002195 final void internalSetPostDialWait(String remaining) {
2196 mRemainingPostDialSequence = remaining;
2197 firePostDialWait(mRemainingPostDialSequence);
2198 }
2199
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07002200 /** {@hide} */
Santos Cordonf30d7e92014-08-26 09:54:33 -07002201 final void internalSetDisconnected() {
2202 if (mState != Call.STATE_DISCONNECTED) {
2203 mState = Call.STATE_DISCONNECTED;
2204 fireStateChanged(mState);
2205 fireCallDestroyed();
Santos Cordonf30d7e92014-08-26 09:54:33 -07002206 }
2207 }
2208
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002209 /** {@hide} */
2210 final void internalOnConnectionEvent(String event, Bundle extras) {
2211 fireOnConnectionEvent(event, extras);
2212 }
2213
Hall Liu95d55872017-01-25 17:12:49 -08002214 /** {@hide} */
2215 final void internalOnRttUpgradeRequest(final int requestId) {
2216 for (CallbackRecord<Callback> record : mCallbackRecords) {
2217 final Call call = this;
2218 final Callback callback = record.getCallback();
2219 record.getHandler().post(() -> callback.onRttRequest(call, requestId));
2220 }
2221 }
2222
Hall Liu57006aa2017-02-06 10:49:48 -08002223 /** @hide */
2224 final void internalOnRttInitiationFailure(int reason) {
2225 for (CallbackRecord<Callback> record : mCallbackRecords) {
2226 final Call call = this;
2227 final Callback callback = record.getCallback();
2228 record.getHandler().post(() -> callback.onRttInitiationFailure(call, reason));
2229 }
2230 }
2231
Sanket Padawe85291f62017-12-01 13:59:27 -08002232 /** {@hide} */
2233 final void internalOnHandoverFailed(int error) {
2234 for (CallbackRecord<Callback> record : mCallbackRecords) {
2235 final Call call = this;
2236 final Callback callback = record.getCallback();
2237 record.getHandler().post(() -> callback.onHandoverFailed(call, error));
2238 }
2239 }
2240
Tyler Gunn858bfaf2018-01-22 15:17:54 -08002241 /** {@hide} */
2242 final void internalOnHandoverComplete() {
2243 for (CallbackRecord<Callback> record : mCallbackRecords) {
2244 final Call call = this;
2245 final Callback callback = record.getCallback();
2246 record.getHandler().post(() -> callback.onHandoverComplete(call));
2247 }
2248 }
2249
Andrew Lee011728f2015-04-23 15:47:06 -07002250 private void fireStateChanged(final int newState) {
2251 for (CallbackRecord<Callback> record : mCallbackRecords) {
2252 final Call call = this;
2253 final Callback callback = record.getCallback();
2254 record.getHandler().post(new Runnable() {
2255 @Override
2256 public void run() {
2257 callback.onStateChanged(call, newState);
2258 }
2259 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002260 }
2261 }
2262
Andrew Lee011728f2015-04-23 15:47:06 -07002263 private void fireParentChanged(final Call newParent) {
2264 for (CallbackRecord<Callback> record : mCallbackRecords) {
2265 final Call call = this;
2266 final Callback callback = record.getCallback();
2267 record.getHandler().post(new Runnable() {
2268 @Override
2269 public void run() {
2270 callback.onParentChanged(call, newParent);
2271 }
2272 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002273 }
2274 }
2275
Andrew Lee011728f2015-04-23 15:47:06 -07002276 private void fireChildrenChanged(final List<Call> children) {
2277 for (CallbackRecord<Callback> record : mCallbackRecords) {
2278 final Call call = this;
2279 final Callback callback = record.getCallback();
2280 record.getHandler().post(new Runnable() {
2281 @Override
2282 public void run() {
2283 callback.onChildrenChanged(call, children);
2284 }
2285 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002286 }
2287 }
2288
Andrew Lee011728f2015-04-23 15:47:06 -07002289 private void fireDetailsChanged(final Details details) {
2290 for (CallbackRecord<Callback> record : mCallbackRecords) {
2291 final Call call = this;
2292 final Callback callback = record.getCallback();
2293 record.getHandler().post(new Runnable() {
2294 @Override
2295 public void run() {
2296 callback.onDetailsChanged(call, details);
2297 }
2298 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002299 }
2300 }
2301
Andrew Lee011728f2015-04-23 15:47:06 -07002302 private void fireCannedTextResponsesLoaded(final List<String> cannedTextResponses) {
2303 for (CallbackRecord<Callback> record : mCallbackRecords) {
2304 final Call call = this;
2305 final Callback callback = record.getCallback();
2306 record.getHandler().post(new Runnable() {
2307 @Override
2308 public void run() {
2309 callback.onCannedTextResponsesLoaded(call, cannedTextResponses);
2310 }
2311 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002312 }
2313 }
2314
Andrew Lee011728f2015-04-23 15:47:06 -07002315 private void fireVideoCallChanged(final InCallService.VideoCall videoCall) {
2316 for (CallbackRecord<Callback> record : mCallbackRecords) {
2317 final Call call = this;
2318 final Callback callback = record.getCallback();
2319 record.getHandler().post(new Runnable() {
2320 @Override
2321 public void run() {
2322 callback.onVideoCallChanged(call, videoCall);
2323 }
2324 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002325 }
2326 }
2327
Andrew Lee011728f2015-04-23 15:47:06 -07002328 private void firePostDialWait(final String remainingPostDialSequence) {
2329 for (CallbackRecord<Callback> record : mCallbackRecords) {
2330 final Call call = this;
2331 final Callback callback = record.getCallback();
2332 record.getHandler().post(new Runnable() {
2333 @Override
2334 public void run() {
2335 callback.onPostDialWait(call, remainingPostDialSequence);
2336 }
2337 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002338 }
2339 }
2340
2341 private void fireCallDestroyed() {
Roshan Pius1ca62072015-07-07 17:34:51 -07002342 /**
2343 * To preserve the ordering of the Call's onCallDestroyed callback and Phone's
2344 * onCallRemoved callback, we remove this call from the Phone's record
2345 * only once all of the registered onCallDestroyed callbacks are executed.
2346 * All the callbacks get removed from our records as a part of this operation
2347 * since onCallDestroyed is the final callback.
2348 */
2349 final Call call = this;
2350 if (mCallbackRecords.isEmpty()) {
2351 // No callbacks registered, remove the call from Phone's record.
2352 mPhone.internalRemoveCall(call);
2353 }
2354 for (final CallbackRecord<Callback> record : mCallbackRecords) {
Andrew Lee011728f2015-04-23 15:47:06 -07002355 final Callback callback = record.getCallback();
2356 record.getHandler().post(new Runnable() {
2357 @Override
2358 public void run() {
Roshan Pius1ca62072015-07-07 17:34:51 -07002359 boolean isFinalRemoval = false;
2360 RuntimeException toThrow = null;
2361 try {
2362 callback.onCallDestroyed(call);
2363 } catch (RuntimeException e) {
2364 toThrow = e;
2365 }
2366 synchronized(Call.this) {
2367 mCallbackRecords.remove(record);
2368 if (mCallbackRecords.isEmpty()) {
2369 isFinalRemoval = true;
2370 }
2371 }
2372 if (isFinalRemoval) {
2373 mPhone.internalRemoveCall(call);
2374 }
2375 if (toThrow != null) {
2376 throw toThrow;
2377 }
Andrew Lee011728f2015-04-23 15:47:06 -07002378 }
2379 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002380 }
2381 }
2382
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002383 private void fireConferenceableCallsChanged() {
Andrew Lee011728f2015-04-23 15:47:06 -07002384 for (CallbackRecord<Callback> record : mCallbackRecords) {
2385 final Call call = this;
2386 final Callback callback = record.getCallback();
2387 record.getHandler().post(new Runnable() {
2388 @Override
2389 public void run() {
2390 callback.onConferenceableCallsChanged(call, mUnmodifiableConferenceableCalls);
2391 }
2392 });
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002393 }
2394 }
Tyler Gunn1e9bfc62015-08-19 11:18:58 -07002395
2396 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002397 * Notifies listeners of an incoming connection event.
2398 * <p>
2399 * Connection events are issued via {@link Connection#sendConnectionEvent(String, Bundle)}.
2400 *
2401 * @param event
2402 * @param extras
2403 */
2404 private void fireOnConnectionEvent(final String event, final Bundle extras) {
2405 for (CallbackRecord<Callback> record : mCallbackRecords) {
2406 final Call call = this;
2407 final Callback callback = record.getCallback();
2408 record.getHandler().post(new Runnable() {
2409 @Override
2410 public void run() {
2411 callback.onConnectionEvent(call, event, extras);
2412 }
2413 });
2414 }
2415 }
2416
2417 /**
Hall Liu95d55872017-01-25 17:12:49 -08002418 * Notifies listeners of an RTT on/off change
2419 *
2420 * @param enabled True if RTT is now enabled, false otherwise
2421 */
2422 private void fireOnIsRttChanged(final boolean enabled, final RttCall rttCall) {
2423 for (CallbackRecord<Callback> record : mCallbackRecords) {
2424 final Call call = this;
2425 final Callback callback = record.getCallback();
2426 record.getHandler().post(() -> callback.onRttStatusChanged(call, enabled, rttCall));
2427 }
2428 }
2429
2430 /**
2431 * Notifies listeners of a RTT mode change
2432 *
2433 * @param mode The new RTT mode
2434 */
2435 private void fireOnRttModeChanged(final int mode) {
2436 for (CallbackRecord<Callback> record : mCallbackRecords) {
2437 final Call call = this;
2438 final Callback callback = record.getCallback();
2439 record.getHandler().post(() -> callback.onRttModeChanged(call, mode));
2440 }
2441 }
2442
2443 /**
Tyler Gunn1e9bfc62015-08-19 11:18:58 -07002444 * Determines if two bundles are equal.
2445 *
2446 * @param bundle The original bundle.
2447 * @param newBundle The bundle to compare with.
2448 * @retrun {@code true} if the bundles are equal, {@code false} otherwise.
2449 */
2450 private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) {
2451 if (bundle == null || newBundle == null) {
2452 return bundle == newBundle;
2453 }
2454
2455 if (bundle.size() != newBundle.size()) {
2456 return false;
2457 }
2458
2459 for(String key : bundle.keySet()) {
2460 if (key != null) {
2461 final Object value = bundle.get(key);
2462 final Object newValue = newBundle.get(key);
2463 if (!Objects.equals(value, newValue)) {
2464 return false;
2465 }
2466 }
2467 }
2468 return true;
2469 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002470}