blob: 9273939b8cc4863a865b4c43096134971ac5216f [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;
Andrew Lee011728f2015-04-23 15:47:06 -070022import android.os.Handler;
Ihab Awade63fadb2014-07-09 21:52:04 -070023
Andrew Lee50aca232014-07-22 16:41:54 -070024import java.lang.String;
Ihab Awade63fadb2014-07-09 21:52:04 -070025import java.util.ArrayList;
26import java.util.Collections;
Andrew Lee011728f2015-04-23 15:47:06 -070027import java.util.LinkedList;
Ihab Awade63fadb2014-07-09 21:52:04 -070028import java.util.List;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070029import java.util.Map;
Ihab Awade63fadb2014-07-09 21:52:04 -070030import java.util.Objects;
Jay Shrauner229e3822014-08-15 09:23:07 -070031import java.util.concurrent.CopyOnWriteArrayList;
Ihab Awade63fadb2014-07-09 21:52:04 -070032
33/**
34 * Represents an ongoing phone call that the in-call app should present to the user.
35 */
36public final class Call {
37 /**
38 * The state of a {@code Call} when newly created.
39 */
40 public static final int STATE_NEW = 0;
41
42 /**
43 * The state of an outgoing {@code Call} when dialing the remote number, but not yet connected.
44 */
45 public static final int STATE_DIALING = 1;
46
47 /**
48 * The state of an incoming {@code Call} when ringing locally, but not yet connected.
49 */
50 public static final int STATE_RINGING = 2;
51
52 /**
53 * The state of a {@code Call} when in a holding state.
54 */
55 public static final int STATE_HOLDING = 3;
56
57 /**
58 * The state of a {@code Call} when actively supporting conversation.
59 */
60 public static final int STATE_ACTIVE = 4;
61
62 /**
63 * The state of a {@code Call} when no further voice or other communication is being
64 * transmitted, the remote side has been or will inevitably be informed that the {@code Call}
65 * is no longer active, and the local data transport has or inevitably will release resources
66 * associated with this {@code Call}.
67 */
68 public static final int STATE_DISCONNECTED = 7;
69
Nancy Chen5da0fd52014-07-08 14:16:17 -070070 /**
Santos Cordone3c507b2015-04-23 14:44:19 -070071 * The state of an outgoing {@code Call} when waiting on user to select a
72 * {@link PhoneAccount} through which to place the call.
Nancy Chen5da0fd52014-07-08 14:16:17 -070073 */
Santos Cordone3c507b2015-04-23 14:44:19 -070074 public static final int STATE_SELECT_PHONE_ACCOUNT = 8;
75
76 /**
77 * @hide
78 * @deprecated use STATE_SELECT_PHONE_ACCOUNT.
79 */
80 @Deprecated
81 @SystemApi
82 public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT;
Nancy Chen5da0fd52014-07-08 14:16:17 -070083
Nancy Chene20930f2014-08-07 16:17:21 -070084 /**
Nancy Chene9b7a8e2014-08-08 14:26:27 -070085 * The initial state of an outgoing {@code Call}.
86 * Common transitions are to {@link #STATE_DIALING} state for a successful call or
87 * {@link #STATE_DISCONNECTED} if it failed.
Nancy Chene20930f2014-08-07 16:17:21 -070088 */
89 public static final int STATE_CONNECTING = 9;
90
Nancy Chen513c8922014-09-17 14:47:20 -070091 /**
Tyler Gunn4afc6af2014-10-07 10:14:55 -070092 * The state of a {@code Call} when the user has initiated a disconnection of the call, but the
93 * call has not yet been disconnected by the underlying {@code ConnectionService}. The next
94 * state of the call is (potentially) {@link #STATE_DISCONNECTED}.
95 */
96 public static final int STATE_DISCONNECTING = 10;
97
98 /**
Nancy Chen513c8922014-09-17 14:47:20 -070099 * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
100 * extras. Used to pass the phone accounts to display on the front end to the user in order to
101 * select phone accounts to (for example) place a call.
Nancy Chen513c8922014-09-17 14:47:20 -0700102 */
103 public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
104
Ihab Awade63fadb2014-07-09 21:52:04 -0700105 public static class Details {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800106
107 /** Call can currently be put on hold or unheld. */
108 public static final int CAPABILITY_HOLD = 0x00000001;
109
110 /** Call supports the hold feature. */
111 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
112
113 /**
114 * Calls within a conference can be merged. A {@link ConnectionService} has the option to
115 * add a {@link Conference} call before the child {@link Connection}s are merged. This is how
116 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
117 * capability allows a merge button to be shown while the conference call is in the foreground
118 * of the in-call UI.
119 * <p>
120 * This is only intended for use by a {@link Conference}.
121 */
122 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
123
124 /**
125 * Calls within a conference can be swapped between foreground and background.
126 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
127 * <p>
128 * This is only intended for use by a {@link Conference}.
129 */
130 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
131
132 /**
133 * @hide
134 */
135 public static final int CAPABILITY_UNUSED = 0x00000010;
136
137 /** Call supports responding via text option. */
138 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
139
140 /** Call can be muted. */
141 public static final int CAPABILITY_MUTE = 0x00000040;
142
143 /**
144 * Call supports conference call management. This capability only applies to {@link Conference}
145 * calls which can have {@link Connection}s as children.
146 */
147 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
148
149 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700150 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800151 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700152 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800153
154 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700155 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800156 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700157 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800158
159 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700160 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800161 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700162 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700163 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800164
165 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700166 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800167 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700168 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
169
170 /**
171 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700172 */
173 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
174
175 /**
176 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700177 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700178 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700179 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800180
181 /**
182 * Call is able to be separated from its parent {@code Conference}, if any.
183 */
184 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
185
186 /**
187 * Call is able to be individually disconnected when in a {@code Conference}.
188 */
189 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
190
191 /**
192 * Whether the call is a generic conference, where we do not know the precise state of
193 * participants in the conference (eg. on CDMA).
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800194 */
195 public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
196
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700197 /**
198 * Call is using high definition audio.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700199 */
200 public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00008000;
201
202 /**
203 * Call is using WIFI.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700204 */
205 public static final int CAPABILITY_WIFI = 0x00010000;
206
Tyler Gunn068085b2015-02-06 13:56:52 -0800207 /**
208 * Indicates that the current device callback number should be shown.
Tyler Gunn068085b2015-02-06 13:56:52 -0800209 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700210 public static final int CAPABILITY_SHOW_CALLBACK_NUMBER = 0x00020000;
211
212 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500213 * Speed up audio setup for MT call.
214 * @hide
215 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700216 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
217
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700218 /**
219 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700220 * @hide
221 */
222 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
223
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700224 /**
225 * For video calls, indicates whether the outgoing video for the call can be paused using
226 * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState.
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700227 */
228 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
229
Tyler Gunnd11a3152015-03-18 13:09:14 -0700230 //******************************************************************************************
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700231 // Next CAPABILITY value: 0x00200000
Tyler Gunnd11a3152015-03-18 13:09:14 -0700232 //******************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800233
Ihab Awade63fadb2014-07-09 21:52:04 -0700234 private final Uri mHandle;
235 private final int mHandlePresentation;
236 private final String mCallerDisplayName;
237 private final int mCallerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700238 private final PhoneAccountHandle mAccountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700239 private final int mCallCapabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700240 private final int mCallProperties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700241 private final DisconnectCause mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700242 private final long mConnectTimeMillis;
243 private final GatewayInfo mGatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700244 private final int mVideoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700245 private final StatusHints mStatusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700246 private final Bundle mExtras;
Ihab Awade63fadb2014-07-09 21:52:04 -0700247
248 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800249 * Whether the supplied capabilities supports the specified capability.
250 *
251 * @param capabilities A bit field of capabilities.
252 * @param capability The capability to check capabilities for.
253 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800254 */
255 public static boolean can(int capabilities, int capability) {
256 return (capabilities & capability) != 0;
257 }
258
259 /**
260 * Whether the capabilities of this {@code Details} supports the specified capability.
261 *
262 * @param capability The capability to check capabilities for.
263 * @return Whether the specified capability is supported.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800264 */
265 public boolean can(int capability) {
266 return can(mCallCapabilities, capability);
267 }
268
269 /**
270 * Render a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
271 *
272 * @param capabilities A capability bit field.
273 * @return A human readable string representation.
274 */
275 public static String capabilitiesToString(int capabilities) {
276 StringBuilder builder = new StringBuilder();
277 builder.append("[Capabilities:");
278 if (can(capabilities, CAPABILITY_HOLD)) {
279 builder.append(" CAPABILITY_HOLD");
280 }
281 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
282 builder.append(" CAPABILITY_SUPPORT_HOLD");
283 }
284 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
285 builder.append(" CAPABILITY_MERGE_CONFERENCE");
286 }
287 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
288 builder.append(" CAPABILITY_SWAP_CONFERENCE");
289 }
290 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
291 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
292 }
293 if (can(capabilities, CAPABILITY_MUTE)) {
294 builder.append(" CAPABILITY_MUTE");
295 }
296 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
297 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
298 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700299 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
300 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
301 }
302 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
303 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
304 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700305 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
306 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800307 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700308 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
309 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
310 }
311 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
312 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
313 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700314 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
315 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800316 }
Andrew Lee80fff3c2014-11-25 17:36:51 -0800317 if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
318 builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800319 }
Andrew Lee1a8ae3e2015-02-02 13:42:38 -0800320 if (can(capabilities, CAPABILITY_WIFI)) {
321 builder.append(" CAPABILITY_WIFI");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800322 }
323 if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
324 builder.append(" CAPABILITY_GENERIC_CONFERENCE");
325 }
Tyler Gunn068085b2015-02-06 13:56:52 -0800326 if (can(capabilities, CAPABILITY_SHOW_CALLBACK_NUMBER)) {
327 builder.append(" CAPABILITY_SHOW_CALLBACK_NUMBER");
328 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500329 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700330 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500331 }
Rekha Kumar07366812015-03-24 16:42:31 -0700332 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
333 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
334 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700335 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
336 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
337 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800338 builder.append("]");
339 return builder.toString();
340 }
341
342 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700343 * @return The handle (e.g., phone number) to which the {@code Call} is currently
344 * connected.
345 */
346 public Uri getHandle() {
347 return mHandle;
348 }
349
350 /**
351 * @return The presentation requirements for the handle. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700352 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700353 */
354 public int getHandlePresentation() {
355 return mHandlePresentation;
356 }
357
358 /**
359 * @return The display name for the caller.
360 */
361 public String getCallerDisplayName() {
362 return mCallerDisplayName;
363 }
364
365 /**
366 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700367 * {@link TelecomManager} for valid values.
Ihab Awade63fadb2014-07-09 21:52:04 -0700368 */
369 public int getCallerDisplayNamePresentation() {
370 return mCallerDisplayNamePresentation;
371 }
372
373 /**
Evan Charlton6eb262c2014-07-19 18:18:19 -0700374 * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being
375 * routed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700376 */
Evan Charlton8c8a0622014-07-20 12:31:00 -0700377 public PhoneAccountHandle getAccountHandle() {
378 return mAccountHandle;
Ihab Awade63fadb2014-07-09 21:52:04 -0700379 }
380
381 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800382 * @return A bitmask of the capabilities of the {@code Call}, as defined by the various
383 * {@code CAPABILITY_*} constants in this class.
Ihab Awade63fadb2014-07-09 21:52:04 -0700384 */
Ihab Awad5d0410f2014-07-30 10:07:40 -0700385 public int getCallCapabilities() {
386 return mCallCapabilities;
Ihab Awade63fadb2014-07-09 21:52:04 -0700387 }
388
389 /**
Andrew Lee223ad142014-08-27 16:33:08 -0700390 * @return A bitmask of the properties of the {@code Call}, as defined in
391 * {@link CallProperties}.
392 */
393 public int getCallProperties() {
394 return mCallProperties;
395 }
396
397 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700398 * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700399 * by {@link android.telecom.DisconnectCause}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700400 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700401 public DisconnectCause getDisconnectCause() {
402 return mDisconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700403 }
404
405 /**
406 * @return The time the {@code Call} has been connected. This information is updated
407 * periodically, but user interfaces should not rely on this to display any "call time
408 * clock".
409 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -0700410 public final long getConnectTimeMillis() {
Ihab Awade63fadb2014-07-09 21:52:04 -0700411 return mConnectTimeMillis;
412 }
413
414 /**
415 * @return Information about any calling gateway the {@code Call} may be using.
416 */
417 public GatewayInfo getGatewayInfo() {
418 return mGatewayInfo;
419 }
420
Andrew Lee7a341382014-07-15 17:05:08 -0700421 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700422 * @return The video state of the {@code Call}.
Andrew Lee7a341382014-07-15 17:05:08 -0700423 */
424 public int getVideoState() {
425 return mVideoState;
426 }
427
Ihab Awad5d0410f2014-07-30 10:07:40 -0700428 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700429 * @return The current {@link android.telecom.StatusHints}, or {@code null} if none
Ihab Awad5d0410f2014-07-30 10:07:40 -0700430 * have been set.
Evan Charlton5b49ade2014-07-15 17:03:20 -0700431 */
432 public StatusHints getStatusHints() {
433 return mStatusHints;
434 }
435
Nancy Chen10798dc2014-08-08 14:00:25 -0700436 /**
437 * @return A bundle extras to pass with the call
438 */
439 public Bundle getExtras() {
440 return mExtras;
441 }
442
Ihab Awade63fadb2014-07-09 21:52:04 -0700443 @Override
444 public boolean equals(Object o) {
445 if (o instanceof Details) {
446 Details d = (Details) o;
447 return
448 Objects.equals(mHandle, d.mHandle) &&
449 Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
450 Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
451 Objects.equals(mCallerDisplayNamePresentation,
452 d.mCallerDisplayNamePresentation) &&
Evan Charlton8c8a0622014-07-20 12:31:00 -0700453 Objects.equals(mAccountHandle, d.mAccountHandle) &&
Ihab Awad5d0410f2014-07-30 10:07:40 -0700454 Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
Andrew Lee223ad142014-08-27 16:33:08 -0700455 Objects.equals(mCallProperties, d.mCallProperties) &&
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700456 Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
Ihab Awade63fadb2014-07-09 21:52:04 -0700457 Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
Andrew Lee85f5d422014-07-11 17:22:03 -0700458 Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Evan Charlton5b49ade2014-07-15 17:03:20 -0700459 Objects.equals(mVideoState, d.mVideoState) &&
Nancy Chen10798dc2014-08-08 14:00:25 -0700460 Objects.equals(mStatusHints, d.mStatusHints) &&
Jay Shrauner8f988432015-04-16 12:52:19 -0700461 Objects.equals(mExtras, d.mExtras);
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) +
Jay Shrauner8f988432015-04-16 12:52:19 -0700481 Objects.hashCode(mExtras);
Ihab Awade63fadb2014-07-09 21:52:04 -0700482 }
483
484 /** {@hide} */
485 public Details(
486 Uri handle,
487 int handlePresentation,
488 String callerDisplayName,
489 int callerDisplayNamePresentation,
Evan Charlton8c8a0622014-07-20 12:31:00 -0700490 PhoneAccountHandle accountHandle,
Ihab Awade63fadb2014-07-09 21:52:04 -0700491 int capabilities,
Andrew Lee223ad142014-08-27 16:33:08 -0700492 int properties,
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700493 DisconnectCause disconnectCause,
Ihab Awade63fadb2014-07-09 21:52:04 -0700494 long connectTimeMillis,
Andrew Lee85f5d422014-07-11 17:22:03 -0700495 GatewayInfo gatewayInfo,
Evan Charlton5b49ade2014-07-15 17:03:20 -0700496 int videoState,
Nancy Chen10798dc2014-08-08 14:00:25 -0700497 StatusHints statusHints,
Jay Shrauner8f988432015-04-16 12:52:19 -0700498 Bundle extras) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700499 mHandle = handle;
500 mHandlePresentation = handlePresentation;
501 mCallerDisplayName = callerDisplayName;
502 mCallerDisplayNamePresentation = callerDisplayNamePresentation;
Evan Charlton8c8a0622014-07-20 12:31:00 -0700503 mAccountHandle = accountHandle;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700504 mCallCapabilities = capabilities;
Andrew Lee223ad142014-08-27 16:33:08 -0700505 mCallProperties = properties;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700506 mDisconnectCause = disconnectCause;
Ihab Awade63fadb2014-07-09 21:52:04 -0700507 mConnectTimeMillis = connectTimeMillis;
508 mGatewayInfo = gatewayInfo;
Andrew Lee85f5d422014-07-11 17:22:03 -0700509 mVideoState = videoState;
Evan Charlton5b49ade2014-07-15 17:03:20 -0700510 mStatusHints = statusHints;
Nancy Chen10798dc2014-08-08 14:00:25 -0700511 mExtras = extras;
Ihab Awade63fadb2014-07-09 21:52:04 -0700512 }
513 }
514
Andrew Leeda80c872015-04-15 14:09:50 -0700515 public static abstract class Callback {
Ihab Awade63fadb2014-07-09 21:52:04 -0700516 /**
517 * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
518 *
Ihab Awade63fadb2014-07-09 21:52:04 -0700519 * @param call The {@code Call} invoking this method.
520 * @param state The new state of the {@code Call}.
521 */
522 public void onStateChanged(Call call, int state) {}
523
524 /**
525 * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
526 *
527 * @param call The {@code Call} invoking this method.
528 * @param parent The new parent of the {@code Call}.
529 */
530 public void onParentChanged(Call call, Call parent) {}
531
532 /**
533 * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}.
534 *
535 * @param call The {@code Call} invoking this method.
536 * @param children The new children of the {@code Call}.
537 */
538 public void onChildrenChanged(Call call, List<Call> children) {}
539
540 /**
541 * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}.
542 *
543 * @param call The {@code Call} invoking this method.
544 * @param details A {@code Details} object describing the {@code Call}.
545 */
546 public void onDetailsChanged(Call call, Details details) {}
547
548 /**
549 * Invoked when the text messages that can be used as responses to the incoming
550 * {@code Call} are loaded from the relevant database.
551 * See {@link #getCannedTextResponses()}.
552 *
553 * @param call The {@code Call} invoking this method.
554 * @param cannedTextResponses The text messages useable as responses.
555 */
556 public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
557
558 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700559 * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause
560 * character. This causes the post-dial signals to stop pending user confirmation. An
561 * implementation should present this choice to the user and invoke
562 * {@link #postDialContinue(boolean)} when the user makes the choice.
563 *
564 * @param call The {@code Call} invoking this method.
565 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
566 */
567 public void onPostDialWait(Call call, String remainingPostDialSequence) {}
568
569 /**
Andrew Lee50aca232014-07-22 16:41:54 -0700570 * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed.
Ihab Awade63fadb2014-07-09 21:52:04 -0700571 *
572 * @param call The {@code Call} invoking this method.
Andrew Lee50aca232014-07-22 16:41:54 -0700573 * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700574 */
Andrew Lee50aca232014-07-22 16:41:54 -0700575 public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {}
Ihab Awade63fadb2014-07-09 21:52:04 -0700576
577 /**
578 * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning
579 * up their UI for the {@code Call} in response to state transitions. Specifically,
580 * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of
581 * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather,
582 * clients should wait for this method to be invoked.
583 *
584 * @param call The {@code Call} being destroyed.
585 */
586 public void onCallDestroyed(Call call) {}
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700587
588 /**
589 * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
590 * conferenced.
591 *
592 * @param call The {@code Call} being updated.
593 * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
594 * conferenced.
595 */
596 public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
Ihab Awade63fadb2014-07-09 21:52:04 -0700597 }
598
Andrew Leeda80c872015-04-15 14:09:50 -0700599 /**
600 * @deprecated Use {@code Call.Callback} instead.
601 * @hide
602 */
603 @Deprecated
604 @SystemApi
605 public static abstract class Listener extends Callback { }
606
Ihab Awade63fadb2014-07-09 21:52:04 -0700607 private final Phone mPhone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700608 private final String mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700609 private final InCallAdapter mInCallAdapter;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700610 private final List<String> mChildrenIds = new ArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -0700611 private final List<Call> mChildren = new ArrayList<>();
612 private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
Andrew Lee011728f2015-04-23 15:47:06 -0700613 private final List<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArrayList<>();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700614 private final List<Call> mConferenceableCalls = new ArrayList<>();
615 private final List<Call> mUnmodifiableConferenceableCalls =
616 Collections.unmodifiableList(mConferenceableCalls);
617
Santos Cordon823fd3c2014-08-07 18:35:18 -0700618 private boolean mChildrenCached;
619 private String mParentId = null;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700620 private int mState;
Ihab Awade63fadb2014-07-09 21:52:04 -0700621 private List<String> mCannedTextResponses = null;
622 private String mRemainingPostDialSequence;
Andrew Lee50aca232014-07-22 16:41:54 -0700623 private InCallService.VideoCall mVideoCall;
Ihab Awade63fadb2014-07-09 21:52:04 -0700624 private Details mDetails;
Ihab Awade63fadb2014-07-09 21:52:04 -0700625
626 /**
627 * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
628 *
629 * @return The remaining post-dial sequence, or {@code null} if there is no post-dial sequence
630 * remaining or this {@code Call} is not in a post-dial state.
631 */
632 public String getRemainingPostDialSequence() {
633 return mRemainingPostDialSequence;
634 }
635
636 /**
637 * Instructs this {@link #STATE_RINGING} {@code Call} to answer.
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700638 * @param videoState The video state in which to answer the call.
Ihab Awade63fadb2014-07-09 21:52:04 -0700639 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700640 public void answer(int videoState) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700641 mInCallAdapter.answerCall(mTelecomCallId, videoState);
Ihab Awade63fadb2014-07-09 21:52:04 -0700642 }
643
644 /**
645 * Instructs this {@link #STATE_RINGING} {@code Call} to reject.
646 *
647 * @param rejectWithMessage Whether to reject with a text message.
648 * @param textMessage An optional text message with which to respond.
649 */
650 public void reject(boolean rejectWithMessage, String textMessage) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700651 mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
Ihab Awade63fadb2014-07-09 21:52:04 -0700652 }
653
654 /**
655 * Instructs this {@code Call} to disconnect.
656 */
657 public void disconnect() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700658 mInCallAdapter.disconnectCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700659 }
660
661 /**
662 * Instructs this {@code Call} to go on hold.
663 */
664 public void hold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700665 mInCallAdapter.holdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700666 }
667
668 /**
669 * Instructs this {@link #STATE_HOLDING} call to release from hold.
670 */
671 public void unhold() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700672 mInCallAdapter.unholdCall(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700673 }
674
675 /**
676 * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
677 *
678 * Any other currently playing DTMF tone in the specified call is immediately stopped.
679 *
680 * @param digit A character representing the DTMF digit for which to play the tone. This
681 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
682 */
683 public void playDtmfTone(char digit) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700684 mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
Ihab Awade63fadb2014-07-09 21:52:04 -0700685 }
686
687 /**
688 * Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone
689 * currently playing.
690 *
691 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
692 * currently playing, this method will do nothing.
693 */
694 public void stopDtmfTone() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700695 mInCallAdapter.stopDtmfTone(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700696 }
697
698 /**
699 * Instructs this {@code Call} to continue playing a post-dial DTMF string.
700 *
701 * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
702 * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
Ihab Awade63fadb2014-07-09 21:52:04 -0700703 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700704 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awade63fadb2014-07-09 21:52:04 -0700705 * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
706 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700707 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Leeda80c872015-04-15 14:09:50 -0700708 * {@code Call} will pause playing the tones and notify callbacks via
709 * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
Ihab Awade63fadb2014-07-09 21:52:04 -0700710 * should display to the user an indication of this state and an affordance to continue
711 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
712 * app should invoke the {@link #postDialContinue(boolean)} method.
713 *
714 * @param proceed Whether or not to continue with the post-dial sequence.
715 */
716 public void postDialContinue(boolean proceed) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700717 mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
Ihab Awade63fadb2014-07-09 21:52:04 -0700718 }
719
720 /**
Evan Charlton8c8a0622014-07-20 12:31:00 -0700721 * Notifies this {@code Call} that an account has been selected and to proceed with placing
Nancy Chen36c62f32014-10-21 18:36:39 -0700722 * an outgoing call. Optionally sets this account as the default account.
Nancy Chen5da0fd52014-07-08 14:16:17 -0700723 */
Nancy Chen36c62f32014-10-21 18:36:39 -0700724 public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) {
725 mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);
Nancy Chen5da0fd52014-07-08 14:16:17 -0700726
727 }
728
729 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700730 * Instructs this {@code Call} to enter a conference.
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700731 *
732 * @param callToConferenceWith The other call with which to conference.
Ihab Awade63fadb2014-07-09 21:52:04 -0700733 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700734 public void conference(Call callToConferenceWith) {
735 if (callToConferenceWith != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700736 mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700737 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700738 }
739
740 /**
741 * Instructs this {@code Call} to split from any conference call with which it may be
742 * connected.
743 */
744 public void splitFromConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700745 mInCallAdapter.splitFromConference(mTelecomCallId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700746 }
747
748 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800749 * Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700750 */
751 public void mergeConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700752 mInCallAdapter.mergeConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -0700753 }
754
755 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800756 * Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700757 */
758 public void swapConference() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700759 mInCallAdapter.swapConference(mTelecomCallId);
Santos Cordona4868042014-09-04 17:39:22 -0700760 }
761
762 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700763 * Obtains the parent of this {@code Call} in a conference, if any.
764 *
765 * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
766 * child of any conference {@code Call}s.
767 */
768 public Call getParent() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700769 if (mParentId != null) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700770 return mPhone.internalGetCallByTelecomId(mParentId);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700771 }
772 return null;
Ihab Awade63fadb2014-07-09 21:52:04 -0700773 }
774
775 /**
776 * Obtains the children of this conference {@code Call}, if any.
777 *
778 * @return The children of this {@code Call} if this {@code Call} is a conference, or an empty
779 * {@code List} otherwise.
780 */
781 public List<Call> getChildren() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700782 if (!mChildrenCached) {
783 mChildrenCached = true;
784 mChildren.clear();
785
786 for(String id : mChildrenIds) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700787 Call call = mPhone.internalGetCallByTelecomId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700788 if (call == null) {
789 // At least one child was still not found, so do not save true for "cached"
790 mChildrenCached = false;
791 } else {
792 mChildren.add(call);
793 }
794 }
795 }
796
Ihab Awade63fadb2014-07-09 21:52:04 -0700797 return mUnmodifiableChildren;
798 }
799
800 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700801 * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
802 *
803 * @return The list of conferenceable {@code Call}s.
804 */
805 public List<Call> getConferenceableCalls() {
806 return mUnmodifiableConferenceableCalls;
807 }
808
809 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700810 * Obtains the state of this {@code Call}.
811 *
812 * @return A state value, chosen from the {@code STATE_*} constants.
813 */
814 public int getState() {
815 return mState;
816 }
817
818 /**
819 * Obtains a list of canned, pre-configured message responses to present to the user as
820 * ways of rejecting this {@code Call} using via a text message.
821 *
822 * @see #reject(boolean, String)
823 *
824 * @return A list of canned text message responses.
825 */
826 public List<String> getCannedTextResponses() {
827 return mCannedTextResponses;
828 }
829
830 /**
831 * Obtains an object that can be used to display video from this {@code Call}.
832 *
Andrew Lee50aca232014-07-22 16:41:54 -0700833 * @return An {@code Call.VideoCall}.
Ihab Awade63fadb2014-07-09 21:52:04 -0700834 */
Andrew Lee50aca232014-07-22 16:41:54 -0700835 public InCallService.VideoCall getVideoCall() {
836 return mVideoCall;
Ihab Awade63fadb2014-07-09 21:52:04 -0700837 }
838
839 /**
840 * Obtains an object containing call details.
841 *
842 * @return A {@link Details} object. Depending on the state of the {@code Call}, the
843 * result may be {@code null}.
844 */
845 public Details getDetails() {
846 return mDetails;
847 }
848
849 /**
Andrew Leeda80c872015-04-15 14:09:50 -0700850 * Registers a callback to this {@code Call}.
851 *
852 * @param callback A {@code Callback}.
853 */
854 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700855 registerCallback(callback, new Handler());
856 }
857
858 /**
859 * Registers a callback to this {@code Call}.
860 *
861 * @param callback A {@code Callback}.
862 * @param handler A handler which command and status changes will be delivered to.
863 */
864 public void registerCallback(Callback callback, Handler handler) {
865 unregisterCallback(callback);
866 if (callback != null && handler != null) {
867 mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler));
868 }
Andrew Leeda80c872015-04-15 14:09:50 -0700869 }
870
871 /**
872 * Unregisters a callback from this {@code Call}.
873 *
874 * @param callback A {@code Callback}.
875 */
876 public void unregisterCallback(Callback callback) {
877 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700878 for (CallbackRecord<Callback> record : mCallbackRecords) {
879 if (record.getCallback() == callback) {
880 mCallbackRecords.remove(record);
881 break;
882 }
883 }
Andrew Leeda80c872015-04-15 14:09:50 -0700884 }
885 }
886
887 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700888 * Adds a listener to this {@code Call}.
889 *
890 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -0700891 * @deprecated Use {@link #registerCallback} instead.
892 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -0700893 */
Andrew Leeda80c872015-04-15 14:09:50 -0700894 @Deprecated
895 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -0700896 public void addListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -0700897 registerCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -0700898 }
899
900 /**
901 * Removes a listener from this {@code Call}.
902 *
903 * @param listener A {@code Listener}.
Andrew Leeda80c872015-04-15 14:09:50 -0700904 * @deprecated Use {@link #unregisterCallback} instead.
905 * @hide
Ihab Awade63fadb2014-07-09 21:52:04 -0700906 */
Andrew Leeda80c872015-04-15 14:09:50 -0700907 @Deprecated
908 @SystemApi
Ihab Awade63fadb2014-07-09 21:52:04 -0700909 public void removeListener(Listener listener) {
Andrew Leeda80c872015-04-15 14:09:50 -0700910 unregisterCallback(listener);
Ihab Awade63fadb2014-07-09 21:52:04 -0700911 }
912
Andrew Leeda80c872015-04-15 14:09:50 -0700913
Ihab Awade63fadb2014-07-09 21:52:04 -0700914 /** {@hide} */
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700915 Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700916 mPhone = phone;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700917 mTelecomCallId = telecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700918 mInCallAdapter = inCallAdapter;
919 mState = STATE_NEW;
920 }
921
922 /** {@hide} */
923 final String internalGetCallId() {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700924 return mTelecomCallId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700925 }
926
927 /** {@hide} */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700928 final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700929 // First, we update the internal state as far as possible before firing any updates.
Ihab Awade63fadb2014-07-09 21:52:04 -0700930 Details details = new Details(
Santos Cordon88b771d2014-07-19 13:10:40 -0700931 parcelableCall.getHandle(),
932 parcelableCall.getHandlePresentation(),
933 parcelableCall.getCallerDisplayName(),
934 parcelableCall.getCallerDisplayNamePresentation(),
935 parcelableCall.getAccountHandle(),
936 parcelableCall.getCapabilities(),
Andrew Lee223ad142014-08-27 16:33:08 -0700937 parcelableCall.getProperties(),
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700938 parcelableCall.getDisconnectCause(),
Santos Cordon88b771d2014-07-19 13:10:40 -0700939 parcelableCall.getConnectTimeMillis(),
940 parcelableCall.getGatewayInfo(),
941 parcelableCall.getVideoState(),
Nancy Chen10798dc2014-08-08 14:00:25 -0700942 parcelableCall.getStatusHints(),
Jay Shrauner8f988432015-04-16 12:52:19 -0700943 parcelableCall.getExtras());
Ihab Awade63fadb2014-07-09 21:52:04 -0700944 boolean detailsChanged = !Objects.equals(mDetails, details);
945 if (detailsChanged) {
946 mDetails = details;
947 }
948
949 boolean cannedTextResponsesChanged = false;
Santos Cordon88b771d2014-07-19 13:10:40 -0700950 if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
951 && !parcelableCall.getCannedSmsResponses().isEmpty()) {
952 mCannedTextResponses =
953 Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
Ihab Awade63fadb2014-07-09 21:52:04 -0700954 }
955
Tyler Gunn75958422015-04-15 14:23:42 -0700956 boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
957 !Objects.equals(mVideoCall, parcelableCall.getVideoCall());
Andrew Lee50aca232014-07-22 16:41:54 -0700958 if (videoCallChanged) {
959 mVideoCall = parcelableCall.getVideoCall();
Ihab Awade63fadb2014-07-09 21:52:04 -0700960 }
961
Santos Cordone3c507b2015-04-23 14:44:19 -0700962 int state = parcelableCall.getState();
Ihab Awade63fadb2014-07-09 21:52:04 -0700963 boolean stateChanged = mState != state;
964 if (stateChanged) {
965 mState = state;
966 }
967
Santos Cordon823fd3c2014-08-07 18:35:18 -0700968 String parentId = parcelableCall.getParentCallId();
969 boolean parentChanged = !Objects.equals(mParentId, parentId);
970 if (parentChanged) {
971 mParentId = parentId;
Ihab Awade63fadb2014-07-09 21:52:04 -0700972 }
973
Santos Cordon823fd3c2014-08-07 18:35:18 -0700974 List<String> childCallIds = parcelableCall.getChildCallIds();
975 boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
976 if (childrenChanged) {
977 mChildrenIds.clear();
978 mChildrenIds.addAll(parcelableCall.getChildCallIds());
979 mChildrenCached = false;
Ihab Awade63fadb2014-07-09 21:52:04 -0700980 }
981
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700982 List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
983 List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
984 for (String otherId : conferenceableCallIds) {
985 if (callIdMap.containsKey(otherId)) {
986 conferenceableCalls.add(callIdMap.get(otherId));
987 }
988 }
989
990 if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
991 mConferenceableCalls.clear();
992 mConferenceableCalls.addAll(conferenceableCalls);
993 fireConferenceableCallsChanged();
994 }
995
Ihab Awade63fadb2014-07-09 21:52:04 -0700996 // Now we fire updates, ensuring that any client who listens to any of these notifications
997 // gets the most up-to-date state.
998
999 if (stateChanged) {
1000 fireStateChanged(mState);
1001 }
1002 if (detailsChanged) {
1003 fireDetailsChanged(mDetails);
1004 }
1005 if (cannedTextResponsesChanged) {
1006 fireCannedTextResponsesLoaded(mCannedTextResponses);
1007 }
Andrew Lee50aca232014-07-22 16:41:54 -07001008 if (videoCallChanged) {
1009 fireVideoCallChanged(mVideoCall);
Ihab Awade63fadb2014-07-09 21:52:04 -07001010 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001011 if (parentChanged) {
1012 fireParentChanged(getParent());
1013 }
1014 if (childrenChanged) {
1015 fireChildrenChanged(getChildren());
1016 }
Ihab Awade63fadb2014-07-09 21:52:04 -07001017
1018 // If we have transitioned to DISCONNECTED, that means we need to notify clients and
1019 // remove ourselves from the Phone. Note that we do this after completing all state updates
1020 // so a client can cleanly transition all their UI to the state appropriate for a
1021 // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
1022 if (mState == STATE_DISCONNECTED) {
1023 fireCallDestroyed();
1024 mPhone.internalRemoveCall(this);
1025 }
1026 }
1027
1028 /** {@hide} */
Ihab Awade63fadb2014-07-09 21:52:04 -07001029 final void internalSetPostDialWait(String remaining) {
1030 mRemainingPostDialSequence = remaining;
1031 firePostDialWait(mRemainingPostDialSequence);
1032 }
1033
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001034 /** {@hide} */
Santos Cordonf30d7e92014-08-26 09:54:33 -07001035 final void internalSetDisconnected() {
1036 if (mState != Call.STATE_DISCONNECTED) {
1037 mState = Call.STATE_DISCONNECTED;
1038 fireStateChanged(mState);
1039 fireCallDestroyed();
1040 mPhone.internalRemoveCall(this);
1041 }
1042 }
1043
Andrew Lee011728f2015-04-23 15:47:06 -07001044 private void fireStateChanged(final int newState) {
1045 for (CallbackRecord<Callback> record : mCallbackRecords) {
1046 final Call call = this;
1047 final Callback callback = record.getCallback();
1048 record.getHandler().post(new Runnable() {
1049 @Override
1050 public void run() {
1051 callback.onStateChanged(call, newState);
1052 }
1053 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001054 }
1055 }
1056
Andrew Lee011728f2015-04-23 15:47:06 -07001057 private void fireParentChanged(final Call newParent) {
1058 for (CallbackRecord<Callback> record : mCallbackRecords) {
1059 final Call call = this;
1060 final Callback callback = record.getCallback();
1061 record.getHandler().post(new Runnable() {
1062 @Override
1063 public void run() {
1064 callback.onParentChanged(call, newParent);
1065 }
1066 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001067 }
1068 }
1069
Andrew Lee011728f2015-04-23 15:47:06 -07001070 private void fireChildrenChanged(final List<Call> children) {
1071 for (CallbackRecord<Callback> record : mCallbackRecords) {
1072 final Call call = this;
1073 final Callback callback = record.getCallback();
1074 record.getHandler().post(new Runnable() {
1075 @Override
1076 public void run() {
1077 callback.onChildrenChanged(call, children);
1078 }
1079 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001080 }
1081 }
1082
Andrew Lee011728f2015-04-23 15:47:06 -07001083 private void fireDetailsChanged(final Details details) {
1084 for (CallbackRecord<Callback> record : mCallbackRecords) {
1085 final Call call = this;
1086 final Callback callback = record.getCallback();
1087 record.getHandler().post(new Runnable() {
1088 @Override
1089 public void run() {
1090 callback.onDetailsChanged(call, details);
1091 }
1092 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001093 }
1094 }
1095
Andrew Lee011728f2015-04-23 15:47:06 -07001096 private void fireCannedTextResponsesLoaded(final List<String> cannedTextResponses) {
1097 for (CallbackRecord<Callback> record : mCallbackRecords) {
1098 final Call call = this;
1099 final Callback callback = record.getCallback();
1100 record.getHandler().post(new Runnable() {
1101 @Override
1102 public void run() {
1103 callback.onCannedTextResponsesLoaded(call, cannedTextResponses);
1104 }
1105 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001106 }
1107 }
1108
Andrew Lee011728f2015-04-23 15:47:06 -07001109 private void fireVideoCallChanged(final InCallService.VideoCall videoCall) {
1110 for (CallbackRecord<Callback> record : mCallbackRecords) {
1111 final Call call = this;
1112 final Callback callback = record.getCallback();
1113 record.getHandler().post(new Runnable() {
1114 @Override
1115 public void run() {
1116 callback.onVideoCallChanged(call, videoCall);
1117 }
1118 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001119 }
1120 }
1121
Andrew Lee011728f2015-04-23 15:47:06 -07001122 private void firePostDialWait(final String remainingPostDialSequence) {
1123 for (CallbackRecord<Callback> record : mCallbackRecords) {
1124 final Call call = this;
1125 final Callback callback = record.getCallback();
1126 record.getHandler().post(new Runnable() {
1127 @Override
1128 public void run() {
1129 callback.onPostDialWait(call, remainingPostDialSequence);
1130 }
1131 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001132 }
1133 }
1134
1135 private void fireCallDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -07001136 for (CallbackRecord<Callback> record: mCallbackRecords) {
1137 final Call call = this;
1138 final Callback callback = record.getCallback();
1139 record.getHandler().post(new Runnable() {
1140 @Override
1141 public void run() {
1142 callback.onCallDestroyed(call);
1143 }
1144 });
Ihab Awade63fadb2014-07-09 21:52:04 -07001145 }
1146 }
1147
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001148 private void fireConferenceableCallsChanged() {
Andrew Lee011728f2015-04-23 15:47:06 -07001149 for (CallbackRecord<Callback> record : mCallbackRecords) {
1150 final Call call = this;
1151 final Callback callback = record.getCallback();
1152 record.getHandler().post(new Runnable() {
1153 @Override
1154 public void run() {
1155 callback.onConferenceableCallsChanged(call, mUnmodifiableConferenceableCalls);
1156 }
1157 });
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001158 }
1159 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001160}