blob: 03fec0104d7c117ba7761f5f2f040101af21fefd [file] [log] [blame]
Ihab Awad542e0ea2014-05-16 10:22:16 -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 Awad542e0ea2014-05-16 10:22:16 -070018
Tyler Gunnef9f6f92014-09-12 22:16:17 -070019import com.android.internal.telecom.IVideoCallback;
20import com.android.internal.telecom.IVideoProvider;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070021
Evan Charlton0e094d92014-11-08 15:49:16 -080022import android.annotation.SystemApi;
Ihab Awad542e0ea2014-05-16 10:22:16 -070023import android.net.Uri;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070024import android.os.Handler;
25import android.os.IBinder;
26import android.os.Message;
27import android.os.RemoteException;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070028import android.view.Surface;
Ihab Awad542e0ea2014-05-16 10:22:16 -070029
Santos Cordonb6939982014-06-04 20:20:58 -070030import java.util.ArrayList;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070031import java.util.Collections;
Santos Cordonb6939982014-06-04 20:20:58 -070032import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070033import java.util.Set;
Jay Shrauner229e3822014-08-15 09:23:07 -070034import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070035
36/**
37 * Represents a connection to a remote endpoint that carries voice traffic.
Ihab Awad6107bab2014-08-18 09:23:25 -070038 * <p>
39 * Implementations create a custom subclass of {@code Connection} and return it to the framework
40 * as the return value of
41 * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
42 * or
43 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
44 * Implementations are then responsible for updating the state of the {@code Connection}, and
45 * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
46 * longer used and associated resources may be recovered.
Evan Charlton0e094d92014-11-08 15:49:16 -080047 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -070048 */
Evan Charlton0e094d92014-11-08 15:49:16 -080049@SystemApi
Tyler Gunn6d76ca02014-11-17 15:49:51 -080050public abstract class Connection implements IConferenceable {
Ihab Awad542e0ea2014-05-16 10:22:16 -070051
Ihab Awadb19a0bc2014-08-07 19:46:01 -070052 public static final int STATE_INITIALIZING = 0;
53
54 public static final int STATE_NEW = 1;
55
56 public static final int STATE_RINGING = 2;
57
58 public static final int STATE_DIALING = 3;
59
60 public static final int STATE_ACTIVE = 4;
61
62 public static final int STATE_HOLDING = 5;
63
64 public static final int STATE_DISCONNECTED = 6;
65
Ihab Awad5c9c86e2014-11-12 13:41:16 -080066 /** Connection can currently be put on hold or unheld. */
67 public static final int CAPABILITY_HOLD = 0x00000001;
68
69 /** Connection supports the hold feature. */
70 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
71
72 /**
73 * Connections within a conference can be merged. A {@link ConnectionService} has the option to
74 * add a {@link Conference} before the child {@link Connection}s are merged. This is how
75 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
76 * capability allows a merge button to be shown while the conference is in the foreground
77 * of the in-call UI.
78 * <p>
79 * This is only intended for use by a {@link Conference}.
80 */
81 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
82
83 /**
84 * Connections within a conference can be swapped between foreground and background.
85 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
86 * <p>
87 * This is only intended for use by a {@link Conference}.
88 */
89 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
90
91 /**
92 * @hide
93 */
94 public static final int CAPABILITY_UNUSED = 0x00000010;
95
96 /** Connection supports responding via text option. */
97 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
98
99 /** Connection can be muted. */
100 public static final int CAPABILITY_MUTE = 0x00000040;
101
102 /**
103 * Connection supports conference management. This capability only applies to
104 * {@link Conference}s which can have {@link Connection}s as children.
105 */
106 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
107
108 /**
109 * Local device supports video telephony.
110 * @hide
111 */
112 public static final int CAPABILITY_SUPPORTS_VT_LOCAL = 0x00000100;
113
114 /**
115 * Remote device supports video telephony.
116 * @hide
117 */
118 public static final int CAPABILITY_SUPPORTS_VT_REMOTE = 0x00000200;
119
120 /**
Andrew Lee80fff3c2014-11-25 17:36:51 -0800121 * Connection is using high definition audio.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800122 * @hide
123 */
Andrew Lee80fff3c2014-11-25 17:36:51 -0800124 public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00000400;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800125
126 /**
127 * Connection is using voice over WIFI.
128 * @hide
129 */
130 public static final int CAPABILITY_VoWIFI = 0x00000800;
131
132 /**
133 * Connection is able to be separated from its parent {@code Conference}, if any.
134 */
135 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
136
137 /**
138 * Connection is able to be individually disconnected when in a {@code Conference}.
139 */
140 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
141
142 /**
143 * Whether the call is a generic conference, where we do not know the precise state of
144 * participants in the conference (eg. on CDMA).
145 *
146 * @hide
147 */
148 public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
149
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700150 // Flag controlling whether PII is emitted into the logs
151 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
152
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800153 /**
154 * Whether the given capabilities support the specified capability.
155 *
156 * @param capabilities A capability bit field.
157 * @param capability The capability to check capabilities for.
158 * @return Whether the specified capability is supported.
159 * @hide
160 */
161 public static boolean can(int capabilities, int capability) {
162 return (capabilities & capability) != 0;
163 }
164
165 /**
166 * Whether the capabilities of this {@code Connection} supports the specified capability.
167 *
168 * @param capability The capability to check capabilities for.
169 * @return Whether the specified capability is supported.
170 * @hide
171 */
172 public boolean can(int capability) {
173 return can(mConnectionCapabilities, capability);
174 }
175
176 /**
177 * Removes the specified capability from the set of capabilities of this {@code Connection}.
178 *
179 * @param capability The capability to remove from the set.
180 * @hide
181 */
182 public void removeCapability(int capability) {
183 mConnectionCapabilities &= ~capability;
184 }
185
186 /**
187 * Adds the specified capability to the set of capabilities of this {@code Connection}.
188 *
189 * @param capability The capability to add to the set.
190 * @hide
191 */
192 public void addCapability(int capability) {
193 mConnectionCapabilities |= capability;
194 }
195
196
197 public static String capabilitiesToString(int capabilities) {
198 StringBuilder builder = new StringBuilder();
199 builder.append("[Capabilities:");
200 if (can(capabilities, CAPABILITY_HOLD)) {
201 builder.append(" CAPABILITY_HOLD");
202 }
203 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
204 builder.append(" CAPABILITY_SUPPORT_HOLD");
205 }
206 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
207 builder.append(" CAPABILITY_MERGE_CONFERENCE");
208 }
209 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
210 builder.append(" CAPABILITY_SWAP_CONFERENCE");
211 }
212 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
213 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
214 }
215 if (can(capabilities, CAPABILITY_MUTE)) {
216 builder.append(" CAPABILITY_MUTE");
217 }
218 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
219 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
220 }
221 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL)) {
222 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL");
223 }
224 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE)) {
225 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE");
226 }
Andrew Lee80fff3c2014-11-25 17:36:51 -0800227 if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
228 builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800229 }
230 if (can(capabilities, CAPABILITY_VoWIFI)) {
231 builder.append(" CAPABILITY_VoWIFI");
232 }
233 if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
234 builder.append(" CAPABILITY_GENERIC_CONFERENCE");
235 }
236 builder.append("]");
237 return builder.toString();
238 }
239
Sailesh Nepal091768c2014-06-30 15:15:23 -0700240 /** @hide */
Sailesh Nepal61203862014-07-11 14:50:13 -0700241 public abstract static class Listener {
Ihab Awad542e0ea2014-05-16 10:22:16 -0700242 public void onStateChanged(Connection c, int state) {}
Andrew Lee100e2932014-09-08 15:34:24 -0700243 public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
Sailesh Nepal61203862014-07-11 14:50:13 -0700244 public void onCallerDisplayNameChanged(
245 Connection c, String callerDisplayName, int presentation) {}
Tyler Gunnaa07df82014-07-17 07:50:22 -0700246 public void onVideoStateChanged(Connection c, int videoState) {}
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700247 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {}
Sailesh Nepal091768c2014-06-30 15:15:23 -0700248 public void onPostDialWait(Connection c, String remaining) {}
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800249 public void onPostDialChar(Connection c, char nextChar) {}
Andrew Lee100e2932014-09-08 15:34:24 -0700250 public void onRingbackRequested(Connection c, boolean ringback) {}
Sailesh Nepal61203862014-07-11 14:50:13 -0700251 public void onDestroyed(Connection c) {}
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800252 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700253 public void onVideoProviderChanged(
254 Connection c, VideoProvider videoProvider) {}
Sailesh Nepal001bbbb2014-07-15 14:40:39 -0700255 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
256 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
Tyler Gunn6d76ca02014-11-17 15:49:51 -0800257 public void onConferenceablesChanged(
258 Connection c, List<IConferenceable> conferenceables) {}
Santos Cordon823fd3c2014-08-07 18:35:18 -0700259 public void onConferenceChanged(Connection c, Conference conference) {}
Tyler Gunn3bffcf72014-10-28 13:51:27 -0700260 /** @hide */
Tyler Gunnab4650c2014-11-06 20:06:23 -0800261 public void onConferenceParticipantsChanged(Connection c,
262 List<ConferenceParticipant> participants) {}
Tyler Gunn8a2b1192015-01-29 11:47:24 -0800263 public void onConferenceStarted() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -0700264 }
265
Tyler Gunn27d1e252014-08-21 16:38:40 -0700266 /** @hide */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700267 public static abstract class VideoProvider {
Ihab Awad542e0ea2014-05-16 10:22:16 -0700268
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700269 /**
270 * Video is not being received (no protocol pause was issued).
271 */
272 public static final int SESSION_EVENT_RX_PAUSE = 1;
Evan Charltonbf11f982014-07-20 22:06:28 -0700273
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700274 /**
275 * Video reception has resumed after a SESSION_EVENT_RX_PAUSE.
276 */
277 public static final int SESSION_EVENT_RX_RESUME = 2;
278
279 /**
280 * Video transmission has begun. This occurs after a negotiated start of video transmission
281 * when the underlying protocol has actually begun transmitting video to the remote party.
282 */
283 public static final int SESSION_EVENT_TX_START = 3;
284
285 /**
286 * Video transmission has stopped. This occurs after a negotiated stop of video transmission
287 * when the underlying protocol has actually stopped transmitting video to the remote party.
288 */
289 public static final int SESSION_EVENT_TX_STOP = 4;
290
291 /**
292 * A camera failure has occurred for the selected camera. The In-Call UI can use this as a
293 * cue to inform the user the camera is not available.
294 */
295 public static final int SESSION_EVENT_CAMERA_FAILURE = 5;
296
297 /**
298 * Issued after {@code SESSION_EVENT_CAMERA_FAILURE} when the camera is once again ready for
299 * operation. The In-Call UI can use this as a cue to inform the user that the camera has
300 * become available again.
301 */
302 public static final int SESSION_EVENT_CAMERA_READY = 6;
303
304 /**
305 * Session modify request was successful.
306 */
307 public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1;
308
309 /**
310 * Session modify request failed.
311 */
312 public static final int SESSION_MODIFY_REQUEST_FAIL = 2;
313
314 /**
315 * Session modify request ignored due to invalid parameters.
316 */
317 public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
318
Ihab Awada64627c2014-08-20 09:36:40 -0700319 private static final int MSG_SET_VIDEO_CALLBACK = 1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700320 private static final int MSG_SET_CAMERA = 2;
321 private static final int MSG_SET_PREVIEW_SURFACE = 3;
322 private static final int MSG_SET_DISPLAY_SURFACE = 4;
323 private static final int MSG_SET_DEVICE_ORIENTATION = 5;
324 private static final int MSG_SET_ZOOM = 6;
325 private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7;
326 private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8;
327 private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800328 private static final int MSG_REQUEST_CONNECTION_DATA_USAGE = 10;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700329 private static final int MSG_SET_PAUSE_IMAGE = 11;
330
331 private final VideoProvider.VideoProviderHandler
332 mMessageHandler = new VideoProvider.VideoProviderHandler();
333 private final VideoProvider.VideoProviderBinder mBinder;
Ihab Awada64627c2014-08-20 09:36:40 -0700334 private IVideoCallback mVideoCallback;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700335
336 /**
337 * Default handler used to consolidate binder method calls onto a single thread.
338 */
339 private final class VideoProviderHandler extends Handler {
340 @Override
341 public void handleMessage(Message msg) {
342 switch (msg.what) {
Ihab Awada64627c2014-08-20 09:36:40 -0700343 case MSG_SET_VIDEO_CALLBACK:
344 mVideoCallback = IVideoCallback.Stub.asInterface((IBinder) msg.obj);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700345 break;
346 case MSG_SET_CAMERA:
347 onSetCamera((String) msg.obj);
348 break;
349 case MSG_SET_PREVIEW_SURFACE:
350 onSetPreviewSurface((Surface) msg.obj);
351 break;
352 case MSG_SET_DISPLAY_SURFACE:
353 onSetDisplaySurface((Surface) msg.obj);
354 break;
355 case MSG_SET_DEVICE_ORIENTATION:
356 onSetDeviceOrientation(msg.arg1);
357 break;
358 case MSG_SET_ZOOM:
359 onSetZoom((Float) msg.obj);
360 break;
361 case MSG_SEND_SESSION_MODIFY_REQUEST:
362 onSendSessionModifyRequest((VideoProfile) msg.obj);
363 break;
364 case MSG_SEND_SESSION_MODIFY_RESPONSE:
365 onSendSessionModifyResponse((VideoProfile) msg.obj);
366 break;
367 case MSG_REQUEST_CAMERA_CAPABILITIES:
368 onRequestCameraCapabilities();
369 break;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800370 case MSG_REQUEST_CONNECTION_DATA_USAGE:
371 onRequestConnectionDataUsage();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700372 break;
373 case MSG_SET_PAUSE_IMAGE:
374 onSetPauseImage((String) msg.obj);
375 break;
376 default:
377 break;
378 }
379 }
380 }
381
382 /**
383 * IVideoProvider stub implementation.
384 */
385 private final class VideoProviderBinder extends IVideoProvider.Stub {
Ihab Awada64627c2014-08-20 09:36:40 -0700386 public void setVideoCallback(IBinder videoCallbackBinder) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700387 mMessageHandler.obtainMessage(
Ihab Awada64627c2014-08-20 09:36:40 -0700388 MSG_SET_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700389 }
390
391 public void setCamera(String cameraId) {
392 mMessageHandler.obtainMessage(MSG_SET_CAMERA, cameraId).sendToTarget();
393 }
394
395 public void setPreviewSurface(Surface surface) {
396 mMessageHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget();
397 }
398
399 public void setDisplaySurface(Surface surface) {
400 mMessageHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget();
401 }
402
403 public void setDeviceOrientation(int rotation) {
404 mMessageHandler.obtainMessage(MSG_SET_DEVICE_ORIENTATION, rotation).sendToTarget();
405 }
406
407 public void setZoom(float value) {
408 mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget();
409 }
410
411 public void sendSessionModifyRequest(VideoProfile requestProfile) {
412 mMessageHandler.obtainMessage(
413 MSG_SEND_SESSION_MODIFY_REQUEST, requestProfile).sendToTarget();
414 }
415
416 public void sendSessionModifyResponse(VideoProfile responseProfile) {
417 mMessageHandler.obtainMessage(
418 MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget();
419 }
420
421 public void requestCameraCapabilities() {
422 mMessageHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget();
423 }
424
425 public void requestCallDataUsage() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800426 mMessageHandler.obtainMessage(MSG_REQUEST_CONNECTION_DATA_USAGE).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700427 }
428
429 public void setPauseImage(String uri) {
430 mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget();
431 }
432 }
433
434 public VideoProvider() {
435 mBinder = new VideoProvider.VideoProviderBinder();
436 }
437
438 /**
439 * Returns binder object which can be used across IPC methods.
440 * @hide
441 */
442 public final IVideoProvider getInterface() {
443 return mBinder;
444 }
445
446 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800447 * Sets the camera to be used for video recording in a video connection.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700448 *
449 * @param cameraId The id of the camera.
450 */
451 public abstract void onSetCamera(String cameraId);
452
453 /**
454 * Sets the surface to be used for displaying a preview of what the user's camera is
455 * currently capturing. When video transmission is enabled, this is the video signal which
456 * is sent to the remote device.
457 *
458 * @param surface The surface.
459 */
460 public abstract void onSetPreviewSurface(Surface surface);
461
462 /**
463 * Sets the surface to be used for displaying the video received from the remote device.
464 *
465 * @param surface The surface.
466 */
467 public abstract void onSetDisplaySurface(Surface surface);
468
469 /**
470 * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of
471 * the device is 0 degrees.
472 *
473 * @param rotation The device orientation, in degrees.
474 */
475 public abstract void onSetDeviceOrientation(int rotation);
476
477 /**
478 * Sets camera zoom ratio.
479 *
480 * @param value The camera zoom ratio.
481 */
482 public abstract void onSetZoom(float value);
483
484 /**
485 * Issues a request to modify the properties of the current session. The request is
486 * sent to the remote device where it it handled by the In-Call UI.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800487 * Some examples of session modification requests: upgrade connection from audio to video,
488 * downgrade connection from video to audio, pause video.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700489 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800490 * @param requestProfile The requested connection video properties.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700491 */
492 public abstract void onSendSessionModifyRequest(VideoProfile requestProfile);
493
494 /**te
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800495 * Provides a response to a request to change the current connection session video
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700496 * properties.
497 * This is in response to a request the InCall UI has received via the InCall UI.
498 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800499 * @param responseProfile The response connection video properties.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700500 */
501 public abstract void onSendSessionModifyResponse(VideoProfile responseProfile);
502
503 /**
504 * Issues a request to the video provider to retrieve the camera capabilities.
505 * Camera capabilities are reported back to the caller via the In-Call UI.
506 */
507 public abstract void onRequestCameraCapabilities();
508
509 /**
510 * Issues a request to the video telephony framework to retrieve the cumulative data usage
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800511 * for the current connection. Data usage is reported back to the caller via the
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700512 * InCall UI.
513 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800514 public abstract void onRequestConnectionDataUsage();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700515
516 /**
517 * Provides the video telephony framework with the URI of an image to be displayed to remote
518 * devices when the video signal is paused.
519 *
520 * @param uri URI of image to display.
521 */
522 public abstract void onSetPauseImage(String uri);
523
524 /**
525 * Invokes callback method defined in In-Call UI.
526 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800527 * @param videoProfile The requested video connection profile.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700528 */
529 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700530 if (mVideoCallback != null) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700531 try {
Ihab Awada64627c2014-08-20 09:36:40 -0700532 mVideoCallback.receiveSessionModifyRequest(videoProfile);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700533 } catch (RemoteException ignored) {
534 }
535 }
536 }
537
538 /**
539 * Invokes callback method defined in In-Call UI.
540 *
541 * @param status Status of the session modify request. Valid values are
542 * {@link VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS},
543 * {@link VideoProvider#SESSION_MODIFY_REQUEST_FAIL},
544 * {@link VideoProvider#SESSION_MODIFY_REQUEST_INVALID}
545 * @param requestedProfile The original request which was sent to the remote device.
546 * @param responseProfile The actual profile changes made by the remote device.
547 */
548 public void receiveSessionModifyResponse(int status,
549 VideoProfile requestedProfile, VideoProfile responseProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700550 if (mVideoCallback != null) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700551 try {
Ihab Awada64627c2014-08-20 09:36:40 -0700552 mVideoCallback.receiveSessionModifyResponse(
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700553 status, requestedProfile, responseProfile);
554 } catch (RemoteException ignored) {
555 }
556 }
557 }
558
559 /**
560 * Invokes callback method defined in In-Call UI.
561 *
562 * Valid values are: {@link VideoProvider#SESSION_EVENT_RX_PAUSE},
563 * {@link VideoProvider#SESSION_EVENT_RX_RESUME},
564 * {@link VideoProvider#SESSION_EVENT_TX_START},
565 * {@link VideoProvider#SESSION_EVENT_TX_STOP}
566 *
567 * @param event The event.
568 */
569 public void handleCallSessionEvent(int event) {
Ihab Awada64627c2014-08-20 09:36:40 -0700570 if (mVideoCallback != null) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700571 try {
Ihab Awada64627c2014-08-20 09:36:40 -0700572 mVideoCallback.handleCallSessionEvent(event);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700573 } catch (RemoteException ignored) {
574 }
575 }
576 }
577
578 /**
579 * Invokes callback method defined in In-Call UI.
580 *
581 * @param width The updated peer video width.
582 * @param height The updated peer video height.
583 */
584 public void changePeerDimensions(int width, int height) {
Ihab Awada64627c2014-08-20 09:36:40 -0700585 if (mVideoCallback != null) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700586 try {
Ihab Awada64627c2014-08-20 09:36:40 -0700587 mVideoCallback.changePeerDimensions(width, height);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700588 } catch (RemoteException ignored) {
589 }
590 }
591 }
592
593 /**
594 * Invokes callback method defined in In-Call UI.
595 *
596 * @param dataUsage The updated data usage.
597 */
598 public void changeCallDataUsage(int dataUsage) {
Ihab Awada64627c2014-08-20 09:36:40 -0700599 if (mVideoCallback != null) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700600 try {
Ihab Awada64627c2014-08-20 09:36:40 -0700601 mVideoCallback.changeCallDataUsage(dataUsage);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700602 } catch (RemoteException ignored) {
603 }
604 }
605 }
606
607 /**
608 * Invokes callback method defined in In-Call UI.
609 *
610 * @param cameraCapabilities The changed camera capabilities.
611 */
612 public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
Ihab Awada64627c2014-08-20 09:36:40 -0700613 if (mVideoCallback != null) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700614 try {
Ihab Awada64627c2014-08-20 09:36:40 -0700615 mVideoCallback.changeCameraCapabilities(cameraCapabilities);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700616 } catch (RemoteException ignored) {
617 }
618 }
619 }
Ihab Awad542e0ea2014-05-16 10:22:16 -0700620 }
621
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700622 private final Listener mConnectionDeathListener = new Listener() {
623 @Override
624 public void onDestroyed(Connection c) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -0800625 if (mConferenceables.remove(c)) {
626 fireOnConferenceableConnectionsChanged();
627 }
628 }
629 };
630
631 private final Conference.Listener mConferenceDeathListener = new Conference.Listener() {
632 @Override
633 public void onDestroyed(Conference c) {
634 if (mConferenceables.remove(c)) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700635 fireOnConferenceableConnectionsChanged();
636 }
637 }
638 };
639
Jay Shrauner229e3822014-08-15 09:23:07 -0700640 /**
641 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
642 * load factor before resizing, 1 means we only expect a single thread to
643 * access the map so make only a single shard
644 */
645 private final Set<Listener> mListeners = Collections.newSetFromMap(
646 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
Tyler Gunn6d76ca02014-11-17 15:49:51 -0800647 private final List<IConferenceable> mConferenceables = new ArrayList<>();
648 private final List<IConferenceable> mUnmodifiableConferenceables =
649 Collections.unmodifiableList(mConferenceables);
Santos Cordonb6939982014-06-04 20:20:58 -0700650
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700651 private int mState = STATE_NEW;
652 private AudioState mAudioState;
Andrew Lee100e2932014-09-08 15:34:24 -0700653 private Uri mAddress;
654 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700655 private String mCallerDisplayName;
656 private int mCallerDisplayNamePresentation;
Andrew Lee100e2932014-09-08 15:34:24 -0700657 private boolean mRingbackRequested = false;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800658 private int mConnectionCapabilities;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700659 private VideoProvider mVideoProvider;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700660 private boolean mAudioModeIsVoip;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700661 private StatusHints mStatusHints;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700662 private int mVideoState;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700663 private DisconnectCause mDisconnectCause;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700664 private Conference mConference;
665 private ConnectionService mConnectionService;
Ihab Awad542e0ea2014-05-16 10:22:16 -0700666
667 /**
668 * Create a new Connection.
669 */
Santos Cordonf2951102014-07-20 19:06:29 -0700670 public Connection() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -0700671
672 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700673 * @return The address (e.g., phone number) to which this Connection is currently communicating.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700674 */
Andrew Lee100e2932014-09-08 15:34:24 -0700675 public final Uri getAddress() {
676 return mAddress;
Ihab Awad542e0ea2014-05-16 10:22:16 -0700677 }
678
679 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700680 * @return The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700681 * See {@link TelecomManager} for valid values.
Sailesh Nepal61203862014-07-11 14:50:13 -0700682 */
Andrew Lee100e2932014-09-08 15:34:24 -0700683 public final int getAddressPresentation() {
684 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700685 }
686
687 /**
688 * @return The caller display name (CNAP).
689 */
690 public final String getCallerDisplayName() {
691 return mCallerDisplayName;
692 }
693
694 /**
Nancy Chen9d568c02014-09-08 14:17:59 -0700695 * @return The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700696 * See {@link TelecomManager} for valid values.
Sailesh Nepal61203862014-07-11 14:50:13 -0700697 */
698 public final int getCallerDisplayNamePresentation() {
699 return mCallerDisplayNamePresentation;
700 }
701
702 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -0700703 * @return The state of this Connection.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700704 */
705 public final int getState() {
706 return mState;
707 }
708
709 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800710 * Returns the video state of the connection.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700711 * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
712 * {@link VideoProfile.VideoState#BIDIRECTIONAL},
713 * {@link VideoProfile.VideoState#TX_ENABLED},
714 * {@link VideoProfile.VideoState#RX_ENABLED}.
Tyler Gunnaa07df82014-07-17 07:50:22 -0700715 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800716 * @return The video state of the connection.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700717 * @hide
Tyler Gunnaa07df82014-07-17 07:50:22 -0700718 */
719 public final int getVideoState() {
720 return mVideoState;
721 }
722
723 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800724 * @return The audio state of the connection, describing how its audio is currently
Ihab Awad542e0ea2014-05-16 10:22:16 -0700725 * being routed by the system. This is {@code null} if this Connection
726 * does not directly know about its audio state.
727 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700728 public final AudioState getAudioState() {
729 return mAudioState;
Ihab Awad542e0ea2014-05-16 10:22:16 -0700730 }
731
732 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -0700733 * @return The conference that this connection is a part of. Null if it is not part of any
734 * conference.
735 */
736 public final Conference getConference() {
737 return mConference;
738 }
739
740 /**
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700741 * Returns whether this connection is requesting that the system play a ringback tone
742 * on its behalf.
743 */
Andrew Lee100e2932014-09-08 15:34:24 -0700744 public final boolean isRingbackRequested() {
745 return mRingbackRequested;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700746 }
747
748 /**
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700749 * @return True if the connection's audio mode is VOIP.
750 */
751 public final boolean getAudioModeIsVoip() {
752 return mAudioModeIsVoip;
753 }
754
755 /**
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700756 * @return The status hints for this connection.
757 */
758 public final StatusHints getStatusHints() {
759 return mStatusHints;
760 }
761
762 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -0700763 * Assign a listener to be notified of state changes.
764 *
765 * @param l A listener.
766 * @return This Connection.
767 *
768 * @hide
769 */
770 public final Connection addConnectionListener(Listener l) {
Santos Cordond34e5712014-08-05 18:54:03 +0000771 mListeners.add(l);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700772 return this;
773 }
774
775 /**
776 * Remove a previously assigned listener that was being notified of state changes.
777 *
778 * @param l A Listener.
779 * @return This Connection.
780 *
781 * @hide
782 */
783 public final Connection removeConnectionListener(Listener l) {
Jay Shrauner229e3822014-08-15 09:23:07 -0700784 if (l != null) {
785 mListeners.remove(l);
786 }
Ihab Awad542e0ea2014-05-16 10:22:16 -0700787 return this;
788 }
789
790 /**
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700791 * @return The {@link DisconnectCause} for this connection.
Evan Charltonbf11f982014-07-20 22:06:28 -0700792 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700793 public final DisconnectCause getDisconnectCause() {
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700794 return mDisconnectCause;
Evan Charltonbf11f982014-07-20 22:06:28 -0700795 }
796
797 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -0700798 * Inform this Connection that the state of its audio output has been changed externally.
799 *
800 * @param state The new audio state.
Sailesh Nepal400cc482014-06-26 12:04:00 -0700801 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -0700802 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700803 final void setAudioState(AudioState state) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800804 checkImmutable();
Ihab Awad60ac30b2014-05-20 22:32:12 -0700805 Log.d(this, "setAudioState %s", state);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700806 mAudioState = state;
Nancy Chen354b2bd2014-09-08 18:27:26 -0700807 onAudioStateChanged(state);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700808 }
809
810 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700811 * @param state An integer value of a {@code STATE_*} constant.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700812 * @return A string representation of the value.
813 */
814 public static String stateToString(int state) {
815 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700816 case STATE_INITIALIZING:
817 return "STATE_INITIALIZING";
818 case STATE_NEW:
819 return "STATE_NEW";
820 case STATE_RINGING:
821 return "STATE_RINGING";
822 case STATE_DIALING:
823 return "STATE_DIALING";
824 case STATE_ACTIVE:
825 return "STATE_ACTIVE";
826 case STATE_HOLDING:
827 return "STATE_HOLDING";
828 case STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -0700829 return "DISCONNECTED";
830 default:
Ihab Awad60ac30b2014-05-20 22:32:12 -0700831 Log.wtf(Connection.class, "Unknown state %d", state);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700832 return "UNKNOWN";
833 }
834 }
835
836 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800837 * Returns the connection's capabilities, as a bit mask of the {@code CAPABILITY_*} constants.
Ihab Awad52a28f62014-06-18 10:26:34 -0700838 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800839 public final int getConnectionCapabilities() {
840 return mConnectionCapabilities;
Ihab Awad52a28f62014-06-18 10:26:34 -0700841 }
842
Sailesh Nepalef77f0e2014-12-02 15:18:25 -0800843 /** @hide */
844 @SystemApi @Deprecated public final int getCallCapabilities() {
845 return getConnectionCapabilities();
846 }
847
Ihab Awad52a28f62014-06-18 10:26:34 -0700848 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700849 * Sets the value of the {@link #getAddress()} property.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700850 *
Andrew Lee100e2932014-09-08 15:34:24 -0700851 * @param address The new address.
852 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700853 * See {@link TelecomManager} for valid values.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700854 */
Andrew Lee100e2932014-09-08 15:34:24 -0700855 public final void setAddress(Uri address, int presentation) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800856 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -0700857 Log.d(this, "setAddress %s", address);
858 mAddress = address;
859 mAddressPresentation = presentation;
Santos Cordond34e5712014-08-05 18:54:03 +0000860 for (Listener l : mListeners) {
Andrew Lee100e2932014-09-08 15:34:24 -0700861 l.onAddressChanged(this, address, presentation);
Santos Cordond34e5712014-08-05 18:54:03 +0000862 }
Ihab Awad542e0ea2014-05-16 10:22:16 -0700863 }
864
865 /**
Sailesh Nepal61203862014-07-11 14:50:13 -0700866 * Sets the caller display name (CNAP).
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700867 *
Sailesh Nepal61203862014-07-11 14:50:13 -0700868 * @param callerDisplayName The new display name.
Nancy Chen9d568c02014-09-08 14:17:59 -0700869 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700870 * See {@link TelecomManager} for valid values.
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700871 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700872 public final void setCallerDisplayName(String callerDisplayName, int presentation) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800873 checkImmutable();
Sailesh Nepal61203862014-07-11 14:50:13 -0700874 Log.d(this, "setCallerDisplayName %s", callerDisplayName);
Santos Cordond34e5712014-08-05 18:54:03 +0000875 mCallerDisplayName = callerDisplayName;
876 mCallerDisplayNamePresentation = presentation;
877 for (Listener l : mListeners) {
878 l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
879 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700880 }
881
882 /**
Tyler Gunnaa07df82014-07-17 07:50:22 -0700883 * Set the video state for the connection.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700884 * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
885 * {@link VideoProfile.VideoState#BIDIRECTIONAL},
886 * {@link VideoProfile.VideoState#TX_ENABLED},
887 * {@link VideoProfile.VideoState#RX_ENABLED}.
Tyler Gunnaa07df82014-07-17 07:50:22 -0700888 *
889 * @param videoState The new video state.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700890 * @hide
Tyler Gunnaa07df82014-07-17 07:50:22 -0700891 */
892 public final void setVideoState(int videoState) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800893 checkImmutable();
Tyler Gunnaa07df82014-07-17 07:50:22 -0700894 Log.d(this, "setVideoState %d", videoState);
Santos Cordond34e5712014-08-05 18:54:03 +0000895 mVideoState = videoState;
896 for (Listener l : mListeners) {
897 l.onVideoStateChanged(this, mVideoState);
898 }
Tyler Gunnaa07df82014-07-17 07:50:22 -0700899 }
900
901 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800902 * Sets state to active (e.g., an ongoing connection where two or more parties can actively
Ihab Awad542e0ea2014-05-16 10:22:16 -0700903 * communicate).
904 */
Sailesh Nepal400cc482014-06-26 12:04:00 -0700905 public final void setActive() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800906 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -0700907 setRingbackRequested(false);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700908 setState(STATE_ACTIVE);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700909 }
910
911 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800912 * Sets state to ringing (e.g., an inbound ringing connection).
Ihab Awad542e0ea2014-05-16 10:22:16 -0700913 */
Sailesh Nepal400cc482014-06-26 12:04:00 -0700914 public final void setRinging() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800915 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700916 setState(STATE_RINGING);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700917 }
918
919 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700920 * Sets state to initializing (this Connection is not yet ready to be used).
921 */
922 public final void setInitializing() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800923 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700924 setState(STATE_INITIALIZING);
Evan Charltonbf11f982014-07-20 22:06:28 -0700925 }
926
927 /**
928 * Sets state to initialized (the Connection has been set up and is now ready to be used).
929 */
930 public final void setInitialized() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800931 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700932 setState(STATE_NEW);
Evan Charltonbf11f982014-07-20 22:06:28 -0700933 }
934
935 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800936 * Sets state to dialing (e.g., dialing an outbound connection).
Ihab Awad542e0ea2014-05-16 10:22:16 -0700937 */
Sailesh Nepal400cc482014-06-26 12:04:00 -0700938 public final void setDialing() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800939 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700940 setState(STATE_DIALING);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700941 }
942
943 /**
944 * Sets state to be on hold.
945 */
Sailesh Nepal400cc482014-06-26 12:04:00 -0700946 public final void setOnHold() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800947 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700948 setState(STATE_HOLDING);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700949 }
950
951 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800952 * Sets the video connection provider.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700953 * @param videoProvider The video provider.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700954 * @hide
Andrew Lee5ffbe8b2014-06-20 16:29:33 -0700955 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700956 public final void setVideoProvider(VideoProvider videoProvider) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800957 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700958 mVideoProvider = videoProvider;
Santos Cordond34e5712014-08-05 18:54:03 +0000959 for (Listener l : mListeners) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700960 l.onVideoProviderChanged(this, videoProvider);
Santos Cordond34e5712014-08-05 18:54:03 +0000961 }
Andrew Lee5ffbe8b2014-06-20 16:29:33 -0700962 }
963
Tyler Gunn27d1e252014-08-21 16:38:40 -0700964 /** @hide */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700965 public final VideoProvider getVideoProvider() {
966 return mVideoProvider;
Andrew Leea27a1932014-07-09 17:07:13 -0700967 }
968
Andrew Lee5ffbe8b2014-06-20 16:29:33 -0700969 /**
Sailesh Nepal091768c2014-06-30 15:15:23 -0700970 * Sets state to disconnected.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700971 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700972 * @param disconnectCause The reason for the disconnection, as specified by
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700973 * {@link DisconnectCause}.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700974 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700975 public final void setDisconnected(DisconnectCause disconnectCause) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800976 checkImmutable();
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700977 mDisconnectCause = disconnectCause;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700978 setState(STATE_DISCONNECTED);
mike dooleyf34519b2014-09-16 17:33:40 -0700979 Log.d(this, "Disconnected with cause %s", disconnectCause);
Santos Cordond34e5712014-08-05 18:54:03 +0000980 for (Listener l : mListeners) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700981 l.onDisconnected(this, disconnectCause);
Santos Cordond34e5712014-08-05 18:54:03 +0000982 }
Ihab Awad542e0ea2014-05-16 10:22:16 -0700983 }
984
985 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800986 * Informs listeners that this {@code Connection} is in a post-dial wait state. This is done
987 * when (a) the {@code Connection} is issuing a DTMF sequence; (b) it has encountered a "wait"
988 * character; and (c) it wishes to inform the In-Call app that it is waiting for the end-user
989 * to send an {@link #onPostDialContinue(boolean)} signal.
990 *
991 * @param remaining The DTMF character sequence remaining to be emitted once the
992 * {@link #onPostDialContinue(boolean)} is received, including any "wait" characters
993 * that remaining sequence may contain.
Sailesh Nepal091768c2014-06-30 15:15:23 -0700994 */
995 public final void setPostDialWait(String remaining) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800996 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +0000997 for (Listener l : mListeners) {
998 l.onPostDialWait(this, remaining);
999 }
Sailesh Nepal091768c2014-06-30 15:15:23 -07001000 }
1001
1002 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001003 * Informs listeners that this {@code Connection} has processed a character in the post-dial
1004 * started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence;
1005 * (b) it has encountered a "wait" character; and (c) it wishes to signal Telecom to play
1006 * the corresponding DTMF tone locally.
1007 *
1008 * @param nextChar The DTMF character that was just processed by the {@code Connection}.
1009 *
1010 * @hide
1011 */
1012 public final void setNextPostDialWaitChar(char nextChar) {
1013 checkImmutable();
1014 for (Listener l : mListeners) {
1015 l.onPostDialChar(this, nextChar);
1016 }
1017 }
1018
1019 /**
Ihab Awadf8358972014-05-28 16:46:42 -07001020 * Requests that the framework play a ringback tone. This is to be invoked by implementations
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001021 * that do not play a ringback tone themselves in the connection's audio stream.
Ihab Awadf8358972014-05-28 16:46:42 -07001022 *
1023 * @param ringback Whether the ringback tone is to be played.
1024 */
Andrew Lee100e2932014-09-08 15:34:24 -07001025 public final void setRingbackRequested(boolean ringback) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001026 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001027 if (mRingbackRequested != ringback) {
1028 mRingbackRequested = ringback;
Santos Cordond34e5712014-08-05 18:54:03 +00001029 for (Listener l : mListeners) {
Andrew Lee100e2932014-09-08 15:34:24 -07001030 l.onRingbackRequested(this, ringback);
Santos Cordond34e5712014-08-05 18:54:03 +00001031 }
1032 }
Ihab Awadf8358972014-05-28 16:46:42 -07001033 }
1034
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001035 /** @hide */
Ihab Awadde061332014-12-01 12:19:57 -08001036 @SystemApi @Deprecated public final void setCallCapabilities(int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001037 setConnectionCapabilities(connectionCapabilities);
1038 }
1039
Ihab Awadf8358972014-05-28 16:46:42 -07001040 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001041 * Sets the connection's capabilities as a bit mask of the {@code CAPABILITY_*} constants.
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001042 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001043 * @param connectionCapabilities The new connection capabilities.
Santos Cordonb6939982014-06-04 20:20:58 -07001044 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001045 public final void setConnectionCapabilities(int connectionCapabilities) {
1046 checkImmutable();
1047 if (mConnectionCapabilities != connectionCapabilities) {
1048 mConnectionCapabilities = connectionCapabilities;
Santos Cordond34e5712014-08-05 18:54:03 +00001049 for (Listener l : mListeners) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001050 l.onConnectionCapabilitiesChanged(this, mConnectionCapabilities);
Santos Cordond34e5712014-08-05 18:54:03 +00001051 }
1052 }
Santos Cordonb6939982014-06-04 20:20:58 -07001053 }
1054
1055 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001056 * Tears down the Connection object.
Santos Cordonb6939982014-06-04 20:20:58 -07001057 */
Evan Charlton36a71342014-07-19 16:31:02 -07001058 public final void destroy() {
Jay Shrauner229e3822014-08-15 09:23:07 -07001059 for (Listener l : mListeners) {
1060 l.onDestroyed(this);
Santos Cordond34e5712014-08-05 18:54:03 +00001061 }
Santos Cordonb6939982014-06-04 20:20:58 -07001062 }
1063
1064 /**
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001065 * Requests that the framework use VOIP audio mode for this connection.
1066 *
1067 * @param isVoip True if the audio mode is VOIP.
1068 */
1069 public final void setAudioModeIsVoip(boolean isVoip) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001070 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00001071 mAudioModeIsVoip = isVoip;
1072 for (Listener l : mListeners) {
1073 l.onAudioModeIsVoipChanged(this, isVoip);
1074 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001075 }
1076
1077 /**
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001078 * Sets the label and icon status to display in the in-call UI.
1079 *
1080 * @param statusHints The status label and icon to set.
1081 */
1082 public final void setStatusHints(StatusHints statusHints) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001083 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00001084 mStatusHints = statusHints;
1085 for (Listener l : mListeners) {
1086 l.onStatusHintsChanged(this, statusHints);
1087 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001088 }
1089
1090 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001091 * Sets the connections with which this connection can be conferenced.
1092 *
1093 * @param conferenceableConnections The set of connections this connection can conference with.
1094 */
1095 public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001096 checkImmutable();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001097 clearConferenceableList();
1098 for (Connection c : conferenceableConnections) {
1099 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
1100 // small amount of items here.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001101 if (!mConferenceables.contains(c)) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001102 c.addConnectionListener(mConnectionDeathListener);
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001103 mConferenceables.add(c);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001104 }
1105 }
1106 fireOnConferenceableConnectionsChanged();
1107 }
1108
1109 /**
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001110 * Similar to {@link #setConferenceableConnections(java.util.List)}, sets a list of connections
1111 * or conferences with which this connection can be conferenced.
1112 *
1113 * @param conferenceables The conferenceables.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001114 */
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001115 public final void setConferenceables(List<IConferenceable> conferenceables) {
1116 clearConferenceableList();
1117 for (IConferenceable c : conferenceables) {
1118 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
1119 // small amount of items here.
1120 if (!mConferenceables.contains(c)) {
1121 if (c instanceof Connection) {
1122 Connection connection = (Connection) c;
1123 connection.addConnectionListener(mConnectionDeathListener);
1124 } else if (c instanceof Conference) {
1125 Conference conference = (Conference) c;
1126 conference.addListener(mConferenceDeathListener);
1127 }
1128 mConferenceables.add(c);
1129 }
1130 }
1131 fireOnConferenceableConnectionsChanged();
1132 }
1133
1134 /**
1135 * Returns the connections or conferences with which this connection can be conferenced.
1136 */
1137 public final List<IConferenceable> getConferenceables() {
1138 return mUnmodifiableConferenceables;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001139 }
1140
Evan Charlton8635c572014-09-24 14:04:51 -07001141 /*
Santos Cordon823fd3c2014-08-07 18:35:18 -07001142 * @hide
1143 */
1144 public final void setConnectionService(ConnectionService connectionService) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001145 checkImmutable();
Santos Cordon823fd3c2014-08-07 18:35:18 -07001146 if (mConnectionService != null) {
1147 Log.e(this, new Exception(), "Trying to set ConnectionService on a connection " +
1148 "which is already associated with another ConnectionService.");
1149 } else {
1150 mConnectionService = connectionService;
1151 }
1152 }
1153
1154 /**
1155 * @hide
1156 */
1157 public final void unsetConnectionService(ConnectionService connectionService) {
1158 if (mConnectionService != connectionService) {
1159 Log.e(this, new Exception(), "Trying to remove ConnectionService from a Connection " +
1160 "that does not belong to the ConnectionService.");
1161 } else {
1162 mConnectionService = null;
1163 }
1164 }
1165
1166 /**
Santos Cordonaf1b2962014-10-16 19:23:54 -07001167 * @hide
1168 */
1169 public final ConnectionService getConnectionService() {
1170 return mConnectionService;
1171 }
1172
1173 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07001174 * Sets the conference that this connection is a part of. This will fail if the connection is
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001175 * already part of a conference. {@link #resetConference} to un-set the conference first.
Santos Cordon823fd3c2014-08-07 18:35:18 -07001176 *
1177 * @param conference The conference.
1178 * @return {@code true} if the conference was successfully set.
1179 * @hide
1180 */
1181 public final boolean setConference(Conference conference) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001182 checkImmutable();
Santos Cordon823fd3c2014-08-07 18:35:18 -07001183 // We check to see if it is already part of another conference.
Santos Cordon0159ac02014-08-21 14:28:11 -07001184 if (mConference == null) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001185 mConference = conference;
Santos Cordon0159ac02014-08-21 14:28:11 -07001186 if (mConnectionService != null && mConnectionService.containsConference(conference)) {
1187 fireConferenceChanged();
1188 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001189 return true;
1190 }
1191 return false;
1192 }
1193
1194 /**
1195 * Resets the conference that this connection is a part of.
1196 * @hide
1197 */
1198 public final void resetConference() {
1199 if (mConference != null) {
Santos Cordon0159ac02014-08-21 14:28:11 -07001200 Log.d(this, "Conference reset");
Santos Cordon823fd3c2014-08-07 18:35:18 -07001201 mConference = null;
1202 fireConferenceChanged();
1203 }
1204 }
1205
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001206 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001207 * Notifies this Connection that the {@link #getAudioState()} property has a new value.
Sailesh Nepal400cc482014-06-26 12:04:00 -07001208 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001209 * @param state The new connection audio state.
Sailesh Nepal400cc482014-06-26 12:04:00 -07001210 */
Nancy Chen354b2bd2014-09-08 18:27:26 -07001211 public void onAudioStateChanged(AudioState state) {}
Sailesh Nepal400cc482014-06-26 12:04:00 -07001212
1213 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07001214 * Notifies this Connection of an internal state change. This method is called after the
1215 * state is changed.
Ihab Awadf8358972014-05-28 16:46:42 -07001216 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001217 * @param state The new state, one of the {@code STATE_*} constants.
Ihab Awadf8358972014-05-28 16:46:42 -07001218 */
Nancy Chen354b2bd2014-09-08 18:27:26 -07001219 public void onStateChanged(int state) {}
Ihab Awadf8358972014-05-28 16:46:42 -07001220
1221 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001222 * Notifies this Connection of a request to play a DTMF tone.
1223 *
1224 * @param c A DTMF character.
1225 */
Santos Cordonf2951102014-07-20 19:06:29 -07001226 public void onPlayDtmfTone(char c) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001227
1228 /**
1229 * Notifies this Connection of a request to stop any currently playing DTMF tones.
1230 */
Santos Cordonf2951102014-07-20 19:06:29 -07001231 public void onStopDtmfTone() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001232
1233 /**
1234 * Notifies this Connection of a request to disconnect.
1235 */
Santos Cordonf2951102014-07-20 19:06:29 -07001236 public void onDisconnect() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001237
1238 /**
Tyler Gunn3b4b1dc2014-11-04 14:53:37 -08001239 * Notifies this Connection of a request to disconnect a participant of the conference managed
1240 * by the connection.
1241 *
1242 * @param endpoint the {@link Uri} of the participant to disconnect.
1243 * @hide
1244 */
1245 public void onDisconnectConferenceParticipant(Uri endpoint) {}
1246
1247 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001248 * Notifies this Connection of a request to separate from its parent conference.
Santos Cordonb6939982014-06-04 20:20:58 -07001249 */
Santos Cordonf2951102014-07-20 19:06:29 -07001250 public void onSeparate() {}
Santos Cordonb6939982014-06-04 20:20:58 -07001251
1252 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001253 * Notifies this Connection of a request to abort.
1254 */
Santos Cordonf2951102014-07-20 19:06:29 -07001255 public void onAbort() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001256
1257 /**
1258 * Notifies this Connection of a request to hold.
1259 */
Santos Cordonf2951102014-07-20 19:06:29 -07001260 public void onHold() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001261
1262 /**
1263 * Notifies this Connection of a request to exit a hold state.
1264 */
Santos Cordonf2951102014-07-20 19:06:29 -07001265 public void onUnhold() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001266
1267 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001268 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Santos Cordond34e5712014-08-05 18:54:03 +00001269 * a request to accept.
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001270 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001271 * @param videoState The video state in which to answer the connection.
Tyler Gunnbe74de02014-08-29 14:51:48 -07001272 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -07001273 */
Santos Cordonf2951102014-07-20 19:06:29 -07001274 public void onAnswer(int videoState) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001275
1276 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001277 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Tyler Gunnbe74de02014-08-29 14:51:48 -07001278 * a request to accept.
1279 */
1280 public void onAnswer() {
1281 onAnswer(VideoProfile.VideoState.AUDIO_ONLY);
1282 }
1283
1284 /**
1285 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Santos Cordond34e5712014-08-05 18:54:03 +00001286 * a request to reject.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001287 */
Santos Cordonf2951102014-07-20 19:06:29 -07001288 public void onReject() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001289
Evan Charlton6dea4ac2014-06-03 14:07:13 -07001290 /**
1291 * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
1292 */
Santos Cordonf2951102014-07-20 19:06:29 -07001293 public void onPostDialContinue(boolean proceed) {}
Evan Charlton6dea4ac2014-06-03 14:07:13 -07001294
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001295 static String toLogSafePhoneNumber(String number) {
1296 // For unknown number, log empty string.
1297 if (number == null) {
1298 return "";
1299 }
1300
1301 if (PII_DEBUG) {
1302 // When PII_DEBUG is true we emit PII.
1303 return number;
1304 }
1305
1306 // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
1307 // sanitized phone numbers.
1308 StringBuilder builder = new StringBuilder();
1309 for (int i = 0; i < number.length(); i++) {
1310 char c = number.charAt(i);
1311 if (c == '-' || c == '@' || c == '.') {
1312 builder.append(c);
1313 } else {
1314 builder.append('x');
1315 }
1316 }
1317 return builder.toString();
1318 }
1319
Ihab Awad542e0ea2014-05-16 10:22:16 -07001320 private void setState(int state) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001321 checkImmutable();
Ihab Awad6107bab2014-08-18 09:23:25 -07001322 if (mState == STATE_DISCONNECTED && mState != state) {
1323 Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
Evan Charltonbf11f982014-07-20 22:06:28 -07001324 return;
Sailesh Nepal400cc482014-06-26 12:04:00 -07001325 }
Evan Charltonbf11f982014-07-20 22:06:28 -07001326 if (mState != state) {
1327 Log.d(this, "setState: %s", stateToString(state));
1328 mState = state;
Nancy Chen354b2bd2014-09-08 18:27:26 -07001329 onStateChanged(state);
Evan Charltonbf11f982014-07-20 22:06:28 -07001330 for (Listener l : mListeners) {
1331 l.onStateChanged(this, state);
1332 }
Evan Charltonbf11f982014-07-20 22:06:28 -07001333 }
1334 }
1335
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001336 private static class FailureSignalingConnection extends Connection {
Ihab Awad90e34e32014-12-01 16:23:17 -08001337 private boolean mImmutable = false;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001338 public FailureSignalingConnection(DisconnectCause disconnectCause) {
1339 setDisconnected(disconnectCause);
Ihab Awad90e34e32014-12-01 16:23:17 -08001340 mImmutable = true;
Ihab Awad6107bab2014-08-18 09:23:25 -07001341 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001342
1343 public void checkImmutable() {
Ihab Awad90e34e32014-12-01 16:23:17 -08001344 if (mImmutable) {
1345 throw new UnsupportedOperationException("Connection is immutable");
1346 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001347 }
Ihab Awad6107bab2014-08-18 09:23:25 -07001348 }
1349
Evan Charltonbf11f982014-07-20 22:06:28 -07001350 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001351 * Return a {@code Connection} which represents a failed connection attempt. The returned
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001352 * {@code Connection} will have a {@link android.telecom.DisconnectCause} and as specified,
1353 * and a {@link #getState()} of {@link #STATE_DISCONNECTED}.
Ihab Awad6107bab2014-08-18 09:23:25 -07001354 * <p>
1355 * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
1356 * so users of this method need not maintain a reference to its return value to destroy it.
Evan Charltonbf11f982014-07-20 22:06:28 -07001357 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001358 * @param disconnectCause The disconnect cause, ({@see android.telecomm.DisconnectCause}).
Ihab Awad6107bab2014-08-18 09:23:25 -07001359 * @return A {@code Connection} which indicates failure.
Evan Charltonbf11f982014-07-20 22:06:28 -07001360 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001361 public static Connection createFailedConnection(DisconnectCause disconnectCause) {
1362 return new FailureSignalingConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001363 }
1364
Evan Charltonbf11f982014-07-20 22:06:28 -07001365 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001366 * Override to throw an {@link UnsupportedOperationException} if this {@code Connection} is
1367 * not intended to be mutated, e.g., if it is a marker for failure. Only for framework use;
1368 * this should never be un-@hide-den.
1369 *
1370 * @hide
1371 */
1372 public void checkImmutable() {}
1373
1374 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001375 * Return a {@code Connection} which represents a canceled connection attempt. The returned
1376 * {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
1377 * that state. This connection should not be used for anything, and no other
1378 * {@code Connection}s should be attempted.
1379 * <p>
Ihab Awad6107bab2014-08-18 09:23:25 -07001380 * so users of this method need not maintain a reference to its return value to destroy it.
Evan Charltonbf11f982014-07-20 22:06:28 -07001381 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001382 * @return A {@code Connection} which indicates that the underlying connection should
1383 * be canceled.
Evan Charltonbf11f982014-07-20 22:06:28 -07001384 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001385 public static Connection createCanceledConnection() {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001386 return new FailureSignalingConnection(new DisconnectCause(DisconnectCause.CANCELED));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001387 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001388
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001389 private final void fireOnConferenceableConnectionsChanged() {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001390 for (Listener l : mListeners) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001391 l.onConferenceablesChanged(this, getConferenceables());
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001392 }
1393 }
1394
Santos Cordon823fd3c2014-08-07 18:35:18 -07001395 private final void fireConferenceChanged() {
1396 for (Listener l : mListeners) {
1397 l.onConferenceChanged(this, mConference);
1398 }
1399 }
1400
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001401 private final void clearConferenceableList() {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001402 for (IConferenceable c : mConferenceables) {
1403 if (c instanceof Connection) {
1404 Connection connection = (Connection) c;
1405 connection.removeConnectionListener(mConnectionDeathListener);
1406 } else if (c instanceof Conference) {
1407 Conference conference = (Conference) c;
1408 conference.removeListener(mConferenceDeathListener);
1409 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001410 }
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001411 mConferenceables.clear();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001412 }
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001413
1414 /**
Tyler Gunnab4650c2014-11-06 20:06:23 -08001415 * Notifies listeners of a change to conference participant(s).
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001416 *
Tyler Gunnab4650c2014-11-06 20:06:23 -08001417 * @param conferenceParticipants The participants.
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001418 * @hide
1419 */
Tyler Gunnab4650c2014-11-06 20:06:23 -08001420 protected final void updateConferenceParticipants(
1421 List<ConferenceParticipant> conferenceParticipants) {
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001422 for (Listener l : mListeners) {
Tyler Gunnab4650c2014-11-06 20:06:23 -08001423 l.onConferenceParticipantsChanged(this, conferenceParticipants);
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001424 }
1425 }
Tyler Gunn8a2b1192015-01-29 11:47:24 -08001426
1427 /**
1428 * Notifies listeners that a conference call has been started.
1429 */
1430 protected void notifyConferenceStarted() {
1431 for (Listener l : mListeners) {
1432 l.onConferenceStarted();
1433 }
1434 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001435}