blob: deb98f4211b160664950167e904cdbd6ecda44a5 [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 Gunn45382162015-05-06 08:52:27 -070019import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070020import com.android.internal.telecom.IVideoCallback;
21import com.android.internal.telecom.IVideoProvider;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070022
Santos Cordon6b7f9552015-05-27 17:21:45 -070023import android.annotation.Nullable;
Yorke Lee4af59352015-05-13 14:14:54 -070024import android.annotation.SystemApi;
Tyler Gunnb702ef82015-05-29 11:51:53 -070025import android.hardware.camera2.CameraManager;
Ihab Awad542e0ea2014-05-16 10:22:16 -070026import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070027import android.os.Bundle;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070028import android.os.Handler;
29import android.os.IBinder;
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -070030import android.os.Looper;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070031import android.os.Message;
32import android.os.RemoteException;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070033import android.view.Surface;
Ihab Awad542e0ea2014-05-16 10:22:16 -070034
Santos Cordonb6939982014-06-04 20:20:58 -070035import java.util.ArrayList;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070036import java.util.Collections;
Santos Cordonb6939982014-06-04 20:20:58 -070037import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070038import java.util.Set;
Jay Shrauner229e3822014-08-15 09:23:07 -070039import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070040
41/**
Santos Cordon895d4b82015-06-25 16:41:48 -070042 * Represents a phone call or connection to a remote endpoint that carries voice and/or video
43 * traffic.
Ihab Awad6107bab2014-08-18 09:23:25 -070044 * <p>
45 * Implementations create a custom subclass of {@code Connection} and return it to the framework
46 * as the return value of
47 * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
48 * or
49 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
50 * Implementations are then responsible for updating the state of the {@code Connection}, and
51 * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
52 * longer used and associated resources may be recovered.
Ihab Awad542e0ea2014-05-16 10:22:16 -070053 */
Yorke Leeabfcfdc2015-05-13 18:55:18 -070054public abstract class Connection extends Conferenceable {
Ihab Awad542e0ea2014-05-16 10:22:16 -070055
Santos Cordon895d4b82015-06-25 16:41:48 -070056 /**
57 * The connection is initializing. This is generally the first state for a {@code Connection}
58 * returned by a {@link ConnectionService}.
59 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070060 public static final int STATE_INITIALIZING = 0;
61
Santos Cordon895d4b82015-06-25 16:41:48 -070062 /**
63 * The connection is new and not connected.
64 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070065 public static final int STATE_NEW = 1;
66
Santos Cordon895d4b82015-06-25 16:41:48 -070067 /**
68 * An incoming connection is in the ringing state. During this state, the user's ringer or
69 * vibration feature will be activated.
70 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070071 public static final int STATE_RINGING = 2;
72
Santos Cordon895d4b82015-06-25 16:41:48 -070073 /**
74 * An outgoing connection is in the dialing state. In this state the other party has not yet
75 * answered the call and the user traditionally hears a ringback tone.
76 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070077 public static final int STATE_DIALING = 3;
78
Santos Cordon895d4b82015-06-25 16:41:48 -070079 /**
80 * A connection is active. Both parties are connected to the call and can actively communicate.
81 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070082 public static final int STATE_ACTIVE = 4;
83
Santos Cordon895d4b82015-06-25 16:41:48 -070084 /**
85 * A connection is on hold.
86 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070087 public static final int STATE_HOLDING = 5;
88
Santos Cordon895d4b82015-06-25 16:41:48 -070089 /**
90 * A connection has been disconnected. This is the final state once the user has been
91 * disconnected from a call either locally, remotely or by an error in the service.
92 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070093 public static final int STATE_DISCONNECTED = 6;
94
Santos Cordon895d4b82015-06-25 16:41:48 -070095 /**
96 * Connection can currently be put on hold or unheld. This is distinct from
97 * {@link #CAPABILITY_SUPPORT_HOLD} in that although a connection may support 'hold' most times,
98 * it does not at the moment support the function. This can be true while the call is in the
99 * state {@link #STATE_DIALING}, for example. During this condition, an in-call UI may
100 * display a disabled 'hold' button.
101 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800102 public static final int CAPABILITY_HOLD = 0x00000001;
103
104 /** Connection supports the hold feature. */
105 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
106
107 /**
108 * Connections within a conference can be merged. A {@link ConnectionService} has the option to
109 * add a {@link Conference} before the child {@link Connection}s are merged. This is how
110 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
111 * capability allows a merge button to be shown while the conference is in the foreground
112 * of the in-call UI.
113 * <p>
114 * This is only intended for use by a {@link Conference}.
115 */
116 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
117
118 /**
119 * Connections within a conference can be swapped between foreground and background.
120 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
121 * <p>
122 * This is only intended for use by a {@link Conference}.
123 */
124 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
125
126 /**
127 * @hide
128 */
129 public static final int CAPABILITY_UNUSED = 0x00000010;
130
131 /** Connection supports responding via text option. */
132 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
133
134 /** Connection can be muted. */
135 public static final int CAPABILITY_MUTE = 0x00000040;
136
137 /**
138 * Connection supports conference management. This capability only applies to
139 * {@link Conference}s which can have {@link Connection}s as children.
140 */
141 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
142
143 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700144 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800145 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700146 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800147
148 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700149 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800150 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700151 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800152
153 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700154 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800155 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700156 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700157 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800158
159 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700160 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800161 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700162 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
163
164 /**
165 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700166 */
167 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
168
169 /**
170 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700171 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700172 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700173 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800174
175 /**
176 * Connection is able to be separated from its parent {@code Conference}, if any.
177 */
178 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
179
180 /**
181 * Connection is able to be individually disconnected when in a {@code Conference}.
182 */
183 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
184
185 /**
186 * Whether the call is a generic conference, where we do not know the precise state of
187 * participants in the conference (eg. on CDMA).
188 *
189 * @hide
190 */
191 public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
192
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700193 /**
194 * Connection is using high definition audio.
195 * @hide
196 */
197 public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00008000;
198
199 /**
200 * Connection is using WIFI.
201 * @hide
202 */
Tyler Gunnd11a3152015-03-18 13:09:14 -0700203 public static final int CAPABILITY_WIFI = 0x00010000;
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700204
Tyler Gunn068085b2015-02-06 13:56:52 -0800205 /**
206 * Indicates that the current device callback number should be shown.
207 *
208 * @hide
209 */
Tyler Gunn96d6c402015-03-18 12:39:23 -0700210 public static final int CAPABILITY_SHOW_CALLBACK_NUMBER = 0x00020000;
Tyler Gunn068085b2015-02-06 13:56:52 -0800211
Tyler Gunn96d6c402015-03-18 12:39:23 -0700212 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500213 * Speed up audio setup for MT call.
214 * @hide
Tyler Gunn96d6c402015-03-18 12:39:23 -0700215 */
216 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
Tyler Gunn068085b2015-02-06 13:56:52 -0800217
Rekha Kumar07366812015-03-24 16:42:31 -0700218 /**
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700219 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700220 */
221 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
222
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700223 /**
224 * For video calls, indicates whether the outgoing video for the call can be paused using
Yorke Lee32f24732015-05-12 16:18:03 -0700225 * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700226 */
227 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
228
Tyler Gunnd4091732015-06-29 09:15:37 -0700229 /**
230 * For a conference, indicates the conference will not have child connections.
231 * <p>
232 * An example of a conference with child connections is a GSM conference call, where the radio
233 * retains connections to the individual participants of the conference. Another example is an
234 * IMS conference call where conference event package functionality is supported; in this case
235 * the conference server ensures the radio is aware of the participants in the conference, which
236 * are represented by child connections.
237 * <p>
238 * An example of a conference with no child connections is an IMS conference call with no
239 * conference event package support. Such a conference is represented by the radio as a single
240 * connection to the IMS conference server.
241 * <p>
242 * Indicating whether a conference has children or not is important to help user interfaces
243 * visually represent a conference. A conference with no children, for example, will have the
244 * conference connection shown in the list of calls on a Bluetooth device, where if the
245 * conference has children, only the children will be shown in the list of calls on a Bluetooth
246 * device.
247 * @hide
248 */
249 public static final int CAPABILITY_CONFERENCE_HAS_NO_CHILDREN = 0x00200000;
250
Bryce Lee81901682015-08-28 16:38:02 -0700251 /**
252 * Indicates that the connection itself wants to handle any sort of reply response, rather than
253 * relying on SMS.
254 * @hide
255 */
256 public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00400000;
257
Tyler Gunn96d6c402015-03-18 12:39:23 -0700258 //**********************************************************************************************
Bryce Lee81901682015-08-28 16:38:02 -0700259 // Next CAPABILITY value: 0x00800000
Tyler Gunn96d6c402015-03-18 12:39:23 -0700260 //**********************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800261
Tyler Gunn335ff2e2015-07-30 14:18:33 -0700262 /**
263 * Connection extra key used to store the last forwarded number associated with the current
264 * connection. Used to communicate to the user interface that the connection was forwarded via
265 * the specified number.
266 */
267 public static final String EXTRA_LAST_FORWARDED_NUMBER =
268 "android.telecom.extra.LAST_FORWARDED_NUMBER";
269
270 /**
271 * Connection extra key used to store a child number associated with the current connection.
272 * Used to communicate to the user interface that the connection was received via
273 * a child address (i.e. phone number) associated with the {@link PhoneAccount}'s primary
274 * address.
275 */
276 public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
277
278 /**
279 * Connection extra key used to store the subject for an incoming call. The user interface can
280 * query this extra and display its contents for incoming calls. Will only be used if the
281 * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
282 */
283 public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
284
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700285 // Flag controlling whether PII is emitted into the logs
286 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
287
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800288 /**
289 * Whether the given capabilities support the specified capability.
290 *
291 * @param capabilities A capability bit field.
292 * @param capability The capability to check capabilities for.
293 * @return Whether the specified capability is supported.
294 * @hide
295 */
296 public static boolean can(int capabilities, int capability) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800297 return (capabilities & capability) == capability;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800298 }
299
300 /**
301 * Whether the capabilities of this {@code Connection} supports the specified capability.
302 *
303 * @param capability The capability to check capabilities for.
304 * @return Whether the specified capability is supported.
305 * @hide
306 */
307 public boolean can(int capability) {
308 return can(mConnectionCapabilities, capability);
309 }
310
311 /**
312 * Removes the specified capability from the set of capabilities of this {@code Connection}.
313 *
314 * @param capability The capability to remove from the set.
315 * @hide
316 */
317 public void removeCapability(int capability) {
318 mConnectionCapabilities &= ~capability;
319 }
320
321 /**
322 * Adds the specified capability to the set of capabilities of this {@code Connection}.
323 *
324 * @param capability The capability to add to the set.
325 * @hide
326 */
327 public void addCapability(int capability) {
328 mConnectionCapabilities |= capability;
329 }
330
331
332 public static String capabilitiesToString(int capabilities) {
333 StringBuilder builder = new StringBuilder();
334 builder.append("[Capabilities:");
335 if (can(capabilities, CAPABILITY_HOLD)) {
336 builder.append(" CAPABILITY_HOLD");
337 }
338 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
339 builder.append(" CAPABILITY_SUPPORT_HOLD");
340 }
341 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
342 builder.append(" CAPABILITY_MERGE_CONFERENCE");
343 }
344 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
345 builder.append(" CAPABILITY_SWAP_CONFERENCE");
346 }
347 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
348 builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
349 }
350 if (can(capabilities, CAPABILITY_MUTE)) {
351 builder.append(" CAPABILITY_MUTE");
352 }
353 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
354 builder.append(" CAPABILITY_MANAGE_CONFERENCE");
355 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700356 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
357 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_RX");
358 }
359 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
360 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_TX");
361 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700362 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
363 builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800364 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700365 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
366 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_RX");
367 }
368 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
369 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
370 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700371 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
372 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800373 }
Andrew Lee80fff3c2014-11-25 17:36:51 -0800374 if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
375 builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800376 }
Andrew Lee1a8ae3e2015-02-02 13:42:38 -0800377 if (can(capabilities, CAPABILITY_WIFI)) {
378 builder.append(" CAPABILITY_WIFI");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800379 }
380 if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
381 builder.append(" CAPABILITY_GENERIC_CONFERENCE");
382 }
Tyler Gunn068085b2015-02-06 13:56:52 -0800383 if (can(capabilities, CAPABILITY_SHOW_CALLBACK_NUMBER)) {
384 builder.append(" CAPABILITY_SHOW_CALLBACK_NUMBER");
385 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500386 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Tyler Gunnd11a3152015-03-18 13:09:14 -0700387 builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500388 }
Rekha Kumar07366812015-03-24 16:42:31 -0700389 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
390 builder.append(" CAPABILITY_CAN_UPGRADE_TO_VIDEO");
391 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700392 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
393 builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
394 }
Tyler Gunnd4091732015-06-29 09:15:37 -0700395 if (can(capabilities, CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) {
396 builder.append(" CAPABILITY_SINGLE_PARTY_CONFERENCE");
397 }
Bryce Lee81901682015-08-28 16:38:02 -0700398 if (can(capabilities, CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION)) {
399 builder.append(" CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION");
400 }
401
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800402 builder.append("]");
403 return builder.toString();
404 }
405
Sailesh Nepal091768c2014-06-30 15:15:23 -0700406 /** @hide */
Sailesh Nepal61203862014-07-11 14:50:13 -0700407 public abstract static class Listener {
Ihab Awad542e0ea2014-05-16 10:22:16 -0700408 public void onStateChanged(Connection c, int state) {}
Andrew Lee100e2932014-09-08 15:34:24 -0700409 public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
Sailesh Nepal61203862014-07-11 14:50:13 -0700410 public void onCallerDisplayNameChanged(
411 Connection c, String callerDisplayName, int presentation) {}
Tyler Gunnaa07df82014-07-17 07:50:22 -0700412 public void onVideoStateChanged(Connection c, int videoState) {}
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700413 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {}
Sailesh Nepal091768c2014-06-30 15:15:23 -0700414 public void onPostDialWait(Connection c, String remaining) {}
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800415 public void onPostDialChar(Connection c, char nextChar) {}
Andrew Lee100e2932014-09-08 15:34:24 -0700416 public void onRingbackRequested(Connection c, boolean ringback) {}
Sailesh Nepal61203862014-07-11 14:50:13 -0700417 public void onDestroyed(Connection c) {}
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800418 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700419 public void onVideoProviderChanged(
420 Connection c, VideoProvider videoProvider) {}
Sailesh Nepal001bbbb2014-07-15 14:40:39 -0700421 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
422 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
Tyler Gunn6d76ca02014-11-17 15:49:51 -0800423 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -0700424 Connection c, List<Conferenceable> conferenceables) {}
Santos Cordon823fd3c2014-08-07 18:35:18 -0700425 public void onConferenceChanged(Connection c, Conference conference) {}
Tyler Gunn3bffcf72014-10-28 13:51:27 -0700426 /** @hide */
Tyler Gunnab4650c2014-11-06 20:06:23 -0800427 public void onConferenceParticipantsChanged(Connection c,
428 List<ConferenceParticipant> participants) {}
Tyler Gunn8a2b1192015-01-29 11:47:24 -0800429 public void onConferenceStarted() {}
Anthony Lee17455a32015-04-24 15:25:29 -0700430 public void onConferenceMergeFailed(Connection c) {}
Santos Cordon6b7f9552015-05-27 17:21:45 -0700431 public void onExtrasChanged(Connection c, Bundle extras) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -0700432 }
433
Tyler Gunnb702ef82015-05-29 11:51:53 -0700434 /**
435 * Provides a means of controlling the video session associated with a {@link Connection}.
436 * <p>
437 * Implementations create a custom subclass of {@link VideoProvider} and the
438 * {@link ConnectionService} creates an instance sets it on the {@link Connection} using
439 * {@link Connection#setVideoProvider(VideoProvider)}. Any connection which supports video
440 * should set the {@link VideoProvider}.
441 * <p>
442 * The {@link VideoProvider} serves two primary purposes: it provides a means for Telecom and
443 * {@link InCallService} implementations to issue requests related to the video session;
444 * it provides a means for the {@link ConnectionService} to report events and information
445 * related to the video session to Telecom and the {@link InCallService} implementations.
446 * <p>
447 * {@link InCallService} implementations interact with the {@link VideoProvider} via
448 * {@link android.telecom.InCallService.VideoCall}.
449 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700450 public static abstract class VideoProvider {
Ihab Awad542e0ea2014-05-16 10:22:16 -0700451
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700452 /**
453 * Video is not being received (no protocol pause was issued).
Tyler Gunnb702ef82015-05-29 11:51:53 -0700454 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700455 */
456 public static final int SESSION_EVENT_RX_PAUSE = 1;
Evan Charltonbf11f982014-07-20 22:06:28 -0700457
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700458 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700459 * Video reception has resumed after a {@link #SESSION_EVENT_RX_PAUSE}.
460 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700461 */
462 public static final int SESSION_EVENT_RX_RESUME = 2;
463
464 /**
465 * Video transmission has begun. This occurs after a negotiated start of video transmission
466 * when the underlying protocol has actually begun transmitting video to the remote party.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700467 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700468 */
469 public static final int SESSION_EVENT_TX_START = 3;
470
471 /**
472 * Video transmission has stopped. This occurs after a negotiated stop of video transmission
473 * when the underlying protocol has actually stopped transmitting video to the remote party.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700474 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700475 */
476 public static final int SESSION_EVENT_TX_STOP = 4;
477
478 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700479 * A camera failure has occurred for the selected camera. The {@link InCallService} can use
480 * this as a cue to inform the user the camera is not available.
481 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700482 */
483 public static final int SESSION_EVENT_CAMERA_FAILURE = 5;
484
485 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700486 * Issued after {@link #SESSION_EVENT_CAMERA_FAILURE} when the camera is once again ready
487 * for operation. The {@link InCallService} can use this as a cue to inform the user that
488 * the camera has become available again.
489 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700490 */
491 public static final int SESSION_EVENT_CAMERA_READY = 6;
492
493 /**
494 * Session modify request was successful.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700495 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700496 */
497 public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1;
498
499 /**
500 * Session modify request failed.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700501 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700502 */
503 public static final int SESSION_MODIFY_REQUEST_FAIL = 2;
504
505 /**
506 * Session modify request ignored due to invalid parameters.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700507 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700508 */
509 public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
510
Rekha Kumar07366812015-03-24 16:42:31 -0700511 /**
512 * Session modify request timed out.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700513 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Rekha Kumar07366812015-03-24 16:42:31 -0700514 */
515 public static final int SESSION_MODIFY_REQUEST_TIMED_OUT = 4;
516
517 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700518 * Session modify request rejected by remote user.
519 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Rekha Kumar07366812015-03-24 16:42:31 -0700520 */
521 public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5;
522
Tyler Gunn75958422015-04-15 14:23:42 -0700523 private static final int MSG_ADD_VIDEO_CALLBACK = 1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700524 private static final int MSG_SET_CAMERA = 2;
525 private static final int MSG_SET_PREVIEW_SURFACE = 3;
526 private static final int MSG_SET_DISPLAY_SURFACE = 4;
527 private static final int MSG_SET_DEVICE_ORIENTATION = 5;
528 private static final int MSG_SET_ZOOM = 6;
529 private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7;
530 private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8;
531 private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800532 private static final int MSG_REQUEST_CONNECTION_DATA_USAGE = 10;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700533 private static final int MSG_SET_PAUSE_IMAGE = 11;
Tyler Gunn75958422015-04-15 14:23:42 -0700534 private static final int MSG_REMOVE_VIDEO_CALLBACK = 12;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700535
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -0700536 private VideoProvider.VideoProviderHandler mMessageHandler;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700537 private final VideoProvider.VideoProviderBinder mBinder;
Tyler Gunn75958422015-04-15 14:23:42 -0700538
539 /**
540 * Stores a list of the video callbacks, keyed by IBinder.
Tyler Gunn84f381b2015-06-12 09:26:45 -0700541 *
542 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
543 * load factor before resizing, 1 means we only expect a single thread to
544 * access the map so make only a single shard
Tyler Gunn75958422015-04-15 14:23:42 -0700545 */
Tyler Gunn84f381b2015-06-12 09:26:45 -0700546 private ConcurrentHashMap<IBinder, IVideoCallback> mVideoCallbacks =
547 new ConcurrentHashMap<IBinder, IVideoCallback>(8, 0.9f, 1);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700548
549 /**
550 * Default handler used to consolidate binder method calls onto a single thread.
551 */
552 private final class VideoProviderHandler extends Handler {
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -0700553 public VideoProviderHandler() {
554 super();
555 }
556
557 public VideoProviderHandler(Looper looper) {
558 super(looper);
559 }
560
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700561 @Override
562 public void handleMessage(Message msg) {
563 switch (msg.what) {
Tyler Gunn75958422015-04-15 14:23:42 -0700564 case MSG_ADD_VIDEO_CALLBACK: {
565 IBinder binder = (IBinder) msg.obj;
566 IVideoCallback callback = IVideoCallback.Stub
567 .asInterface((IBinder) msg.obj);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700568 if (callback == null) {
569 Log.w(this, "addVideoProvider - skipped; callback is null.");
570 break;
571 }
572
Tyler Gunn75958422015-04-15 14:23:42 -0700573 if (mVideoCallbacks.containsKey(binder)) {
574 Log.i(this, "addVideoProvider - skipped; already present.");
575 break;
576 }
577 mVideoCallbacks.put(binder, callback);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700578 break;
Tyler Gunn75958422015-04-15 14:23:42 -0700579 }
580 case MSG_REMOVE_VIDEO_CALLBACK: {
581 IBinder binder = (IBinder) msg.obj;
582 IVideoCallback callback = IVideoCallback.Stub
583 .asInterface((IBinder) msg.obj);
584 if (!mVideoCallbacks.containsKey(binder)) {
585 Log.i(this, "removeVideoProvider - skipped; not present.");
586 break;
587 }
588 mVideoCallbacks.remove(binder);
589 break;
590 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700591 case MSG_SET_CAMERA:
592 onSetCamera((String) msg.obj);
593 break;
594 case MSG_SET_PREVIEW_SURFACE:
595 onSetPreviewSurface((Surface) msg.obj);
596 break;
597 case MSG_SET_DISPLAY_SURFACE:
598 onSetDisplaySurface((Surface) msg.obj);
599 break;
600 case MSG_SET_DEVICE_ORIENTATION:
601 onSetDeviceOrientation(msg.arg1);
602 break;
603 case MSG_SET_ZOOM:
604 onSetZoom((Float) msg.obj);
605 break;
Tyler Gunn45382162015-05-06 08:52:27 -0700606 case MSG_SEND_SESSION_MODIFY_REQUEST: {
607 SomeArgs args = (SomeArgs) msg.obj;
608 try {
609 onSendSessionModifyRequest((VideoProfile) args.arg1,
610 (VideoProfile) args.arg2);
611 } finally {
612 args.recycle();
613 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700614 break;
Tyler Gunn45382162015-05-06 08:52:27 -0700615 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700616 case MSG_SEND_SESSION_MODIFY_RESPONSE:
617 onSendSessionModifyResponse((VideoProfile) msg.obj);
618 break;
619 case MSG_REQUEST_CAMERA_CAPABILITIES:
620 onRequestCameraCapabilities();
621 break;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800622 case MSG_REQUEST_CONNECTION_DATA_USAGE:
623 onRequestConnectionDataUsage();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700624 break;
625 case MSG_SET_PAUSE_IMAGE:
Yorke Lee32f24732015-05-12 16:18:03 -0700626 onSetPauseImage((Uri) msg.obj);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700627 break;
628 default:
629 break;
630 }
631 }
632 }
633
634 /**
635 * IVideoProvider stub implementation.
636 */
637 private final class VideoProviderBinder extends IVideoProvider.Stub {
Tyler Gunn75958422015-04-15 14:23:42 -0700638 public void addVideoCallback(IBinder videoCallbackBinder) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700639 mMessageHandler.obtainMessage(
Tyler Gunn75958422015-04-15 14:23:42 -0700640 MSG_ADD_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
641 }
642
643 public void removeVideoCallback(IBinder videoCallbackBinder) {
644 mMessageHandler.obtainMessage(
645 MSG_REMOVE_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700646 }
647
648 public void setCamera(String cameraId) {
649 mMessageHandler.obtainMessage(MSG_SET_CAMERA, cameraId).sendToTarget();
650 }
651
652 public void setPreviewSurface(Surface surface) {
653 mMessageHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget();
654 }
655
656 public void setDisplaySurface(Surface surface) {
657 mMessageHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget();
658 }
659
660 public void setDeviceOrientation(int rotation) {
Rekha Kumar07366812015-03-24 16:42:31 -0700661 mMessageHandler.obtainMessage(
662 MSG_SET_DEVICE_ORIENTATION, rotation, 0).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700663 }
664
665 public void setZoom(float value) {
666 mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget();
667 }
668
Tyler Gunn45382162015-05-06 08:52:27 -0700669 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
670 SomeArgs args = SomeArgs.obtain();
671 args.arg1 = fromProfile;
672 args.arg2 = toProfile;
673 mMessageHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700674 }
675
676 public void sendSessionModifyResponse(VideoProfile responseProfile) {
677 mMessageHandler.obtainMessage(
678 MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget();
679 }
680
681 public void requestCameraCapabilities() {
682 mMessageHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget();
683 }
684
685 public void requestCallDataUsage() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800686 mMessageHandler.obtainMessage(MSG_REQUEST_CONNECTION_DATA_USAGE).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700687 }
688
Yorke Lee32f24732015-05-12 16:18:03 -0700689 public void setPauseImage(Uri uri) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700690 mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget();
691 }
692 }
693
694 public VideoProvider() {
695 mBinder = new VideoProvider.VideoProviderBinder();
Tyler Gunn84f381b2015-06-12 09:26:45 -0700696 mMessageHandler = new VideoProvider.VideoProviderHandler(Looper.getMainLooper());
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -0700697 }
698
699 /**
700 * Creates an instance of the {@link VideoProvider}, specifying the looper to use.
701 *
702 * @param looper The looper.
703 * @hide
704 */
705 public VideoProvider(Looper looper) {
706 mBinder = new VideoProvider.VideoProviderBinder();
707 mMessageHandler = new VideoProvider.VideoProviderHandler(looper);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700708 }
709
710 /**
711 * Returns binder object which can be used across IPC methods.
712 * @hide
713 */
714 public final IVideoProvider getInterface() {
715 return mBinder;
716 }
717
718 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700719 * Sets the camera to be used for the outgoing video.
720 * <p>
721 * The {@link VideoProvider} should respond by communicating the capabilities of the chosen
722 * camera via
723 * {@link VideoProvider#changeCameraCapabilities(VideoProfile.CameraCapabilities)}.
724 * <p>
725 * Sent from the {@link InCallService} via
726 * {@link InCallService.VideoCall#setCamera(String)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700727 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700728 * @param cameraId The id of the camera (use ids as reported by
729 * {@link CameraManager#getCameraIdList()}).
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700730 */
731 public abstract void onSetCamera(String cameraId);
732
733 /**
734 * Sets the surface to be used for displaying a preview of what the user's camera is
735 * currently capturing. When video transmission is enabled, this is the video signal which
736 * is sent to the remote device.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700737 * <p>
738 * Sent from the {@link InCallService} via
739 * {@link InCallService.VideoCall#setPreviewSurface(Surface)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700740 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700741 * @param surface The {@link Surface}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700742 */
743 public abstract void onSetPreviewSurface(Surface surface);
744
745 /**
746 * Sets the surface to be used for displaying the video received from the remote device.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700747 * <p>
748 * Sent from the {@link InCallService} via
749 * {@link InCallService.VideoCall#setDisplaySurface(Surface)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700750 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700751 * @param surface The {@link Surface}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700752 */
753 public abstract void onSetDisplaySurface(Surface surface);
754
755 /**
756 * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of
757 * the device is 0 degrees.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700758 * <p>
759 * Sent from the {@link InCallService} via
760 * {@link InCallService.VideoCall#setDeviceOrientation(int)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700761 *
762 * @param rotation The device orientation, in degrees.
763 */
764 public abstract void onSetDeviceOrientation(int rotation);
765
766 /**
767 * Sets camera zoom ratio.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700768 * <p>
769 * Sent from the {@link InCallService} via {@link InCallService.VideoCall#setZoom(float)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700770 *
771 * @param value The camera zoom ratio.
772 */
773 public abstract void onSetZoom(float value);
774
775 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700776 * Issues a request to modify the properties of the current video session.
777 * <p>
778 * Example scenarios include: requesting an audio-only call to be upgraded to a
779 * bi-directional video call, turning on or off the user's camera, sending a pause signal
780 * when the {@link InCallService} is no longer the foreground application.
781 * <p>
782 * If the {@link VideoProvider} determines a request to be invalid, it should call
783 * {@link #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)} to report the
784 * invalid request back to the {@link InCallService}.
785 * <p>
786 * Where a request requires confirmation from the user of the peer device, the
787 * {@link VideoProvider} must communicate the request to the peer device and handle the
788 * user's response. {@link #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)}
789 * is used to inform the {@link InCallService} of the result of the request.
790 * <p>
791 * Sent from the {@link InCallService} via
792 * {@link InCallService.VideoCall#sendSessionModifyRequest(VideoProfile)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700793 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700794 * @param fromProfile The video profile prior to the request.
795 * @param toProfile The video profile with the requested changes made.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700796 */
Tyler Gunn45382162015-05-06 08:52:27 -0700797 public abstract void onSendSessionModifyRequest(VideoProfile fromProfile,
798 VideoProfile toProfile);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700799
Tyler Gunnb702ef82015-05-29 11:51:53 -0700800 /**
801 * Provides a response to a request to change the current video session properties.
802 * <p>
803 * For example, if the peer requests and upgrade from an audio-only call to a bi-directional
804 * video call, could decline the request and keep the call as audio-only.
805 * In such a scenario, the {@code responseProfile} would have a video state of
806 * {@link VideoProfile#STATE_AUDIO_ONLY}. If the user had decided to accept the request,
807 * the video state would be {@link VideoProfile#STATE_BIDIRECTIONAL}.
808 * <p>
809 * Sent from the {@link InCallService} via
810 * {@link InCallService.VideoCall#sendSessionModifyResponse(VideoProfile)} in response to
811 * a {@link InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)}
812 * callback.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700813 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700814 * @param responseProfile The response video profile.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700815 */
816 public abstract void onSendSessionModifyResponse(VideoProfile responseProfile);
817
818 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700819 * Issues a request to the {@link VideoProvider} to retrieve the camera capabilities.
820 * <p>
821 * The {@link VideoProvider} should respond by communicating the capabilities of the chosen
822 * camera via
823 * {@link VideoProvider#changeCameraCapabilities(VideoProfile.CameraCapabilities)}.
824 * <p>
825 * Sent from the {@link InCallService} via
826 * {@link InCallService.VideoCall#requestCameraCapabilities()}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700827 */
828 public abstract void onRequestCameraCapabilities();
829
830 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700831 * Issues a request to the {@link VideoProvider} to retrieve the current data usage for the
832 * video component of the current {@link Connection}.
833 * <p>
834 * The {@link VideoProvider} should respond by communicating current data usage, in bytes,
835 * via {@link VideoProvider#setCallDataUsage(long)}.
836 * <p>
837 * Sent from the {@link InCallService} via
838 * {@link InCallService.VideoCall#requestCallDataUsage()}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700839 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800840 public abstract void onRequestConnectionDataUsage();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700841
842 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700843 * Provides the {@link VideoProvider} with the {@link Uri} of an image to be displayed to
844 * the peer device when the video signal is paused.
845 * <p>
846 * Sent from the {@link InCallService} via
847 * {@link InCallService.VideoCall#setPauseImage(Uri)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700848 *
849 * @param uri URI of image to display.
850 */
Yorke Lee32f24732015-05-12 16:18:03 -0700851 public abstract void onSetPauseImage(Uri uri);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700852
853 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700854 * Used to inform listening {@link InCallService} implementations when the
855 * {@link VideoProvider} receives a session modification request.
856 * <p>
857 * Received by the {@link InCallService} via
858 * {@link InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)},
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700859 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700860 * @param videoProfile The requested video profile.
861 * @see #onSendSessionModifyRequest(VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700862 */
863 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunn75958422015-04-15 14:23:42 -0700864 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -0700865 for (IVideoCallback callback : mVideoCallbacks.values()) {
866 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700867 callback.receiveSessionModifyRequest(videoProfile);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700868 } catch (RemoteException ignored) {
869 Log.w(this, "receiveSessionModifyRequest callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -0700870 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700871 }
872 }
873 }
874
875 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700876 * Used to inform listening {@link InCallService} implementations when the
877 * {@link VideoProvider} receives a response to a session modification request.
878 * <p>
879 * Received by the {@link InCallService} via
880 * {@link InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
881 * VideoProfile, VideoProfile)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700882 *
883 * @param status Status of the session modify request. Valid values are
884 * {@link VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS},
885 * {@link VideoProvider#SESSION_MODIFY_REQUEST_FAIL},
Tyler Gunnb702ef82015-05-29 11:51:53 -0700886 * {@link VideoProvider#SESSION_MODIFY_REQUEST_INVALID},
887 * {@link VideoProvider#SESSION_MODIFY_REQUEST_TIMED_OUT},
888 * {@link VideoProvider#SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE}
889 * @param requestedProfile The original request which was sent to the peer device.
890 * @param responseProfile The actual profile changes agreed to by the peer device.
891 * @see #onSendSessionModifyRequest(VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700892 */
893 public void receiveSessionModifyResponse(int status,
894 VideoProfile requestedProfile, VideoProfile responseProfile) {
Tyler Gunn75958422015-04-15 14:23:42 -0700895 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -0700896 for (IVideoCallback callback : mVideoCallbacks.values()) {
897 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700898 callback.receiveSessionModifyResponse(status, requestedProfile,
899 responseProfile);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700900 } catch (RemoteException ignored) {
901 Log.w(this, "receiveSessionModifyResponse callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -0700902 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700903 }
904 }
905 }
906
907 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700908 * Used to inform listening {@link InCallService} implementations when the
909 * {@link VideoProvider} reports a call session event.
910 * <p>
911 * Received by the {@link InCallService} via
912 * {@link InCallService.VideoCall.Callback#onCallSessionEvent(int)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700913 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700914 * @param event The event. Valid values are: {@link VideoProvider#SESSION_EVENT_RX_PAUSE},
915 * {@link VideoProvider#SESSION_EVENT_RX_RESUME},
916 * {@link VideoProvider#SESSION_EVENT_TX_START},
917 * {@link VideoProvider#SESSION_EVENT_TX_STOP},
918 * {@link VideoProvider#SESSION_EVENT_CAMERA_FAILURE},
919 * {@link VideoProvider#SESSION_EVENT_CAMERA_READY}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700920 */
921 public void handleCallSessionEvent(int event) {
Tyler Gunn75958422015-04-15 14:23:42 -0700922 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -0700923 for (IVideoCallback callback : mVideoCallbacks.values()) {
924 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700925 callback.handleCallSessionEvent(event);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700926 } catch (RemoteException ignored) {
927 Log.w(this, "handleCallSessionEvent callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -0700928 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700929 }
930 }
931 }
932
933 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700934 * Used to inform listening {@link InCallService} implementations when the dimensions of the
935 * peer's video have changed.
936 * <p>
937 * This could occur if, for example, the peer rotates their device, changing the aspect
938 * ratio of the video, or if the user switches between the back and front cameras.
939 * <p>
940 * Received by the {@link InCallService} via
941 * {@link InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700942 *
943 * @param width The updated peer video width.
944 * @param height The updated peer video height.
945 */
946 public void changePeerDimensions(int width, int height) {
Tyler Gunn75958422015-04-15 14:23:42 -0700947 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -0700948 for (IVideoCallback callback : mVideoCallbacks.values()) {
949 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700950 callback.changePeerDimensions(width, height);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700951 } catch (RemoteException ignored) {
952 Log.w(this, "changePeerDimensions callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -0700953 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700954 }
955 }
956 }
957
958 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700959 * Used to inform listening {@link InCallService} implementations when the data usage of the
960 * video associated with the current {@link Connection} has changed.
961 * <p>
962 * This could be in response to a preview request via
963 * {@link #onRequestConnectionDataUsage()}, or as a periodic update by the
Tyler Gunn295f5d72015-06-04 11:08:54 -0700964 * {@link VideoProvider}. Where periodic updates of data usage are provided, they should be
965 * provided at most for every 1 MB of data transferred and no more than once every 10 sec.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700966 * <p>
967 * Received by the {@link InCallService} via
968 * {@link InCallService.VideoCall.Callback#onCallDataUsageChanged(long)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700969 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700970 * @param dataUsage The updated data usage (in bytes). Reported as the cumulative bytes
971 * used since the start of the call.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700972 */
Yorke Lee32f24732015-05-12 16:18:03 -0700973 public void setCallDataUsage(long dataUsage) {
Tyler Gunn75958422015-04-15 14:23:42 -0700974 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -0700975 for (IVideoCallback callback : mVideoCallbacks.values()) {
976 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700977 callback.changeCallDataUsage(dataUsage);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700978 } catch (RemoteException ignored) {
979 Log.w(this, "setCallDataUsage callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -0700980 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700981 }
982 }
983 }
984
985 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700986 * @see #setCallDataUsage(long)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700987 *
Tyler Gunnb702ef82015-05-29 11:51:53 -0700988 * @param dataUsage The updated data usage (in byes).
Yorke Lee32f24732015-05-12 16:18:03 -0700989 * @deprecated - Use {@link #setCallDataUsage(long)} instead.
990 * @hide
991 */
992 public void changeCallDataUsage(long dataUsage) {
993 setCallDataUsage(dataUsage);
994 }
995
996 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700997 * Used to inform listening {@link InCallService} implementations when the capabilities of
998 * the current camera have changed.
999 * <p>
1000 * The {@link VideoProvider} should call this in response to
1001 * {@link VideoProvider#onRequestCameraCapabilities()}, or when the current camera is
1002 * changed via {@link VideoProvider#onSetCamera(String)}.
1003 * <p>
1004 * Received by the {@link InCallService} via
1005 * {@link InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
1006 * VideoProfile.CameraCapabilities)}.
Yorke Lee32f24732015-05-12 16:18:03 -07001007 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001008 * @param cameraCapabilities The new camera capabilities.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001009 */
Yorke Lee400470f2015-05-12 13:31:25 -07001010 public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunn75958422015-04-15 14:23:42 -07001011 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001012 for (IVideoCallback callback : mVideoCallbacks.values()) {
1013 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001014 callback.changeCameraCapabilities(cameraCapabilities);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001015 } catch (RemoteException ignored) {
1016 Log.w(this, "changeCameraCapabilities callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001017 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001018 }
1019 }
1020 }
Rekha Kumar07366812015-03-24 16:42:31 -07001021
1022 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001023 * Used to inform listening {@link InCallService} implementations when the video quality
1024 * of the call has changed.
1025 * <p>
1026 * Received by the {@link InCallService} via
1027 * {@link InCallService.VideoCall.Callback#onVideoQualityChanged(int)}.
Rekha Kumar07366812015-03-24 16:42:31 -07001028 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001029 * @param videoQuality The updated video quality. Valid values:
1030 * {@link VideoProfile#QUALITY_HIGH},
1031 * {@link VideoProfile#QUALITY_MEDIUM},
1032 * {@link VideoProfile#QUALITY_LOW},
1033 * {@link VideoProfile#QUALITY_DEFAULT}.
Rekha Kumar07366812015-03-24 16:42:31 -07001034 */
1035 public void changeVideoQuality(int videoQuality) {
Tyler Gunn75958422015-04-15 14:23:42 -07001036 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001037 for (IVideoCallback callback : mVideoCallbacks.values()) {
1038 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001039 callback.changeVideoQuality(videoQuality);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001040 } catch (RemoteException ignored) {
1041 Log.w(this, "changeVideoQuality callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001042 }
Rekha Kumar07366812015-03-24 16:42:31 -07001043 }
1044 }
1045 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001046 }
1047
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001048 private final Listener mConnectionDeathListener = new Listener() {
1049 @Override
1050 public void onDestroyed(Connection c) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001051 if (mConferenceables.remove(c)) {
1052 fireOnConferenceableConnectionsChanged();
1053 }
1054 }
1055 };
1056
1057 private final Conference.Listener mConferenceDeathListener = new Conference.Listener() {
1058 @Override
1059 public void onDestroyed(Conference c) {
1060 if (mConferenceables.remove(c)) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001061 fireOnConferenceableConnectionsChanged();
1062 }
1063 }
1064 };
1065
Jay Shrauner229e3822014-08-15 09:23:07 -07001066 /**
1067 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
1068 * load factor before resizing, 1 means we only expect a single thread to
1069 * access the map so make only a single shard
1070 */
1071 private final Set<Listener> mListeners = Collections.newSetFromMap(
1072 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001073 private final List<Conferenceable> mConferenceables = new ArrayList<>();
1074 private final List<Conferenceable> mUnmodifiableConferenceables =
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001075 Collections.unmodifiableList(mConferenceables);
Santos Cordonb6939982014-06-04 20:20:58 -07001076
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001077 // The internal telecom call ID associated with this connection.
1078 private String mTelecomCallId;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001079 private int mState = STATE_NEW;
Yorke Lee4af59352015-05-13 14:14:54 -07001080 private CallAudioState mCallAudioState;
Andrew Lee100e2932014-09-08 15:34:24 -07001081 private Uri mAddress;
1082 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -07001083 private String mCallerDisplayName;
1084 private int mCallerDisplayNamePresentation;
Andrew Lee100e2932014-09-08 15:34:24 -07001085 private boolean mRingbackRequested = false;
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001086 private int mConnectionCapabilities;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001087 private VideoProvider mVideoProvider;
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001088 private boolean mAudioModeIsVoip;
Roshan Piuse927ec02015-07-15 15:47:21 -07001089 private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001090 private StatusHints mStatusHints;
Tyler Gunnaa07df82014-07-17 07:50:22 -07001091 private int mVideoState;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001092 private DisconnectCause mDisconnectCause;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001093 private Conference mConference;
1094 private ConnectionService mConnectionService;
Santos Cordon6b7f9552015-05-27 17:21:45 -07001095 private Bundle mExtras;
Ihab Awad542e0ea2014-05-16 10:22:16 -07001096
1097 /**
1098 * Create a new Connection.
1099 */
Santos Cordonf2951102014-07-20 19:06:29 -07001100 public Connection() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001101
1102 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001103 * Returns the Telecom internal call ID associated with this connection. Should only be used
1104 * for debugging and tracing purposes.
1105 *
1106 * @return The Telecom call ID.
1107 * @hide
1108 */
1109 public final String getTelecomCallId() {
1110 return mTelecomCallId;
1111 }
1112
1113 /**
Andrew Lee100e2932014-09-08 15:34:24 -07001114 * @return The address (e.g., phone number) to which this Connection is currently communicating.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001115 */
Andrew Lee100e2932014-09-08 15:34:24 -07001116 public final Uri getAddress() {
1117 return mAddress;
Ihab Awad542e0ea2014-05-16 10:22:16 -07001118 }
1119
1120 /**
Andrew Lee100e2932014-09-08 15:34:24 -07001121 * @return The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001122 * See {@link TelecomManager} for valid values.
Sailesh Nepal61203862014-07-11 14:50:13 -07001123 */
Andrew Lee100e2932014-09-08 15:34:24 -07001124 public final int getAddressPresentation() {
1125 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -07001126 }
1127
1128 /**
1129 * @return The caller display name (CNAP).
1130 */
1131 public final String getCallerDisplayName() {
1132 return mCallerDisplayName;
1133 }
1134
1135 /**
Nancy Chen9d568c02014-09-08 14:17:59 -07001136 * @return The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001137 * See {@link TelecomManager} for valid values.
Sailesh Nepal61203862014-07-11 14:50:13 -07001138 */
1139 public final int getCallerDisplayNamePresentation() {
1140 return mCallerDisplayNamePresentation;
1141 }
1142
1143 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001144 * @return The state of this Connection.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001145 */
1146 public final int getState() {
1147 return mState;
1148 }
1149
1150 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001151 * Returns the video state of the connection.
Yorke Lee32f24732015-05-12 16:18:03 -07001152 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
1153 * {@link VideoProfile#STATE_BIDIRECTIONAL},
1154 * {@link VideoProfile#STATE_TX_ENABLED},
1155 * {@link VideoProfile#STATE_RX_ENABLED}.
Tyler Gunnaa07df82014-07-17 07:50:22 -07001156 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001157 * @return The video state of the connection.
Tyler Gunn27d1e252014-08-21 16:38:40 -07001158 * @hide
Tyler Gunnaa07df82014-07-17 07:50:22 -07001159 */
1160 public final int getVideoState() {
1161 return mVideoState;
1162 }
1163
1164 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001165 * @return The audio state of the connection, describing how its audio is currently
Ihab Awad542e0ea2014-05-16 10:22:16 -07001166 * being routed by the system. This is {@code null} if this Connection
1167 * does not directly know about its audio state.
Yorke Lee4af59352015-05-13 14:14:54 -07001168 * @deprecated Use {@link #getCallAudioState()} instead.
1169 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -07001170 */
Yorke Lee4af59352015-05-13 14:14:54 -07001171 @SystemApi
1172 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001173 public final AudioState getAudioState() {
Sailesh Nepal000d38a2015-06-21 10:25:13 -07001174 if (mCallAudioState == null) {
1175 return null;
1176 }
Yorke Lee4af59352015-05-13 14:14:54 -07001177 return new AudioState(mCallAudioState);
1178 }
1179
1180 /**
1181 * @return The audio state of the connection, describing how its audio is currently
1182 * being routed by the system. This is {@code null} if this Connection
1183 * does not directly know about its audio state.
1184 */
1185 public final CallAudioState getCallAudioState() {
1186 return mCallAudioState;
Ihab Awad542e0ea2014-05-16 10:22:16 -07001187 }
1188
1189 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07001190 * @return The conference that this connection is a part of. Null if it is not part of any
1191 * conference.
1192 */
1193 public final Conference getConference() {
1194 return mConference;
1195 }
1196
1197 /**
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001198 * Returns whether this connection is requesting that the system play a ringback tone
1199 * on its behalf.
1200 */
Andrew Lee100e2932014-09-08 15:34:24 -07001201 public final boolean isRingbackRequested() {
1202 return mRingbackRequested;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001203 }
1204
1205 /**
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001206 * @return True if the connection's audio mode is VOIP.
1207 */
1208 public final boolean getAudioModeIsVoip() {
1209 return mAudioModeIsVoip;
1210 }
1211
1212 /**
Roshan Piuse927ec02015-07-15 15:47:21 -07001213 * Retrieves the connection start time of the {@code Connnection}, if specified. A value of
1214 * {@link Conference#CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the
1215 * start time of the conference.
1216 *
1217 * @return The time at which the {@code Connnection} was connected.
1218 *
1219 * @hide
1220 */
1221 public final long getConnectTimeMillis() {
1222 return mConnectTimeMillis;
1223 }
1224
1225 /**
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001226 * @return The status hints for this connection.
1227 */
1228 public final StatusHints getStatusHints() {
1229 return mStatusHints;
1230 }
1231
1232 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -07001233 * @return The extras associated with this connection.
1234 */
1235 public final Bundle getExtras() {
1236 return mExtras;
1237 }
1238
1239 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001240 * Assign a listener to be notified of state changes.
1241 *
1242 * @param l A listener.
1243 * @return This Connection.
1244 *
1245 * @hide
1246 */
1247 public final Connection addConnectionListener(Listener l) {
Santos Cordond34e5712014-08-05 18:54:03 +00001248 mListeners.add(l);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001249 return this;
1250 }
1251
1252 /**
1253 * Remove a previously assigned listener that was being notified of state changes.
1254 *
1255 * @param l A Listener.
1256 * @return This Connection.
1257 *
1258 * @hide
1259 */
1260 public final Connection removeConnectionListener(Listener l) {
Jay Shrauner229e3822014-08-15 09:23:07 -07001261 if (l != null) {
1262 mListeners.remove(l);
1263 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001264 return this;
1265 }
1266
1267 /**
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001268 * @return The {@link DisconnectCause} for this connection.
Evan Charltonbf11f982014-07-20 22:06:28 -07001269 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001270 public final DisconnectCause getDisconnectCause() {
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001271 return mDisconnectCause;
Evan Charltonbf11f982014-07-20 22:06:28 -07001272 }
1273
1274 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001275 * Sets the telecom call ID associated with this Connection. The Telecom Call ID should be used
1276 * ONLY for debugging purposes.
1277 *
1278 * @param callId The telecom call ID.
1279 * @hide
1280 */
1281 public void setTelecomCallId(String callId) {
1282 mTelecomCallId = callId;
1283 }
1284
1285 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001286 * Inform this Connection that the state of its audio output has been changed externally.
1287 *
1288 * @param state The new audio state.
Sailesh Nepal400cc482014-06-26 12:04:00 -07001289 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -07001290 */
Yorke Lee4af59352015-05-13 14:14:54 -07001291 final void setCallAudioState(CallAudioState state) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001292 checkImmutable();
Ihab Awad60ac30b2014-05-20 22:32:12 -07001293 Log.d(this, "setAudioState %s", state);
Yorke Lee4af59352015-05-13 14:14:54 -07001294 mCallAudioState = state;
1295 onAudioStateChanged(getAudioState());
1296 onCallAudioStateChanged(state);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001297 }
1298
1299 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001300 * @param state An integer value of a {@code STATE_*} constant.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001301 * @return A string representation of the value.
1302 */
1303 public static String stateToString(int state) {
1304 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001305 case STATE_INITIALIZING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001306 return "INITIALIZING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001307 case STATE_NEW:
Yorke Leee911c8d2015-07-14 11:39:36 -07001308 return "NEW";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001309 case STATE_RINGING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001310 return "RINGING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001311 case STATE_DIALING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001312 return "DIALING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001313 case STATE_ACTIVE:
Yorke Leee911c8d2015-07-14 11:39:36 -07001314 return "ACTIVE";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001315 case STATE_HOLDING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001316 return "HOLDING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001317 case STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001318 return "DISCONNECTED";
1319 default:
Ihab Awad60ac30b2014-05-20 22:32:12 -07001320 Log.wtf(Connection.class, "Unknown state %d", state);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001321 return "UNKNOWN";
1322 }
1323 }
1324
1325 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001326 * Returns the connection's capabilities, as a bit mask of the {@code CAPABILITY_*} constants.
Ihab Awad52a28f62014-06-18 10:26:34 -07001327 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001328 public final int getConnectionCapabilities() {
1329 return mConnectionCapabilities;
Ihab Awad52a28f62014-06-18 10:26:34 -07001330 }
1331
1332 /**
Andrew Lee100e2932014-09-08 15:34:24 -07001333 * Sets the value of the {@link #getAddress()} property.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001334 *
Andrew Lee100e2932014-09-08 15:34:24 -07001335 * @param address The new address.
1336 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001337 * See {@link TelecomManager} for valid values.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001338 */
Andrew Lee100e2932014-09-08 15:34:24 -07001339 public final void setAddress(Uri address, int presentation) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001340 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001341 Log.d(this, "setAddress %s", address);
1342 mAddress = address;
1343 mAddressPresentation = presentation;
Santos Cordond34e5712014-08-05 18:54:03 +00001344 for (Listener l : mListeners) {
Andrew Lee100e2932014-09-08 15:34:24 -07001345 l.onAddressChanged(this, address, presentation);
Santos Cordond34e5712014-08-05 18:54:03 +00001346 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001347 }
1348
1349 /**
Sailesh Nepal61203862014-07-11 14:50:13 -07001350 * Sets the caller display name (CNAP).
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001351 *
Sailesh Nepal61203862014-07-11 14:50:13 -07001352 * @param callerDisplayName The new display name.
Nancy Chen9d568c02014-09-08 14:17:59 -07001353 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001354 * See {@link TelecomManager} for valid values.
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001355 */
Sailesh Nepal61203862014-07-11 14:50:13 -07001356 public final void setCallerDisplayName(String callerDisplayName, int presentation) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001357 checkImmutable();
Sailesh Nepal61203862014-07-11 14:50:13 -07001358 Log.d(this, "setCallerDisplayName %s", callerDisplayName);
Santos Cordond34e5712014-08-05 18:54:03 +00001359 mCallerDisplayName = callerDisplayName;
1360 mCallerDisplayNamePresentation = presentation;
1361 for (Listener l : mListeners) {
1362 l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
1363 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001364 }
1365
1366 /**
Tyler Gunnaa07df82014-07-17 07:50:22 -07001367 * Set the video state for the connection.
Yorke Lee32f24732015-05-12 16:18:03 -07001368 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
1369 * {@link VideoProfile#STATE_BIDIRECTIONAL},
1370 * {@link VideoProfile#STATE_TX_ENABLED},
1371 * {@link VideoProfile#STATE_RX_ENABLED}.
Tyler Gunnaa07df82014-07-17 07:50:22 -07001372 *
1373 * @param videoState The new video state.
1374 */
1375 public final void setVideoState(int videoState) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001376 checkImmutable();
Tyler Gunnaa07df82014-07-17 07:50:22 -07001377 Log.d(this, "setVideoState %d", videoState);
Santos Cordond34e5712014-08-05 18:54:03 +00001378 mVideoState = videoState;
1379 for (Listener l : mListeners) {
1380 l.onVideoStateChanged(this, mVideoState);
1381 }
Tyler Gunnaa07df82014-07-17 07:50:22 -07001382 }
1383
1384 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001385 * Sets state to active (e.g., an ongoing connection where two or more parties can actively
Ihab Awad542e0ea2014-05-16 10:22:16 -07001386 * communicate).
1387 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001388 public final void setActive() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001389 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001390 setRingbackRequested(false);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001391 setState(STATE_ACTIVE);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001392 }
1393
1394 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001395 * Sets state to ringing (e.g., an inbound ringing connection).
Ihab Awad542e0ea2014-05-16 10:22:16 -07001396 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001397 public final void setRinging() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001398 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001399 setState(STATE_RINGING);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001400 }
1401
1402 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07001403 * Sets state to initializing (this Connection is not yet ready to be used).
1404 */
1405 public final void setInitializing() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001406 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001407 setState(STATE_INITIALIZING);
Evan Charltonbf11f982014-07-20 22:06:28 -07001408 }
1409
1410 /**
1411 * Sets state to initialized (the Connection has been set up and is now ready to be used).
1412 */
1413 public final void setInitialized() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001414 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001415 setState(STATE_NEW);
Evan Charltonbf11f982014-07-20 22:06:28 -07001416 }
1417
1418 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001419 * Sets state to dialing (e.g., dialing an outbound connection).
Ihab Awad542e0ea2014-05-16 10:22:16 -07001420 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001421 public final void setDialing() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001422 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001423 setState(STATE_DIALING);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001424 }
1425
1426 /**
1427 * Sets state to be on hold.
1428 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001429 public final void setOnHold() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001430 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001431 setState(STATE_HOLDING);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001432 }
1433
1434 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001435 * Sets the video connection provider.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001436 * @param videoProvider The video provider.
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001437 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001438 public final void setVideoProvider(VideoProvider videoProvider) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001439 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001440 mVideoProvider = videoProvider;
Santos Cordond34e5712014-08-05 18:54:03 +00001441 for (Listener l : mListeners) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001442 l.onVideoProviderChanged(this, videoProvider);
Santos Cordond34e5712014-08-05 18:54:03 +00001443 }
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001444 }
1445
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001446 public final VideoProvider getVideoProvider() {
1447 return mVideoProvider;
Andrew Leea27a1932014-07-09 17:07:13 -07001448 }
1449
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001450 /**
Sailesh Nepal091768c2014-06-30 15:15:23 -07001451 * Sets state to disconnected.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001452 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001453 * @param disconnectCause The reason for the disconnection, as specified by
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001454 * {@link DisconnectCause}.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001455 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001456 public final void setDisconnected(DisconnectCause disconnectCause) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001457 checkImmutable();
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001458 mDisconnectCause = disconnectCause;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001459 setState(STATE_DISCONNECTED);
mike dooleyf34519b2014-09-16 17:33:40 -07001460 Log.d(this, "Disconnected with cause %s", disconnectCause);
Santos Cordond34e5712014-08-05 18:54:03 +00001461 for (Listener l : mListeners) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001462 l.onDisconnected(this, disconnectCause);
Santos Cordond34e5712014-08-05 18:54:03 +00001463 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001464 }
1465
1466 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001467 * Informs listeners that this {@code Connection} is in a post-dial wait state. This is done
1468 * when (a) the {@code Connection} is issuing a DTMF sequence; (b) it has encountered a "wait"
1469 * character; and (c) it wishes to inform the In-Call app that it is waiting for the end-user
1470 * to send an {@link #onPostDialContinue(boolean)} signal.
1471 *
1472 * @param remaining The DTMF character sequence remaining to be emitted once the
1473 * {@link #onPostDialContinue(boolean)} is received, including any "wait" characters
1474 * that remaining sequence may contain.
Sailesh Nepal091768c2014-06-30 15:15:23 -07001475 */
1476 public final void setPostDialWait(String remaining) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001477 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00001478 for (Listener l : mListeners) {
1479 l.onPostDialWait(this, remaining);
1480 }
Sailesh Nepal091768c2014-06-30 15:15:23 -07001481 }
1482
1483 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001484 * Informs listeners that this {@code Connection} has processed a character in the post-dial
1485 * started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence;
Sailesh Nepal1ed85612015-01-31 15:17:19 -08001486 * and (b) it wishes to signal Telecom to play the corresponding DTMF tone locally.
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001487 *
1488 * @param nextChar The DTMF character that was just processed by the {@code Connection}.
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001489 */
Sailesh Nepal1ed85612015-01-31 15:17:19 -08001490 public final void setNextPostDialChar(char nextChar) {
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001491 checkImmutable();
1492 for (Listener l : mListeners) {
1493 l.onPostDialChar(this, nextChar);
1494 }
1495 }
1496
1497 /**
Ihab Awadf8358972014-05-28 16:46:42 -07001498 * Requests that the framework play a ringback tone. This is to be invoked by implementations
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001499 * that do not play a ringback tone themselves in the connection's audio stream.
Ihab Awadf8358972014-05-28 16:46:42 -07001500 *
1501 * @param ringback Whether the ringback tone is to be played.
1502 */
Andrew Lee100e2932014-09-08 15:34:24 -07001503 public final void setRingbackRequested(boolean ringback) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001504 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001505 if (mRingbackRequested != ringback) {
1506 mRingbackRequested = ringback;
Santos Cordond34e5712014-08-05 18:54:03 +00001507 for (Listener l : mListeners) {
Andrew Lee100e2932014-09-08 15:34:24 -07001508 l.onRingbackRequested(this, ringback);
Santos Cordond34e5712014-08-05 18:54:03 +00001509 }
1510 }
Ihab Awadf8358972014-05-28 16:46:42 -07001511 }
1512
1513 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001514 * Sets the connection's capabilities as a bit mask of the {@code CAPABILITY_*} constants.
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001515 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001516 * @param connectionCapabilities The new connection capabilities.
Santos Cordonb6939982014-06-04 20:20:58 -07001517 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001518 public final void setConnectionCapabilities(int connectionCapabilities) {
1519 checkImmutable();
1520 if (mConnectionCapabilities != connectionCapabilities) {
1521 mConnectionCapabilities = connectionCapabilities;
Santos Cordond34e5712014-08-05 18:54:03 +00001522 for (Listener l : mListeners) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001523 l.onConnectionCapabilitiesChanged(this, mConnectionCapabilities);
Santos Cordond34e5712014-08-05 18:54:03 +00001524 }
1525 }
Santos Cordonb6939982014-06-04 20:20:58 -07001526 }
1527
1528 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001529 * Tears down the Connection object.
Santos Cordonb6939982014-06-04 20:20:58 -07001530 */
Evan Charlton36a71342014-07-19 16:31:02 -07001531 public final void destroy() {
Jay Shrauner229e3822014-08-15 09:23:07 -07001532 for (Listener l : mListeners) {
1533 l.onDestroyed(this);
Santos Cordond34e5712014-08-05 18:54:03 +00001534 }
Santos Cordonb6939982014-06-04 20:20:58 -07001535 }
1536
1537 /**
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001538 * Requests that the framework use VOIP audio mode for this connection.
1539 *
1540 * @param isVoip True if the audio mode is VOIP.
1541 */
1542 public final void setAudioModeIsVoip(boolean isVoip) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001543 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00001544 mAudioModeIsVoip = isVoip;
1545 for (Listener l : mListeners) {
1546 l.onAudioModeIsVoipChanged(this, isVoip);
1547 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001548 }
1549
1550 /**
Roshan Piuse927ec02015-07-15 15:47:21 -07001551 * Sets the time at which a call became active on this Connection. This is set only
1552 * when a conference call becomes active on this connection.
1553 *
1554 * @param connectionTimeMillis The connection time, in milliseconds.
1555 *
1556 * @hide
1557 */
1558 public final void setConnectTimeMillis(long connectTimeMillis) {
1559 mConnectTimeMillis = connectTimeMillis;
1560 }
1561
1562 /**
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001563 * Sets the label and icon status to display in the in-call UI.
1564 *
1565 * @param statusHints The status label and icon to set.
1566 */
1567 public final void setStatusHints(StatusHints statusHints) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001568 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00001569 mStatusHints = statusHints;
1570 for (Listener l : mListeners) {
1571 l.onStatusHintsChanged(this, statusHints);
1572 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001573 }
1574
1575 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001576 * Sets the connections with which this connection can be conferenced.
1577 *
1578 * @param conferenceableConnections The set of connections this connection can conference with.
1579 */
1580 public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001581 checkImmutable();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001582 clearConferenceableList();
1583 for (Connection c : conferenceableConnections) {
1584 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
1585 // small amount of items here.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001586 if (!mConferenceables.contains(c)) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001587 c.addConnectionListener(mConnectionDeathListener);
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001588 mConferenceables.add(c);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001589 }
1590 }
1591 fireOnConferenceableConnectionsChanged();
1592 }
1593
1594 /**
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001595 * Similar to {@link #setConferenceableConnections(java.util.List)}, sets a list of connections
1596 * or conferences with which this connection can be conferenced.
1597 *
1598 * @param conferenceables The conferenceables.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001599 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001600 public final void setConferenceables(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001601 clearConferenceableList();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001602 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001603 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
1604 // small amount of items here.
1605 if (!mConferenceables.contains(c)) {
1606 if (c instanceof Connection) {
1607 Connection connection = (Connection) c;
1608 connection.addConnectionListener(mConnectionDeathListener);
1609 } else if (c instanceof Conference) {
1610 Conference conference = (Conference) c;
1611 conference.addListener(mConferenceDeathListener);
1612 }
1613 mConferenceables.add(c);
1614 }
1615 }
1616 fireOnConferenceableConnectionsChanged();
1617 }
1618
1619 /**
1620 * Returns the connections or conferences with which this connection can be conferenced.
1621 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001622 public final List<Conferenceable> getConferenceables() {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001623 return mUnmodifiableConferenceables;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001624 }
1625
Yorke Lee53463962015-08-04 16:07:19 -07001626 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07001627 * @hide
1628 */
1629 public final void setConnectionService(ConnectionService connectionService) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001630 checkImmutable();
Santos Cordon823fd3c2014-08-07 18:35:18 -07001631 if (mConnectionService != null) {
1632 Log.e(this, new Exception(), "Trying to set ConnectionService on a connection " +
1633 "which is already associated with another ConnectionService.");
1634 } else {
1635 mConnectionService = connectionService;
1636 }
1637 }
1638
1639 /**
1640 * @hide
1641 */
1642 public final void unsetConnectionService(ConnectionService connectionService) {
1643 if (mConnectionService != connectionService) {
1644 Log.e(this, new Exception(), "Trying to remove ConnectionService from a Connection " +
1645 "that does not belong to the ConnectionService.");
1646 } else {
1647 mConnectionService = null;
1648 }
1649 }
1650
1651 /**
Santos Cordonaf1b2962014-10-16 19:23:54 -07001652 * @hide
1653 */
1654 public final ConnectionService getConnectionService() {
1655 return mConnectionService;
1656 }
1657
1658 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07001659 * Sets the conference that this connection is a part of. This will fail if the connection is
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001660 * already part of a conference. {@link #resetConference} to un-set the conference first.
Santos Cordon823fd3c2014-08-07 18:35:18 -07001661 *
1662 * @param conference The conference.
1663 * @return {@code true} if the conference was successfully set.
1664 * @hide
1665 */
1666 public final boolean setConference(Conference conference) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001667 checkImmutable();
Santos Cordon823fd3c2014-08-07 18:35:18 -07001668 // We check to see if it is already part of another conference.
Santos Cordon0159ac02014-08-21 14:28:11 -07001669 if (mConference == null) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001670 mConference = conference;
Santos Cordon0159ac02014-08-21 14:28:11 -07001671 if (mConnectionService != null && mConnectionService.containsConference(conference)) {
1672 fireConferenceChanged();
1673 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001674 return true;
1675 }
1676 return false;
1677 }
1678
1679 /**
1680 * Resets the conference that this connection is a part of.
1681 * @hide
1682 */
1683 public final void resetConference() {
1684 if (mConference != null) {
Santos Cordon0159ac02014-08-21 14:28:11 -07001685 Log.d(this, "Conference reset");
Santos Cordon823fd3c2014-08-07 18:35:18 -07001686 mConference = null;
1687 fireConferenceChanged();
1688 }
1689 }
1690
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001691 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -07001692 * Set some extras that can be associated with this {@code Connection}. No assumptions should
1693 * be made as to how an In-Call UI or service will handle these extras.
1694 * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
1695 *
1696 * @param extras The extras associated with this {@code Connection}.
1697 */
1698 public final void setExtras(@Nullable Bundle extras) {
1699 checkImmutable();
1700 mExtras = extras;
1701 for (Listener l : mListeners) {
1702 l.onExtrasChanged(this, extras);
1703 }
1704 }
1705
1706 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001707 * Notifies this Connection that the {@link #getAudioState()} property has a new value.
Sailesh Nepal400cc482014-06-26 12:04:00 -07001708 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001709 * @param state The new connection audio state.
Yorke Lee4af59352015-05-13 14:14:54 -07001710 * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead.
1711 * @hide
Sailesh Nepal400cc482014-06-26 12:04:00 -07001712 */
Yorke Lee4af59352015-05-13 14:14:54 -07001713 @SystemApi
1714 @Deprecated
Nancy Chen354b2bd2014-09-08 18:27:26 -07001715 public void onAudioStateChanged(AudioState state) {}
Sailesh Nepal400cc482014-06-26 12:04:00 -07001716
1717 /**
Yorke Lee4af59352015-05-13 14:14:54 -07001718 * Notifies this Connection that the {@link #getCallAudioState()} property has a new value.
1719 *
1720 * @param state The new connection audio state.
1721 */
1722 public void onCallAudioStateChanged(CallAudioState state) {}
1723
1724 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07001725 * Notifies this Connection of an internal state change. This method is called after the
1726 * state is changed.
Ihab Awadf8358972014-05-28 16:46:42 -07001727 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001728 * @param state The new state, one of the {@code STATE_*} constants.
Ihab Awadf8358972014-05-28 16:46:42 -07001729 */
Nancy Chen354b2bd2014-09-08 18:27:26 -07001730 public void onStateChanged(int state) {}
Ihab Awadf8358972014-05-28 16:46:42 -07001731
1732 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001733 * Notifies this Connection of a request to play a DTMF tone.
1734 *
1735 * @param c A DTMF character.
1736 */
Santos Cordonf2951102014-07-20 19:06:29 -07001737 public void onPlayDtmfTone(char c) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001738
1739 /**
1740 * Notifies this Connection of a request to stop any currently playing DTMF tones.
1741 */
Santos Cordonf2951102014-07-20 19:06:29 -07001742 public void onStopDtmfTone() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001743
1744 /**
1745 * Notifies this Connection of a request to disconnect.
1746 */
Santos Cordonf2951102014-07-20 19:06:29 -07001747 public void onDisconnect() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001748
1749 /**
Tyler Gunn3b4b1dc2014-11-04 14:53:37 -08001750 * Notifies this Connection of a request to disconnect a participant of the conference managed
1751 * by the connection.
1752 *
1753 * @param endpoint the {@link Uri} of the participant to disconnect.
1754 * @hide
1755 */
1756 public void onDisconnectConferenceParticipant(Uri endpoint) {}
1757
1758 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001759 * Notifies this Connection of a request to separate from its parent conference.
Santos Cordonb6939982014-06-04 20:20:58 -07001760 */
Santos Cordonf2951102014-07-20 19:06:29 -07001761 public void onSeparate() {}
Santos Cordonb6939982014-06-04 20:20:58 -07001762
1763 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001764 * Notifies this Connection of a request to abort.
1765 */
Santos Cordonf2951102014-07-20 19:06:29 -07001766 public void onAbort() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001767
1768 /**
1769 * Notifies this Connection of a request to hold.
1770 */
Santos Cordonf2951102014-07-20 19:06:29 -07001771 public void onHold() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001772
1773 /**
1774 * Notifies this Connection of a request to exit a hold state.
1775 */
Santos Cordonf2951102014-07-20 19:06:29 -07001776 public void onUnhold() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001777
1778 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001779 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Santos Cordond34e5712014-08-05 18:54:03 +00001780 * a request to accept.
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001781 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001782 * @param videoState The video state in which to answer the connection.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001783 */
Santos Cordonf2951102014-07-20 19:06:29 -07001784 public void onAnswer(int videoState) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001785
1786 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001787 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Tyler Gunnbe74de02014-08-29 14:51:48 -07001788 * a request to accept.
1789 */
1790 public void onAnswer() {
Tyler Gunn87b73f32015-06-03 10:09:59 -07001791 onAnswer(VideoProfile.STATE_AUDIO_ONLY);
Tyler Gunnbe74de02014-08-29 14:51:48 -07001792 }
1793
1794 /**
1795 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Santos Cordond34e5712014-08-05 18:54:03 +00001796 * a request to reject.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001797 */
Santos Cordonf2951102014-07-20 19:06:29 -07001798 public void onReject() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001799
Evan Charlton6dea4ac2014-06-03 14:07:13 -07001800 /**
Bryce Lee81901682015-08-28 16:38:02 -07001801 * Notifies ths Connection of a request reject with a message.
1802 *
1803 * @hide
1804 */
1805 public void onReject(String replyMessage) {}
1806
1807 /**
Bryce Leecac50772015-11-17 15:13:29 -08001808 * Notifies the Connection of a request to silence the ringer.
1809 *
1810 * @hide
1811 */
1812 public void onSilence() {}
1813
1814 /**
Evan Charlton6dea4ac2014-06-03 14:07:13 -07001815 * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
1816 */
Santos Cordonf2951102014-07-20 19:06:29 -07001817 public void onPostDialContinue(boolean proceed) {}
Evan Charlton6dea4ac2014-06-03 14:07:13 -07001818
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001819 static String toLogSafePhoneNumber(String number) {
1820 // For unknown number, log empty string.
1821 if (number == null) {
1822 return "";
1823 }
1824
1825 if (PII_DEBUG) {
1826 // When PII_DEBUG is true we emit PII.
1827 return number;
1828 }
1829
1830 // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
1831 // sanitized phone numbers.
1832 StringBuilder builder = new StringBuilder();
1833 for (int i = 0; i < number.length(); i++) {
1834 char c = number.charAt(i);
1835 if (c == '-' || c == '@' || c == '.') {
1836 builder.append(c);
1837 } else {
1838 builder.append('x');
1839 }
1840 }
1841 return builder.toString();
1842 }
1843
Ihab Awad542e0ea2014-05-16 10:22:16 -07001844 private void setState(int state) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001845 checkImmutable();
Ihab Awad6107bab2014-08-18 09:23:25 -07001846 if (mState == STATE_DISCONNECTED && mState != state) {
1847 Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
Evan Charltonbf11f982014-07-20 22:06:28 -07001848 return;
Sailesh Nepal400cc482014-06-26 12:04:00 -07001849 }
Evan Charltonbf11f982014-07-20 22:06:28 -07001850 if (mState != state) {
1851 Log.d(this, "setState: %s", stateToString(state));
1852 mState = state;
Nancy Chen354b2bd2014-09-08 18:27:26 -07001853 onStateChanged(state);
Evan Charltonbf11f982014-07-20 22:06:28 -07001854 for (Listener l : mListeners) {
1855 l.onStateChanged(this, state);
1856 }
Evan Charltonbf11f982014-07-20 22:06:28 -07001857 }
1858 }
1859
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001860 private static class FailureSignalingConnection extends Connection {
Ihab Awad90e34e32014-12-01 16:23:17 -08001861 private boolean mImmutable = false;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001862 public FailureSignalingConnection(DisconnectCause disconnectCause) {
1863 setDisconnected(disconnectCause);
Ihab Awad90e34e32014-12-01 16:23:17 -08001864 mImmutable = true;
Ihab Awad6107bab2014-08-18 09:23:25 -07001865 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001866
1867 public void checkImmutable() {
Ihab Awad90e34e32014-12-01 16:23:17 -08001868 if (mImmutable) {
1869 throw new UnsupportedOperationException("Connection is immutable");
1870 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001871 }
Ihab Awad6107bab2014-08-18 09:23:25 -07001872 }
1873
Evan Charltonbf11f982014-07-20 22:06:28 -07001874 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001875 * Return a {@code Connection} which represents a failed connection attempt. The returned
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001876 * {@code Connection} will have a {@link android.telecom.DisconnectCause} and as specified,
1877 * and a {@link #getState()} of {@link #STATE_DISCONNECTED}.
Ihab Awad6107bab2014-08-18 09:23:25 -07001878 * <p>
1879 * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
1880 * so users of this method need not maintain a reference to its return value to destroy it.
Evan Charltonbf11f982014-07-20 22:06:28 -07001881 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001882 * @param disconnectCause The disconnect cause, ({@see android.telecomm.DisconnectCause}).
Ihab Awad6107bab2014-08-18 09:23:25 -07001883 * @return A {@code Connection} which indicates failure.
Evan Charltonbf11f982014-07-20 22:06:28 -07001884 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001885 public static Connection createFailedConnection(DisconnectCause disconnectCause) {
1886 return new FailureSignalingConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001887 }
1888
Evan Charltonbf11f982014-07-20 22:06:28 -07001889 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001890 * Override to throw an {@link UnsupportedOperationException} if this {@code Connection} is
1891 * not intended to be mutated, e.g., if it is a marker for failure. Only for framework use;
1892 * this should never be un-@hide-den.
1893 *
1894 * @hide
1895 */
1896 public void checkImmutable() {}
1897
1898 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001899 * Return a {@code Connection} which represents a canceled connection attempt. The returned
1900 * {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
1901 * that state. This connection should not be used for anything, and no other
1902 * {@code Connection}s should be attempted.
1903 * <p>
Ihab Awad6107bab2014-08-18 09:23:25 -07001904 * so users of this method need not maintain a reference to its return value to destroy it.
Evan Charltonbf11f982014-07-20 22:06:28 -07001905 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001906 * @return A {@code Connection} which indicates that the underlying connection should
1907 * be canceled.
Evan Charltonbf11f982014-07-20 22:06:28 -07001908 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001909 public static Connection createCanceledConnection() {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001910 return new FailureSignalingConnection(new DisconnectCause(DisconnectCause.CANCELED));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001911 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001912
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001913 private final void fireOnConferenceableConnectionsChanged() {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001914 for (Listener l : mListeners) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001915 l.onConferenceablesChanged(this, getConferenceables());
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001916 }
1917 }
1918
Santos Cordon823fd3c2014-08-07 18:35:18 -07001919 private final void fireConferenceChanged() {
1920 for (Listener l : mListeners) {
1921 l.onConferenceChanged(this, mConference);
1922 }
1923 }
1924
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001925 private final void clearConferenceableList() {
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001926 for (Conferenceable c : mConferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001927 if (c instanceof Connection) {
1928 Connection connection = (Connection) c;
1929 connection.removeConnectionListener(mConnectionDeathListener);
1930 } else if (c instanceof Conference) {
1931 Conference conference = (Conference) c;
1932 conference.removeListener(mConferenceDeathListener);
1933 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001934 }
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001935 mConferenceables.clear();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001936 }
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001937
1938 /**
Anthony Lee17455a32015-04-24 15:25:29 -07001939 * Notifies listeners that the merge request failed.
1940 *
1941 * @hide
1942 */
1943 protected final void notifyConferenceMergeFailed() {
1944 for (Listener l : mListeners) {
1945 l.onConferenceMergeFailed(this);
1946 }
1947 }
1948
1949 /**
Tyler Gunnab4650c2014-11-06 20:06:23 -08001950 * Notifies listeners of a change to conference participant(s).
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001951 *
Tyler Gunnab4650c2014-11-06 20:06:23 -08001952 * @param conferenceParticipants The participants.
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001953 * @hide
1954 */
Tyler Gunnab4650c2014-11-06 20:06:23 -08001955 protected final void updateConferenceParticipants(
1956 List<ConferenceParticipant> conferenceParticipants) {
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001957 for (Listener l : mListeners) {
Tyler Gunnab4650c2014-11-06 20:06:23 -08001958 l.onConferenceParticipantsChanged(this, conferenceParticipants);
Tyler Gunn3bffcf72014-10-28 13:51:27 -07001959 }
1960 }
Tyler Gunn8a2b1192015-01-29 11:47:24 -08001961
1962 /**
1963 * Notifies listeners that a conference call has been started.
Jay Shrauner55b97522015-04-09 15:15:43 -07001964 * @hide
Tyler Gunn8a2b1192015-01-29 11:47:24 -08001965 */
1966 protected void notifyConferenceStarted() {
1967 for (Listener l : mListeners) {
1968 l.onConferenceStarted();
1969 }
1970 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001971}