blob: d92c0c7d0ba1c461c3acc70db54a481be199ccb8 [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
Andrew Leeda80c872015-04-15 14:09:50 -070019import android.annotation.SystemApi;
Ihab Awade63fadb2014-07-09 21:52:04 -070020import android.net.Uri;
Nancy Chen10798dc2014-08-08 14:00:25 -070021import android.os.Bundle;
Ihab Awade63fadb2014-07-09 21:52:04 -070022
Andrew Lee50aca232014-07-22 16:41:54 -070023import java.lang.String;
Ihab Awade63fadb2014-07-09 21:52:04 -070024import java.util.ArrayList;
25import java.util.Collections;
26import java.util.List;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070027import java.util.Map;
Ihab Awade63fadb2014-07-09 21:52:04 -070028import java.util.Objects;
Jay Shrauner229e3822014-08-15 09:23:07 -070029import java.util.concurrent.CopyOnWriteArrayList;
Ihab Awade63fadb2014-07-09 21:52:04 -070030
31/**
32 * Represents an ongoing phone call that the in-call app should present to the user.
33 */
34public final class Call {
35 /**
36 * The state of a {@code Call} when newly created.
37 */
38 public static final int STATE_NEW = 0;
39
40 /**
41 * The state of an outgoing {@code Call} when dialing the remote number, but not yet connected.
42 */
43 public static final int STATE_DIALING = 1;
44
45 /**
46 * The state of an incoming {@code Call} when ringing locally, but not yet connected.
47 */
48 public static final int STATE_RINGING = 2;
49
50 /**
51 * The state of a {@code Call} when in a holding state.
52 */
53 public static final int STATE_HOLDING = 3;
54
55 /**
56 * The state of a {@code Call} when actively supporting conversation.
57 */
58 public static final int STATE_ACTIVE = 4;
59
60 /**
61 * The state of a {@code Call} when no further voice or other communication is being
62 * transmitted, the remote side has been or will inevitably be informed that the {@code Call}
63 * is no longer active, and the local data transport has or inevitably will release resources
64 * associated with this {@code Call}.
65 */
66 public static final int STATE_DISCONNECTED = 7;
67
Nancy Chen5da0fd52014-07-08 14:16:17 -070068 /**
Santos Cordone3c507b2015-04-23 14:44:19 -070069 * The state of an outgoing {@code Call} when waiting on user to select a
70 * {@link PhoneAccount} through which to place the call.
Nancy Chen5da0fd52014-07-08 14:16:17 -070071 */
Santos Cordone3c507b2015-04-23 14:44:19 -070072 public static final int STATE_SELECT_PHONE_ACCOUNT = 8;
73
74 /**
75 * @hide
76 * @deprecated use STATE_SELECT_PHONE_ACCOUNT.
77 */
78 @Deprecated
79 @SystemApi
80 public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT;
Nancy Chen5da0fd52014-07-08 14:16:17 -070081
Nancy Chene20930f2014-08-07 16:17:21 -070082 /**
Nancy Chene9b7a8e2014-08-08 14:26:27 -070083 * The initial state of an outgoing {@code Call}.
84 * Common transitions are to {@link #STATE_DIALING} state for a successful call or
85 * {@link #STATE_DISCONNECTED} if it failed.
Nancy Chene20930f2014-08-07 16:17:21 -070086 */
87 public static final int STATE_CONNECTING = 9;
88
Nancy Chen513c8922014-09-17 14:47:20 -070089 /**
Tyler Gunn4afc6af2014-10-07 10:14:55 -070090 * The state of a {@code Call} when the user has initiated a disconnection of the call, but the
91 * call has not yet been disconnected by the underlying {@code ConnectionService}. The next
92 * state of the call is (potentially) {@link #STATE_DISCONNECTED}.
93 */
94 public static final int STATE_DISCONNECTING = 10;
95
96 /**
Nancy Chen513c8922014-09-17 14:47:20 -070097 * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
98 * extras. Used to pass the phone accounts to display on the front end to the user in order to
99 * select phone accounts to (for example) place a call.
Nancy Chen513c8922014-09-17 14:47:20 -0700100 */
101 public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
102
Ihab Awade63fadb2014-07-09 21:52:04 -0700103 public static class Details {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800104
105 /** Call can currently be put on hold or unheld. */
106 public static final int CAPABILITY_HOLD = 0x00000001;
107
108 /** Call supports the hold feature. */
109 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
110
111 /**
112 * Calls within a conference can be merged. A {@link ConnectionService} has the option to
113 * add a {@link Conference} call before the child {@link Connection}s are merged. This is how
114 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
115 * capability allows a merge button to be shown while the conference call is in the foreground
116 * of the in-call UI.
117 * <p>
118 * This is only intended for use by a {@link Conference}.
119 */
120 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
121
122 /**
123 * Calls within a conference can be swapped between foreground and background.
124 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
125 * <p>
126 * This is only intended for use by a {@link Conference}.
127 */
128 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
129
130 /**
131 * @hide
132 */
133 public static final int CAPABILITY_UNUSED = 0x00000010;
134
135 /** Call supports responding via text option. */
136 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
137
138 /** Call can be muted. */
139 public static final int CAPABILITY_MUTE = 0x00000040;
140
141 /**
142 * Call supports conference call management. This capability only applies to {@link Conference}
143 * calls which can have {@link Connection}s as children.
144 */
145 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
146
147 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700148 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800149 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700150 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800151
152 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700153 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800154 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700155 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800156
157 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700158 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800159 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700160 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700161 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800162
163 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700164 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800165 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700166 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
167
168 /**
169 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700170 */
171 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
172
173 /**
174 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700175 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700176 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700177 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800178
179 /**
180 * Call is able to be separated from its parent {@code Conference}, if any.
181 */
182 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
183
184 /**
185 * Call is able to be individually disconnected when in a {@code Conference}.
186 */
187 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
188
189 /**
190 * Whether the call is a generic conference, where we do not know the precise state of
191 * participants in the conference (eg. on CDMA).
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800192 */
193 public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
194
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700195 /**
196 * Call is using high definition audio.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700197 */
198 public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00008000;
199
200 /**
201 * Call is using WIFI.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700202 */
203 public static final int CAPABILITY_WIFI = 0x00010000;
204
Tyler Gunn068085b2015-02-06 13:56:52 -0800205 /**
206 * Indicates that the current device callback number should be shown.
Tyler Gunn068085b2015-02-06 13:56:52 -0800207 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700208 public static final int CAPABILITY_SHOW_CALLBACK_NUMBER = 0x00020000;
209
210 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500211 * Speed up audio setup for MT call.
212 * @hide
213 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700214 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
215
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700216 /**
217 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700218 * @hide
219 */
220 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
221
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700222 /**
223 * For video calls, indicates whether the outgoing video for the call can be paused using
224 * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState.
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700225 */
226 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
227
Tyler Gunnd11a3152015-03-18 13:09:14 -0700228 //******************************************************************************************
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700229 // Next CAPABILITY value: 0x00200000
Tyler Gunnd11a3152015-03-18 13:09:14 -0700230 //******************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800231
Ihab Awade63fadb2014-07-09 21:52:04 -0700232 private final Uri mHandle;
233 private final int mHandlePresentation;
234 private final String mCallerDisplayName;
235 private final int mCallerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700236 private final PhoneAccountHandle mAccountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700237 private final int mCallCapabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700238 private final int mCallProperties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700239 private final DisconnectCause mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700240 private final long mConnectTimeMillis;
241 private final GatewayInfo mGatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700242 private final int mVideoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700243 private final StatusHints mStatusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700244 private final Bundle mExtras;
Ihab Awade63fadb2014-07-09 21:52:04 -0700245
246 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800247 * Whether the supplied capabilities supports the specified capability.
248 *
249 * @param capabilities A bit field of capabilities.
250 * @param capability The capability to check capabilities for.
251 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800252 */
253 public static boolean can(int capabilities, int capability) {
254 return (capabilities & capability) != 0;
255 }
256
257 /**
258 * Whether the capabilities of this {@code Details} supports the specified capability.
259 *
260 * @param capability The capability to check capabilities for.
261 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800262 */
263 public boolean can(int capability) {
264 return can(mCallCapabilities, capability);
265 }
266
267 /**
268 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
269 *
270 * @param capabilities A capability bit field.
271 * @return A human readable string representation.
272 */
273 public static String capabilitiesToString(int capabilities) {
274 StringBuilder builder = new StringBuilder();
275 builder.append("[Capabilities:");
276 if (can(capabilities, CAPABILITY_HOLD)) {
277 builder.append(" CAPABILITY_HOLD");
278 }
279 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
280 builder.append(" CAPABILITY_SUPPORT_HOLD");
281 }
282 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
283 builder.append(" CAPABILITY_MERGE_CONFERENCE");
284 }
285 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
286 builder.append(" CAPABILITY_SWAP_CONFERENCE");
287 }
288 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
289 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
290 }
291 if (can(capabilities, CAPABILITY_MUTE)) {
292 builder.append(" CAPABILITY_MUTE");
293 }
294 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
295 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
296 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700297 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
298 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
299 }
300 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
301 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
302 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700303 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
304 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800305 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700306 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
307 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
308 }
309 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
310 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
311 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700312 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
313 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800314 }
Andrew Lee80fff3c2014-11-25 17:36:51 -0800315 if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
316 builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800317 }
Andrew Lee1a8ae3e2015-02-02 13:42:38 -0800318 if (can(capabilities, CAPABILITY_WIFI)) {
319 builder.append(" CAPABILITY_WIFI");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800320 }
321 if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
322 builder.append(" CAPABILITY_GENERIC_CONFERENCE");
323 }
Tyler Gunn068085b2015-02-06 13:56:52 -0800324 if (can(capabilities, CAPABILITY_SHOW_CALLBACK_NUMBER)) {
325 builder.append(" CAPABILITY_SHOW_CALLBACK_NUMBER");
326 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500327 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700328 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500329 }
Rekha Kumar07366812015-03-24 16:42:31 -0700330 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
331 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
332 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700333 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
334 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
335 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800336 builder.append("]");
337 return builder.toString();
338 }
339
340 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700341 * @return The handle (e.g., phone number) to which the {@code Call} is currently
342 * connected.
343 */
344 public Uri getHandle() {
345 return mHandle;
346 }
347
348 /**
349 * @return The presentation requirements for the handle. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700350 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700351 */
352 public int getHandlePresentation() {
353 return mHandlePresentation;
354 }
355
356 /**
357 * @return The display name for the caller.
358 */
359 public String getCallerDisplayName() {
360 return mCallerDisplayName;
361 }
362
363 /**
364 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700365 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700366 */
367 public int getCallerDisplayNamePresentation() {
368 return mCallerDisplayNamePresentation;
369 }
370
371 /**
Evan Charlton6eb262c2014-07-19 18:18:19 -0700372 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being
373 * routed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700374 */
Evan Charlton8c8a0622014-07-20 12:31:00 -0700375 public PhoneAccountHandle getAccountHandle() {
376 return mAccountHandle;
Ihab Awade63fadb2014-07-09 21:52:04 -0700377 }
378
379 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800380 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various
381 * {@code CAPABILITY_*} constants in this class.
Ihab Awade63fadb2014-07-09 21:52:04 -0700382 */
Ihab Awad5d0410f2014-07-30 10:07:40 -0700383 public int getCallCapabilities() {
384 return mCallCapabilities;
Ihab Awade63fadb2014-07-09 21:52:04 -0700385 }
386
387 /**
Andrew Lee223ad142014-08-27 16:33:08 -0700388 * @return A bitmask of the properties of the {@code Call}, as defined in
389 * {@link CallProperties}.
390 */
391 public int getCallProperties() {
392 return mCallProperties;
393 }
394
395 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700396 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700397 * by {@link android.telecom.DisconnectCause}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700398 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700399 public DisconnectCause getDisconnectCause() {
400 return mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700401 }
402
403 /**
404 * @return The time the {@code Call} has been connected. This information is updated
405 * periodically, but user interfaces should not rely on this to display any "call time
406 * clock".
407 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700408 public final long getConnectTimeMillis() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700409 return mConnectTimeMillis;
410 }
411
412 /**
413 * @return Information about any calling gateway the {@code Call} may be using.
414 */
415 public GatewayInfo getGatewayInfo() {
416 return mGatewayInfo;
417 }
418
Andrew Lee7a341382014-07-15 17:05:08 -0700419 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700420 * @return The video state of the {@code Call}.
Andrew Lee7a341382014-07-15 17:05:08 -0700421 */
422 public int getVideoState() {
423 return mVideoState;
424 }
425
Ihab Awad5d0410f2014-07-30 10:07:40 -0700426 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700427 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none
Ihab Awad5d0410f2014-07-30 10:07:40 -0700428 * have been set.
Evan Charlton5b49ade2014-07-15 17:03:20 -0700429 */
430 public StatusHints getStatusHints() {
431 return mStatusHints;
432 }
433
Nancy Chen10798dc2014-08-08 14:00:25 -0700434 /**
435 * @return A bundle extras to pass with the call
436 */
437 public Bundle getExtras() {
438 return mExtras;
439 }
440
Ihab Awade63fadb2014-07-09 21:52:04 -0700441 @Override
442 public boolean equals(Object o) {
443 if (o instanceof Details) {
444 Details d = (Details) o;
445 return
446 Objects.equals(mHandle, d.mHandle) &&
447 Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
448 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
449 Objects.equals(mCallerDisplayNamePresentation,
450 d.mCallerDisplayNamePresentation) &&
Evan Charlton8c8a0622014-07-20 12:31:00 -0700451 Objects.equals(mAccountHandle, d.mAccountHandle) &&
Ihab Awad5d0410f2014-07-30 10:07:40 -0700452 Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
Andrew Lee223ad142014-08-27 16:33:08 -0700453 Objects.equals(mCallProperties, d.mCallProperties) &&
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700454 Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
Ihab Awade63fadb2014-07-09 21:52:04 -0700455 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
Andrew Lee85f5d422014-07-11 17:22:03 -0700456 Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Evan Charlton5b49ade2014-07-15 17:03:20 -0700457 Objects.equals(mVideoState, d.mVideoState) &&
Nancy Chen10798dc2014-08-08 14:00:25 -0700458 Objects.equals(mStatusHints, d.mStatusHints) &&
Jay Shrauner8f988432015-04-16 12:52:19 -0700459 Objects.equals(mExtras, d.mExtras);
Ihab Awade63fadb2014-07-09 21:52:04 -0700460 }
461 return false;
462 }
463
464 @Override
465 public int hashCode() {
466 return
467 Objects.hashCode(mHandle) +
468 Objects.hashCode(mHandlePresentation) +
469 Objects.hashCode(mCallerDisplayName) +
470 Objects.hashCode(mCallerDisplayNamePresentation) +
Evan Charlton8c8a0622014-07-20 12:31:00 -0700471 Objects.hashCode(mAccountHandle) +
Ihab Awad5d0410f2014-07-30 10:07:40 -0700472 Objects.hashCode(mCallCapabilities) +
Andrew Lee223ad142014-08-27 16:33:08 -0700473 Objects.hashCode(mCallProperties) +
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700474 Objects.hashCode(mDisconnectCause) +
Ihab Awade63fadb2014-07-09 21:52:04 -0700475 Objects.hashCode(mConnectTimeMillis) +
Andrew Lee85f5d422014-07-11 17:22:03 -0700476 Objects.hashCode(mGatewayInfo) +
Evan Charlton5b49ade2014-07-15 17:03:20 -0700477 Objects.hashCode(mVideoState) +
Nancy Chen10798dc2014-08-08 14:00:25 -0700478 Objects.hashCode(mStatusHints) +
Jay Shrauner8f988432015-04-16 12:52:19 -0700479 Objects.hashCode(mExtras);
Ihab Awade63fadb2014-07-09 21:52:04 -0700480 }
481
482 /** {@hide} */
483 public Details(
484 Uri handle,
485 int handlePresentation,
486 String callerDisplayName,
487 int callerDisplayNamePresentation,
Evan Charlton8c8a0622014-07-20 12:31:00 -0700488 PhoneAccountHandle accountHandle,
Ihab Awade63fadb2014-07-09 21:52:04 -0700489 int capabilities,
Andrew Lee223ad142014-08-27 16:33:08 -0700490 int properties,
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700491 DisconnectCause disconnectCause,
Ihab Awade63fadb2014-07-09 21:52:04 -0700492 long connectTimeMillis,
Andrew Lee85f5d422014-07-11 17:22:03 -0700493 GatewayInfo gatewayInfo,
Evan Charlton5b49ade2014-07-15 17:03:20 -0700494 int videoState,
Nancy Chen10798dc2014-08-08 14:00:25 -0700495 StatusHints statusHints,
Jay Shrauner8f988432015-04-16 12:52:19 -0700496 Bundle extras) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700497 mHandle = handle;
498 mHandlePresentation = handlePresentation;
499 mCallerDisplayName = callerDisplayName;
500 mCallerDisplayNamePresentation = callerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700501 mAccountHandle = accountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700502 mCallCapabilities = capabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700503 mCallProperties = properties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700504 mDisconnectCause = disconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700505 mConnectTimeMillis = connectTimeMillis;
506 mGatewayInfo = gatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700507 mVideoState = videoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700508 mStatusHints = statusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700509 mExtras = extras;
Ihab Awade63fadb2014-07-09 21:52:04 -0700510 }
511 }
512
Andrew Leeda80c872015-04-15 14:09:50 -0700513 public static abstract class Callback {
Ihab Awade63fadb2014-07-09 21:52:04 -0700514 /**
515 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
516 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700517 * @param call The {@code Call} invoking this method.
518 * @param state The new state of the {@code Call}.
519 */
520 public void onStateChanged(Call call, int state) {}
521
522 /**
523 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
524 *
525 * @param call The {@code Call} invoking this method.
526 * @param parent The new parent of the {@code Call}.
527 */
528 public void onParentChanged(Call call, Call parent) {}
529
530 /**
531 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}.
532 *
533 * @param call The {@code Call} invoking this method.
534 * @param children The new children of the {@code Call}.
535 */
536 public void onChildrenChanged(Call call, List<Call> children) {}
537
538 /**
539 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}.
540 *
541 * @param call The {@code Call} invoking this method.
542 * @param details A {@code Details} object describing the {@code Call}.
543 */
544 public void onDetailsChanged(Call call, Details details) {}
545
546 /**
547 * Invoked when the text messages that can be used as responses to the incoming
548 * {@code Call} are loaded from the relevant database.
549 * See {@link #getCannedTextResponses()}.
550 *
551 * @param call The {@code Call} invoking this method.
552 * @param cannedTextResponses The text messages useable as responses.
553 */
554 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
555
556 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700557 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
558 * character. This causes the post-dial signals to stop pending user confirmation. An
559 * implementation should present this choice to the user and invoke
560 * {@link #postDialContinue(boolean)} when the user makes the choice.
561 *
562 * @param call The {@code Call} invoking this method.
563 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
564 */
565 public void onPostDialWait(Call call, String remainingPostDialSequence) {}
566
567 /**
Andrew Lee50aca232014-07-22 16:41:54 -0700568 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700569 *
570 * @param call The {@code Call} invoking this method.
Andrew Lee50aca232014-07-22 16:41:54 -0700571 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700572 */
Andrew Lee50aca232014-07-22 16:41:54 -0700573 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
Ihab Awade63fadb2014-07-09 21:52:04 -0700574
575 /**
576 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning
577 * up their UI for the {@code Call} in response to state transitions. Specifically,
578 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of
579 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather,
580 * clients should wait for this method to be invoked.
581 *
582 * @param call The {@code Call} being destroyed.
583 */
584 public void onCallDestroyed(Call call) {}
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700585
586 /**
587 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
588 * conferenced.
589 *
590 * @param call The {@code Call} being updated.
591 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
592 * conferenced.
593 */
594 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
Ihab Awade63fadb2014-07-09 21:52:04 -0700595 }
596
Andrew Leeda80c872015-04-15 14:09:50 -0700597 /**
598 * @deprecated Use {@code Call.Callback} instead.
599 * @hide
600 */
601 @Deprecated
602 @SystemApi
603 public static abstract class Listener extends Callback { }
604
Ihab Awade63fadb2014-07-09 21:52:04 -0700605 private final Phone mPhone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700606 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700607 private final InCallAdapter mInCallAdapter;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700608 private final List<String> mChildrenIds = new ArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -0700609 private final List<Call> mChildren = new ArrayList<>();
610 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
Andrew Leeda80c872015-04-15 14:09:50 -0700611 private final List<Callback> mCallbacks = new CopyOnWriteArrayList<>();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700612 private final List<Call> mConferenceableCalls = new ArrayList<>();
613 private final List<Call> mUnmodifiableConferenceableCalls =
614 Collections.unmodifiableList(mConferenceableCalls);
615
Santos Cordon823fd3c2014-08-07 18:35:18 -0700616 private boolean mChildrenCached;
617 private String mParentId = null;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700618 private int mState;
Ihab Awade63fadb2014-07-09 21:52:04 -0700619 private List<String> mCannedTextResponses = null;
620 private String mRemainingPostDialSequence;
Andrew Lee50aca232014-07-22 16:41:54 -0700621 private InCallService.VideoCall mVideoCall;
Ihab Awade63fadb2014-07-09 21:52:04 -0700622 private Details mDetails;
Ihab Awade63fadb2014-07-09 21:52:04 -0700623
624 /**
625 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
626 *
627 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence
628 * remaining or this {@code Call} is not in a post-dial state.
629 */
630 public String getRemainingPostDialSequence() {
631 return mRemainingPostDialSequence;
632 }
633
634 /**
635 * Instructs this {@link #STATE_RINGING} {@code Call} to answer.
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700636 * @param videoState The video state in which to answer the call.
Ihab Awade63fadb2014-07-09 21:52:04 -0700637 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700638 public void answer(int videoState) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700639 mInCallAdapter.answerCall(mTelecomCallId, videoState);
Ihab Awade63fadb2014-07-09 21:52:04 -0700640 }
641
642 /**
643 * Instructs this {@link #STATE_RINGING} {@code Call} to reject.
644 *
645 * @param rejectWithMessage Whether to reject with a text message.
646 * @param textMessage An optional text message with which to respond.
647 */
648 public void reject(boolean rejectWithMessage, String textMessage) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700649 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
Ihab Awade63fadb2014-07-09 21:52:04 -0700650 }
651
652 /**
653 * Instructs this {@code Call} to disconnect.
654 */
655 public void disconnect() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700656 mInCallAdapter.disconnectCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700657 }
658
659 /**
660 * Instructs this {@code Call} to go on hold.
661 */
662 public void hold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700663 mInCallAdapter.holdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700664 }
665
666 /**
667 * Instructs this {@link #STATE_HOLDING} call to release from hold.
668 */
669 public void unhold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700670 mInCallAdapter.unholdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700671 }
672
673 /**
674 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
675 *
676 * Any other currently playing DTMF tone in the specified call is immediately stopped.
677 *
678 * @param digit A character representing the DTMF digit for which to play the tone. This
679 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
680 */
681 public void playDtmfTone(char digit) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700682 mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
Ihab Awade63fadb2014-07-09 21:52:04 -0700683 }
684
685 /**
686 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone
687 * currently playing.
688 *
689 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
690 * currently playing, this method will do nothing.
691 */
692 public void stopDtmfTone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700693 mInCallAdapter.stopDtmfTone(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700694 }
695
696 /**
697 * Instructs this {@code Call} to continue playing a post-dial DTMF string.
698 *
699 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
700 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
Ihab Awade63fadb2014-07-09 21:52:04 -0700701 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700702 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awade63fadb2014-07-09 21:52:04 -0700703 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
704 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700705 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Leeda80c872015-04-15 14:09:50 -0700706 * {@code Call} will pause playing the tones and notify callbacks via
707 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
Ihab Awade63fadb2014-07-09 21:52:04 -0700708 * should display to the user an indication of this state and an affordance to continue
709 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
710 * app should invoke the {@link #postDialContinue(boolean)} method.
711 *
712 * @param proceed Whether or not to continue with the post-dial sequence.
713 */
714 public void postDialContinue(boolean proceed) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700715 mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
Ihab Awade63fadb2014-07-09 21:52:04 -0700716 }
717
718 /**
Evan Charlton8c8a0622014-07-20 12:31:00 -0700719 * Notifies this {@code Call} that an account has been selected and to proceed with placing
Nancy Chen36c62f32014-10-21 18:36:39 -0700720 * an outgoing call. Optionally sets this account as the default account.
Nancy Chen5da0fd52014-07-08 14:16:17 -0700721 */
Nancy Chen36c62f32014-10-21 18:36:39 -0700722 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) {
723 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);
Nancy Chen5da0fd52014-07-08 14:16:17 -0700724
725 }
726
727 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700728 * Instructs this {@code Call} to enter a conference.
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700729 *
730 * @param callToConferenceWith The other call with which to conference.
Ihab Awade63fadb2014-07-09 21:52:04 -0700731 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700732 public void conference(Call callToConferenceWith) {
733 if (callToConferenceWith != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700734 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700735 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700736 }
737
738 /**
739 * Instructs this {@code Call} to split from any conference call with which it may be
740 * connected.
741 */
742 public void splitFromConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700743 mInCallAdapter.splitFromConference(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700744 }
745
746 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800747 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700748 */
749 public void mergeConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700750 mInCallAdapter.mergeConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -0700751 }
752
753 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800754 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700755 */
756 public void swapConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700757 mInCallAdapter.swapConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -0700758 }
759
760 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700761 * Obtains the parent of this {@code Call} in a conference, if any.
762 *
763 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
764 * child of any conference {@code Call}s.
765 */
766 public Call getParent() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700767 if (mParentId != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700768 return mPhone.internalGetCallByTelecomId(mParentId);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700769 }
770 return null;
Ihab Awade63fadb2014-07-09 21:52:04 -0700771 }
772
773 /**
774 * Obtains the children of this conference {@code Call}, if any.
775 *
776 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty
777 * {@code List} otherwise.
778 */
779 public List<Call> getChildren() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700780 if (!mChildrenCached) {
781 mChildrenCached = true;
782 mChildren.clear();
783
784 for(String id : mChildrenIds) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700785 Call call = mPhone.internalGetCallByTelecomId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700786 if (call == null) {
787 // At least one child was still not found, so do not save true for "cached"
788 mChildrenCached = false;
789 } else {
790 mChildren.add(call);
791 }
792 }
793 }
794
Ihab Awade63fadb2014-07-09 21:52:04 -0700795 return mUnmodifiableChildren;
796 }
797
798 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700799 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
800 *
801 * @return The list of conferenceable {@code Call}s.
802 */
803 public List<Call> getConferenceableCalls() {
804 return mUnmodifiableConferenceableCalls;
805 }
806
807 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700808 * Obtains the state of this {@code Call}.
809 *
810 * @return A state value, chosen from the {@code STATE_*} constants.
811 */
812 public int getState() {
813 return mState;
814 }
815
816 /**
817 * Obtains a list of canned, pre-configured message responses to present to the user as
818 * ways of rejecting this {@code Call} using via a text message.
819 *
820 * @see #reject(boolean, String)
821 *
822 * @return A list of canned text message responses.
823 */
824 public List<String> getCannedTextResponses() {
825 return mCannedTextResponses;
826 }
827
828 /**
829 * Obtains an object that can be used to display video from this {@code Call}.
830 *
Andrew Lee50aca232014-07-22 16:41:54 -0700831 * @return An {@code Call.VideoCall}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700832 */
Andrew Lee50aca232014-07-22 16:41:54 -0700833 public InCallService.VideoCall getVideoCall() {
834 return mVideoCall;
Ihab Awade63fadb2014-07-09 21:52:04 -0700835 }
836
837 /**
838 * Obtains an object containing call details.
839 *
840 * @return A {@link Details} object. Depending on the state of the {@code Call}, the
841 * result may be {@code null}.
842 */
843 public Details getDetails() {
844 return mDetails;
845 }
846
847 /**
Andrew Leeda80c872015-04-15 14:09:50 -0700848 * Registers a callback to this {@code Call}.
849 *
850 * @param callback A {@code Callback}.
851 */
852 public void registerCallback(Callback callback) {
853 mCallbacks.add(callback);
854 }
855
856 /**
857 * Unregisters a callback from this {@code Call}.
858 *
859 * @param callback A {@code Callback}.
860 */
861 public void unregisterCallback(Callback callback) {
862 if (callback != null) {
863 mCallbacks.remove(callback);
864 }
865 }
866
867 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700868 * Adds a listener to this {@code Call}.
869 *
870 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -0700871 * @deprecated Use {@link #registerCallback} instead.
872 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -0700873 */
Andrew Leeda80c872015-04-15 14:09:50 -0700874 @Deprecated
875 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -0700876 public void addListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -0700877 registerCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -0700878 }
879
880 /**
881 * Removes a listener from this {@code Call}.
882 *
883 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -0700884 * @deprecated Use {@link #unregisterCallback} instead.
885 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -0700886 */
Andrew Leeda80c872015-04-15 14:09:50 -0700887 @Deprecated
888 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -0700889 public void removeListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -0700890 unregisterCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -0700891 }
892
Andrew Leeda80c872015-04-15 14:09:50 -0700893
Ihab Awade63fadb2014-07-09 21:52:04 -0700894 /** {@hide} */
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700895 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700896 mPhone = phone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700897 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700898 mInCallAdapter = inCallAdapter;
899 mState = STATE_NEW;
900 }
901
902 /** {@hide} */
903 final String internalGetCallId() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700904 return mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700905 }
906
907 /** {@hide} */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700908 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700909 // First, we update the internal state as far as possible before firing any updates.
Ihab Awade63fadb2014-07-09 21:52:04 -0700910 Details details = new Details(
Santos Cordon88b771d2014-07-19 13:10:40 -0700911 parcelableCall.getHandle(),
912 parcelableCall.getHandlePresentation(),
913 parcelableCall.getCallerDisplayName(),
914 parcelableCall.getCallerDisplayNamePresentation(),
915 parcelableCall.getAccountHandle(),
916 parcelableCall.getCapabilities(),
Andrew Lee223ad142014-08-27 16:33:08 -0700917 parcelableCall.getProperties(),
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700918 parcelableCall.getDisconnectCause(),
Santos Cordon88b771d2014-07-19 13:10:40 -0700919 parcelableCall.getConnectTimeMillis(),
920 parcelableCall.getGatewayInfo(),
921 parcelableCall.getVideoState(),
Nancy Chen10798dc2014-08-08 14:00:25 -0700922 parcelableCall.getStatusHints(),
Jay Shrauner8f988432015-04-16 12:52:19 -0700923 parcelableCall.getExtras());
Ihab Awade63fadb2014-07-09 21:52:04 -0700924 boolean detailsChanged = !Objects.equals(mDetails, details);
925 if (detailsChanged) {
926 mDetails = details;
927 }
928
929 boolean cannedTextResponsesChanged = false;
Santos Cordon88b771d2014-07-19 13:10:40 -0700930 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
931 && !parcelableCall.getCannedSmsResponses().isEmpty()) {
932 mCannedTextResponses =
933 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
Ihab Awade63fadb2014-07-09 21:52:04 -0700934 }
935
Tyler Gunn75958422015-04-15 14:23:42 -0700936 boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
937 !Objects.equals(mVideoCall, parcelableCall.getVideoCall());
Andrew Lee50aca232014-07-22 16:41:54 -0700938 if (videoCallChanged) {
939 mVideoCall = parcelableCall.getVideoCall();
Ihab Awade63fadb2014-07-09 21:52:04 -0700940 }
941
Santos Cordone3c507b2015-04-23 14:44:19 -0700942 int state = parcelableCall.getState();
Ihab Awade63fadb2014-07-09 21:52:04 -0700943 boolean stateChanged = mState != state;
944 if (stateChanged) {
945 mState = state;
946 }
947
Santos Cordon823fd3c2014-08-07 18:35:18 -0700948 String parentId = parcelableCall.getParentCallId();
949 boolean parentChanged = !Objects.equals(mParentId, parentId);
950 if (parentChanged) {
951 mParentId = parentId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700952 }
953
Santos Cordon823fd3c2014-08-07 18:35:18 -0700954 List<String> childCallIds = parcelableCall.getChildCallIds();
955 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
956 if (childrenChanged) {
957 mChildrenIds.clear();
958 mChildrenIds.addAll(parcelableCall.getChildCallIds());
959 mChildrenCached = false;
Ihab Awade63fadb2014-07-09 21:52:04 -0700960 }
961
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700962 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
963 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
964 for (String otherId : conferenceableCallIds) {
965 if (callIdMap.containsKey(otherId)) {
966 conferenceableCalls.add(callIdMap.get(otherId));
967 }
968 }
969
970 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
971 mConferenceableCalls.clear();
972 mConferenceableCalls.addAll(conferenceableCalls);
973 fireConferenceableCallsChanged();
974 }
975
Ihab Awade63fadb2014-07-09 21:52:04 -0700976 // Now we fire updates, ensuring that any client who listens to any of these notifications
977 // gets the most up-to-date state.
978
979 if (stateChanged) {
980 fireStateChanged(mState);
981 }
982 if (detailsChanged) {
983 fireDetailsChanged(mDetails);
984 }
985 if (cannedTextResponsesChanged) {
986 fireCannedTextResponsesLoaded(mCannedTextResponses);
987 }
Andrew Lee50aca232014-07-22 16:41:54 -0700988 if (videoCallChanged) {
989 fireVideoCallChanged(mVideoCall);
Ihab Awade63fadb2014-07-09 21:52:04 -0700990 }
Santos Cordon823fd3c2014-08-07 18:35:18 -0700991 if (parentChanged) {
992 fireParentChanged(getParent());
993 }
994 if (childrenChanged) {
995 fireChildrenChanged(getChildren());
996 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700997
998 // If we have transitioned to DISCONNECTED, that means we need to notify clients and
999 // remove ourselves from the Phone. Note that we do this after completing all state updates
1000 // so a client can cleanly transition all their UI to the state appropriate for a
1001 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
1002 if (mState == STATE_DISCONNECTED) {
1003 fireCallDestroyed();
1004 mPhone.internalRemoveCall(this);
1005 }
1006 }
1007
1008 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07001009 final void internalSetPostDialWait(String remaining) {
1010 mRemainingPostDialSequence = remaining;
1011 firePostDialWait(mRemainingPostDialSequence);
1012 }
1013
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001014 /** {@hide} */
Santos Cordonf30d7e92014-08-26 09:54:33 -07001015 final void internalSetDisconnected() {
1016 if (mState != Call.STATE_DISCONNECTED) {
1017 mState = Call.STATE_DISCONNECTED;
1018 fireStateChanged(mState);
1019 fireCallDestroyed();
1020 mPhone.internalRemoveCall(this);
1021 }
1022 }
1023
Ihab Awade63fadb2014-07-09 21:52:04 -07001024 private void fireStateChanged(int newState) {
Andrew Leeda80c872015-04-15 14:09:50 -07001025 for (Callback callback : mCallbacks) {
1026 callback.onStateChanged(this, newState);
Ihab Awade63fadb2014-07-09 21:52:04 -07001027 }
1028 }
1029
1030 private void fireParentChanged(Call newParent) {
Andrew Leeda80c872015-04-15 14:09:50 -07001031 for (Callback callback : mCallbacks) {
1032 callback.onParentChanged(this, newParent);
Ihab Awade63fadb2014-07-09 21:52:04 -07001033 }
1034 }
1035
1036 private void fireChildrenChanged(List<Call> children) {
Andrew Leeda80c872015-04-15 14:09:50 -07001037 for (Callback callback : mCallbacks) {
1038 callback.onChildrenChanged(this, children);
Ihab Awade63fadb2014-07-09 21:52:04 -07001039 }
1040 }
1041
1042 private void fireDetailsChanged(Details details) {
Andrew Leeda80c872015-04-15 14:09:50 -07001043 for (Callback callback : mCallbacks) {
1044 callback.onDetailsChanged(this, details);
Ihab Awade63fadb2014-07-09 21:52:04 -07001045 }
1046 }
1047
1048 private void fireCannedTextResponsesLoaded(List<String> cannedTextResponses) {
Andrew Leeda80c872015-04-15 14:09:50 -07001049 for (Callback callback : mCallbacks) {
1050 callback.onCannedTextResponsesLoaded(this, cannedTextResponses);
Ihab Awade63fadb2014-07-09 21:52:04 -07001051 }
1052 }
1053
Andrew Lee50aca232014-07-22 16:41:54 -07001054 private void fireVideoCallChanged(InCallService.VideoCall videoCall) {
Andrew Leeda80c872015-04-15 14:09:50 -07001055 for (Callback callback : mCallbacks) {
1056 callback.onVideoCallChanged(this, videoCall);
Ihab Awade63fadb2014-07-09 21:52:04 -07001057 }
1058 }
1059
Ihab Awade63fadb2014-07-09 21:52:04 -07001060 private void firePostDialWait(String remainingPostDialSequence) {
Andrew Leeda80c872015-04-15 14:09:50 -07001061 for (Callback callback : mCallbacks) {
1062 callback.onPostDialWait(this, remainingPostDialSequence);
Ihab Awade63fadb2014-07-09 21:52:04 -07001063 }
1064 }
1065
1066 private void fireCallDestroyed() {
Andrew Leeda80c872015-04-15 14:09:50 -07001067 for (Callback callback : mCallbacks) {
1068 callback.onCallDestroyed(this);
Ihab Awade63fadb2014-07-09 21:52:04 -07001069 }
1070 }
1071
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001072 private void fireConferenceableCallsChanged() {
Andrew Leeda80c872015-04-15 14:09:50 -07001073 for (Callback callback : mCallbacks) {
1074 callback.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001075 }
1076 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001077}