blob: 9adeea04f5df957bc1995bc7677d66cf156b0965 [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 Gunn94f8f112018-12-17 09:56:11 -0800545 private final @CallDirection int mCallDirection;
Ihab Awade63fadb2014-07-09 21:52:04 -0700546
547 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800548 * Whether the supplied capabilities supports the specified capability.
549 *
550 * @param capabilities A bit field of capabilities.
551 * @param capability The capability to check capabilities for.
552 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800553 */
554 public static boolean can(int capabilities, int capability) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800555 return (capabilities & capability) == capability;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800556 }
557
558 /**
559 * Whether the capabilities of this {@code Details} supports the specified capability.
560 *
561 * @param capability The capability to check capabilities for.
562 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800563 */
564 public boolean can(int capability) {
565 return can(mCallCapabilities, capability);
566 }
567
568 /**
569 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
570 *
571 * @param capabilities A capability bit field.
572 * @return A human readable string representation.
573 */
574 public static String capabilitiesToString(int capabilities) {
575 StringBuilder builder = new StringBuilder();
576 builder.append("[Capabilities:");
577 if (can(capabilities, CAPABILITY_HOLD)) {
578 builder.append(" CAPABILITY_HOLD");
579 }
580 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
581 builder.append(" CAPABILITY_SUPPORT_HOLD");
582 }
583 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
584 builder.append(" CAPABILITY_MERGE_CONFERENCE");
585 }
586 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
587 builder.append(" CAPABILITY_SWAP_CONFERENCE");
588 }
589 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
590 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
591 }
592 if (can(capabilities, CAPABILITY_MUTE)) {
593 builder.append(" CAPABILITY_MUTE");
594 }
595 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
596 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
597 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700598 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
599 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
600 }
601 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
602 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
603 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700604 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
605 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800606 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700607 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
608 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
609 }
610 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
611 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
612 }
Tyler Gunnf97a0092016-01-19 15:59:34 -0800613 if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
614 builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO");
615 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700616 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
617 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800618 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500619 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700620 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500621 }
Rekha Kumar07366812015-03-24 16:42:31 -0700622 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
623 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
624 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700625 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
626 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
627 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700628 if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
629 builder.append(" CAPABILITY_CAN_PULL_CALL");
630 }
Pooja Jaind34698d2017-12-28 14:15:31 +0530631 if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) {
632 builder.append(" CAPABILITY_SUPPORT_DEFLECT");
633 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800634 builder.append("]");
635 return builder.toString();
636 }
637
638 /**
Andrew Lee2378ea72015-04-29 14:38:11 -0700639 * Whether the supplied properties includes the specified property.
640 *
641 * @param properties A bit field of properties.
642 * @param property The property to check properties for.
643 * @return Whether the specified property is supported.
644 */
645 public static boolean hasProperty(int properties, int property) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800646 return (properties & property) == property;
Andrew Lee2378ea72015-04-29 14:38:11 -0700647 }
648
649 /**
650 * Whether the properties of this {@code Details} includes the specified property.
651 *
652 * @param property The property to check properties for.
653 * @return Whether the specified property is supported.
654 */
655 public boolean hasProperty(int property) {
656 return hasProperty(mCallProperties, property);
657 }
658
659 /**
660 * Render a set of property bits ({@code PROPERTY_*}) as a human readable string.
661 *
662 * @param properties A property bit field.
663 * @return A human readable string representation.
664 */
665 public static String propertiesToString(int properties) {
666 StringBuilder builder = new StringBuilder();
667 builder.append("[Properties:");
668 if (hasProperty(properties, PROPERTY_CONFERENCE)) {
669 builder.append(" PROPERTY_CONFERENCE");
670 }
671 if (hasProperty(properties, PROPERTY_GENERIC_CONFERENCE)) {
672 builder.append(" PROPERTY_GENERIC_CONFERENCE");
673 }
674 if (hasProperty(properties, PROPERTY_WIFI)) {
675 builder.append(" PROPERTY_WIFI");
676 }
677 if (hasProperty(properties, PROPERTY_HIGH_DEF_AUDIO)) {
678 builder.append(" PROPERTY_HIGH_DEF_AUDIO");
679 }
680 if (hasProperty(properties, PROPERTY_EMERGENCY_CALLBACK_MODE)) {
Yorke Leebe2a4a22015-06-12 10:10:55 -0700681 builder.append(" PROPERTY_EMERGENCY_CALLBACK_MODE");
Andrew Lee2378ea72015-04-29 14:38:11 -0700682 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700683 if (hasProperty(properties, PROPERTY_IS_EXTERNAL_CALL)) {
684 builder.append(" PROPERTY_IS_EXTERNAL_CALL");
685 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700686 if (hasProperty(properties, PROPERTY_HAS_CDMA_VOICE_PRIVACY)) {
Brad Ebinger15847072016-05-18 11:08:36 -0700687 builder.append(" PROPERTY_HAS_CDMA_VOICE_PRIVACY");
688 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700689 if (hasProperty(properties, PROPERTY_ASSISTED_DIALING_USED)) {
Eric Erfanianec881872017-12-06 16:27:53 -0800690 builder.append(" PROPERTY_ASSISTED_DIALING_USED");
691 }
Tyler Gunn5bd90852018-09-21 09:37:07 -0700692 if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
693 builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL");
694 }
Tyler Gunn80a5e1e2018-06-22 15:52:27 -0700695 if (hasProperty(properties, PROPERTY_RTT)) {
696 builder.append(" PROPERTY_RTT");
697 }
698 if (hasProperty(properties, PROPERTY_VOIP_AUDIO_MODE)) {
699 builder.append(" PROPERTY_VOIP_AUDIO_MODE");
700 }
Andrew Lee2378ea72015-04-29 14:38:11 -0700701 builder.append("]");
702 return builder.toString();
703 }
704
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800705 /** {@hide} */
706 public String getTelecomCallId() {
707 return mTelecomCallId;
708 }
709
Andrew Lee2378ea72015-04-29 14:38:11 -0700710 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700711 * @return The handle (e.g., phone number) to which the {@code Call} is currently
712 * connected.
713 */
714 public Uri getHandle() {
715 return mHandle;
716 }
717
718 /**
719 * @return The presentation requirements for the handle. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700720 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700721 */
722 public int getHandlePresentation() {
723 return mHandlePresentation;
724 }
725
726 /**
Tyler Gunnd081f042018-12-04 12:56:45 -0800727 * The display name for the caller.
728 * <p>
729 * This is the name as reported by the {@link ConnectionService} associated with this call.
Tyler Gunnd081f042018-12-04 12:56:45 -0800730 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700731 * @return The display name for the caller.
732 */
733 public String getCallerDisplayName() {
734 return mCallerDisplayName;
735 }
736
737 /**
738 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700739 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700740 */
741 public int getCallerDisplayNamePresentation() {
742 return mCallerDisplayNamePresentation;
743 }
744
745 /**
Evan Charlton6eb262c2014-07-19 18:18:19 -0700746 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being
747 * routed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700748 */
Evan Charlton8c8a0622014-07-20 12:31:00 -0700749 public PhoneAccountHandle getAccountHandle() {
750 return mAccountHandle;
Ihab Awade63fadb2014-07-09 21:52:04 -0700751 }
752
753 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800754 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various
755 * {@code CAPABILITY_*} constants in this class.
Ihab Awade63fadb2014-07-09 21:52:04 -0700756 */
Ihab Awad5d0410f2014-07-30 10:07:40 -0700757 public int getCallCapabilities() {
758 return mCallCapabilities;
Ihab Awade63fadb2014-07-09 21:52:04 -0700759 }
760
761 /**
Andrew Lee2378ea72015-04-29 14:38:11 -0700762 * @return A bitmask of the properties of the {@code Call}, as defined by the various
763 * {@code PROPERTY_*} constants in this class.
Andrew Lee223ad142014-08-27 16:33:08 -0700764 */
765 public int getCallProperties() {
766 return mCallProperties;
767 }
768
769 /**
Christine Hallstrom4e22d6d2016-11-30 16:06:42 -0800770 * @return a bitmask of the audio routes available for the call.
771 *
772 * @hide
773 */
774 public int getSupportedAudioRoutes() {
775 return mSupportedAudioRoutes;
776 }
777
778 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700779 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700780 * by {@link android.telecom.DisconnectCause}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700781 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700782 public DisconnectCause getDisconnectCause() {
783 return mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700784 }
785
786 /**
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700787 * Returns the time the {@link Call} connected (i.e. became active). This information is
788 * updated periodically, but user interfaces should not rely on this to display the "call
789 * time clock". For the time when the call was first added to Telecom, see
790 * {@link #getCreationTimeMillis()}.
791 *
792 * @return The time the {@link Call} connected in milliseconds since the epoch.
Ihab Awade63fadb2014-07-09 21:52:04 -0700793 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700794 public final long getConnectTimeMillis() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700795 return mConnectTimeMillis;
796 }
797
798 /**
799 * @return Information about any calling gateway the {@code Call} may be using.
800 */
801 public GatewayInfo getGatewayInfo() {
802 return mGatewayInfo;
803 }
804
Andrew Lee7a341382014-07-15 17:05:08 -0700805 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700806 * @return The video state of the {@code Call}.
Andrew Lee7a341382014-07-15 17:05:08 -0700807 */
808 public int getVideoState() {
809 return mVideoState;
810 }
811
Ihab Awad5d0410f2014-07-30 10:07:40 -0700812 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700813 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none
Ihab Awad5d0410f2014-07-30 10:07:40 -0700814 * have been set.
Evan Charlton5b49ade2014-07-15 17:03:20 -0700815 */
816 public StatusHints getStatusHints() {
817 return mStatusHints;
818 }
819
Nancy Chen10798dc2014-08-08 14:00:25 -0700820 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700821 * @return The extras associated with this call.
Nancy Chen10798dc2014-08-08 14:00:25 -0700822 */
823 public Bundle getExtras() {
824 return mExtras;
825 }
826
Santos Cordon6b7f9552015-05-27 17:21:45 -0700827 /**
828 * @return The extras used with the original intent to place this call.
829 */
830 public Bundle getIntentExtras() {
831 return mIntentExtras;
832 }
833
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700834 /**
835 * Returns the time when the call was first created and added to Telecom. This is the same
836 * time that is logged as the start time in the Call Log (see
837 * {@link android.provider.CallLog.Calls#DATE}). To determine when the call was connected
838 * (became active), see {@link #getConnectTimeMillis()}.
839 *
840 * @return The creation time of the call, in millis since the epoch.
841 */
842 public long getCreationTimeMillis() {
843 return mCreationTimeMillis;
844 }
845
Tyler Gunnd081f042018-12-04 12:56:45 -0800846 /**
Tyler Gunn94f8f112018-12-17 09:56:11 -0800847 * Indicates whether the call is an incoming or outgoing call.
848 * @return The call's direction.
849 */
850 public @CallDirection int getCallDirection() {
851 return mCallDirection;
852 }
853
Ihab Awade63fadb2014-07-09 21:52:04 -0700854 @Override
855 public boolean equals(Object o) {
856 if (o instanceof Details) {
857 Details d = (Details) o;
858 return
859 Objects.equals(mHandle, d.mHandle) &&
860 Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
861 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
862 Objects.equals(mCallerDisplayNamePresentation,
863 d.mCallerDisplayNamePresentation) &&
Evan Charlton8c8a0622014-07-20 12:31:00 -0700864 Objects.equals(mAccountHandle, d.mAccountHandle) &&
Ihab Awad5d0410f2014-07-30 10:07:40 -0700865 Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
Andrew Lee223ad142014-08-27 16:33:08 -0700866 Objects.equals(mCallProperties, d.mCallProperties) &&
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700867 Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
Ihab Awade63fadb2014-07-09 21:52:04 -0700868 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
Andrew Lee85f5d422014-07-11 17:22:03 -0700869 Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Evan Charlton5b49ade2014-07-15 17:03:20 -0700870 Objects.equals(mVideoState, d.mVideoState) &&
Nancy Chen10798dc2014-08-08 14:00:25 -0700871 Objects.equals(mStatusHints, d.mStatusHints) &&
Tyler Gunn1e9bfc62015-08-19 11:18:58 -0700872 areBundlesEqual(mExtras, d.mExtras) &&
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700873 areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
Tyler Gunnd081f042018-12-04 12:56:45 -0800874 Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
Tyler Gunn94f8f112018-12-17 09:56:11 -0800875 Objects.equals(mCallDirection, d.mCallDirection);
Ihab Awade63fadb2014-07-09 21:52:04 -0700876 }
877 return false;
878 }
879
880 @Override
881 public int hashCode() {
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700882 return Objects.hash(mHandle,
883 mHandlePresentation,
884 mCallerDisplayName,
885 mCallerDisplayNamePresentation,
886 mAccountHandle,
887 mCallCapabilities,
888 mCallProperties,
889 mDisconnectCause,
890 mConnectTimeMillis,
891 mGatewayInfo,
892 mVideoState,
893 mStatusHints,
894 mExtras,
895 mIntentExtras,
Tyler Gunnd081f042018-12-04 12:56:45 -0800896 mCreationTimeMillis,
Tyler Gunn94f8f112018-12-17 09:56:11 -0800897 mCallDirection);
Ihab Awade63fadb2014-07-09 21:52:04 -0700898 }
899
900 /** {@hide} */
901 public Details(
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800902 String telecomCallId,
Ihab Awade63fadb2014-07-09 21:52:04 -0700903 Uri handle,
904 int handlePresentation,
905 String callerDisplayName,
906 int callerDisplayNamePresentation,
Evan Charlton8c8a0622014-07-20 12:31:00 -0700907 PhoneAccountHandle accountHandle,
Ihab Awade63fadb2014-07-09 21:52:04 -0700908 int capabilities,
Andrew Lee223ad142014-08-27 16:33:08 -0700909 int properties,
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700910 DisconnectCause disconnectCause,
Ihab Awade63fadb2014-07-09 21:52:04 -0700911 long connectTimeMillis,
Andrew Lee85f5d422014-07-11 17:22:03 -0700912 GatewayInfo gatewayInfo,
Evan Charlton5b49ade2014-07-15 17:03:20 -0700913 int videoState,
Nancy Chen10798dc2014-08-08 14:00:25 -0700914 StatusHints statusHints,
Santos Cordon6b7f9552015-05-27 17:21:45 -0700915 Bundle extras,
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700916 Bundle intentExtras,
Tyler Gunnd081f042018-12-04 12:56:45 -0800917 long creationTimeMillis,
Tyler Gunn94f8f112018-12-17 09:56:11 -0800918 int callDirection) {
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800919 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700920 mHandle = handle;
921 mHandlePresentation = handlePresentation;
922 mCallerDisplayName = callerDisplayName;
923 mCallerDisplayNamePresentation = callerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700924 mAccountHandle = accountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700925 mCallCapabilities = capabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700926 mCallProperties = properties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700927 mDisconnectCause = disconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700928 mConnectTimeMillis = connectTimeMillis;
929 mGatewayInfo = gatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700930 mVideoState = videoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700931 mStatusHints = statusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700932 mExtras = extras;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700933 mIntentExtras = intentExtras;
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700934 mCreationTimeMillis = creationTimeMillis;
Tyler Gunn94f8f112018-12-17 09:56:11 -0800935 mCallDirection = callDirection;
Ihab Awade63fadb2014-07-09 21:52:04 -0700936 }
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800937
938 /** {@hide} */
939 public static Details createFromParcelableCall(ParcelableCall parcelableCall) {
940 return new Details(
941 parcelableCall.getId(),
942 parcelableCall.getHandle(),
943 parcelableCall.getHandlePresentation(),
944 parcelableCall.getCallerDisplayName(),
945 parcelableCall.getCallerDisplayNamePresentation(),
946 parcelableCall.getAccountHandle(),
947 parcelableCall.getCapabilities(),
948 parcelableCall.getProperties(),
949 parcelableCall.getDisconnectCause(),
950 parcelableCall.getConnectTimeMillis(),
951 parcelableCall.getGatewayInfo(),
952 parcelableCall.getVideoState(),
953 parcelableCall.getStatusHints(),
954 parcelableCall.getExtras(),
Tyler Gunnc0bf6de2017-03-17 11:27:09 -0700955 parcelableCall.getIntentExtras(),
Tyler Gunnd081f042018-12-04 12:56:45 -0800956 parcelableCall.getCreationTimeMillis(),
Tyler Gunn94f8f112018-12-17 09:56:11 -0800957 parcelableCall.getCallDirection());
Sailesh Nepal1bef3392016-01-24 18:21:53 -0800958 }
Santos Cordon3c20d632016-02-25 16:12:35 -0800959
960 @Override
961 public String toString() {
962 StringBuilder sb = new StringBuilder();
Tyler Gunn3cd820f2018-11-30 14:21:18 -0800963 sb.append("[id: ");
964 sb.append(mTelecomCallId);
965 sb.append(", pa: ");
Santos Cordon3c20d632016-02-25 16:12:35 -0800966 sb.append(mAccountHandle);
967 sb.append(", hdl: ");
Tyler Gunn3cd820f2018-11-30 14:21:18 -0800968 sb.append(Log.piiHandle(mHandle));
969 sb.append(", hdlPres: ");
970 sb.append(mHandlePresentation);
971 sb.append(", videoState: ");
972 sb.append(VideoProfile.videoStateToString(mVideoState));
Santos Cordon3c20d632016-02-25 16:12:35 -0800973 sb.append(", caps: ");
974 sb.append(capabilitiesToString(mCallCapabilities));
975 sb.append(", props: ");
Tyler Gunn720c6642016-03-22 09:02:47 -0700976 sb.append(propertiesToString(mCallProperties));
Santos Cordon3c20d632016-02-25 16:12:35 -0800977 sb.append("]");
978 return sb.toString();
979 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700980 }
981
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700982 /**
983 * Defines callbacks which inform the {@link InCallService} of changes to a {@link Call}.
984 * These callbacks can originate from the Telecom framework, or a {@link ConnectionService}
985 * implementation.
986 * <p>
987 * You can handle these callbacks by extending the {@link Callback} class and overriding the
988 * callbacks that your {@link InCallService} is interested in. The callback methods include the
989 * {@link Call} for which the callback applies, allowing reuse of a single instance of your
990 * {@link Callback} implementation, if desired.
991 * <p>
992 * Use {@link Call#registerCallback(Callback)} to register your callback(s). Ensure
993 * {@link Call#unregisterCallback(Callback)} is called when you no longer require callbacks
994 * (typically in {@link InCallService#onCallRemoved(Call)}).
995 * Note: Callbacks which occur before you call {@link Call#registerCallback(Callback)} will not
996 * reach your implementation of {@link Callback}, so it is important to register your callback
997 * as soon as your {@link InCallService} is notified of a new call via
998 * {@link InCallService#onCallAdded(Call)}.
999 */
Andrew Leeda80c872015-04-15 14:09:50 -07001000 public static abstract class Callback {
Ihab Awade63fadb2014-07-09 21:52:04 -07001001 /**
Sanket Padawea8eddd42017-11-03 11:07:35 -07001002 * @hide
1003 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001004 @IntDef(prefix = { "HANDOVER_" },
1005 value = {HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_NOT_SUPPORTED,
Tyler Gunn5c60d712018-03-16 09:53:44 -07001006 HANDOVER_FAILURE_USER_REJECTED, HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL,
Tyler Gunn9d127732018-03-02 15:45:51 -08001007 HANDOVER_FAILURE_UNKNOWN})
Sanket Padawea8eddd42017-11-03 11:07:35 -07001008 @Retention(RetentionPolicy.SOURCE)
1009 public @interface HandoverFailureErrors {}
1010
1011 /**
1012 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the app
Tyler Gunn9d127732018-03-02 15:45:51 -08001013 * to handover the call to rejects the handover request.
1014 * <p>
1015 * Will be returned when {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} is called
1016 * and the destination {@link PhoneAccountHandle}'s {@link ConnectionService} returns a
1017 * {@code null} {@link Connection} from
1018 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
1019 * ConnectionRequest)}.
1020 * <p>
1021 * For more information on call handovers, see
1022 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001023 */
1024 public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1;
1025
1026 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08001027 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
1028 * is initiated but the source or destination app does not support handover.
1029 * <p>
1030 * Will be returned when a handover is requested via
1031 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)} and the destination
1032 * {@link PhoneAccountHandle} does not declare
1033 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}. May also be returned when a handover is
1034 * requested at the {@link PhoneAccountHandle} for the current call (i.e. the source call's
1035 * {@link Details#getAccountHandle()}) does not declare
1036 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
1037 * <p>
1038 * For more information on call handovers, see
1039 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001040 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001041 public static final int HANDOVER_FAILURE_NOT_SUPPORTED = 2;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001042
1043 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08001044 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the remote
1045 * user rejects the handover request.
1046 * <p>
1047 * For more information on call handovers, see
1048 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001049 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001050 public static final int HANDOVER_FAILURE_USER_REJECTED = 3;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001051
Sanket Padawe85291f62017-12-01 13:59:27 -08001052 /**
1053 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there
1054 * is ongoing emergency call.
Tyler Gunn9d127732018-03-02 15:45:51 -08001055 * <p>
1056 * This error code is returned when {@link #handoverTo(PhoneAccountHandle, int, Bundle)} is
1057 * called on an emergency call, or if any other call is an emergency call.
1058 * <p>
1059 * Handovers are not permitted while there are ongoing emergency calls.
1060 * <p>
1061 * For more information on call handovers, see
1062 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
Sanket Padawe85291f62017-12-01 13:59:27 -08001063 */
Tyler Gunn5c60d712018-03-16 09:53:44 -07001064 public static final int HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL = 4;
Sanket Padawe85291f62017-12-01 13:59:27 -08001065
Tyler Gunn9d127732018-03-02 15:45:51 -08001066 /**
1067 * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
1068 * fails for an unknown reason.
1069 * <p>
1070 * For more information on call handovers, see
1071 * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
1072 */
1073 public static final int HANDOVER_FAILURE_UNKNOWN = 5;
Sanket Padawea8eddd42017-11-03 11:07:35 -07001074
1075 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001076 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
1077 *
Ihab Awade63fadb2014-07-09 21:52:04 -07001078 * @param call The {@code Call} invoking this method.
1079 * @param state The new state of the {@code Call}.
1080 */
1081 public void onStateChanged(Call call, int state) {}
1082
1083 /**
1084 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
1085 *
1086 * @param call The {@code Call} invoking this method.
1087 * @param parent The new parent of the {@code Call}.
1088 */
1089 public void onParentChanged(Call call, Call parent) {}
1090
1091 /**
1092 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}.
1093 *
1094 * @param call The {@code Call} invoking this method.
1095 * @param children The new children of the {@code Call}.
1096 */
1097 public void onChildrenChanged(Call call, List<Call> children) {}
1098
1099 /**
1100 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}.
1101 *
1102 * @param call The {@code Call} invoking this method.
1103 * @param details A {@code Details} object describing the {@code Call}.
1104 */
1105 public void onDetailsChanged(Call call, Details details) {}
1106
1107 /**
1108 * Invoked when the text messages that can be used as responses to the incoming
1109 * {@code Call} are loaded from the relevant database.
1110 * See {@link #getCannedTextResponses()}.
1111 *
1112 * @param call The {@code Call} invoking this method.
1113 * @param cannedTextResponses The text messages useable as responses.
1114 */
1115 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
1116
1117 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001118 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
1119 * character. This causes the post-dial signals to stop pending user confirmation. An
1120 * implementation should present this choice to the user and invoke
1121 * {@link #postDialContinue(boolean)} when the user makes the choice.
1122 *
1123 * @param call The {@code Call} invoking this method.
1124 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
1125 */
1126 public void onPostDialWait(Call call, String remainingPostDialSequence) {}
1127
1128 /**
Andrew Lee50aca232014-07-22 16:41:54 -07001129 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed.
Ihab Awade63fadb2014-07-09 21:52:04 -07001130 *
1131 * @param call The {@code Call} invoking this method.
Andrew Lee50aca232014-07-22 16:41:54 -07001132 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
Ihab Awade63fadb2014-07-09 21:52:04 -07001133 */
Andrew Lee50aca232014-07-22 16:41:54 -07001134 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
Ihab Awade63fadb2014-07-09 21:52:04 -07001135
1136 /**
1137 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning
1138 * up their UI for the {@code Call} in response to state transitions. Specifically,
1139 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of
1140 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather,
1141 * clients should wait for this method to be invoked.
1142 *
1143 * @param call The {@code Call} being destroyed.
1144 */
1145 public void onCallDestroyed(Call call) {}
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001146
1147 /**
1148 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
1149 * conferenced.
1150 *
1151 * @param call The {@code Call} being updated.
1152 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
1153 * conferenced.
1154 */
1155 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001156
1157 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001158 * Invoked when a {@link Call} receives an event from its associated {@link Connection}.
1159 * <p>
1160 * Where possible, the Call should make an attempt to handle {@link Connection} events which
1161 * are part of the {@code android.telecom.*} namespace. The Call should ignore any events
1162 * it does not wish to handle. Unexpected events should be handled gracefully, as it is
1163 * possible that a {@link ConnectionService} has defined its own Connection events which a
1164 * Call is not aware of.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001165 * <p>
1166 * See {@link Connection#sendConnectionEvent(String, Bundle)}.
1167 *
1168 * @param call The {@code Call} receiving the event.
1169 * @param event The event.
1170 * @param extras Extras associated with the connection event.
1171 */
1172 public void onConnectionEvent(Call call, String event, Bundle extras) {}
Hall Liu95d55872017-01-25 17:12:49 -08001173
1174 /**
1175 * Invoked when the RTT mode changes for this call.
1176 * @param call The call whose RTT mode has changed.
1177 * @param mode the new RTT mode, one of
1178 * {@link RttCall#RTT_MODE_FULL}, {@link RttCall#RTT_MODE_HCO},
1179 * or {@link RttCall#RTT_MODE_VCO}
1180 */
1181 public void onRttModeChanged(Call call, int mode) {}
1182
1183 /**
1184 * Invoked when the call's RTT status changes, either from off to on or from on to off.
1185 * @param call The call whose RTT status has changed.
1186 * @param enabled whether RTT is now enabled or disabled
1187 * @param rttCall the {@link RttCall} object to use for reading and writing if RTT is now
1188 * on, null otherwise.
1189 */
1190 public void onRttStatusChanged(Call call, boolean enabled, RttCall rttCall) {}
1191
1192 /**
1193 * Invoked when the remote end of the connection has requested that an RTT communication
1194 * channel be opened. A response to this should be sent via {@link #respondToRttRequest}
1195 * with the same ID that this method is invoked with.
1196 * @param call The call which the RTT request was placed on
1197 * @param id The ID of the request.
1198 */
1199 public void onRttRequest(Call call, int id) {}
Hall Liu57006aa2017-02-06 10:49:48 -08001200
1201 /**
1202 * Invoked when the RTT session failed to initiate for some reason, including rejection
1203 * by the remote party.
1204 * @param call The call which the RTT initiation failure occurred on.
1205 * @param reason One of the status codes defined in
1206 * {@link android.telecom.Connection.RttModifyStatus}, with the exception of
1207 * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
1208 */
1209 public void onRttInitiationFailure(Call call, int reason) {}
Sanket Padawea8eddd42017-11-03 11:07:35 -07001210
1211 /**
1212 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
1213 * has completed successfully.
Tyler Gunn9d127732018-03-02 15:45:51 -08001214 * <p>
1215 * For a full discussion of the handover process and the APIs involved, see
1216 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
1217 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07001218 * @param call The call which had initiated handover.
1219 */
1220 public void onHandoverComplete(Call call) {}
1221
1222 /**
1223 * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
1224 * has failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08001225 * <p>
1226 * For a full discussion of the handover process and the APIs involved, see
1227 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
1228 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07001229 * @param call The call which had initiated handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08001230 * @param failureReason Error reason for failure.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001231 */
1232 public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {}
Hall Liu95d55872017-01-25 17:12:49 -08001233 }
1234
1235 /**
1236 * A class that holds the state that describes the state of the RTT channel to the remote
1237 * party, if it is active.
1238 */
1239 public static final class RttCall {
Hall Liu07094df2017-02-28 15:17:44 -08001240 /** @hide */
Hall Liu95d55872017-01-25 17:12:49 -08001241 @Retention(RetentionPolicy.SOURCE)
1242 @IntDef({RTT_MODE_INVALID, RTT_MODE_FULL, RTT_MODE_HCO, RTT_MODE_VCO})
1243 public @interface RttAudioMode {}
1244
1245 /**
1246 * For metrics use. Default value in the proto.
1247 * @hide
1248 */
1249 public static final int RTT_MODE_INVALID = 0;
1250
1251 /**
1252 * Indicates that there should be a bidirectional audio stream between the two parties
1253 * on the call.
1254 */
1255 public static final int RTT_MODE_FULL = 1;
1256
1257 /**
1258 * Indicates that the local user should be able to hear the audio stream from the remote
1259 * user, but not vice versa. Equivalent to muting the microphone.
1260 */
1261 public static final int RTT_MODE_HCO = 2;
1262
1263 /**
1264 * Indicates that the remote user should be able to hear the audio stream from the local
1265 * user, but not vice versa. Equivalent to setting the volume to zero.
1266 */
1267 public static final int RTT_MODE_VCO = 3;
1268
1269 private static final int READ_BUFFER_SIZE = 1000;
1270
1271 private InputStreamReader mReceiveStream;
1272 private OutputStreamWriter mTransmitStream;
1273 private int mRttMode;
1274 private final InCallAdapter mInCallAdapter;
Hall Liu57006aa2017-02-06 10:49:48 -08001275 private final String mTelecomCallId;
Hall Liu95d55872017-01-25 17:12:49 -08001276 private char[] mReadBuffer = new char[READ_BUFFER_SIZE];
1277
1278 /**
1279 * @hide
1280 */
Hall Liu57006aa2017-02-06 10:49:48 -08001281 public RttCall(String telecomCallId, InputStreamReader receiveStream,
1282 OutputStreamWriter transmitStream, int mode, InCallAdapter inCallAdapter) {
1283 mTelecomCallId = telecomCallId;
Hall Liu95d55872017-01-25 17:12:49 -08001284 mReceiveStream = receiveStream;
1285 mTransmitStream = transmitStream;
1286 mRttMode = mode;
1287 mInCallAdapter = inCallAdapter;
1288 }
1289
1290 /**
1291 * Returns the current RTT audio mode.
1292 * @return Current RTT audio mode. One of {@link #RTT_MODE_FULL}, {@link #RTT_MODE_VCO}, or
1293 * {@link #RTT_MODE_HCO}.
1294 */
1295 public int getRttAudioMode() {
1296 return mRttMode;
1297 }
1298
1299 /**
1300 * Sets the RTT audio mode. The requested mode change will be communicated through
1301 * {@link Callback#onRttModeChanged(Call, int)}.
1302 * @param mode The desired RTT audio mode, one of {@link #RTT_MODE_FULL},
1303 * {@link #RTT_MODE_VCO}, or {@link #RTT_MODE_HCO}.
1304 */
1305 public void setRttMode(@RttAudioMode int mode) {
Hall Liu57006aa2017-02-06 10:49:48 -08001306 mInCallAdapter.setRttMode(mTelecomCallId, mode);
Hall Liu95d55872017-01-25 17:12:49 -08001307 }
1308
1309 /**
1310 * Writes the string {@param input} into the outgoing text stream for this RTT call. Since
1311 * RTT transmits text in real-time, this method should be called once for each character
1312 * the user enters into the device.
1313 *
1314 * This method is not thread-safe -- calling it from multiple threads simultaneously may
1315 * lead to interleaved text.
1316 * @param input The message to send to the remote user.
1317 */
1318 public void write(String input) throws IOException {
1319 mTransmitStream.write(input);
1320 mTransmitStream.flush();
1321 }
1322
1323 /**
1324 * Reads a string from the remote user, blocking if there is no data available. Returns
1325 * {@code null} if the RTT conversation has been terminated and there is no further data
1326 * to read.
1327 *
1328 * This method is not thread-safe -- calling it from multiple threads simultaneously may
1329 * lead to interleaved text.
1330 * @return A string containing text sent by the remote user, or {@code null} if the
1331 * conversation has been terminated or if there was an error while reading.
1332 */
Hall Liub1c8a772017-07-17 17:04:41 -07001333 public String read() {
1334 try {
1335 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
1336 if (numRead < 0) {
1337 return null;
1338 }
1339 return new String(mReadBuffer, 0, numRead);
1340 } catch (IOException e) {
1341 Log.w(this, "Exception encountered when reading from InputStreamReader: %s", e);
Jeff Sharkey90396362017-06-12 16:26:53 -06001342 return null;
Hall Liuffa4a812017-03-02 16:11:00 -08001343 }
Hall Liuffa4a812017-03-02 16:11:00 -08001344 }
1345
1346 /**
1347 * Non-blocking version of {@link #read()}. Returns {@code null} if there is nothing to
1348 * be read.
1349 * @return A string containing text entered by the user, or {@code null} if the user has
1350 * not entered any new text yet.
1351 */
1352 public String readImmediately() throws IOException {
1353 if (mReceiveStream.ready()) {
Hall Liub1c8a772017-07-17 17:04:41 -07001354 int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
1355 if (numRead < 0) {
1356 return null;
1357 }
1358 return new String(mReadBuffer, 0, numRead);
Hall Liuffa4a812017-03-02 16:11:00 -08001359 } else {
Hall Liu95d55872017-01-25 17:12:49 -08001360 return null;
1361 }
1362 }
Hall Liue9041242018-02-09 16:40:03 -08001363
1364 /**
1365 * Closes the underlying file descriptors
1366 * @hide
1367 */
1368 public void close() {
1369 try {
1370 mReceiveStream.close();
1371 } catch (IOException e) {
1372 // ignore
1373 }
1374 try {
1375 mTransmitStream.close();
1376 } catch (IOException e) {
1377 // ignore
1378 }
1379 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001380 }
1381
Andrew Leeda80c872015-04-15 14:09:50 -07001382 /**
1383 * @deprecated Use {@code Call.Callback} instead.
1384 * @hide
1385 */
1386 @Deprecated
1387 @SystemApi
1388 public static abstract class Listener extends Callback { }
1389
Ihab Awade63fadb2014-07-09 21:52:04 -07001390 private final Phone mPhone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001391 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07001392 private final InCallAdapter mInCallAdapter;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001393 private final List<String> mChildrenIds = new ArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -07001394 private final List<Call> mChildren = new ArrayList<>();
1395 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
Andrew Lee011728f2015-04-23 15:47:06 -07001396 private final List<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArrayList<>();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001397 private final List<Call> mConferenceableCalls = new ArrayList<>();
1398 private final List<Call> mUnmodifiableConferenceableCalls =
1399 Collections.unmodifiableList(mConferenceableCalls);
1400
Santos Cordon823fd3c2014-08-07 18:35:18 -07001401 private boolean mChildrenCached;
1402 private String mParentId = null;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001403 private int mState;
Ihab Awade63fadb2014-07-09 21:52:04 -07001404 private List<String> mCannedTextResponses = null;
Tyler Gunnb88b3112016-11-09 10:19:23 -08001405 private String mCallingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08001406 private int mTargetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -07001407 private String mRemainingPostDialSequence;
Tyler Gunn584ba6c2015-12-08 10:53:41 -08001408 private VideoCallImpl mVideoCallImpl;
Hall Liu95d55872017-01-25 17:12:49 -08001409 private RttCall mRttCall;
Ihab Awade63fadb2014-07-09 21:52:04 -07001410 private Details mDetails;
Tyler Gunndee56a82016-03-23 16:06:34 -07001411 private Bundle mExtras;
Ihab Awade63fadb2014-07-09 21:52:04 -07001412
1413 /**
1414 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
1415 *
1416 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence
1417 * remaining or this {@code Call} is not in a post-dial state.
1418 */
1419 public String getRemainingPostDialSequence() {
1420 return mRemainingPostDialSequence;
1421 }
1422
1423 /**
1424 * Instructs this {@link #STATE_RINGING} {@code Call} to answer.
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001425 * @param videoState The video state in which to answer the call.
Ihab Awade63fadb2014-07-09 21:52:04 -07001426 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001427 public void answer(@VideoProfile.VideoState int videoState) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001428 mInCallAdapter.answerCall(mTelecomCallId, videoState);
Ihab Awade63fadb2014-07-09 21:52:04 -07001429 }
1430
1431 /**
Pooja Jaind34698d2017-12-28 14:15:31 +05301432 * Instructs this {@link #STATE_RINGING} {@code Call} to deflect.
1433 *
1434 * @param address The address to which the call will be deflected.
1435 */
1436 public void deflect(Uri address) {
1437 mInCallAdapter.deflectCall(mTelecomCallId, address);
1438 }
1439
1440 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001441 * Instructs this {@link #STATE_RINGING} {@code Call} to reject.
1442 *
1443 * @param rejectWithMessage Whether to reject with a text message.
1444 * @param textMessage An optional text message with which to respond.
1445 */
1446 public void reject(boolean rejectWithMessage, String textMessage) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001447 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
Ihab Awade63fadb2014-07-09 21:52:04 -07001448 }
1449
1450 /**
1451 * Instructs this {@code Call} to disconnect.
1452 */
1453 public void disconnect() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001454 mInCallAdapter.disconnectCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001455 }
1456
1457 /**
1458 * Instructs this {@code Call} to go on hold.
1459 */
1460 public void hold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001461 mInCallAdapter.holdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001462 }
1463
1464 /**
1465 * Instructs this {@link #STATE_HOLDING} call to release from hold.
1466 */
1467 public void unhold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001468 mInCallAdapter.unholdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001469 }
1470
1471 /**
1472 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
1473 *
1474 * Any other currently playing DTMF tone in the specified call is immediately stopped.
1475 *
1476 * @param digit A character representing the DTMF digit for which to play the tone. This
1477 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
1478 */
1479 public void playDtmfTone(char digit) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001480 mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
Ihab Awade63fadb2014-07-09 21:52:04 -07001481 }
1482
1483 /**
1484 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone
1485 * currently playing.
1486 *
1487 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
1488 * currently playing, this method will do nothing.
1489 */
1490 public void stopDtmfTone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001491 mInCallAdapter.stopDtmfTone(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001492 }
1493
1494 /**
1495 * Instructs this {@code Call} to continue playing a post-dial DTMF string.
1496 *
1497 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
1498 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
Ihab Awade63fadb2014-07-09 21:52:04 -07001499 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001500 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awade63fadb2014-07-09 21:52:04 -07001501 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
1502 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001503 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Leeda80c872015-04-15 14:09:50 -07001504 * {@code Call} will pause playing the tones and notify callbacks via
1505 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
Ihab Awade63fadb2014-07-09 21:52:04 -07001506 * should display to the user an indication of this state and an affordance to continue
1507 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
1508 * app should invoke the {@link #postDialContinue(boolean)} method.
1509 *
1510 * @param proceed Whether or not to continue with the post-dial sequence.
1511 */
1512 public void postDialContinue(boolean proceed) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001513 mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
Ihab Awade63fadb2014-07-09 21:52:04 -07001514 }
1515
1516 /**
Evan Charlton8c8a0622014-07-20 12:31:00 -07001517 * Notifies this {@code Call} that an account has been selected and to proceed with placing
Nancy Chen36c62f32014-10-21 18:36:39 -07001518 * an outgoing call. Optionally sets this account as the default account.
Nancy Chen5da0fd52014-07-08 14:16:17 -07001519 */
Nancy Chen36c62f32014-10-21 18:36:39 -07001520 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) {
1521 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);
Nancy Chen5da0fd52014-07-08 14:16:17 -07001522
1523 }
1524
1525 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001526 * Instructs this {@code Call} to enter a conference.
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001527 *
1528 * @param callToConferenceWith The other call with which to conference.
Ihab Awade63fadb2014-07-09 21:52:04 -07001529 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001530 public void conference(Call callToConferenceWith) {
1531 if (callToConferenceWith != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001532 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001533 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001534 }
1535
1536 /**
1537 * Instructs this {@code Call} to split from any conference call with which it may be
1538 * connected.
1539 */
1540 public void splitFromConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001541 mInCallAdapter.splitFromConference(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -07001542 }
1543
1544 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001545 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -07001546 */
1547 public void mergeConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001548 mInCallAdapter.mergeConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -07001549 }
1550
1551 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001552 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -07001553 */
1554 public void swapConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001555 mInCallAdapter.swapConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -07001556 }
1557
1558 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001559 * Initiates a request to the {@link ConnectionService} to pull an external call to the local
1560 * device.
1561 * <p>
1562 * Calls to this method are ignored if the call does not have the
1563 * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property set.
1564 * <p>
1565 * An {@link InCallService} will only see calls which support this method if it has the
1566 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
1567 * in its manifest.
1568 */
1569 public void pullExternalCall() {
1570 // If this isn't an external call, ignore the request.
1571 if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) {
1572 return;
1573 }
1574
1575 mInCallAdapter.pullExternalCall(mTelecomCallId);
1576 }
1577
1578 /**
1579 * Sends a {@code Call} event from this {@code Call} to the associated {@link Connection} in
1580 * the {@link ConnectionService}.
1581 * <p>
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001582 * Call events are used to communicate point in time information from an {@link InCallService}
1583 * to a {@link ConnectionService}. A {@link ConnectionService} implementation could define
1584 * events which enable the {@link InCallService}, for example, toggle a unique feature of the
1585 * {@link ConnectionService}.
1586 * <p>
1587 * A {@link ConnectionService} can communicate to the {@link InCallService} using
1588 * {@link Connection#sendConnectionEvent(String, Bundle)}.
1589 * <p>
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001590 * Events are exposed to {@link ConnectionService} implementations via
1591 * {@link android.telecom.Connection#onCallEvent(String, Bundle)}.
1592 * <p>
1593 * No assumptions should be made as to how a {@link ConnectionService} will handle these events.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07001594 * The {@link InCallService} must assume that the {@link ConnectionService} could chose to
1595 * ignore some events altogether.
1596 * <p>
1597 * Events should be fully qualified (e.g., {@code com.example.event.MY_EVENT}) to avoid
1598 * conflicts between {@link InCallService} implementations. Further, {@link InCallService}
1599 * implementations shall not re-purpose events in the {@code android.*} namespace, nor shall
1600 * they define their own event types in this namespace. When defining a custom event type,
1601 * ensure the contents of the extras {@link Bundle} is clearly defined. Extra keys for this
1602 * bundle should be named similar to the event type (e.g. {@code com.example.extra.MY_EXTRA}).
1603 * <p>
1604 * When defining events and the associated extras, it is important to keep their behavior
1605 * consistent when the associated {@link InCallService} is updated. Support for deprecated
1606 * events/extras should me maintained to ensure backwards compatibility with older
1607 * {@link ConnectionService} implementations which were built to support the older behavior.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001608 *
1609 * @param event The connection event.
1610 * @param extras Bundle containing extra information associated with the event.
1611 */
1612 public void sendCallEvent(String event, Bundle extras) {
Sanket Padawef6a9e5b2018-01-05 14:26:16 -08001613 mInCallAdapter.sendCallEvent(mTelecomCallId, event, mTargetSdkVersion, extras);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001614 }
1615
1616 /**
Hall Liu95d55872017-01-25 17:12:49 -08001617 * Sends an RTT upgrade request to the remote end of the connection. Success is not
1618 * guaranteed, and notification of success will be via the
1619 * {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
1620 */
1621 public void sendRttRequest() {
Hall Liu57006aa2017-02-06 10:49:48 -08001622 mInCallAdapter.sendRttRequest(mTelecomCallId);
Hall Liu95d55872017-01-25 17:12:49 -08001623 }
1624
1625 /**
1626 * Responds to an RTT request received via the {@link Callback#onRttRequest(Call, int)} )}
1627 * callback.
1628 * The ID used here should be the same as the ID that was received via the callback.
1629 * @param id The request ID received via {@link Callback#onRttRequest(Call, int)}
1630 * @param accept {@code true} if the RTT request should be accepted, {@code false} otherwise.
1631 */
1632 public void respondToRttRequest(int id, boolean accept) {
Hall Liu57006aa2017-02-06 10:49:48 -08001633 mInCallAdapter.respondToRttRequest(mTelecomCallId, id, accept);
Hall Liu95d55872017-01-25 17:12:49 -08001634 }
1635
1636 /**
Sanket Padawea8eddd42017-11-03 11:07:35 -07001637 * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified
1638 * by {@code toHandle}. The videoState specified indicates the desired video state after the
1639 * handover.
1640 * <p>
Tyler Gunn9d127732018-03-02 15:45:51 -08001641 * A call handover is the process where an ongoing call is transferred from one app (i.e.
1642 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
1643 * mobile network call in a video calling app. The mobile network call via the Telephony stack
1644 * is referred to as the source of the handover, and the video calling app is referred to as the
1645 * destination.
1646 * <p>
1647 * When considering a handover scenario the device this method is called on is considered the
1648 * <em>initiating</em> device (since the user initiates the handover from this device), and the
1649 * other device is considered the <em>receiving</em> device.
1650 * <p>
1651 * When this method is called on the <em>initiating</em> device, the Telecom framework will bind
1652 * to the {@link ConnectionService} defined by the {@code toHandle} {@link PhoneAccountHandle}
1653 * and invoke
1654 * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
1655 * ConnectionRequest)} to inform the destination app that a request has been made to handover a
1656 * call to it. The app returns an instance of {@link Connection} to represent the handover call
1657 * At this point the app should display UI to indicate to the user that a call
1658 * handover is in process.
1659 * <p>
1660 * The destination app is responsible for communicating the handover request from the
1661 * <em>initiating</em> device to the <em>receiving</em> device.
1662 * <p>
1663 * When the app on the <em>receiving</em> device receives the handover request, it calls
1664 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to continue the handover
1665 * process from the <em>initiating</em> device to the <em>receiving</em> device. At this point
1666 * the destination app on the <em>receiving</em> device should show UI to allow the user to
1667 * choose whether they want to continue their call in the destination app.
1668 * <p>
1669 * When the destination app on the <em>receiving</em> device calls
1670 * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)}, Telecom will bind to its
1671 * {@link ConnectionService} and call
1672 * {@link ConnectionService#onCreateIncomingHandoverConnection(PhoneAccountHandle,
1673 * ConnectionRequest)} to inform it of the handover request. The app returns an instance of
1674 * {@link Connection} to represent the handover call.
1675 * <p>
1676 * If the user of the <em>receiving</em> device accepts the handover, the app calls
1677 * {@link Connection#setActive()} to complete the handover process; Telecom will disconnect the
1678 * original call. If the user rejects the handover, the app calls
1679 * {@link Connection#setDisconnected(DisconnectCause)} and specifies a {@link DisconnectCause}
1680 * of {@link DisconnectCause#CANCELED} to indicate that the handover has been cancelled.
1681 * <p>
1682 * Telecom will only allow handovers from {@link PhoneAccount}s which declare
1683 * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}. Similarly, the {@link PhoneAccount}
1684 * specified by {@code toHandle} must declare {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}.
1685 * <p>
1686 * Errors in the handover process are reported to the {@link InCallService} via
1687 * {@link Callback#onHandoverFailed(Call, int)}. Errors in the handover process are reported to
1688 * the involved {@link ConnectionService}s via
1689 * {@link ConnectionService#onHandoverFailed(ConnectionRequest, int)}.
Sanket Padawea8eddd42017-11-03 11:07:35 -07001690 *
1691 * @param toHandle {@link PhoneAccountHandle} of the {@link ConnectionService} to handover
1692 * this call to.
Tyler Gunn9d127732018-03-02 15:45:51 -08001693 * @param videoState Indicates the video state desired after the handover (see the
1694 * {@code STATE_*} constants defined in {@link VideoProfile}).
Sanket Padawea8eddd42017-11-03 11:07:35 -07001695 * @param extras Bundle containing extra information to be passed to the
1696 * {@link ConnectionService}
1697 */
Tyler Gunn9d127732018-03-02 15:45:51 -08001698 public void handoverTo(PhoneAccountHandle toHandle, @VideoProfile.VideoState int videoState,
1699 Bundle extras) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07001700 mInCallAdapter.handoverTo(mTelecomCallId, toHandle, videoState, extras);
1701 }
1702
1703 /**
Hall Liu95d55872017-01-25 17:12:49 -08001704 * Terminate the RTT session on this call. The resulting state change will be notified via
1705 * the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
1706 */
1707 public void stopRtt() {
Hall Liu57006aa2017-02-06 10:49:48 -08001708 mInCallAdapter.stopRtt(mTelecomCallId);
Hall Liu95d55872017-01-25 17:12:49 -08001709 }
1710
1711 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07001712 * Adds some extras to this {@link Call}. Existing keys are replaced and new ones are
1713 * added.
1714 * <p>
1715 * No assumptions should be made as to how an In-Call UI or service will handle these
1716 * extras. Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
1717 *
1718 * @param extras The extras to add.
1719 */
1720 public final void putExtras(Bundle extras) {
1721 if (extras == null) {
1722 return;
1723 }
1724
1725 if (mExtras == null) {
1726 mExtras = new Bundle();
1727 }
1728 mExtras.putAll(extras);
1729 mInCallAdapter.putExtras(mTelecomCallId, extras);
1730 }
1731
1732 /**
1733 * Adds a boolean extra to this {@link Call}.
1734 *
1735 * @param key The extra key.
1736 * @param value The value.
1737 * @hide
1738 */
1739 public final void putExtra(String key, boolean value) {
1740 if (mExtras == null) {
1741 mExtras = new Bundle();
1742 }
1743 mExtras.putBoolean(key, value);
1744 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1745 }
1746
1747 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001748 * Adds an integer extra to this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001749 *
1750 * @param key The extra key.
1751 * @param value The value.
1752 * @hide
1753 */
1754 public final void putExtra(String key, int value) {
1755 if (mExtras == null) {
1756 mExtras = new Bundle();
1757 }
1758 mExtras.putInt(key, value);
1759 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1760 }
1761
1762 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001763 * Adds a string extra to this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001764 *
1765 * @param key The extra key.
1766 * @param value The value.
1767 * @hide
1768 */
1769 public final void putExtra(String key, String value) {
1770 if (mExtras == null) {
1771 mExtras = new Bundle();
1772 }
1773 mExtras.putString(key, value);
1774 mInCallAdapter.putExtra(mTelecomCallId, key, value);
1775 }
1776
1777 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001778 * Removes extras from this {@link Call}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001779 *
1780 * @param keys The keys of the extras to remove.
1781 */
1782 public final void removeExtras(List<String> keys) {
1783 if (mExtras != null) {
1784 for (String key : keys) {
1785 mExtras.remove(key);
1786 }
1787 if (mExtras.size() == 0) {
1788 mExtras = null;
1789 }
1790 }
1791 mInCallAdapter.removeExtras(mTelecomCallId, keys);
1792 }
1793
1794 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07001795 * Removes extras from this {@link Call}.
1796 *
1797 * @param keys The keys of the extras to remove.
1798 */
1799 public final void removeExtras(String ... keys) {
1800 removeExtras(Arrays.asList(keys));
1801 }
1802
1803 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001804 * Obtains the parent of this {@code Call} in a conference, if any.
1805 *
1806 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
1807 * child of any conference {@code Call}s.
1808 */
1809 public Call getParent() {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001810 if (mParentId != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001811 return mPhone.internalGetCallByTelecomId(mParentId);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001812 }
1813 return null;
Ihab Awade63fadb2014-07-09 21:52:04 -07001814 }
1815
1816 /**
1817 * Obtains the children of this conference {@code Call}, if any.
1818 *
1819 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty
1820 * {@code List} otherwise.
1821 */
1822 public List<Call> getChildren() {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001823 if (!mChildrenCached) {
1824 mChildrenCached = true;
1825 mChildren.clear();
1826
1827 for(String id : mChildrenIds) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001828 Call call = mPhone.internalGetCallByTelecomId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001829 if (call == null) {
1830 // At least one child was still not found, so do not save true for "cached"
1831 mChildrenCached = false;
1832 } else {
1833 mChildren.add(call);
1834 }
1835 }
1836 }
1837
Ihab Awade63fadb2014-07-09 21:52:04 -07001838 return mUnmodifiableChildren;
1839 }
1840
1841 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001842 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
1843 *
1844 * @return The list of conferenceable {@code Call}s.
1845 */
1846 public List<Call> getConferenceableCalls() {
1847 return mUnmodifiableConferenceableCalls;
1848 }
1849
1850 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001851 * Obtains the state of this {@code Call}.
1852 *
1853 * @return A state value, chosen from the {@code STATE_*} constants.
1854 */
1855 public int getState() {
1856 return mState;
1857 }
1858
1859 /**
1860 * Obtains a list of canned, pre-configured message responses to present to the user as
1861 * ways of rejecting this {@code Call} using via a text message.
1862 *
1863 * @see #reject(boolean, String)
1864 *
1865 * @return A list of canned text message responses.
1866 */
1867 public List<String> getCannedTextResponses() {
1868 return mCannedTextResponses;
1869 }
1870
1871 /**
1872 * Obtains an object that can be used to display video from this {@code Call}.
1873 *
Andrew Lee50aca232014-07-22 16:41:54 -07001874 * @return An {@code Call.VideoCall}.
Ihab Awade63fadb2014-07-09 21:52:04 -07001875 */
Andrew Lee50aca232014-07-22 16:41:54 -07001876 public InCallService.VideoCall getVideoCall() {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08001877 return mVideoCallImpl;
Ihab Awade63fadb2014-07-09 21:52:04 -07001878 }
1879
1880 /**
1881 * Obtains an object containing call details.
1882 *
1883 * @return A {@link Details} object. Depending on the state of the {@code Call}, the
1884 * result may be {@code null}.
1885 */
1886 public Details getDetails() {
1887 return mDetails;
1888 }
1889
1890 /**
Hall Liu95d55872017-01-25 17:12:49 -08001891 * Returns this call's RttCall object. The {@link RttCall} instance is used to send and
1892 * receive RTT text data, as well as to change the RTT mode.
1893 * @return A {@link Call.RttCall}. {@code null} if there is no active RTT connection.
1894 */
1895 public @Nullable RttCall getRttCall() {
1896 return mRttCall;
1897 }
1898
1899 /**
1900 * Returns whether this call has an active RTT connection.
1901 * @return true if there is a connection, false otherwise.
1902 */
1903 public boolean isRttActive() {
Hall Liue9041242018-02-09 16:40:03 -08001904 return mRttCall != null && mDetails.hasProperty(Details.PROPERTY_RTT);
Hall Liu95d55872017-01-25 17:12:49 -08001905 }
1906
1907 /**
Andrew Leeda80c872015-04-15 14:09:50 -07001908 * Registers a callback to this {@code Call}.
1909 *
1910 * @param callback A {@code Callback}.
1911 */
1912 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -07001913 registerCallback(callback, new Handler());
1914 }
1915
1916 /**
1917 * Registers a callback to this {@code Call}.
1918 *
1919 * @param callback A {@code Callback}.
1920 * @param handler A handler which command and status changes will be delivered to.
1921 */
1922 public void registerCallback(Callback callback, Handler handler) {
1923 unregisterCallback(callback);
Roshan Pius1ca62072015-07-07 17:34:51 -07001924 // Don't allow new callback registration if the call is already being destroyed.
1925 if (callback != null && handler != null && mState != STATE_DISCONNECTED) {
Andrew Lee011728f2015-04-23 15:47:06 -07001926 mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler));
1927 }
Andrew Leeda80c872015-04-15 14:09:50 -07001928 }
1929
1930 /**
1931 * Unregisters a callback from this {@code Call}.
1932 *
1933 * @param callback A {@code Callback}.
1934 */
1935 public void unregisterCallback(Callback callback) {
Roshan Pius1ca62072015-07-07 17:34:51 -07001936 // Don't allow callback deregistration if the call is already being destroyed.
1937 if (callback != null && mState != STATE_DISCONNECTED) {
Andrew Lee011728f2015-04-23 15:47:06 -07001938 for (CallbackRecord<Callback> record : mCallbackRecords) {
1939 if (record.getCallback() == callback) {
1940 mCallbackRecords.remove(record);
1941 break;
1942 }
1943 }
Andrew Leeda80c872015-04-15 14:09:50 -07001944 }
1945 }
1946
Santos Cordon3c20d632016-02-25 16:12:35 -08001947 @Override
1948 public String toString() {
1949 return new StringBuilder().
1950 append("Call [id: ").
1951 append(mTelecomCallId).
1952 append(", state: ").
1953 append(stateToString(mState)).
1954 append(", details: ").
1955 append(mDetails).
1956 append("]").toString();
1957 }
1958
1959 /**
1960 * @param state An integer value of a {@code STATE_*} constant.
1961 * @return A string representation of the value.
1962 */
1963 private static String stateToString(int state) {
1964 switch (state) {
1965 case STATE_NEW:
1966 return "NEW";
1967 case STATE_RINGING:
1968 return "RINGING";
1969 case STATE_DIALING:
1970 return "DIALING";
1971 case STATE_ACTIVE:
1972 return "ACTIVE";
1973 case STATE_HOLDING:
1974 return "HOLDING";
1975 case STATE_DISCONNECTED:
1976 return "DISCONNECTED";
1977 case STATE_CONNECTING:
1978 return "CONNECTING";
1979 case STATE_DISCONNECTING:
1980 return "DISCONNECTING";
1981 case STATE_SELECT_PHONE_ACCOUNT:
1982 return "SELECT_PHONE_ACCOUNT";
1983 default:
1984 Log.w(Call.class, "Unknown state %d", state);
1985 return "UNKNOWN";
1986 }
1987 }
1988
Andrew Leeda80c872015-04-15 14:09:50 -07001989 /**
Ihab Awade63fadb2014-07-09 21:52:04 -07001990 * Adds a listener to this {@code Call}.
1991 *
1992 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -07001993 * @deprecated Use {@link #registerCallback} instead.
1994 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -07001995 */
Andrew Leeda80c872015-04-15 14:09:50 -07001996 @Deprecated
1997 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -07001998 public void addListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -07001999 registerCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -07002000 }
2001
2002 /**
2003 * Removes a listener from this {@code Call}.
2004 *
2005 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -07002006 * @deprecated Use {@link #unregisterCallback} instead.
2007 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -07002008 */
Andrew Leeda80c872015-04-15 14:09:50 -07002009 @Deprecated
2010 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -07002011 public void removeListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -07002012 unregisterCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -07002013 }
2014
2015 /** {@hide} */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002016 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage,
2017 int targetSdkVersion) {
Ihab Awade63fadb2014-07-09 21:52:04 -07002018 mPhone = phone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002019 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002020 mInCallAdapter = inCallAdapter;
2021 mState = STATE_NEW;
Tyler Gunnb88b3112016-11-09 10:19:23 -08002022 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08002023 mTargetSdkVersion = targetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -07002024 }
2025
2026 /** {@hide} */
Tyler Gunnb88b3112016-11-09 10:19:23 -08002027 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state,
Tyler Gunn159f35c2017-03-02 09:28:37 -08002028 String callingPackage, int targetSdkVersion) {
Shriram Ganeshddf570e2015-05-31 09:18:48 -07002029 mPhone = phone;
2030 mTelecomCallId = telecomCallId;
2031 mInCallAdapter = inCallAdapter;
2032 mState = state;
Tyler Gunnb88b3112016-11-09 10:19:23 -08002033 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -08002034 mTargetSdkVersion = targetSdkVersion;
Shriram Ganeshddf570e2015-05-31 09:18:48 -07002035 }
2036
2037 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07002038 final String internalGetCallId() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002039 return mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002040 }
2041
2042 /** {@hide} */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002043 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
Tyler Gunnb88b3112016-11-09 10:19:23 -08002044
Ihab Awade63fadb2014-07-09 21:52:04 -07002045 // First, we update the internal state as far as possible before firing any updates.
Sailesh Nepal1bef3392016-01-24 18:21:53 -08002046 Details details = Details.createFromParcelableCall(parcelableCall);
Ihab Awade63fadb2014-07-09 21:52:04 -07002047 boolean detailsChanged = !Objects.equals(mDetails, details);
2048 if (detailsChanged) {
2049 mDetails = details;
2050 }
2051
2052 boolean cannedTextResponsesChanged = false;
Santos Cordon88b771d2014-07-19 13:10:40 -07002053 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
2054 && !parcelableCall.getCannedSmsResponses().isEmpty()) {
2055 mCannedTextResponses =
2056 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
Yorke Leee886f632015-08-04 13:43:31 -07002057 cannedTextResponsesChanged = true;
Ihab Awade63fadb2014-07-09 21:52:04 -07002058 }
2059
Tyler Gunn159f35c2017-03-02 09:28:37 -08002060 VideoCallImpl newVideoCallImpl = parcelableCall.getVideoCallImpl(mCallingPackage,
2061 mTargetSdkVersion);
Tyler Gunn75958422015-04-15 14:23:42 -07002062 boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002063 !Objects.equals(mVideoCallImpl, newVideoCallImpl);
Andrew Lee50aca232014-07-22 16:41:54 -07002064 if (videoCallChanged) {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002065 mVideoCallImpl = newVideoCallImpl;
2066 }
2067 if (mVideoCallImpl != null) {
2068 mVideoCallImpl.setVideoState(getDetails().getVideoState());
Ihab Awade63fadb2014-07-09 21:52:04 -07002069 }
2070
Santos Cordone3c507b2015-04-23 14:44:19 -07002071 int state = parcelableCall.getState();
Ihab Awade63fadb2014-07-09 21:52:04 -07002072 boolean stateChanged = mState != state;
2073 if (stateChanged) {
2074 mState = state;
2075 }
2076
Santos Cordon823fd3c2014-08-07 18:35:18 -07002077 String parentId = parcelableCall.getParentCallId();
2078 boolean parentChanged = !Objects.equals(mParentId, parentId);
2079 if (parentChanged) {
2080 mParentId = parentId;
Ihab Awade63fadb2014-07-09 21:52:04 -07002081 }
2082
Santos Cordon823fd3c2014-08-07 18:35:18 -07002083 List<String> childCallIds = parcelableCall.getChildCallIds();
2084 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
2085 if (childrenChanged) {
2086 mChildrenIds.clear();
2087 mChildrenIds.addAll(parcelableCall.getChildCallIds());
2088 mChildrenCached = false;
Ihab Awade63fadb2014-07-09 21:52:04 -07002089 }
2090
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002091 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
2092 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
2093 for (String otherId : conferenceableCallIds) {
2094 if (callIdMap.containsKey(otherId)) {
2095 conferenceableCalls.add(callIdMap.get(otherId));
2096 }
2097 }
2098
2099 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
2100 mConferenceableCalls.clear();
2101 mConferenceableCalls.addAll(conferenceableCalls);
2102 fireConferenceableCallsChanged();
2103 }
2104
Hall Liu95d55872017-01-25 17:12:49 -08002105 boolean isRttChanged = false;
2106 boolean rttModeChanged = false;
Hall Liue9041242018-02-09 16:40:03 -08002107 if (parcelableCall.getIsRttCallChanged()
2108 && mDetails.hasProperty(Details.PROPERTY_RTT)) {
Hall Liu95d55872017-01-25 17:12:49 -08002109 ParcelableRttCall parcelableRttCall = parcelableCall.getParcelableRttCall();
2110 InputStreamReader receiveStream = new InputStreamReader(
2111 new ParcelFileDescriptor.AutoCloseInputStream(
2112 parcelableRttCall.getReceiveStream()),
2113 StandardCharsets.UTF_8);
2114 OutputStreamWriter transmitStream = new OutputStreamWriter(
2115 new ParcelFileDescriptor.AutoCloseOutputStream(
2116 parcelableRttCall.getTransmitStream()),
2117 StandardCharsets.UTF_8);
Hall Liu57006aa2017-02-06 10:49:48 -08002118 RttCall newRttCall = new Call.RttCall(mTelecomCallId,
Hall Liu95d55872017-01-25 17:12:49 -08002119 receiveStream, transmitStream, parcelableRttCall.getRttMode(), mInCallAdapter);
2120 if (mRttCall == null) {
2121 isRttChanged = true;
2122 } else if (mRttCall.getRttAudioMode() != newRttCall.getRttAudioMode()) {
2123 rttModeChanged = true;
2124 }
2125 mRttCall = newRttCall;
2126 } else if (mRttCall != null && parcelableCall.getParcelableRttCall() == null
2127 && parcelableCall.getIsRttCallChanged()) {
2128 isRttChanged = true;
2129 mRttCall = null;
2130 }
2131
Ihab Awade63fadb2014-07-09 21:52:04 -07002132 // Now we fire updates, ensuring that any client who listens to any of these notifications
2133 // gets the most up-to-date state.
2134
2135 if (stateChanged) {
2136 fireStateChanged(mState);
2137 }
2138 if (detailsChanged) {
2139 fireDetailsChanged(mDetails);
2140 }
2141 if (cannedTextResponsesChanged) {
2142 fireCannedTextResponsesLoaded(mCannedTextResponses);
2143 }
Andrew Lee50aca232014-07-22 16:41:54 -07002144 if (videoCallChanged) {
Tyler Gunn584ba6c2015-12-08 10:53:41 -08002145 fireVideoCallChanged(mVideoCallImpl);
Ihab Awade63fadb2014-07-09 21:52:04 -07002146 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002147 if (parentChanged) {
2148 fireParentChanged(getParent());
2149 }
2150 if (childrenChanged) {
2151 fireChildrenChanged(getChildren());
2152 }
Hall Liu95d55872017-01-25 17:12:49 -08002153 if (isRttChanged) {
2154 fireOnIsRttChanged(mRttCall != null, mRttCall);
2155 }
2156 if (rttModeChanged) {
2157 fireOnRttModeChanged(mRttCall.getRttAudioMode());
2158 }
Ihab Awade63fadb2014-07-09 21:52:04 -07002159
2160 // If we have transitioned to DISCONNECTED, that means we need to notify clients and
2161 // remove ourselves from the Phone. Note that we do this after completing all state updates
2162 // so a client can cleanly transition all their UI to the state appropriate for a
2163 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
2164 if (mState == STATE_DISCONNECTED) {
2165 fireCallDestroyed();
Ihab Awade63fadb2014-07-09 21:52:04 -07002166 }
2167 }
2168
2169 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07002170 final void internalSetPostDialWait(String remaining) {
2171 mRemainingPostDialSequence = remaining;
2172 firePostDialWait(mRemainingPostDialSequence);
2173 }
2174
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07002175 /** {@hide} */
Santos Cordonf30d7e92014-08-26 09:54:33 -07002176 final void internalSetDisconnected() {
2177 if (mState != Call.STATE_DISCONNECTED) {
2178 mState = Call.STATE_DISCONNECTED;
2179 fireStateChanged(mState);
2180 fireCallDestroyed();
Santos Cordonf30d7e92014-08-26 09:54:33 -07002181 }
2182 }
2183
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002184 /** {@hide} */
2185 final void internalOnConnectionEvent(String event, Bundle extras) {
2186 fireOnConnectionEvent(event, extras);
2187 }
2188
Hall Liu95d55872017-01-25 17:12:49 -08002189 /** {@hide} */
2190 final void internalOnRttUpgradeRequest(final int requestId) {
2191 for (CallbackRecord<Callback> record : mCallbackRecords) {
2192 final Call call = this;
2193 final Callback callback = record.getCallback();
2194 record.getHandler().post(() -> callback.onRttRequest(call, requestId));
2195 }
2196 }
2197
Hall Liu57006aa2017-02-06 10:49:48 -08002198 /** @hide */
2199 final void internalOnRttInitiationFailure(int reason) {
2200 for (CallbackRecord<Callback> record : mCallbackRecords) {
2201 final Call call = this;
2202 final Callback callback = record.getCallback();
2203 record.getHandler().post(() -> callback.onRttInitiationFailure(call, reason));
2204 }
2205 }
2206
Sanket Padawe85291f62017-12-01 13:59:27 -08002207 /** {@hide} */
2208 final void internalOnHandoverFailed(int error) {
2209 for (CallbackRecord<Callback> record : mCallbackRecords) {
2210 final Call call = this;
2211 final Callback callback = record.getCallback();
2212 record.getHandler().post(() -> callback.onHandoverFailed(call, error));
2213 }
2214 }
2215
Tyler Gunn858bfaf2018-01-22 15:17:54 -08002216 /** {@hide} */
2217 final void internalOnHandoverComplete() {
2218 for (CallbackRecord<Callback> record : mCallbackRecords) {
2219 final Call call = this;
2220 final Callback callback = record.getCallback();
2221 record.getHandler().post(() -> callback.onHandoverComplete(call));
2222 }
2223 }
2224
Andrew Lee011728f2015-04-23 15:47:06 -07002225 private void fireStateChanged(final int newState) {
2226 for (CallbackRecord<Callback> record : mCallbackRecords) {
2227 final Call call = this;
2228 final Callback callback = record.getCallback();
2229 record.getHandler().post(new Runnable() {
2230 @Override
2231 public void run() {
2232 callback.onStateChanged(call, newState);
2233 }
2234 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002235 }
2236 }
2237
Andrew Lee011728f2015-04-23 15:47:06 -07002238 private void fireParentChanged(final Call newParent) {
2239 for (CallbackRecord<Callback> record : mCallbackRecords) {
2240 final Call call = this;
2241 final Callback callback = record.getCallback();
2242 record.getHandler().post(new Runnable() {
2243 @Override
2244 public void run() {
2245 callback.onParentChanged(call, newParent);
2246 }
2247 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002248 }
2249 }
2250
Andrew Lee011728f2015-04-23 15:47:06 -07002251 private void fireChildrenChanged(final List<Call> children) {
2252 for (CallbackRecord<Callback> record : mCallbackRecords) {
2253 final Call call = this;
2254 final Callback callback = record.getCallback();
2255 record.getHandler().post(new Runnable() {
2256 @Override
2257 public void run() {
2258 callback.onChildrenChanged(call, children);
2259 }
2260 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002261 }
2262 }
2263
Andrew Lee011728f2015-04-23 15:47:06 -07002264 private void fireDetailsChanged(final Details details) {
2265 for (CallbackRecord<Callback> record : mCallbackRecords) {
2266 final Call call = this;
2267 final Callback callback = record.getCallback();
2268 record.getHandler().post(new Runnable() {
2269 @Override
2270 public void run() {
2271 callback.onDetailsChanged(call, details);
2272 }
2273 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002274 }
2275 }
2276
Andrew Lee011728f2015-04-23 15:47:06 -07002277 private void fireCannedTextResponsesLoaded(final List<String> cannedTextResponses) {
2278 for (CallbackRecord<Callback> record : mCallbackRecords) {
2279 final Call call = this;
2280 final Callback callback = record.getCallback();
2281 record.getHandler().post(new Runnable() {
2282 @Override
2283 public void run() {
2284 callback.onCannedTextResponsesLoaded(call, cannedTextResponses);
2285 }
2286 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002287 }
2288 }
2289
Andrew Lee011728f2015-04-23 15:47:06 -07002290 private void fireVideoCallChanged(final InCallService.VideoCall videoCall) {
2291 for (CallbackRecord<Callback> record : mCallbackRecords) {
2292 final Call call = this;
2293 final Callback callback = record.getCallback();
2294 record.getHandler().post(new Runnable() {
2295 @Override
2296 public void run() {
2297 callback.onVideoCallChanged(call, videoCall);
2298 }
2299 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002300 }
2301 }
2302
Andrew Lee011728f2015-04-23 15:47:06 -07002303 private void firePostDialWait(final String remainingPostDialSequence) {
2304 for (CallbackRecord<Callback> record : mCallbackRecords) {
2305 final Call call = this;
2306 final Callback callback = record.getCallback();
2307 record.getHandler().post(new Runnable() {
2308 @Override
2309 public void run() {
2310 callback.onPostDialWait(call, remainingPostDialSequence);
2311 }
2312 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002313 }
2314 }
2315
2316 private void fireCallDestroyed() {
Roshan Pius1ca62072015-07-07 17:34:51 -07002317 /**
2318 * To preserve the ordering of the Call's onCallDestroyed callback and Phone's
2319 * onCallRemoved callback, we remove this call from the Phone's record
2320 * only once all of the registered onCallDestroyed callbacks are executed.
2321 * All the callbacks get removed from our records as a part of this operation
2322 * since onCallDestroyed is the final callback.
2323 */
2324 final Call call = this;
2325 if (mCallbackRecords.isEmpty()) {
2326 // No callbacks registered, remove the call from Phone's record.
2327 mPhone.internalRemoveCall(call);
2328 }
2329 for (final CallbackRecord<Callback> record : mCallbackRecords) {
Andrew Lee011728f2015-04-23 15:47:06 -07002330 final Callback callback = record.getCallback();
2331 record.getHandler().post(new Runnable() {
2332 @Override
2333 public void run() {
Roshan Pius1ca62072015-07-07 17:34:51 -07002334 boolean isFinalRemoval = false;
2335 RuntimeException toThrow = null;
2336 try {
2337 callback.onCallDestroyed(call);
2338 } catch (RuntimeException e) {
2339 toThrow = e;
2340 }
2341 synchronized(Call.this) {
2342 mCallbackRecords.remove(record);
2343 if (mCallbackRecords.isEmpty()) {
2344 isFinalRemoval = true;
2345 }
2346 }
2347 if (isFinalRemoval) {
2348 mPhone.internalRemoveCall(call);
2349 }
2350 if (toThrow != null) {
2351 throw toThrow;
2352 }
Andrew Lee011728f2015-04-23 15:47:06 -07002353 }
2354 });
Ihab Awade63fadb2014-07-09 21:52:04 -07002355 }
2356 }
2357
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002358 private void fireConferenceableCallsChanged() {
Andrew Lee011728f2015-04-23 15:47:06 -07002359 for (CallbackRecord<Callback> record : mCallbackRecords) {
2360 final Call call = this;
2361 final Callback callback = record.getCallback();
2362 record.getHandler().post(new Runnable() {
2363 @Override
2364 public void run() {
2365 callback.onConferenceableCallsChanged(call, mUnmodifiableConferenceableCalls);
2366 }
2367 });
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002368 }
2369 }
Tyler Gunn1e9bfc62015-08-19 11:18:58 -07002370
2371 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002372 * Notifies listeners of an incoming connection event.
2373 * <p>
2374 * Connection events are issued via {@link Connection#sendConnectionEvent(String, Bundle)}.
2375 *
2376 * @param event
2377 * @param extras
2378 */
2379 private void fireOnConnectionEvent(final String event, final Bundle extras) {
2380 for (CallbackRecord<Callback> record : mCallbackRecords) {
2381 final Call call = this;
2382 final Callback callback = record.getCallback();
2383 record.getHandler().post(new Runnable() {
2384 @Override
2385 public void run() {
2386 callback.onConnectionEvent(call, event, extras);
2387 }
2388 });
2389 }
2390 }
2391
2392 /**
Hall Liu95d55872017-01-25 17:12:49 -08002393 * Notifies listeners of an RTT on/off change
2394 *
2395 * @param enabled True if RTT is now enabled, false otherwise
2396 */
2397 private void fireOnIsRttChanged(final boolean enabled, final RttCall rttCall) {
2398 for (CallbackRecord<Callback> record : mCallbackRecords) {
2399 final Call call = this;
2400 final Callback callback = record.getCallback();
2401 record.getHandler().post(() -> callback.onRttStatusChanged(call, enabled, rttCall));
2402 }
2403 }
2404
2405 /**
2406 * Notifies listeners of a RTT mode change
2407 *
2408 * @param mode The new RTT mode
2409 */
2410 private void fireOnRttModeChanged(final int mode) {
2411 for (CallbackRecord<Callback> record : mCallbackRecords) {
2412 final Call call = this;
2413 final Callback callback = record.getCallback();
2414 record.getHandler().post(() -> callback.onRttModeChanged(call, mode));
2415 }
2416 }
2417
2418 /**
Tyler Gunn1e9bfc62015-08-19 11:18:58 -07002419 * Determines if two bundles are equal.
2420 *
2421 * @param bundle The original bundle.
2422 * @param newBundle The bundle to compare with.
2423 * @retrun {@code true} if the bundles are equal, {@code false} otherwise.
2424 */
2425 private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) {
2426 if (bundle == null || newBundle == null) {
2427 return bundle == newBundle;
2428 }
2429
2430 if (bundle.size() != newBundle.size()) {
2431 return false;
2432 }
2433
2434 for(String key : bundle.keySet()) {
2435 if (key != null) {
2436 final Object value = bundle.get(key);
2437 final Object newValue = newBundle.get(key);
2438 if (!Objects.equals(value, newValue)) {
2439 return false;
2440 }
2441 }
2442 }
2443 return true;
2444 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002445}