blob: f0bc25de7c6217049876bcefb31ad181d49c0b0d [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 /**
69 * The state of an outgoing {@code Call}, but waiting for user input before proceeding.
70 */
71 public static final int STATE_PRE_DIAL_WAIT = 8;
72
Nancy Chene20930f2014-08-07 16:17:21 -070073 /**
Nancy Chene9b7a8e2014-08-08 14:26:27 -070074 * The initial state of an outgoing {@code Call}.
75 * Common transitions are to {@link #STATE_DIALING} state for a successful call or
76 * {@link #STATE_DISCONNECTED} if it failed.
Nancy Chene20930f2014-08-07 16:17:21 -070077 */
78 public static final int STATE_CONNECTING = 9;
79
Nancy Chen513c8922014-09-17 14:47:20 -070080 /**
Tyler Gunn4afc6af2014-10-07 10:14:55 -070081 * The state of a {@code Call} when the user has initiated a disconnection of the call, but the
82 * call has not yet been disconnected by the underlying {@code ConnectionService}. The next
83 * state of the call is (potentially) {@link #STATE_DISCONNECTED}.
84 */
85 public static final int STATE_DISCONNECTING = 10;
86
87 /**
Nancy Chen513c8922014-09-17 14:47:20 -070088 * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
89 * extras. Used to pass the phone accounts to display on the front end to the user in order to
90 * select phone accounts to (for example) place a call.
Nancy Chen513c8922014-09-17 14:47:20 -070091 */
92 public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
93
Ihab Awade63fadb2014-07-09 21:52:04 -070094 public static class Details {
Ihab Awad5c9c86e2014-11-12 13:41:16 -080095
96 /** Call can currently be put on hold or unheld. */
97 public static final int CAPABILITY_HOLD = 0x00000001;
98
99 /** Call supports the hold feature. */
100 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
101
102 /**
103 * Calls within a conference can be merged. A {@link ConnectionService} has the option to
104 * add a {@link Conference} call before the child {@link Connection}s are merged. This is how
105 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
106 * capability allows a merge button to be shown while the conference call is in the foreground
107 * of the in-call UI.
108 * <p>
109 * This is only intended for use by a {@link Conference}.
110 */
111 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
112
113 /**
114 * Calls within a conference can be swapped between foreground and background.
115 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
116 * <p>
117 * This is only intended for use by a {@link Conference}.
118 */
119 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
120
121 /**
122 * @hide
123 */
124 public static final int CAPABILITY_UNUSED = 0x00000010;
125
126 /** Call supports responding via text option. */
127 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
128
129 /** Call can be muted. */
130 public static final int CAPABILITY_MUTE = 0x00000040;
131
132 /**
133 * Call supports conference call management. This capability only applies to {@link Conference}
134 * calls which can have {@link Connection}s as children.
135 */
136 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
137
138 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700139 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800140 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700141 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800142
143 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700144 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800145 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700146 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800147
148 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700149 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800150 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700151 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700152 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800153
154 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700155 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800156 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700157 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
158
159 /**
160 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700161 */
162 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
163
164 /**
165 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700166 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700167 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700168 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800169
170 /**
171 * Call is able to be separated from its parent {@code Conference}, if any.
172 */
173 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
174
175 /**
176 * Call is able to be individually disconnected when in a {@code Conference}.
177 */
178 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
179
180 /**
181 * Whether the call is a generic conference, where we do not know the precise state of
182 * participants in the conference (eg. on CDMA).
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800183 */
184 public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
185
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700186 /**
187 * Call is using high definition audio.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700188 */
189 public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00008000;
190
191 /**
192 * Call is using WIFI.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700193 */
194 public static final int CAPABILITY_WIFI = 0x00010000;
195
Tyler Gunn068085b2015-02-06 13:56:52 -0800196 /**
197 * Indicates that the current device callback number should be shown.
Tyler Gunn068085b2015-02-06 13:56:52 -0800198 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700199 public static final int CAPABILITY_SHOW_CALLBACK_NUMBER = 0x00020000;
200
201 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500202 * Speed up audio setup for MT call.
203 * @hide
204 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700205 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
206
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700207 /**
208 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700209 * @hide
210 */
211 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
212
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700213 /**
214 * For video calls, indicates whether the outgoing video for the call can be paused using
215 * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState.
216 * @hide
217 */
218 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
219
Tyler Gunnd11a3152015-03-18 13:09:14 -0700220 //******************************************************************************************
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700221 // Next CAPABILITY value: 0x00200000
Tyler Gunnd11a3152015-03-18 13:09:14 -0700222 //******************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800223
Ihab Awade63fadb2014-07-09 21:52:04 -0700224 private final Uri mHandle;
225 private final int mHandlePresentation;
226 private final String mCallerDisplayName;
227 private final int mCallerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700228 private final PhoneAccountHandle mAccountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700229 private final int mCallCapabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700230 private final int mCallProperties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700231 private final DisconnectCause mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700232 private final long mConnectTimeMillis;
233 private final GatewayInfo mGatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700234 private final int mVideoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700235 private final StatusHints mStatusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700236 private final Bundle mExtras;
Rekha Kumar07366812015-03-24 16:42:31 -0700237 private final int mCallSubstate;
Ihab Awade63fadb2014-07-09 21:52:04 -0700238
239 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800240 * Whether the supplied capabilities supports the specified capability.
241 *
242 * @param capabilities A bit field of capabilities.
243 * @param capability The capability to check capabilities for.
244 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800245 */
246 public static boolean can(int capabilities, int capability) {
247 return (capabilities & capability) != 0;
248 }
249
250 /**
251 * Whether the capabilities of this {@code Details} supports the specified capability.
252 *
253 * @param capability The capability to check capabilities for.
254 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800255 */
256 public boolean can(int capability) {
257 return can(mCallCapabilities, capability);
258 }
259
260 /**
261 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
262 *
263 * @param capabilities A capability bit field.
264 * @return A human readable string representation.
265 */
266 public static String capabilitiesToString(int capabilities) {
267 StringBuilder builder = new StringBuilder();
268 builder.append("[Capabilities:");
269 if (can(capabilities, CAPABILITY_HOLD)) {
270 builder.append(" CAPABILITY_HOLD");
271 }
272 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
273 builder.append(" CAPABILITY_SUPPORT_HOLD");
274 }
275 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
276 builder.append(" CAPABILITY_MERGE_CONFERENCE");
277 }
278 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
279 builder.append(" CAPABILITY_SWAP_CONFERENCE");
280 }
281 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
282 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
283 }
284 if (can(capabilities, CAPABILITY_MUTE)) {
285 builder.append(" CAPABILITY_MUTE");
286 }
287 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
288 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
289 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700290 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
291 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
292 }
293 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
294 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
295 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700296 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
297 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800298 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700299 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
300 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
301 }
302 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
303 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
304 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700305 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
306 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800307 }
Andrew Lee80fff3c2014-11-25 17:36:51 -0800308 if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
309 builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800310 }
Andrew Lee1a8ae3e2015-02-02 13:42:38 -0800311 if (can(capabilities, CAPABILITY_WIFI)) {
312 builder.append(" CAPABILITY_WIFI");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800313 }
314 if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
315 builder.append(" CAPABILITY_GENERIC_CONFERENCE");
316 }
Tyler Gunn068085b2015-02-06 13:56:52 -0800317 if (can(capabilities, CAPABILITY_SHOW_CALLBACK_NUMBER)) {
318 builder.append(" CAPABILITY_SHOW_CALLBACK_NUMBER");
319 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500320 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700321 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500322 }
Rekha Kumar07366812015-03-24 16:42:31 -0700323 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
324 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
325 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700326 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
327 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
328 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800329 builder.append("]");
330 return builder.toString();
331 }
332
333 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700334 * @return The handle (e.g., phone number) to which the {@code Call} is currently
335 * connected.
336 */
337 public Uri getHandle() {
338 return mHandle;
339 }
340
341 /**
342 * @return The presentation requirements for the handle. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700343 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700344 */
345 public int getHandlePresentation() {
346 return mHandlePresentation;
347 }
348
349 /**
350 * @return The display name for the caller.
351 */
352 public String getCallerDisplayName() {
353 return mCallerDisplayName;
354 }
355
356 /**
357 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700358 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700359 */
360 public int getCallerDisplayNamePresentation() {
361 return mCallerDisplayNamePresentation;
362 }
363
364 /**
Evan Charlton6eb262c2014-07-19 18:18:19 -0700365 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being
366 * routed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700367 */
Evan Charlton8c8a0622014-07-20 12:31:00 -0700368 public PhoneAccountHandle getAccountHandle() {
369 return mAccountHandle;
Ihab Awade63fadb2014-07-09 21:52:04 -0700370 }
371
372 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800373 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various
374 * {@code CAPABILITY_*} constants in this class.
Ihab Awade63fadb2014-07-09 21:52:04 -0700375 */
Ihab Awad5d0410f2014-07-30 10:07:40 -0700376 public int getCallCapabilities() {
377 return mCallCapabilities;
Ihab Awade63fadb2014-07-09 21:52:04 -0700378 }
379
380 /**
Andrew Lee223ad142014-08-27 16:33:08 -0700381 * @return A bitmask of the properties of the {@code Call}, as defined in
382 * {@link CallProperties}.
383 */
384 public int getCallProperties() {
385 return mCallProperties;
386 }
387
388 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700389 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700390 * by {@link android.telecom.DisconnectCause}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700391 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700392 public DisconnectCause getDisconnectCause() {
393 return mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700394 }
395
396 /**
397 * @return The time the {@code Call} has been connected. This information is updated
398 * periodically, but user interfaces should not rely on this to display any "call time
399 * clock".
400 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700401 public final long getConnectTimeMillis() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700402 return mConnectTimeMillis;
403 }
404
405 /**
406 * @return Information about any calling gateway the {@code Call} may be using.
407 */
408 public GatewayInfo getGatewayInfo() {
409 return mGatewayInfo;
410 }
411
Andrew Lee7a341382014-07-15 17:05:08 -0700412 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700413 * @return The video state of the {@code Call}.
Andrew Lee7a341382014-07-15 17:05:08 -0700414 */
415 public int getVideoState() {
416 return mVideoState;
417 }
418
Ihab Awad5d0410f2014-07-30 10:07:40 -0700419 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700420 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none
Ihab Awad5d0410f2014-07-30 10:07:40 -0700421 * have been set.
Evan Charlton5b49ade2014-07-15 17:03:20 -0700422 */
423 public StatusHints getStatusHints() {
424 return mStatusHints;
425 }
426
Nancy Chen10798dc2014-08-08 14:00:25 -0700427 /**
428 * @return A bundle extras to pass with the call
429 */
430 public Bundle getExtras() {
431 return mExtras;
432 }
433
Rekha Kumar07366812015-03-24 16:42:31 -0700434 /**
435 * @return The substate of the {@code Call}.
436 * @hide
437 */
438 public int getCallSubstate() {
439 return mCallSubstate;
440 }
441
Ihab Awade63fadb2014-07-09 21:52:04 -0700442 @Override
443 public boolean equals(Object o) {
444 if (o instanceof Details) {
445 Details d = (Details) o;
446 return
447 Objects.equals(mHandle, d.mHandle) &&
448 Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
449 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
450 Objects.equals(mCallerDisplayNamePresentation,
451 d.mCallerDisplayNamePresentation) &&
Evan Charlton8c8a0622014-07-20 12:31:00 -0700452 Objects.equals(mAccountHandle, d.mAccountHandle) &&
Ihab Awad5d0410f2014-07-30 10:07:40 -0700453 Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
Andrew Lee223ad142014-08-27 16:33:08 -0700454 Objects.equals(mCallProperties, d.mCallProperties) &&
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700455 Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
Ihab Awade63fadb2014-07-09 21:52:04 -0700456 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
Andrew Lee85f5d422014-07-11 17:22:03 -0700457 Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Evan Charlton5b49ade2014-07-15 17:03:20 -0700458 Objects.equals(mVideoState, d.mVideoState) &&
Nancy Chen10798dc2014-08-08 14:00:25 -0700459 Objects.equals(mStatusHints, d.mStatusHints) &&
Rekha Kumar07366812015-03-24 16:42:31 -0700460 Objects.equals(mExtras, d.mExtras) &&
461 Objects.equals(mCallSubstate, d.mCallSubstate);
Ihab Awade63fadb2014-07-09 21:52:04 -0700462 }
463 return false;
464 }
465
466 @Override
467 public int hashCode() {
468 return
469 Objects.hashCode(mHandle) +
470 Objects.hashCode(mHandlePresentation) +
471 Objects.hashCode(mCallerDisplayName) +
472 Objects.hashCode(mCallerDisplayNamePresentation) +
Evan Charlton8c8a0622014-07-20 12:31:00 -0700473 Objects.hashCode(mAccountHandle) +
Ihab Awad5d0410f2014-07-30 10:07:40 -0700474 Objects.hashCode(mCallCapabilities) +
Andrew Lee223ad142014-08-27 16:33:08 -0700475 Objects.hashCode(mCallProperties) +
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700476 Objects.hashCode(mDisconnectCause) +
Ihab Awade63fadb2014-07-09 21:52:04 -0700477 Objects.hashCode(mConnectTimeMillis) +
Andrew Lee85f5d422014-07-11 17:22:03 -0700478 Objects.hashCode(mGatewayInfo) +
Evan Charlton5b49ade2014-07-15 17:03:20 -0700479 Objects.hashCode(mVideoState) +
Nancy Chen10798dc2014-08-08 14:00:25 -0700480 Objects.hashCode(mStatusHints) +
Rekha Kumar07366812015-03-24 16:42:31 -0700481 Objects.hashCode(mExtras) +
482 Objects.hashCode(mCallSubstate);
Ihab Awade63fadb2014-07-09 21:52:04 -0700483 }
484
485 /** {@hide} */
486 public Details(
487 Uri handle,
488 int handlePresentation,
489 String callerDisplayName,
490 int callerDisplayNamePresentation,
Evan Charlton8c8a0622014-07-20 12:31:00 -0700491 PhoneAccountHandle accountHandle,
Ihab Awade63fadb2014-07-09 21:52:04 -0700492 int capabilities,
Andrew Lee223ad142014-08-27 16:33:08 -0700493 int properties,
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700494 DisconnectCause disconnectCause,
Ihab Awade63fadb2014-07-09 21:52:04 -0700495 long connectTimeMillis,
Andrew Lee85f5d422014-07-11 17:22:03 -0700496 GatewayInfo gatewayInfo,
Evan Charlton5b49ade2014-07-15 17:03:20 -0700497 int videoState,
Nancy Chen10798dc2014-08-08 14:00:25 -0700498 StatusHints statusHints,
Rekha Kumar07366812015-03-24 16:42:31 -0700499 Bundle extras,
500 int callSubstate) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700501 mHandle = handle;
502 mHandlePresentation = handlePresentation;
503 mCallerDisplayName = callerDisplayName;
504 mCallerDisplayNamePresentation = callerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700505 mAccountHandle = accountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700506 mCallCapabilities = capabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700507 mCallProperties = properties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700508 mDisconnectCause = disconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700509 mConnectTimeMillis = connectTimeMillis;
510 mGatewayInfo = gatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700511 mVideoState = videoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700512 mStatusHints = statusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700513 mExtras = extras;
Rekha Kumar07366812015-03-24 16:42:31 -0700514 mCallSubstate = callSubstate;
Ihab Awade63fadb2014-07-09 21:52:04 -0700515 }
516 }
517
Andrew Leeda80c872015-04-15 14:09:50 -0700518 public static abstract class Callback {
Ihab Awade63fadb2014-07-09 21:52:04 -0700519 /**
520 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
521 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700522 * @param call The {@code Call} invoking this method.
523 * @param state The new state of the {@code Call}.
524 */
525 public void onStateChanged(Call call, int state) {}
526
527 /**
528 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
529 *
530 * @param call The {@code Call} invoking this method.
531 * @param parent The new parent of the {@code Call}.
532 */
533 public void onParentChanged(Call call, Call parent) {}
534
535 /**
536 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}.
537 *
538 * @param call The {@code Call} invoking this method.
539 * @param children The new children of the {@code Call}.
540 */
541 public void onChildrenChanged(Call call, List<Call> children) {}
542
543 /**
544 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}.
545 *
546 * @param call The {@code Call} invoking this method.
547 * @param details A {@code Details} object describing the {@code Call}.
548 */
549 public void onDetailsChanged(Call call, Details details) {}
550
551 /**
552 * Invoked when the text messages that can be used as responses to the incoming
553 * {@code Call} are loaded from the relevant database.
554 * See {@link #getCannedTextResponses()}.
555 *
556 * @param call The {@code Call} invoking this method.
557 * @param cannedTextResponses The text messages useable as responses.
558 */
559 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
560
561 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700562 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
563 * character. This causes the post-dial signals to stop pending user confirmation. An
564 * implementation should present this choice to the user and invoke
565 * {@link #postDialContinue(boolean)} when the user makes the choice.
566 *
567 * @param call The {@code Call} invoking this method.
568 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
569 */
570 public void onPostDialWait(Call call, String remainingPostDialSequence) {}
571
572 /**
Andrew Lee50aca232014-07-22 16:41:54 -0700573 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700574 *
575 * @param call The {@code Call} invoking this method.
Andrew Lee50aca232014-07-22 16:41:54 -0700576 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700577 */
Andrew Lee50aca232014-07-22 16:41:54 -0700578 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
Ihab Awade63fadb2014-07-09 21:52:04 -0700579
580 /**
581 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning
582 * up their UI for the {@code Call} in response to state transitions. Specifically,
583 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of
584 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather,
585 * clients should wait for this method to be invoked.
586 *
587 * @param call The {@code Call} being destroyed.
588 */
589 public void onCallDestroyed(Call call) {}
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700590
591 /**
592 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
593 * conferenced.
594 *
595 * @param call The {@code Call} being updated.
596 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
597 * conferenced.
598 */
599 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
Ihab Awade63fadb2014-07-09 21:52:04 -0700600 }
601
Andrew Leeda80c872015-04-15 14:09:50 -0700602 /**
603 * @deprecated Use {@code Call.Callback} instead.
604 * @hide
605 */
606 @Deprecated
607 @SystemApi
608 public static abstract class Listener extends Callback { }
609
Ihab Awade63fadb2014-07-09 21:52:04 -0700610 private final Phone mPhone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700611 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700612 private final InCallAdapter mInCallAdapter;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700613 private final List<String> mChildrenIds = new ArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -0700614 private final List<Call> mChildren = new ArrayList<>();
615 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
Andrew Leeda80c872015-04-15 14:09:50 -0700616 private final List<Callback> mCallbacks = new CopyOnWriteArrayList<>();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700617 private final List<Call> mConferenceableCalls = new ArrayList<>();
618 private final List<Call> mUnmodifiableConferenceableCalls =
619 Collections.unmodifiableList(mConferenceableCalls);
620
Santos Cordon823fd3c2014-08-07 18:35:18 -0700621 private boolean mChildrenCached;
622 private String mParentId = null;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700623 private int mState;
Ihab Awade63fadb2014-07-09 21:52:04 -0700624 private List<String> mCannedTextResponses = null;
625 private String mRemainingPostDialSequence;
Andrew Lee50aca232014-07-22 16:41:54 -0700626 private InCallService.VideoCall mVideoCall;
Ihab Awade63fadb2014-07-09 21:52:04 -0700627 private Details mDetails;
Ihab Awade63fadb2014-07-09 21:52:04 -0700628
629 /**
630 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
631 *
632 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence
633 * remaining or this {@code Call} is not in a post-dial state.
634 */
635 public String getRemainingPostDialSequence() {
636 return mRemainingPostDialSequence;
637 }
638
639 /**
640 * Instructs this {@link #STATE_RINGING} {@code Call} to answer.
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700641 * @param videoState The video state in which to answer the call.
Ihab Awade63fadb2014-07-09 21:52:04 -0700642 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700643 public void answer(int videoState) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700644 mInCallAdapter.answerCall(mTelecomCallId, videoState);
Ihab Awade63fadb2014-07-09 21:52:04 -0700645 }
646
647 /**
648 * Instructs this {@link #STATE_RINGING} {@code Call} to reject.
649 *
650 * @param rejectWithMessage Whether to reject with a text message.
651 * @param textMessage An optional text message with which to respond.
652 */
653 public void reject(boolean rejectWithMessage, String textMessage) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700654 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
Ihab Awade63fadb2014-07-09 21:52:04 -0700655 }
656
657 /**
658 * Instructs this {@code Call} to disconnect.
659 */
660 public void disconnect() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700661 mInCallAdapter.disconnectCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700662 }
663
664 /**
665 * Instructs this {@code Call} to go on hold.
666 */
667 public void hold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700668 mInCallAdapter.holdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700669 }
670
671 /**
672 * Instructs this {@link #STATE_HOLDING} call to release from hold.
673 */
674 public void unhold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700675 mInCallAdapter.unholdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700676 }
677
678 /**
679 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
680 *
681 * Any other currently playing DTMF tone in the specified call is immediately stopped.
682 *
683 * @param digit A character representing the DTMF digit for which to play the tone. This
684 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
685 */
686 public void playDtmfTone(char digit) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700687 mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
Ihab Awade63fadb2014-07-09 21:52:04 -0700688 }
689
690 /**
691 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone
692 * currently playing.
693 *
694 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
695 * currently playing, this method will do nothing.
696 */
697 public void stopDtmfTone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700698 mInCallAdapter.stopDtmfTone(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700699 }
700
701 /**
702 * Instructs this {@code Call} to continue playing a post-dial DTMF string.
703 *
704 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
705 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
Ihab Awade63fadb2014-07-09 21:52:04 -0700706 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700707 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awade63fadb2014-07-09 21:52:04 -0700708 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
709 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700710 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Leeda80c872015-04-15 14:09:50 -0700711 * {@code Call} will pause playing the tones and notify callbacks via
712 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
Ihab Awade63fadb2014-07-09 21:52:04 -0700713 * should display to the user an indication of this state and an affordance to continue
714 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
715 * app should invoke the {@link #postDialContinue(boolean)} method.
716 *
717 * @param proceed Whether or not to continue with the post-dial sequence.
718 */
719 public void postDialContinue(boolean proceed) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700720 mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
Ihab Awade63fadb2014-07-09 21:52:04 -0700721 }
722
723 /**
Evan Charlton8c8a0622014-07-20 12:31:00 -0700724 * Notifies this {@code Call} that an account has been selected and to proceed with placing
Nancy Chen36c62f32014-10-21 18:36:39 -0700725 * an outgoing call. Optionally sets this account as the default account.
Nancy Chen5da0fd52014-07-08 14:16:17 -0700726 */
Nancy Chen36c62f32014-10-21 18:36:39 -0700727 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) {
728 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);
Nancy Chen5da0fd52014-07-08 14:16:17 -0700729
730 }
731
732 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700733 * Instructs this {@code Call} to enter a conference.
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700734 *
735 * @param callToConferenceWith The other call with which to conference.
Ihab Awade63fadb2014-07-09 21:52:04 -0700736 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700737 public void conference(Call callToConferenceWith) {
738 if (callToConferenceWith != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700739 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700740 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700741 }
742
743 /**
744 * Instructs this {@code Call} to split from any conference call with which it may be
745 * connected.
746 */
747 public void splitFromConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700748 mInCallAdapter.splitFromConference(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700749 }
750
751 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800752 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700753 */
754 public void mergeConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700755 mInCallAdapter.mergeConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -0700756 }
757
758 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800759 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700760 */
761 public void swapConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700762 mInCallAdapter.swapConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -0700763 }
764
765 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700766 * Obtains the parent of this {@code Call} in a conference, if any.
767 *
768 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
769 * child of any conference {@code Call}s.
770 */
771 public Call getParent() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700772 if (mParentId != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700773 return mPhone.internalGetCallByTelecomId(mParentId);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700774 }
775 return null;
Ihab Awade63fadb2014-07-09 21:52:04 -0700776 }
777
778 /**
779 * Obtains the children of this conference {@code Call}, if any.
780 *
781 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty
782 * {@code List} otherwise.
783 */
784 public List<Call> getChildren() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700785 if (!mChildrenCached) {
786 mChildrenCached = true;
787 mChildren.clear();
788
789 for(String id : mChildrenIds) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700790 Call call = mPhone.internalGetCallByTelecomId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700791 if (call == null) {
792 // At least one child was still not found, so do not save true for "cached"
793 mChildrenCached = false;
794 } else {
795 mChildren.add(call);
796 }
797 }
798 }
799
Ihab Awade63fadb2014-07-09 21:52:04 -0700800 return mUnmodifiableChildren;
801 }
802
803 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700804 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
805 *
806 * @return The list of conferenceable {@code Call}s.
807 */
808 public List<Call> getConferenceableCalls() {
809 return mUnmodifiableConferenceableCalls;
810 }
811
812 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700813 * Obtains the state of this {@code Call}.
814 *
815 * @return A state value, chosen from the {@code STATE_*} constants.
816 */
817 public int getState() {
818 return mState;
819 }
820
821 /**
822 * Obtains a list of canned, pre-configured message responses to present to the user as
823 * ways of rejecting this {@code Call} using via a text message.
824 *
825 * @see #reject(boolean, String)
826 *
827 * @return A list of canned text message responses.
828 */
829 public List<String> getCannedTextResponses() {
830 return mCannedTextResponses;
831 }
832
833 /**
834 * Obtains an object that can be used to display video from this {@code Call}.
835 *
Andrew Lee50aca232014-07-22 16:41:54 -0700836 * @return An {@code Call.VideoCall}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700837 */
Andrew Lee50aca232014-07-22 16:41:54 -0700838 public InCallService.VideoCall getVideoCall() {
839 return mVideoCall;
Ihab Awade63fadb2014-07-09 21:52:04 -0700840 }
841
842 /**
843 * Obtains an object containing call details.
844 *
845 * @return A {@link Details} object. Depending on the state of the {@code Call}, the
846 * result may be {@code null}.
847 */
848 public Details getDetails() {
849 return mDetails;
850 }
851
852 /**
Andrew Leeda80c872015-04-15 14:09:50 -0700853 * Registers a callback to this {@code Call}.
854 *
855 * @param callback A {@code Callback}.
856 */
857 public void registerCallback(Callback callback) {
858 mCallbacks.add(callback);
859 }
860
861 /**
862 * Unregisters a callback from this {@code Call}.
863 *
864 * @param callback A {@code Callback}.
865 */
866 public void unregisterCallback(Callback callback) {
867 if (callback != null) {
868 mCallbacks.remove(callback);
869 }
870 }
871
872 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700873 * Adds a listener to this {@code Call}.
874 *
875 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -0700876 * @deprecated Use {@link #registerCallback} instead.
877 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -0700878 */
Andrew Leeda80c872015-04-15 14:09:50 -0700879 @Deprecated
880 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -0700881 public void addListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -0700882 registerCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -0700883 }
884
885 /**
886 * Removes a listener from this {@code Call}.
887 *
888 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -0700889 * @deprecated Use {@link #unregisterCallback} instead.
890 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -0700891 */
Andrew Leeda80c872015-04-15 14:09:50 -0700892 @Deprecated
893 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -0700894 public void removeListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -0700895 unregisterCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -0700896 }
897
Andrew Leeda80c872015-04-15 14:09:50 -0700898
Ihab Awade63fadb2014-07-09 21:52:04 -0700899 /** {@hide} */
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700900 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700901 mPhone = phone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700902 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700903 mInCallAdapter = inCallAdapter;
904 mState = STATE_NEW;
905 }
906
907 /** {@hide} */
908 final String internalGetCallId() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700909 return mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700910 }
911
912 /** {@hide} */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700913 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700914 // First, we update the internal state as far as possible before firing any updates.
Ihab Awade63fadb2014-07-09 21:52:04 -0700915 Details details = new Details(
Santos Cordon88b771d2014-07-19 13:10:40 -0700916 parcelableCall.getHandle(),
917 parcelableCall.getHandlePresentation(),
918 parcelableCall.getCallerDisplayName(),
919 parcelableCall.getCallerDisplayNamePresentation(),
920 parcelableCall.getAccountHandle(),
921 parcelableCall.getCapabilities(),
Andrew Lee223ad142014-08-27 16:33:08 -0700922 parcelableCall.getProperties(),
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700923 parcelableCall.getDisconnectCause(),
Santos Cordon88b771d2014-07-19 13:10:40 -0700924 parcelableCall.getConnectTimeMillis(),
925 parcelableCall.getGatewayInfo(),
926 parcelableCall.getVideoState(),
Nancy Chen10798dc2014-08-08 14:00:25 -0700927 parcelableCall.getStatusHints(),
Rekha Kumar07366812015-03-24 16:42:31 -0700928 parcelableCall.getExtras(),
929 parcelableCall.getCallSubstate());
Ihab Awade63fadb2014-07-09 21:52:04 -0700930 boolean detailsChanged = !Objects.equals(mDetails, details);
931 if (detailsChanged) {
932 mDetails = details;
933 }
934
935 boolean cannedTextResponsesChanged = false;
Santos Cordon88b771d2014-07-19 13:10:40 -0700936 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
937 && !parcelableCall.getCannedSmsResponses().isEmpty()) {
938 mCannedTextResponses =
939 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
Ihab Awade63fadb2014-07-09 21:52:04 -0700940 }
941
Andrew Lee50aca232014-07-22 16:41:54 -0700942 boolean videoCallChanged = !Objects.equals(mVideoCall, parcelableCall.getVideoCall());
943 if (videoCallChanged) {
944 mVideoCall = parcelableCall.getVideoCall();
Ihab Awade63fadb2014-07-09 21:52:04 -0700945 }
946
Santos Cordon88b771d2014-07-19 13:10:40 -0700947 int state = stateFromParcelableCallState(parcelableCall.getState());
Ihab Awade63fadb2014-07-09 21:52:04 -0700948 boolean stateChanged = mState != state;
949 if (stateChanged) {
950 mState = state;
951 }
952
Santos Cordon823fd3c2014-08-07 18:35:18 -0700953 String parentId = parcelableCall.getParentCallId();
954 boolean parentChanged = !Objects.equals(mParentId, parentId);
955 if (parentChanged) {
956 mParentId = parentId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700957 }
958
Santos Cordon823fd3c2014-08-07 18:35:18 -0700959 List<String> childCallIds = parcelableCall.getChildCallIds();
960 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
961 if (childrenChanged) {
962 mChildrenIds.clear();
963 mChildrenIds.addAll(parcelableCall.getChildCallIds());
964 mChildrenCached = false;
Ihab Awade63fadb2014-07-09 21:52:04 -0700965 }
966
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700967 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
968 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
969 for (String otherId : conferenceableCallIds) {
970 if (callIdMap.containsKey(otherId)) {
971 conferenceableCalls.add(callIdMap.get(otherId));
972 }
973 }
974
975 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
976 mConferenceableCalls.clear();
977 mConferenceableCalls.addAll(conferenceableCalls);
978 fireConferenceableCallsChanged();
979 }
980
Ihab Awade63fadb2014-07-09 21:52:04 -0700981 // Now we fire updates, ensuring that any client who listens to any of these notifications
982 // gets the most up-to-date state.
983
984 if (stateChanged) {
985 fireStateChanged(mState);
986 }
987 if (detailsChanged) {
988 fireDetailsChanged(mDetails);
989 }
990 if (cannedTextResponsesChanged) {
991 fireCannedTextResponsesLoaded(mCannedTextResponses);
992 }
Andrew Lee50aca232014-07-22 16:41:54 -0700993 if (videoCallChanged) {
994 fireVideoCallChanged(mVideoCall);
Ihab Awade63fadb2014-07-09 21:52:04 -0700995 }
Santos Cordon823fd3c2014-08-07 18:35:18 -0700996 if (parentChanged) {
997 fireParentChanged(getParent());
998 }
999 if (childrenChanged) {
1000 fireChildrenChanged(getChildren());
1001 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001002
1003 // If we have transitioned to DISCONNECTED, that means we need to notify clients and
1004 // remove ourselves from the Phone. Note that we do this after completing all state updates
1005 // so a client can cleanly transition all their UI to the state appropriate for a
1006 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
1007 if (mState == STATE_DISCONNECTED) {
1008 fireCallDestroyed();
1009 mPhone.internalRemoveCall(this);
1010 }
1011 }
1012
1013 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07001014 final void internalSetPostDialWait(String remaining) {
1015 mRemainingPostDialSequence = remaining;
1016 firePostDialWait(mRemainingPostDialSequence);
1017 }
1018
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001019 /** {@hide} */
Santos Cordonf30d7e92014-08-26 09:54:33 -07001020 final void internalSetDisconnected() {
1021 if (mState != Call.STATE_DISCONNECTED) {
1022 mState = Call.STATE_DISCONNECTED;
1023 fireStateChanged(mState);
1024 fireCallDestroyed();
1025 mPhone.internalRemoveCall(this);
1026 }
1027 }
1028
Ihab Awade63fadb2014-07-09 21:52:04 -07001029 private void fireStateChanged(int newState) {
Andrew Leeda80c872015-04-15 14:09:50 -07001030 for (Callback callback : mCallbacks) {
1031 callback.onStateChanged(this, newState);
Ihab Awade63fadb2014-07-09 21:52:04 -07001032 }
1033 }
1034
1035 private void fireParentChanged(Call newParent) {
Andrew Leeda80c872015-04-15 14:09:50 -07001036 for (Callback callback : mCallbacks) {
1037 callback.onParentChanged(this, newParent);
Ihab Awade63fadb2014-07-09 21:52:04 -07001038 }
1039 }
1040
1041 private void fireChildrenChanged(List<Call> children) {
Andrew Leeda80c872015-04-15 14:09:50 -07001042 for (Callback callback : mCallbacks) {
1043 callback.onChildrenChanged(this, children);
Ihab Awade63fadb2014-07-09 21:52:04 -07001044 }
1045 }
1046
1047 private void fireDetailsChanged(Details details) {
Andrew Leeda80c872015-04-15 14:09:50 -07001048 for (Callback callback : mCallbacks) {
1049 callback.onDetailsChanged(this, details);
Ihab Awade63fadb2014-07-09 21:52:04 -07001050 }
1051 }
1052
1053 private void fireCannedTextResponsesLoaded(List<String> cannedTextResponses) {
Andrew Leeda80c872015-04-15 14:09:50 -07001054 for (Callback callback : mCallbacks) {
1055 callback.onCannedTextResponsesLoaded(this, cannedTextResponses);
Ihab Awade63fadb2014-07-09 21:52:04 -07001056 }
1057 }
1058
Andrew Lee50aca232014-07-22 16:41:54 -07001059 private void fireVideoCallChanged(InCallService.VideoCall videoCall) {
Andrew Leeda80c872015-04-15 14:09:50 -07001060 for (Callback callback : mCallbacks) {
1061 callback.onVideoCallChanged(this, videoCall);
Ihab Awade63fadb2014-07-09 21:52:04 -07001062 }
1063 }
1064
Ihab Awade63fadb2014-07-09 21:52:04 -07001065 private void firePostDialWait(String remainingPostDialSequence) {
Andrew Leeda80c872015-04-15 14:09:50 -07001066 for (Callback callback : mCallbacks) {
1067 callback.onPostDialWait(this, remainingPostDialSequence);
Ihab Awade63fadb2014-07-09 21:52:04 -07001068 }
1069 }
1070
1071 private void fireCallDestroyed() {
Andrew Leeda80c872015-04-15 14:09:50 -07001072 for (Callback callback : mCallbacks) {
1073 callback.onCallDestroyed(this);
Ihab Awade63fadb2014-07-09 21:52:04 -07001074 }
1075 }
1076
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001077 private void fireConferenceableCallsChanged() {
Andrew Leeda80c872015-04-15 14:09:50 -07001078 for (Callback callback : mCallbacks) {
1079 callback.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001080 }
1081 }
1082
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001083 private int stateFromParcelableCallState(int parcelableCallState) {
Santos Cordon88b771d2014-07-19 13:10:40 -07001084 switch (parcelableCallState) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001085 case CallState.NEW:
Ihab Awade63fadb2014-07-09 21:52:04 -07001086 return STATE_NEW;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001087 case CallState.CONNECTING:
Nancy Chene20930f2014-08-07 16:17:21 -07001088 return STATE_CONNECTING;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001089 case CallState.PRE_DIAL_WAIT:
Nancy Chen5da0fd52014-07-08 14:16:17 -07001090 return STATE_PRE_DIAL_WAIT;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001091 case CallState.DIALING:
Ihab Awade63fadb2014-07-09 21:52:04 -07001092 return STATE_DIALING;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001093 case CallState.RINGING:
Ihab Awade63fadb2014-07-09 21:52:04 -07001094 return STATE_RINGING;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001095 case CallState.ACTIVE:
Ihab Awade63fadb2014-07-09 21:52:04 -07001096 return STATE_ACTIVE;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001097 case CallState.ON_HOLD:
Ihab Awade63fadb2014-07-09 21:52:04 -07001098 return STATE_HOLDING;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001099 case CallState.DISCONNECTED:
Ihab Awade63fadb2014-07-09 21:52:04 -07001100 return STATE_DISCONNECTED;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001101 case CallState.ABORTED:
Ihab Awade63fadb2014-07-09 21:52:04 -07001102 return STATE_DISCONNECTED;
Tyler Gunn4afc6af2014-10-07 10:14:55 -07001103 case CallState.DISCONNECTING:
1104 return STATE_DISCONNECTING;
Ihab Awade63fadb2014-07-09 21:52:04 -07001105 default:
Santos Cordon88b771d2014-07-19 13:10:40 -07001106 Log.wtf(this, "Unrecognized CallState %s", parcelableCallState);
Ihab Awade63fadb2014-07-09 21:52:04 -07001107 return STATE_NEW;
1108 }
1109 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001110}