blob: b7391b4c57acc9b6baf106aecc096c8062368acf [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
Tyler Gunndee56a82016-03-23 16:06:34 -070023import android.annotation.NonNull;
Santos Cordon6b7f9552015-05-27 17:21:45 -070024import android.annotation.Nullable;
Yorke Lee4af59352015-05-13 14:14:54 -070025import android.annotation.SystemApi;
Tyler Gunnb702ef82015-05-29 11:51:53 -070026import android.hardware.camera2.CameraManager;
Ihab Awad542e0ea2014-05-16 10:22:16 -070027import android.net.Uri;
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -080028import android.os.Binder;
Santos Cordon6b7f9552015-05-27 17:21:45 -070029import android.os.Bundle;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070030import android.os.Handler;
31import android.os.IBinder;
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -070032import android.os.Looper;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070033import android.os.Message;
34import android.os.RemoteException;
Tyler Gunndee56a82016-03-23 16:06:34 -070035import android.util.ArraySet;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070036import android.view.Surface;
Ihab Awad542e0ea2014-05-16 10:22:16 -070037
Santos Cordonb6939982014-06-04 20:20:58 -070038import java.util.ArrayList;
Tyler Gunn071be6f2016-05-10 14:52:33 -070039import java.util.Arrays;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070040import java.util.Collections;
Santos Cordonb6939982014-06-04 20:20:58 -070041import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070042import java.util.Set;
Jay Shrauner229e3822014-08-15 09:23:07 -070043import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070044
45/**
Santos Cordon895d4b82015-06-25 16:41:48 -070046 * Represents a phone call or connection to a remote endpoint that carries voice and/or video
47 * traffic.
Ihab Awad6107bab2014-08-18 09:23:25 -070048 * <p>
49 * Implementations create a custom subclass of {@code Connection} and return it to the framework
50 * as the return value of
51 * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
52 * or
53 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
54 * Implementations are then responsible for updating the state of the {@code Connection}, and
55 * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
56 * longer used and associated resources may be recovered.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -070057 * <p>
58 * Subclasses of {@code Connection} override the {@code on*} methods to provide the the
59 * {@link ConnectionService}'s implementation of calling functionality. The {@code on*} methods are
60 * called by Telecom to inform an instance of a {@code Connection} of actions specific to that
61 * {@code Connection} instance.
62 * <p>
63 * Basic call support requires overriding the following methods: {@link #onAnswer()},
64 * {@link #onDisconnect()}, {@link #onReject()}, {@link #onAbort()}
65 * <p>
66 * Where a {@code Connection} has {@link #CAPABILITY_SUPPORT_HOLD}, the {@link #onHold()} and
67 * {@link #onUnhold()} methods should be overridden to provide hold support for the
68 * {@code Connection}.
69 * <p>
70 * Where a {@code Connection} supports a variation of video calling (e.g. the
71 * {@code CAPABILITY_SUPPORTS_VT_*} capability bits), {@link #onAnswer(int)} should be overridden
72 * to support answering a call as a video call.
73 * <p>
74 * Where a {@code Connection} has {@link #PROPERTY_IS_EXTERNAL_CALL} and
75 * {@link #CAPABILITY_CAN_PULL_CALL}, {@link #onPullExternalCall()} should be overridden to provide
76 * support for pulling the external call.
77 * <p>
78 * Where a {@code Connection} supports conference calling {@link #onSeparate()} should be
79 * overridden.
80 * <p>
81 * There are a number of other {@code on*} methods which a {@code Connection} can choose to
82 * implement, depending on whether it is concerned with the associated calls from Telecom. If,
83 * for example, call events from a {@link InCallService} are handled,
84 * {@link #onCallEvent(String, Bundle)} should be overridden. Another example is
85 * {@link #onExtrasChanged(Bundle)}, which should be overridden if the {@code Connection} wishes to
86 * make use of extra information provided via the {@link Call#putExtras(Bundle)} and
87 * {@link Call#removeExtras(String...)} methods.
Ihab Awad542e0ea2014-05-16 10:22:16 -070088 */
Yorke Leeabfcfdc2015-05-13 18:55:18 -070089public abstract class Connection extends Conferenceable {
Ihab Awad542e0ea2014-05-16 10:22:16 -070090
Santos Cordon895d4b82015-06-25 16:41:48 -070091 /**
92 * The connection is initializing. This is generally the first state for a {@code Connection}
93 * returned by a {@link ConnectionService}.
94 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070095 public static final int STATE_INITIALIZING = 0;
96
Santos Cordon895d4b82015-06-25 16:41:48 -070097 /**
98 * The connection is new and not connected.
99 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700100 public static final int STATE_NEW = 1;
101
Santos Cordon895d4b82015-06-25 16:41:48 -0700102 /**
103 * An incoming connection is in the ringing state. During this state, the user's ringer or
104 * vibration feature will be activated.
105 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700106 public static final int STATE_RINGING = 2;
107
Santos Cordon895d4b82015-06-25 16:41:48 -0700108 /**
109 * An outgoing connection is in the dialing state. In this state the other party has not yet
110 * answered the call and the user traditionally hears a ringback tone.
111 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700112 public static final int STATE_DIALING = 3;
113
Santos Cordon895d4b82015-06-25 16:41:48 -0700114 /**
115 * A connection is active. Both parties are connected to the call and can actively communicate.
116 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700117 public static final int STATE_ACTIVE = 4;
118
Santos Cordon895d4b82015-06-25 16:41:48 -0700119 /**
120 * A connection is on hold.
121 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700122 public static final int STATE_HOLDING = 5;
123
Santos Cordon895d4b82015-06-25 16:41:48 -0700124 /**
125 * A connection has been disconnected. This is the final state once the user has been
126 * disconnected from a call either locally, remotely or by an error in the service.
127 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700128 public static final int STATE_DISCONNECTED = 6;
129
Santos Cordon895d4b82015-06-25 16:41:48 -0700130 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700131 * The state of an external connection which is in the process of being pulled from a remote
132 * device to the local device.
133 * <p>
Tyler Gunn720c6642016-03-22 09:02:47 -0700134 * A connection can only be in this state if the {@link #PROPERTY_IS_EXTERNAL_CALL} property and
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700135 * {@link #CAPABILITY_CAN_PULL_CALL} capability bits are set on the connection.
136 */
137 public static final int STATE_PULLING_CALL = 7;
138
139 /**
Santos Cordon895d4b82015-06-25 16:41:48 -0700140 * Connection can currently be put on hold or unheld. This is distinct from
141 * {@link #CAPABILITY_SUPPORT_HOLD} in that although a connection may support 'hold' most times,
142 * it does not at the moment support the function. This can be true while the call is in the
143 * state {@link #STATE_DIALING}, for example. During this condition, an in-call UI may
144 * display a disabled 'hold' button.
145 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800146 public static final int CAPABILITY_HOLD = 0x00000001;
147
148 /** Connection supports the hold feature. */
149 public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
150
151 /**
152 * Connections within a conference can be merged. A {@link ConnectionService} has the option to
153 * add a {@link Conference} before the child {@link Connection}s are merged. This is how
154 * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
155 * capability allows a merge button to be shown while the conference is in the foreground
156 * of the in-call UI.
157 * <p>
158 * This is only intended for use by a {@link Conference}.
159 */
160 public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
161
162 /**
163 * Connections within a conference can be swapped between foreground and background.
164 * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
165 * <p>
166 * This is only intended for use by a {@link Conference}.
167 */
168 public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
169
170 /**
171 * @hide
172 */
173 public static final int CAPABILITY_UNUSED = 0x00000010;
174
175 /** Connection supports responding via text option. */
176 public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
177
178 /** Connection can be muted. */
179 public static final int CAPABILITY_MUTE = 0x00000040;
180
181 /**
182 * Connection supports conference management. This capability only applies to
183 * {@link Conference}s which can have {@link Connection}s as children.
184 */
185 public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
186
187 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700188 * Local device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800189 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700190 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800191
192 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700193 * Local device supports transmitting video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800194 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700195 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800196
197 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700198 * Local device supports bidirectional video calling.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800199 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700200 public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700201 CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800202
203 /**
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700204 * Remote device supports receiving video.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800205 */
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700206 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400;
207
208 /**
209 * Remote device supports transmitting video.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700210 */
211 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800;
212
213 /**
214 * Remote device supports bidirectional video calling.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700215 */
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700216 public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL =
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700217 CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800218
219 /**
220 * Connection is able to be separated from its parent {@code Conference}, if any.
221 */
222 public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
223
224 /**
225 * Connection is able to be individually disconnected when in a {@code Conference}.
226 */
227 public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
228
229 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700230 * Un-used.
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800231 * @hide
232 */
Tyler Gunn720c6642016-03-22 09:02:47 -0700233 public static final int CAPABILITY_UNUSED_2 = 0x00004000;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800234
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700235 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700236 * Un-used.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700237 * @hide
238 */
Tyler Gunn720c6642016-03-22 09:02:47 -0700239 public static final int CAPABILITY_UNUSED_3 = 0x00008000;
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700240
241 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700242 * Un-used.
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700243 * @hide
244 */
Tyler Gunn720c6642016-03-22 09:02:47 -0700245 public static final int CAPABILITY_UNUSED_4 = 0x00010000;
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700246
Tyler Gunn068085b2015-02-06 13:56:52 -0800247 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700248 * Un-used.
Tyler Gunn068085b2015-02-06 13:56:52 -0800249 * @hide
250 */
Tyler Gunn720c6642016-03-22 09:02:47 -0700251 public static final int CAPABILITY_UNUSED_5 = 0x00020000;
Tyler Gunn068085b2015-02-06 13:56:52 -0800252
Tyler Gunn96d6c402015-03-18 12:39:23 -0700253 /**
Dong Zhou89f41eb2015-03-15 11:59:49 -0500254 * Speed up audio setup for MT call.
255 * @hide
Tyler Gunn96d6c402015-03-18 12:39:23 -0700256 */
257 public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000;
Tyler Gunn068085b2015-02-06 13:56:52 -0800258
Rekha Kumar07366812015-03-24 16:42:31 -0700259 /**
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700260 * Call can be upgraded to a video call.
Rekha Kumar07366812015-03-24 16:42:31 -0700261 */
262 public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
263
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700264 /**
265 * For video calls, indicates whether the outgoing video for the call can be paused using
Yorke Lee32f24732015-05-12 16:18:03 -0700266 * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700267 */
268 public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
269
Tyler Gunnd4091732015-06-29 09:15:37 -0700270 /**
271 * For a conference, indicates the conference will not have child connections.
272 * <p>
273 * An example of a conference with child connections is a GSM conference call, where the radio
274 * retains connections to the individual participants of the conference. Another example is an
275 * IMS conference call where conference event package functionality is supported; in this case
276 * the conference server ensures the radio is aware of the participants in the conference, which
277 * are represented by child connections.
278 * <p>
279 * An example of a conference with no child connections is an IMS conference call with no
280 * conference event package support. Such a conference is represented by the radio as a single
281 * connection to the IMS conference server.
282 * <p>
283 * Indicating whether a conference has children or not is important to help user interfaces
284 * visually represent a conference. A conference with no children, for example, will have the
285 * conference connection shown in the list of calls on a Bluetooth device, where if the
286 * conference has children, only the children will be shown in the list of calls on a Bluetooth
287 * device.
288 * @hide
289 */
290 public static final int CAPABILITY_CONFERENCE_HAS_NO_CHILDREN = 0x00200000;
291
Bryce Lee81901682015-08-28 16:38:02 -0700292 /**
293 * Indicates that the connection itself wants to handle any sort of reply response, rather than
294 * relying on SMS.
Bryce Lee81901682015-08-28 16:38:02 -0700295 */
296 public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00400000;
297
Tyler Gunnf97a0092016-01-19 15:59:34 -0800298 /**
299 * When set, prevents a video call from being downgraded to an audio-only call.
300 * <p>
301 * Should be set when the VideoState has the {@link VideoProfile#STATE_TX_ENABLED} or
302 * {@link VideoProfile#STATE_RX_ENABLED} bits set to indicate that the connection cannot be
303 * downgraded from a video call back to a VideoState of
304 * {@link VideoProfile#STATE_AUDIO_ONLY}.
305 * <p>
306 * Intuitively, a call which can be downgraded to audio should also have local and remote
307 * video
308 * capabilities (see {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
309 * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL}).
310 */
311 public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00800000;
312
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700313 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700314 * When set for an external connection, indicates that this {@code Connection} can be pulled
315 * from a remote device to the current device.
316 * <p>
317 * Should only be set on a {@code Connection} where {@link #PROPERTY_IS_EXTERNAL_CALL}
318 * is set.
319 */
320 public static final int CAPABILITY_CAN_PULL_CALL = 0x01000000;
321
322 //**********************************************************************************************
323 // Next CAPABILITY value: 0x02000000
324 //**********************************************************************************************
325
326 /**
327 * Indicates that the current device callback number should be shown.
328 *
329 * @hide
330 */
Hall Liu25c7c4d2016-08-30 13:41:02 -0700331 public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 1<<0;
Tyler Gunn720c6642016-03-22 09:02:47 -0700332
333 /**
334 * Whether the call is a generic conference, where we do not know the precise state of
335 * participants in the conference (eg. on CDMA).
336 *
337 * @hide
338 */
339 public static final int PROPERTY_GENERIC_CONFERENCE = 1<<1;
340
341 /**
342 * Connection is using high definition audio.
343 * @hide
344 */
345 public static final int PROPERTY_HIGH_DEF_AUDIO = 1<<2;
346
347 /**
348 * Connection is using WIFI.
349 * @hide
350 */
351 public static final int PROPERTY_WIFI = 1<<3;
352
353 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700354 * When set, indicates that the {@code Connection} does not actually exist locally for the
355 * {@link ConnectionService}.
356 * <p>
357 * Consider, for example, a scenario where a user has two devices with the same phone number.
358 * When a user places a call on one devices, the telephony stack can represent that call on the
359 * other device by adding is to the {@link ConnectionService} with the
Tyler Gunn720c6642016-03-22 09:02:47 -0700360 * {@link #PROPERTY_IS_EXTERNAL_CALL} capability set.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700361 * <p>
362 * An {@link ConnectionService} should not assume that all {@link InCallService}s will handle
363 * external connections. Only those {@link InCallService}s which have the
364 * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its
365 * manifest will see external connections.
366 */
Tyler Gunn720c6642016-03-22 09:02:47 -0700367 public static final int PROPERTY_IS_EXTERNAL_CALL = 1<<4;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700368
Brad Ebinger15847072016-05-18 11:08:36 -0700369 /**
370 * Indicates that the connection has CDMA Enhanced Voice Privacy enabled.
371 */
372 public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 1<<5;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700373
Hall Liu9f332c72016-07-14 15:37:37 -0700374 /**
375 * Indicates that the connection represents a downgraded IMS conference.
376 * @hide
377 */
378 public static final int PROPERTY_IS_DOWNGRADED_CONFERENCE = 1<<6;
379
Tyler Gunnf5035432017-01-09 09:43:12 -0800380 /**
381 * Set by the framework to indicate that the {@link Connection} originated from a self-managed
382 * {@link ConnectionService}.
383 * <p>
384 * See {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.
385 */
386 public static final int PROPERTY_SELF_MANAGED = 1<<7;
387
Tyler Gunn96d6c402015-03-18 12:39:23 -0700388 //**********************************************************************************************
Tyler Gunnf5035432017-01-09 09:43:12 -0800389 // Next PROPERTY value: 1<<8
Tyler Gunn96d6c402015-03-18 12:39:23 -0700390 //**********************************************************************************************
Tyler Gunn068085b2015-02-06 13:56:52 -0800391
Tyler Gunn335ff2e2015-07-30 14:18:33 -0700392 /**
393 * Connection extra key used to store the last forwarded number associated with the current
394 * connection. Used to communicate to the user interface that the connection was forwarded via
395 * the specified number.
396 */
397 public static final String EXTRA_LAST_FORWARDED_NUMBER =
398 "android.telecom.extra.LAST_FORWARDED_NUMBER";
399
400 /**
401 * Connection extra key used to store a child number associated with the current connection.
402 * Used to communicate to the user interface that the connection was received via
403 * a child address (i.e. phone number) associated with the {@link PhoneAccount}'s primary
404 * address.
405 */
406 public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
407
408 /**
409 * Connection extra key used to store the subject for an incoming call. The user interface can
410 * query this extra and display its contents for incoming calls. Will only be used if the
411 * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
412 */
413 public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
414
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800415 /**
Tyler Gunn4b6614e2016-06-22 10:35:13 -0700416 * Boolean connection extra key set on a {@link Connection} in
417 * {@link Connection#STATE_RINGING} state to indicate that answering the call will cause the
418 * current active foreground call to be dropped.
419 */
420 public static final String EXTRA_ANSWERING_DROPS_FG_CALL =
421 "android.telecom.extra.ANSWERING_DROPS_FG_CALL";
422
423 /**
Hall Liu10208662016-06-15 17:55:00 -0700424 * Boolean connection extra key on a {@link Connection} which indicates that adding an
Hall Liuee6e86b2016-07-06 16:32:43 -0700425 * additional call is disallowed.
Hall Liu10208662016-06-15 17:55:00 -0700426 * @hide
427 */
Hall Liuee6e86b2016-07-06 16:32:43 -0700428 public static final String EXTRA_DISABLE_ADD_CALL =
429 "android.telecom.extra.DISABLE_ADD_CALL";
Hall Liu10208662016-06-15 17:55:00 -0700430
431 /**
Tyler Gunncd6ccfd2016-10-17 15:48:19 -0700432 * String connection extra key on a {@link Connection} or {@link Conference} which contains the
433 * original Connection ID associated with the connection. Used in
434 * {@link RemoteConnectionService} to track the Connection ID which was originally assigned to a
435 * connection/conference added via
436 * {@link ConnectionService#addExistingConnection(PhoneAccountHandle, Connection)} and
437 * {@link ConnectionService#addConference(Conference)} APIs. This is important to pass to
438 * Telecom for when it deals with RemoteConnections. When the ConnectionManager wraps the
439 * {@link RemoteConnection} and {@link RemoteConference} and adds it to Telecom, there needs to
440 * be a way to ensure that we don't add the connection again as a duplicate.
441 * <p>
442 * For example, the TelephonyCS calls addExistingConnection for a Connection with ID
443 * {@code TelephonyCS@1}. The ConnectionManager learns of this via
444 * {@link ConnectionService#onRemoteExistingConnectionAdded(RemoteConnection)}, and wraps this
445 * in a new {@link Connection} which it adds to Telecom via
446 * {@link ConnectionService#addExistingConnection(PhoneAccountHandle, Connection)}. As part of
447 * this process, the wrapped RemoteConnection gets assigned a new ID (e.g. {@code ConnMan@1}).
448 * The TelephonyCS will ALSO try to add the existing connection to Telecom, except with the
449 * ID it originally referred to the connection as. Thus Telecom needs to know that the
450 * Connection with ID {@code ConnMan@1} is really the same as {@code TelephonyCS@1}.
451 * @hide
452 */
453 public static final String EXTRA_ORIGINAL_CONNECTION_ID =
454 "android.telecom.extra.ORIGINAL_CONNECTION_ID";
455
456 /**
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800457 * Connection event used to inform Telecom that it should play the on hold tone. This is used
458 * to play a tone when the peer puts the current call on hold. Sent to Telecom via
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700459 * {@link #sendConnectionEvent(String, Bundle)}.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800460 * @hide
461 */
462 public static final String EVENT_ON_HOLD_TONE_START =
463 "android.telecom.event.ON_HOLD_TONE_START";
464
465 /**
466 * Connection event used to inform Telecom that it should stop the on hold tone. This is used
467 * to stop a tone when the peer puts the current call on hold. Sent to Telecom via
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700468 * {@link #sendConnectionEvent(String, Bundle)}.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800469 * @hide
470 */
471 public static final String EVENT_ON_HOLD_TONE_END =
472 "android.telecom.event.ON_HOLD_TONE_END";
473
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700474 /**
475 * Connection event used to inform {@link InCallService}s when pulling of an external call has
476 * failed. The user interface should inform the user of the error.
477 * <p>
478 * Expected to be used by the {@link ConnectionService} when the {@link Call#pullExternalCall()}
479 * API is called on a {@link Call} with the properties
480 * {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} and
481 * {@link Call.Details#CAPABILITY_CAN_PULL_CALL}, but the {@link ConnectionService} could not
482 * pull the external call due to an error condition.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700483 * <p>
484 * Sent via {@link #sendConnectionEvent(String, Bundle)}. The {@link Bundle} parameter is
485 * expected to be null when this connection event is used.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700486 */
487 public static final String EVENT_CALL_PULL_FAILED = "android.telecom.event.CALL_PULL_FAILED";
488
Brad Ebinger2c1c16452016-05-27 15:58:10 -0700489 /**
490 * Connection event used to inform {@link InCallService}s when the merging of two calls has
491 * failed. The User Interface should use this message to inform the user of the error.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700492 * <p>
493 * Sent via {@link #sendConnectionEvent(String, Bundle)}. The {@link Bundle} parameter is
494 * expected to be null when this connection event is used.
Brad Ebinger2c1c16452016-05-27 15:58:10 -0700495 */
496 public static final String EVENT_CALL_MERGE_FAILED = "android.telecom.event.CALL_MERGE_FAILED";
497
Tyler Gunnb5ed8602016-08-17 13:48:27 -0700498 /**
499 * Connection event used to inform {@link InCallService}s when a call has been put on hold by
500 * the remote party.
501 * <p>
502 * This is different than the {@link Connection#STATE_HOLDING} state which indicates that the
503 * call is being held locally on the device. When a capable {@link ConnectionService} receives
504 * signalling to indicate that the remote party has put the call on hold, it can send this
505 * connection event.
506 * @hide
507 */
508 public static final String EVENT_CALL_REMOTELY_HELD =
509 "android.telecom.event.CALL_REMOTELY_HELD";
510
511 /**
512 * Connection event used to inform {@link InCallService}s when a call which was remotely held
513 * (see {@link #EVENT_CALL_REMOTELY_HELD}) has been un-held by the remote party.
514 * <p>
515 * This is different than the {@link Connection#STATE_HOLDING} state which indicates that the
516 * call is being held locally on the device. When a capable {@link ConnectionService} receives
517 * signalling to indicate that the remote party has taken the call off hold, it can send this
518 * connection event.
519 * @hide
520 */
521 public static final String EVENT_CALL_REMOTELY_UNHELD =
522 "android.telecom.event.CALL_REMOTELY_UNHELD";
523
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700524 // Flag controlling whether PII is emitted into the logs
525 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
526
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800527 /**
528 * Whether the given capabilities support the specified capability.
529 *
530 * @param capabilities A capability bit field.
531 * @param capability The capability to check capabilities for.
532 * @return Whether the specified capability is supported.
533 * @hide
534 */
535 public static boolean can(int capabilities, int capability) {
Tyler Gunn014c7112015-12-18 14:33:57 -0800536 return (capabilities & capability) == capability;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800537 }
538
539 /**
540 * Whether the capabilities of this {@code Connection} supports the specified capability.
541 *
542 * @param capability The capability to check capabilities for.
543 * @return Whether the specified capability is supported.
544 * @hide
545 */
546 public boolean can(int capability) {
547 return can(mConnectionCapabilities, capability);
548 }
549
550 /**
551 * Removes the specified capability from the set of capabilities of this {@code Connection}.
552 *
553 * @param capability The capability to remove from the set.
554 * @hide
555 */
556 public void removeCapability(int capability) {
557 mConnectionCapabilities &= ~capability;
558 }
559
560 /**
561 * Adds the specified capability to the set of capabilities of this {@code Connection}.
562 *
563 * @param capability The capability to add to the set.
564 * @hide
565 */
566 public void addCapability(int capability) {
567 mConnectionCapabilities |= capability;
568 }
569
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700570 /**
571 * Renders a set of capability bits ({@code CAPABILITY_*}) as a human readable string.
572 *
573 * @param capabilities A capability bit field.
574 * @return A human readable string representation.
575 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800576 public static String capabilitiesToString(int capabilities) {
Santos Cordon1a749302016-07-26 16:08:53 -0700577 return capabilitiesToStringInternal(capabilities, true /* isLong */);
578 }
579
580 /**
581 * Renders a set of capability bits ({@code CAPABILITY_*}) as a *short* human readable
582 * string.
583 *
584 * @param capabilities A capability bit field.
585 * @return A human readable string representation.
586 * @hide
587 */
588 public static String capabilitiesToStringShort(int capabilities) {
589 return capabilitiesToStringInternal(capabilities, false /* isLong */);
590 }
591
592 private static String capabilitiesToStringInternal(int capabilities, boolean isLong) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800593 StringBuilder builder = new StringBuilder();
Santos Cordon1a749302016-07-26 16:08:53 -0700594 builder.append("[");
595 if (isLong) {
596 builder.append("Capabilities:");
597 }
598
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800599 if (can(capabilities, CAPABILITY_HOLD)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700600 builder.append(isLong ? " CAPABILITY_HOLD" : " hld");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800601 }
602 if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700603 builder.append(isLong ? " CAPABILITY_SUPPORT_HOLD" : " sup_hld");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800604 }
605 if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700606 builder.append(isLong ? " CAPABILITY_MERGE_CONFERENCE" : " mrg_cnf");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800607 }
608 if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700609 builder.append(isLong ? " CAPABILITY_SWAP_CONFERENCE" : " swp_cnf");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800610 }
611 if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700612 builder.append(isLong ? " CAPABILITY_RESPOND_VIA_TEXT" : " txt");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800613 }
614 if (can(capabilities, CAPABILITY_MUTE)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700615 builder.append(isLong ? " CAPABILITY_MUTE" : " mut");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800616 }
617 if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700618 builder.append(isLong ? " CAPABILITY_MANAGE_CONFERENCE" : " mng_cnf");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800619 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700620 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_RX)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700621 builder.append(isLong ? " CAPABILITY_SUPPORTS_VT_LOCAL_RX" : " VTlrx");
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700622 }
623 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_TX)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700624 builder.append(isLong ? " CAPABILITY_SUPPORTS_VT_LOCAL_TX" : " VTltx");
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700625 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700626 if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700627 builder.append(isLong ? " CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL" : " VTlbi");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800628 }
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700629 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_RX)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700630 builder.append(isLong ? " CAPABILITY_SUPPORTS_VT_REMOTE_RX" : " VTrrx");
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700631 }
632 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700633 builder.append(isLong ? " CAPABILITY_SUPPORTS_VT_REMOTE_TX" : " VTrtx");
Andrew Lee5e9e8bb2015-03-10 13:58:24 -0700634 }
Andrew Lee9a8f9ce2015-04-10 18:09:46 -0700635 if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700636 builder.append(isLong ? " CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL" : " VTrbi");
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800637 }
Tyler Gunnf97a0092016-01-19 15:59:34 -0800638 if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700639 builder.append(isLong ? " CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO" : " !v2a");
Tyler Gunnf97a0092016-01-19 15:59:34 -0800640 }
Dong Zhou89f41eb2015-03-15 11:59:49 -0500641 if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700642 builder.append(isLong ? " CAPABILITY_SPEED_UP_MT_AUDIO" : " spd_aud");
Dong Zhou89f41eb2015-03-15 11:59:49 -0500643 }
Rekha Kumar07366812015-03-24 16:42:31 -0700644 if (can(capabilities, CAPABILITY_CAN_UPGRADE_TO_VIDEO)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700645 builder.append(isLong ? " CAPABILITY_CAN_UPGRADE_TO_VIDEO" : " a2v");
Rekha Kumar07366812015-03-24 16:42:31 -0700646 }
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700647 if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700648 builder.append(isLong ? " CAPABILITY_CAN_PAUSE_VIDEO" : " paus_VT");
Tyler Gunnb5e0cfb2015-04-07 16:10:51 -0700649 }
Tyler Gunnd4091732015-06-29 09:15:37 -0700650 if (can(capabilities, CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700651 builder.append(isLong ? " CAPABILITY_SINGLE_PARTY_CONFERENCE" : " 1p_cnf");
Tyler Gunnd4091732015-06-29 09:15:37 -0700652 }
Bryce Lee81901682015-08-28 16:38:02 -0700653 if (can(capabilities, CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700654 builder.append(isLong ? " CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION" : " rsp_by_con");
Bryce Lee81901682015-08-28 16:38:02 -0700655 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700656 if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700657 builder.append(isLong ? " CAPABILITY_CAN_PULL_CALL" : " pull");
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700658 }
Bryce Lee81901682015-08-28 16:38:02 -0700659
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800660 builder.append("]");
661 return builder.toString();
662 }
663
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700664 /**
665 * Renders a set of property bits ({@code PROPERTY_*}) as a human readable string.
666 *
667 * @param properties A property bit field.
668 * @return A human readable string representation.
669 */
Tyler Gunn720c6642016-03-22 09:02:47 -0700670 public static String propertiesToString(int properties) {
Santos Cordon1a749302016-07-26 16:08:53 -0700671 return propertiesToStringInternal(properties, true /* isLong */);
672 }
673
674 /**
675 * Renders a set of property bits ({@code PROPERTY_*}) as a *short* human readable string.
676 *
677 * @param properties A property bit field.
678 * @return A human readable string representation.
679 * @hide
680 */
681 public static String propertiesToStringShort(int properties) {
682 return propertiesToStringInternal(properties, false /* isLong */);
683 }
684
685 private static String propertiesToStringInternal(int properties, boolean isLong) {
Tyler Gunn720c6642016-03-22 09:02:47 -0700686 StringBuilder builder = new StringBuilder();
Santos Cordon1a749302016-07-26 16:08:53 -0700687 builder.append("[");
688 if (isLong) {
689 builder.append("Properties:");
690 }
Tyler Gunn720c6642016-03-22 09:02:47 -0700691
Tyler Gunnf5035432017-01-09 09:43:12 -0800692 if (can(properties, PROPERTY_SELF_MANAGED)) {
693 builder.append(isLong ? " PROPERTY_SELF_MANAGED" : " self_mng");
694 }
695
Hall Liu25c7c4d2016-08-30 13:41:02 -0700696 if (can(properties, PROPERTY_EMERGENCY_CALLBACK_MODE)) {
697 builder.append(isLong ? " PROPERTY_EMERGENCY_CALLBACK_MODE" : " ecbm");
Tyler Gunn720c6642016-03-22 09:02:47 -0700698 }
699
700 if (can(properties, PROPERTY_HIGH_DEF_AUDIO)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700701 builder.append(isLong ? " PROPERTY_HIGH_DEF_AUDIO" : " HD");
Tyler Gunn720c6642016-03-22 09:02:47 -0700702 }
703
704 if (can(properties, PROPERTY_WIFI)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700705 builder.append(isLong ? " PROPERTY_WIFI" : " wifi");
Tyler Gunn720c6642016-03-22 09:02:47 -0700706 }
707
708 if (can(properties, PROPERTY_GENERIC_CONFERENCE)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700709 builder.append(isLong ? " PROPERTY_GENERIC_CONFERENCE" : " gen_conf");
Tyler Gunn720c6642016-03-22 09:02:47 -0700710 }
711
712 if (can(properties, PROPERTY_IS_EXTERNAL_CALL)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700713 builder.append(isLong ? " PROPERTY_IS_EXTERNAL_CALL" : " xtrnl");
Tyler Gunn720c6642016-03-22 09:02:47 -0700714 }
715
Brad Ebinger15847072016-05-18 11:08:36 -0700716 if (can(properties, PROPERTY_HAS_CDMA_VOICE_PRIVACY)) {
Santos Cordon1a749302016-07-26 16:08:53 -0700717 builder.append(isLong ? " PROPERTY_HAS_CDMA_VOICE_PRIVACY" : " priv");
Brad Ebinger15847072016-05-18 11:08:36 -0700718 }
719
Tyler Gunn720c6642016-03-22 09:02:47 -0700720 builder.append("]");
721 return builder.toString();
722 }
723
Sailesh Nepal091768c2014-06-30 15:15:23 -0700724 /** @hide */
Sailesh Nepal61203862014-07-11 14:50:13 -0700725 public abstract static class Listener {
Ihab Awad542e0ea2014-05-16 10:22:16 -0700726 public void onStateChanged(Connection c, int state) {}
Andrew Lee100e2932014-09-08 15:34:24 -0700727 public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
Sailesh Nepal61203862014-07-11 14:50:13 -0700728 public void onCallerDisplayNameChanged(
729 Connection c, String callerDisplayName, int presentation) {}
Tyler Gunnaa07df82014-07-17 07:50:22 -0700730 public void onVideoStateChanged(Connection c, int videoState) {}
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700731 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {}
Sailesh Nepal091768c2014-06-30 15:15:23 -0700732 public void onPostDialWait(Connection c, String remaining) {}
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800733 public void onPostDialChar(Connection c, char nextChar) {}
Andrew Lee100e2932014-09-08 15:34:24 -0700734 public void onRingbackRequested(Connection c, boolean ringback) {}
Sailesh Nepal61203862014-07-11 14:50:13 -0700735 public void onDestroyed(Connection c) {}
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800736 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
Tyler Gunn720c6642016-03-22 09:02:47 -0700737 public void onConnectionPropertiesChanged(Connection c, int properties) {}
Christine Hallstrom2830ce92016-11-30 16:06:42 -0800738 public void onSupportedAudioRoutesChanged(Connection c, int supportedAudioRoutes) {}
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700739 public void onVideoProviderChanged(
740 Connection c, VideoProvider videoProvider) {}
Sailesh Nepal001bbbb2014-07-15 14:40:39 -0700741 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
742 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
Tyler Gunn6d76ca02014-11-17 15:49:51 -0800743 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -0700744 Connection c, List<Conferenceable> conferenceables) {}
Santos Cordon823fd3c2014-08-07 18:35:18 -0700745 public void onConferenceChanged(Connection c, Conference conference) {}
Tyler Gunn3bffcf72014-10-28 13:51:27 -0700746 /** @hide */
Tyler Gunnab4650c2014-11-06 20:06:23 -0800747 public void onConferenceParticipantsChanged(Connection c,
748 List<ConferenceParticipant> participants) {}
Tyler Gunn8a2b1192015-01-29 11:47:24 -0800749 public void onConferenceStarted() {}
Anthony Lee17455a32015-04-24 15:25:29 -0700750 public void onConferenceMergeFailed(Connection c) {}
Santos Cordon6b7f9552015-05-27 17:21:45 -0700751 public void onExtrasChanged(Connection c, Bundle extras) {}
Tyler Gunndee56a82016-03-23 16:06:34 -0700752 public void onExtrasRemoved(Connection c, List<String> keys) {}
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700753 public void onConnectionEvent(Connection c, String event, Bundle extras) {}
Tyler Gunn7d633d32016-06-24 07:30:10 -0700754 /** @hide */
755 public void onConferenceSupportedChanged(Connection c, boolean isConferenceSupported) {}
Tyler Gunnf5035432017-01-09 09:43:12 -0800756 public void onAudioRouteChanged(Connection c, int audioRoute) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -0700757 }
758
Tyler Gunnb702ef82015-05-29 11:51:53 -0700759 /**
760 * Provides a means of controlling the video session associated with a {@link Connection}.
761 * <p>
762 * Implementations create a custom subclass of {@link VideoProvider} and the
763 * {@link ConnectionService} creates an instance sets it on the {@link Connection} using
764 * {@link Connection#setVideoProvider(VideoProvider)}. Any connection which supports video
765 * should set the {@link VideoProvider}.
766 * <p>
767 * The {@link VideoProvider} serves two primary purposes: it provides a means for Telecom and
768 * {@link InCallService} implementations to issue requests related to the video session;
769 * it provides a means for the {@link ConnectionService} to report events and information
770 * related to the video session to Telecom and the {@link InCallService} implementations.
771 * <p>
772 * {@link InCallService} implementations interact with the {@link VideoProvider} via
773 * {@link android.telecom.InCallService.VideoCall}.
774 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700775 public static abstract class VideoProvider {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700776 /**
777 * Video is not being received (no protocol pause was issued).
Tyler Gunnb702ef82015-05-29 11:51:53 -0700778 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700779 */
780 public static final int SESSION_EVENT_RX_PAUSE = 1;
Evan Charltonbf11f982014-07-20 22:06:28 -0700781
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700782 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700783 * Video reception has resumed after a {@link #SESSION_EVENT_RX_PAUSE}.
784 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700785 */
786 public static final int SESSION_EVENT_RX_RESUME = 2;
787
788 /**
789 * Video transmission has begun. This occurs after a negotiated start of video transmission
790 * when the underlying protocol has actually begun transmitting video to the remote party.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700791 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700792 */
793 public static final int SESSION_EVENT_TX_START = 3;
794
795 /**
796 * Video transmission has stopped. This occurs after a negotiated stop of video transmission
797 * when the underlying protocol has actually stopped transmitting video to the remote party.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700798 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700799 */
800 public static final int SESSION_EVENT_TX_STOP = 4;
801
802 /**
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800803 * A camera failure has occurred for the selected camera. The {@link VideoProvider} can use
Tyler Gunnb702ef82015-05-29 11:51:53 -0700804 * this as a cue to inform the user the camera is not available.
805 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700806 */
807 public static final int SESSION_EVENT_CAMERA_FAILURE = 5;
808
809 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700810 * Issued after {@link #SESSION_EVENT_CAMERA_FAILURE} when the camera is once again ready
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800811 * for operation. The {@link VideoProvider} can use this as a cue to inform the user that
Tyler Gunnb702ef82015-05-29 11:51:53 -0700812 * the camera has become available again.
813 * @see #handleCallSessionEvent(int)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700814 */
815 public static final int SESSION_EVENT_CAMERA_READY = 6;
816
817 /**
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800818 * Session event raised by Telecom when
819 * {@link android.telecom.InCallService.VideoCall#setCamera(String)} is called and the
820 * caller does not have the necessary {@link android.Manifest.permission#CAMERA} permission.
821 * @see #handleCallSessionEvent(int)
822 */
823 public static final int SESSION_EVENT_CAMERA_PERMISSION_ERROR = 7;
824
825 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700826 * Session modify request was successful.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700827 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700828 */
829 public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1;
830
831 /**
832 * Session modify request failed.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700833 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700834 */
835 public static final int SESSION_MODIFY_REQUEST_FAIL = 2;
836
837 /**
838 * Session modify request ignored due to invalid parameters.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700839 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700840 */
841 public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
842
Rekha Kumar07366812015-03-24 16:42:31 -0700843 /**
844 * Session modify request timed out.
Tyler Gunnb702ef82015-05-29 11:51:53 -0700845 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Rekha Kumar07366812015-03-24 16:42:31 -0700846 */
847 public static final int SESSION_MODIFY_REQUEST_TIMED_OUT = 4;
848
849 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -0700850 * Session modify request rejected by remote user.
851 * @see #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)
Rekha Kumar07366812015-03-24 16:42:31 -0700852 */
853 public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5;
854
Tyler Gunn75958422015-04-15 14:23:42 -0700855 private static final int MSG_ADD_VIDEO_CALLBACK = 1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700856 private static final int MSG_SET_CAMERA = 2;
857 private static final int MSG_SET_PREVIEW_SURFACE = 3;
858 private static final int MSG_SET_DISPLAY_SURFACE = 4;
859 private static final int MSG_SET_DEVICE_ORIENTATION = 5;
860 private static final int MSG_SET_ZOOM = 6;
861 private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7;
862 private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8;
863 private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800864 private static final int MSG_REQUEST_CONNECTION_DATA_USAGE = 10;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700865 private static final int MSG_SET_PAUSE_IMAGE = 11;
Tyler Gunn75958422015-04-15 14:23:42 -0700866 private static final int MSG_REMOVE_VIDEO_CALLBACK = 12;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700867
Tyler Gunn6f657ee2016-09-02 09:55:25 -0700868 private static final String SESSION_EVENT_RX_PAUSE_STR = "RX_PAUSE";
869 private static final String SESSION_EVENT_RX_RESUME_STR = "RX_RESUME";
870 private static final String SESSION_EVENT_TX_START_STR = "TX_START";
871 private static final String SESSION_EVENT_TX_STOP_STR = "TX_STOP";
872 private static final String SESSION_EVENT_CAMERA_FAILURE_STR = "CAMERA_FAIL";
873 private static final String SESSION_EVENT_CAMERA_READY_STR = "CAMERA_READY";
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800874 private static final String SESSION_EVENT_CAMERA_PERMISSION_ERROR_STR =
875 "CAMERA_PERMISSION_ERROR";
Tyler Gunn6f657ee2016-09-02 09:55:25 -0700876 private static final String SESSION_EVENT_UNKNOWN_STR = "UNKNOWN";
877
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -0700878 private VideoProvider.VideoProviderHandler mMessageHandler;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700879 private final VideoProvider.VideoProviderBinder mBinder;
Tyler Gunn75958422015-04-15 14:23:42 -0700880
881 /**
882 * Stores a list of the video callbacks, keyed by IBinder.
Tyler Gunn84f381b2015-06-12 09:26:45 -0700883 *
884 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
885 * load factor before resizing, 1 means we only expect a single thread to
886 * access the map so make only a single shard
Tyler Gunn75958422015-04-15 14:23:42 -0700887 */
Tyler Gunn84f381b2015-06-12 09:26:45 -0700888 private ConcurrentHashMap<IBinder, IVideoCallback> mVideoCallbacks =
889 new ConcurrentHashMap<IBinder, IVideoCallback>(8, 0.9f, 1);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700890
891 /**
892 * Default handler used to consolidate binder method calls onto a single thread.
893 */
894 private final class VideoProviderHandler extends Handler {
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -0700895 public VideoProviderHandler() {
896 super();
897 }
898
899 public VideoProviderHandler(Looper looper) {
900 super(looper);
901 }
902
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700903 @Override
904 public void handleMessage(Message msg) {
905 switch (msg.what) {
Tyler Gunn75958422015-04-15 14:23:42 -0700906 case MSG_ADD_VIDEO_CALLBACK: {
907 IBinder binder = (IBinder) msg.obj;
908 IVideoCallback callback = IVideoCallback.Stub
909 .asInterface((IBinder) msg.obj);
Tyler Gunn84f381b2015-06-12 09:26:45 -0700910 if (callback == null) {
911 Log.w(this, "addVideoProvider - skipped; callback is null.");
912 break;
913 }
914
Tyler Gunn75958422015-04-15 14:23:42 -0700915 if (mVideoCallbacks.containsKey(binder)) {
916 Log.i(this, "addVideoProvider - skipped; already present.");
917 break;
918 }
919 mVideoCallbacks.put(binder, callback);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700920 break;
Tyler Gunn75958422015-04-15 14:23:42 -0700921 }
922 case MSG_REMOVE_VIDEO_CALLBACK: {
923 IBinder binder = (IBinder) msg.obj;
924 IVideoCallback callback = IVideoCallback.Stub
925 .asInterface((IBinder) msg.obj);
926 if (!mVideoCallbacks.containsKey(binder)) {
927 Log.i(this, "removeVideoProvider - skipped; not present.");
928 break;
929 }
930 mVideoCallbacks.remove(binder);
931 break;
932 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700933 case MSG_SET_CAMERA:
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800934 {
935 SomeArgs args = (SomeArgs) msg.obj;
936 try {
937 onSetCamera((String) args.arg1);
938 onSetCamera((String) args.arg1, (String) args.arg2, args.argi1,
939 args.argi2);
940 } finally {
941 args.recycle();
942 }
943 }
944 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700945 case MSG_SET_PREVIEW_SURFACE:
946 onSetPreviewSurface((Surface) msg.obj);
947 break;
948 case MSG_SET_DISPLAY_SURFACE:
949 onSetDisplaySurface((Surface) msg.obj);
950 break;
951 case MSG_SET_DEVICE_ORIENTATION:
952 onSetDeviceOrientation(msg.arg1);
953 break;
954 case MSG_SET_ZOOM:
955 onSetZoom((Float) msg.obj);
956 break;
Tyler Gunn45382162015-05-06 08:52:27 -0700957 case MSG_SEND_SESSION_MODIFY_REQUEST: {
958 SomeArgs args = (SomeArgs) msg.obj;
959 try {
960 onSendSessionModifyRequest((VideoProfile) args.arg1,
961 (VideoProfile) args.arg2);
962 } finally {
963 args.recycle();
964 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700965 break;
Tyler Gunn45382162015-05-06 08:52:27 -0700966 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700967 case MSG_SEND_SESSION_MODIFY_RESPONSE:
968 onSendSessionModifyResponse((VideoProfile) msg.obj);
969 break;
970 case MSG_REQUEST_CAMERA_CAPABILITIES:
971 onRequestCameraCapabilities();
972 break;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800973 case MSG_REQUEST_CONNECTION_DATA_USAGE:
974 onRequestConnectionDataUsage();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700975 break;
976 case MSG_SET_PAUSE_IMAGE:
Yorke Lee32f24732015-05-12 16:18:03 -0700977 onSetPauseImage((Uri) msg.obj);
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700978 break;
979 default:
980 break;
981 }
982 }
983 }
984
985 /**
986 * IVideoProvider stub implementation.
987 */
988 private final class VideoProviderBinder extends IVideoProvider.Stub {
Tyler Gunn75958422015-04-15 14:23:42 -0700989 public void addVideoCallback(IBinder videoCallbackBinder) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700990 mMessageHandler.obtainMessage(
Tyler Gunn75958422015-04-15 14:23:42 -0700991 MSG_ADD_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
992 }
993
994 public void removeVideoCallback(IBinder videoCallbackBinder) {
995 mMessageHandler.obtainMessage(
996 MSG_REMOVE_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700997 }
998
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800999 public void setCamera(String cameraId, String callingPackageName) {
1000 SomeArgs args = SomeArgs.obtain();
1001 args.arg1 = cameraId;
1002 // Propagate the calling package; originally determined in
1003 // android.telecom.InCallService.VideoCall#setCamera(String) from the calling
1004 // process.
1005 args.arg2 = callingPackageName;
1006 // Pass along the uid and pid of the calling app; this gets lost when we put the
1007 // message onto the handler. These are required for Telecom to perform a permission
1008 // check to see if the calling app is able to use the camera.
1009 args.argi1 = Binder.getCallingUid();
1010 args.argi2 = Binder.getCallingPid();
1011 mMessageHandler.obtainMessage(MSG_SET_CAMERA, args).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001012 }
1013
1014 public void setPreviewSurface(Surface surface) {
1015 mMessageHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget();
1016 }
1017
1018 public void setDisplaySurface(Surface surface) {
1019 mMessageHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget();
1020 }
1021
1022 public void setDeviceOrientation(int rotation) {
Rekha Kumar07366812015-03-24 16:42:31 -07001023 mMessageHandler.obtainMessage(
1024 MSG_SET_DEVICE_ORIENTATION, rotation, 0).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001025 }
1026
1027 public void setZoom(float value) {
1028 mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget();
1029 }
1030
Tyler Gunn45382162015-05-06 08:52:27 -07001031 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
1032 SomeArgs args = SomeArgs.obtain();
1033 args.arg1 = fromProfile;
1034 args.arg2 = toProfile;
1035 mMessageHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001036 }
1037
1038 public void sendSessionModifyResponse(VideoProfile responseProfile) {
1039 mMessageHandler.obtainMessage(
1040 MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget();
1041 }
1042
1043 public void requestCameraCapabilities() {
1044 mMessageHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget();
1045 }
1046
1047 public void requestCallDataUsage() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001048 mMessageHandler.obtainMessage(MSG_REQUEST_CONNECTION_DATA_USAGE).sendToTarget();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001049 }
1050
Yorke Lee32f24732015-05-12 16:18:03 -07001051 public void setPauseImage(Uri uri) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001052 mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget();
1053 }
1054 }
1055
1056 public VideoProvider() {
1057 mBinder = new VideoProvider.VideoProviderBinder();
Tyler Gunn84f381b2015-06-12 09:26:45 -07001058 mMessageHandler = new VideoProvider.VideoProviderHandler(Looper.getMainLooper());
Tyler Gunn4e9bbaf2015-05-22 15:43:28 -07001059 }
1060
1061 /**
1062 * Creates an instance of the {@link VideoProvider}, specifying the looper to use.
1063 *
1064 * @param looper The looper.
1065 * @hide
1066 */
1067 public VideoProvider(Looper looper) {
1068 mBinder = new VideoProvider.VideoProviderBinder();
1069 mMessageHandler = new VideoProvider.VideoProviderHandler(looper);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001070 }
1071
1072 /**
1073 * Returns binder object which can be used across IPC methods.
1074 * @hide
1075 */
1076 public final IVideoProvider getInterface() {
1077 return mBinder;
1078 }
1079
1080 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001081 * Sets the camera to be used for the outgoing video.
1082 * <p>
1083 * The {@link VideoProvider} should respond by communicating the capabilities of the chosen
1084 * camera via
1085 * {@link VideoProvider#changeCameraCapabilities(VideoProfile.CameraCapabilities)}.
1086 * <p>
1087 * Sent from the {@link InCallService} via
1088 * {@link InCallService.VideoCall#setCamera(String)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001089 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001090 * @param cameraId The id of the camera (use ids as reported by
1091 * {@link CameraManager#getCameraIdList()}).
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001092 */
1093 public abstract void onSetCamera(String cameraId);
1094
1095 /**
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -08001096 * Sets the camera to be used for the outgoing video.
1097 * <p>
1098 * The {@link VideoProvider} should respond by communicating the capabilities of the chosen
1099 * camera via
1100 * {@link VideoProvider#changeCameraCapabilities(VideoProfile.CameraCapabilities)}.
1101 * <p>
1102 * This prototype is used internally to ensure that the calling package name, UID and PID
1103 * are sent to Telecom so that can perform a camera permission check on the caller.
1104 * <p>
1105 * Sent from the {@link InCallService} via
1106 * {@link InCallService.VideoCall#setCamera(String)}.
1107 *
1108 * @param cameraId The id of the camera (use ids as reported by
1109 * {@link CameraManager#getCameraIdList()}).
1110 * @param callingPackageName The AppOpps package name of the caller.
1111 * @param callingUid The UID of the caller.
1112 * @param callingPid The PID of the caller.
1113 * @hide
1114 */
1115 public void onSetCamera(String cameraId, String callingPackageName, int callingUid,
1116 int callingPid) {}
1117
1118 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001119 * Sets the surface to be used for displaying a preview of what the user's camera is
1120 * currently capturing. When video transmission is enabled, this is the video signal which
1121 * is sent to the remote device.
Tyler Gunnb702ef82015-05-29 11:51:53 -07001122 * <p>
1123 * Sent from the {@link InCallService} via
1124 * {@link InCallService.VideoCall#setPreviewSurface(Surface)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001125 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001126 * @param surface The {@link Surface}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001127 */
1128 public abstract void onSetPreviewSurface(Surface surface);
1129
1130 /**
1131 * Sets the surface to be used for displaying the video received from the remote device.
Tyler Gunnb702ef82015-05-29 11:51:53 -07001132 * <p>
1133 * Sent from the {@link InCallService} via
1134 * {@link InCallService.VideoCall#setDisplaySurface(Surface)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001135 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001136 * @param surface The {@link Surface}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001137 */
1138 public abstract void onSetDisplaySurface(Surface surface);
1139
1140 /**
1141 * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of
1142 * the device is 0 degrees.
Tyler Gunnb702ef82015-05-29 11:51:53 -07001143 * <p>
1144 * Sent from the {@link InCallService} via
1145 * {@link InCallService.VideoCall#setDeviceOrientation(int)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001146 *
1147 * @param rotation The device orientation, in degrees.
1148 */
1149 public abstract void onSetDeviceOrientation(int rotation);
1150
1151 /**
1152 * Sets camera zoom ratio.
Tyler Gunnb702ef82015-05-29 11:51:53 -07001153 * <p>
1154 * Sent from the {@link InCallService} via {@link InCallService.VideoCall#setZoom(float)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001155 *
1156 * @param value The camera zoom ratio.
1157 */
1158 public abstract void onSetZoom(float value);
1159
1160 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001161 * Issues a request to modify the properties of the current video session.
1162 * <p>
1163 * Example scenarios include: requesting an audio-only call to be upgraded to a
1164 * bi-directional video call, turning on or off the user's camera, sending a pause signal
1165 * when the {@link InCallService} is no longer the foreground application.
1166 * <p>
1167 * If the {@link VideoProvider} determines a request to be invalid, it should call
1168 * {@link #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)} to report the
1169 * invalid request back to the {@link InCallService}.
1170 * <p>
1171 * Where a request requires confirmation from the user of the peer device, the
1172 * {@link VideoProvider} must communicate the request to the peer device and handle the
1173 * user's response. {@link #receiveSessionModifyResponse(int, VideoProfile, VideoProfile)}
1174 * is used to inform the {@link InCallService} of the result of the request.
1175 * <p>
1176 * Sent from the {@link InCallService} via
1177 * {@link InCallService.VideoCall#sendSessionModifyRequest(VideoProfile)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001178 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001179 * @param fromProfile The video profile prior to the request.
1180 * @param toProfile The video profile with the requested changes made.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001181 */
Tyler Gunn45382162015-05-06 08:52:27 -07001182 public abstract void onSendSessionModifyRequest(VideoProfile fromProfile,
1183 VideoProfile toProfile);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001184
Tyler Gunnb702ef82015-05-29 11:51:53 -07001185 /**
1186 * Provides a response to a request to change the current video session properties.
1187 * <p>
1188 * For example, if the peer requests and upgrade from an audio-only call to a bi-directional
1189 * video call, could decline the request and keep the call as audio-only.
1190 * In such a scenario, the {@code responseProfile} would have a video state of
1191 * {@link VideoProfile#STATE_AUDIO_ONLY}. If the user had decided to accept the request,
1192 * the video state would be {@link VideoProfile#STATE_BIDIRECTIONAL}.
1193 * <p>
1194 * Sent from the {@link InCallService} via
1195 * {@link InCallService.VideoCall#sendSessionModifyResponse(VideoProfile)} in response to
1196 * a {@link InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)}
1197 * callback.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001198 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001199 * @param responseProfile The response video profile.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001200 */
1201 public abstract void onSendSessionModifyResponse(VideoProfile responseProfile);
1202
1203 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001204 * Issues a request to the {@link VideoProvider} to retrieve the camera capabilities.
1205 * <p>
1206 * The {@link VideoProvider} should respond by communicating the capabilities of the chosen
1207 * camera via
1208 * {@link VideoProvider#changeCameraCapabilities(VideoProfile.CameraCapabilities)}.
1209 * <p>
1210 * Sent from the {@link InCallService} via
1211 * {@link InCallService.VideoCall#requestCameraCapabilities()}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001212 */
1213 public abstract void onRequestCameraCapabilities();
1214
1215 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001216 * Issues a request to the {@link VideoProvider} to retrieve the current data usage for the
1217 * video component of the current {@link Connection}.
1218 * <p>
1219 * The {@link VideoProvider} should respond by communicating current data usage, in bytes,
1220 * via {@link VideoProvider#setCallDataUsage(long)}.
1221 * <p>
1222 * Sent from the {@link InCallService} via
1223 * {@link InCallService.VideoCall#requestCallDataUsage()}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001224 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001225 public abstract void onRequestConnectionDataUsage();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001226
1227 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001228 * Provides the {@link VideoProvider} with the {@link Uri} of an image to be displayed to
1229 * the peer device when the video signal is paused.
1230 * <p>
1231 * Sent from the {@link InCallService} via
1232 * {@link InCallService.VideoCall#setPauseImage(Uri)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001233 *
1234 * @param uri URI of image to display.
1235 */
Yorke Lee32f24732015-05-12 16:18:03 -07001236 public abstract void onSetPauseImage(Uri uri);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001237
1238 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001239 * Used to inform listening {@link InCallService} implementations when the
1240 * {@link VideoProvider} receives a session modification request.
1241 * <p>
1242 * Received by the {@link InCallService} via
1243 * {@link InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)},
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001244 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001245 * @param videoProfile The requested video profile.
1246 * @see #onSendSessionModifyRequest(VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001247 */
1248 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunn75958422015-04-15 14:23:42 -07001249 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001250 for (IVideoCallback callback : mVideoCallbacks.values()) {
1251 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001252 callback.receiveSessionModifyRequest(videoProfile);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001253 } catch (RemoteException ignored) {
1254 Log.w(this, "receiveSessionModifyRequest callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001255 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001256 }
1257 }
1258 }
1259
1260 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001261 * Used to inform listening {@link InCallService} implementations when the
1262 * {@link VideoProvider} receives a response to a session modification request.
1263 * <p>
1264 * Received by the {@link InCallService} via
1265 * {@link InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
1266 * VideoProfile, VideoProfile)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001267 *
1268 * @param status Status of the session modify request. Valid values are
1269 * {@link VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS},
1270 * {@link VideoProvider#SESSION_MODIFY_REQUEST_FAIL},
Tyler Gunnb702ef82015-05-29 11:51:53 -07001271 * {@link VideoProvider#SESSION_MODIFY_REQUEST_INVALID},
1272 * {@link VideoProvider#SESSION_MODIFY_REQUEST_TIMED_OUT},
1273 * {@link VideoProvider#SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE}
1274 * @param requestedProfile The original request which was sent to the peer device.
1275 * @param responseProfile The actual profile changes agreed to by the peer device.
1276 * @see #onSendSessionModifyRequest(VideoProfile, VideoProfile)
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001277 */
1278 public void receiveSessionModifyResponse(int status,
1279 VideoProfile requestedProfile, VideoProfile responseProfile) {
Tyler Gunn75958422015-04-15 14:23:42 -07001280 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001281 for (IVideoCallback callback : mVideoCallbacks.values()) {
1282 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001283 callback.receiveSessionModifyResponse(status, requestedProfile,
1284 responseProfile);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001285 } catch (RemoteException ignored) {
1286 Log.w(this, "receiveSessionModifyResponse callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001287 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001288 }
1289 }
1290 }
1291
1292 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001293 * Used to inform listening {@link InCallService} implementations when the
1294 * {@link VideoProvider} reports a call session event.
1295 * <p>
1296 * Received by the {@link InCallService} via
1297 * {@link InCallService.VideoCall.Callback#onCallSessionEvent(int)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001298 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001299 * @param event The event. Valid values are: {@link VideoProvider#SESSION_EVENT_RX_PAUSE},
1300 * {@link VideoProvider#SESSION_EVENT_RX_RESUME},
1301 * {@link VideoProvider#SESSION_EVENT_TX_START},
1302 * {@link VideoProvider#SESSION_EVENT_TX_STOP},
1303 * {@link VideoProvider#SESSION_EVENT_CAMERA_FAILURE},
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -08001304 * {@link VideoProvider#SESSION_EVENT_CAMERA_READY},
1305 * {@link VideoProvider#SESSION_EVENT_CAMERA_FAILURE}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001306 */
1307 public void handleCallSessionEvent(int event) {
Tyler Gunn75958422015-04-15 14:23:42 -07001308 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001309 for (IVideoCallback callback : mVideoCallbacks.values()) {
1310 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001311 callback.handleCallSessionEvent(event);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001312 } catch (RemoteException ignored) {
1313 Log.w(this, "handleCallSessionEvent callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001314 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001315 }
1316 }
1317 }
1318
1319 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001320 * Used to inform listening {@link InCallService} implementations when the dimensions of the
1321 * peer's video have changed.
1322 * <p>
1323 * This could occur if, for example, the peer rotates their device, changing the aspect
1324 * ratio of the video, or if the user switches between the back and front cameras.
1325 * <p>
1326 * Received by the {@link InCallService} via
1327 * {@link InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001328 *
1329 * @param width The updated peer video width.
1330 * @param height The updated peer video height.
1331 */
1332 public void changePeerDimensions(int width, int height) {
Tyler Gunn75958422015-04-15 14:23:42 -07001333 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001334 for (IVideoCallback callback : mVideoCallbacks.values()) {
1335 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001336 callback.changePeerDimensions(width, height);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001337 } catch (RemoteException ignored) {
1338 Log.w(this, "changePeerDimensions callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001339 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001340 }
1341 }
1342 }
1343
1344 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001345 * Used to inform listening {@link InCallService} implementations when the data usage of the
1346 * video associated with the current {@link Connection} has changed.
1347 * <p>
1348 * This could be in response to a preview request via
1349 * {@link #onRequestConnectionDataUsage()}, or as a periodic update by the
Tyler Gunn295f5d72015-06-04 11:08:54 -07001350 * {@link VideoProvider}. Where periodic updates of data usage are provided, they should be
1351 * 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 -07001352 * <p>
1353 * Received by the {@link InCallService} via
1354 * {@link InCallService.VideoCall.Callback#onCallDataUsageChanged(long)}.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001355 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001356 * @param dataUsage The updated data usage (in bytes). Reported as the cumulative bytes
1357 * used since the start of the call.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001358 */
Yorke Lee32f24732015-05-12 16:18:03 -07001359 public void setCallDataUsage(long dataUsage) {
Tyler Gunn75958422015-04-15 14:23:42 -07001360 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001361 for (IVideoCallback callback : mVideoCallbacks.values()) {
1362 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001363 callback.changeCallDataUsage(dataUsage);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001364 } catch (RemoteException ignored) {
1365 Log.w(this, "setCallDataUsage callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001366 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001367 }
1368 }
1369 }
1370
1371 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001372 * @see #setCallDataUsage(long)
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001373 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001374 * @param dataUsage The updated data usage (in byes).
Yorke Lee32f24732015-05-12 16:18:03 -07001375 * @deprecated - Use {@link #setCallDataUsage(long)} instead.
1376 * @hide
1377 */
1378 public void changeCallDataUsage(long dataUsage) {
1379 setCallDataUsage(dataUsage);
1380 }
1381
1382 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001383 * Used to inform listening {@link InCallService} implementations when the capabilities of
1384 * the current camera have changed.
1385 * <p>
1386 * The {@link VideoProvider} should call this in response to
1387 * {@link VideoProvider#onRequestCameraCapabilities()}, or when the current camera is
1388 * changed via {@link VideoProvider#onSetCamera(String)}.
1389 * <p>
1390 * Received by the {@link InCallService} via
1391 * {@link InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
1392 * VideoProfile.CameraCapabilities)}.
Yorke Lee32f24732015-05-12 16:18:03 -07001393 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001394 * @param cameraCapabilities The new camera capabilities.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001395 */
Yorke Lee400470f2015-05-12 13:31:25 -07001396 public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunn75958422015-04-15 14:23:42 -07001397 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001398 for (IVideoCallback callback : mVideoCallbacks.values()) {
1399 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001400 callback.changeCameraCapabilities(cameraCapabilities);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001401 } catch (RemoteException ignored) {
1402 Log.w(this, "changeCameraCapabilities callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001403 }
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001404 }
1405 }
1406 }
Rekha Kumar07366812015-03-24 16:42:31 -07001407
1408 /**
Tyler Gunnb702ef82015-05-29 11:51:53 -07001409 * Used to inform listening {@link InCallService} implementations when the video quality
1410 * of the call has changed.
1411 * <p>
1412 * Received by the {@link InCallService} via
1413 * {@link InCallService.VideoCall.Callback#onVideoQualityChanged(int)}.
Rekha Kumar07366812015-03-24 16:42:31 -07001414 *
Tyler Gunnb702ef82015-05-29 11:51:53 -07001415 * @param videoQuality The updated video quality. Valid values:
1416 * {@link VideoProfile#QUALITY_HIGH},
1417 * {@link VideoProfile#QUALITY_MEDIUM},
1418 * {@link VideoProfile#QUALITY_LOW},
1419 * {@link VideoProfile#QUALITY_DEFAULT}.
Rekha Kumar07366812015-03-24 16:42:31 -07001420 */
1421 public void changeVideoQuality(int videoQuality) {
Tyler Gunn75958422015-04-15 14:23:42 -07001422 if (mVideoCallbacks != null) {
Tyler Gunn84f381b2015-06-12 09:26:45 -07001423 for (IVideoCallback callback : mVideoCallbacks.values()) {
1424 try {
Tyler Gunn75958422015-04-15 14:23:42 -07001425 callback.changeVideoQuality(videoQuality);
Tyler Gunn84f381b2015-06-12 09:26:45 -07001426 } catch (RemoteException ignored) {
1427 Log.w(this, "changeVideoQuality callback failed", ignored);
Tyler Gunn75958422015-04-15 14:23:42 -07001428 }
Rekha Kumar07366812015-03-24 16:42:31 -07001429 }
1430 }
1431 }
Tyler Gunn6f657ee2016-09-02 09:55:25 -07001432
1433 /**
1434 * Returns a string representation of a call session event.
1435 *
1436 * @param event A call session event passed to {@link #handleCallSessionEvent(int)}.
1437 * @return String representation of the call session event.
1438 * @hide
1439 */
1440 public static String sessionEventToString(int event) {
1441 switch (event) {
1442 case SESSION_EVENT_CAMERA_FAILURE:
1443 return SESSION_EVENT_CAMERA_FAILURE_STR;
1444 case SESSION_EVENT_CAMERA_READY:
1445 return SESSION_EVENT_CAMERA_READY_STR;
1446 case SESSION_EVENT_RX_PAUSE:
1447 return SESSION_EVENT_RX_PAUSE_STR;
1448 case SESSION_EVENT_RX_RESUME:
1449 return SESSION_EVENT_RX_RESUME_STR;
1450 case SESSION_EVENT_TX_START:
1451 return SESSION_EVENT_TX_START_STR;
1452 case SESSION_EVENT_TX_STOP:
1453 return SESSION_EVENT_TX_STOP_STR;
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -08001454 case SESSION_EVENT_CAMERA_PERMISSION_ERROR:
1455 return SESSION_EVENT_CAMERA_PERMISSION_ERROR_STR;
Tyler Gunn6f657ee2016-09-02 09:55:25 -07001456 default:
1457 return SESSION_EVENT_UNKNOWN_STR + " " + event;
1458 }
1459 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001460 }
1461
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001462 private final Listener mConnectionDeathListener = new Listener() {
1463 @Override
1464 public void onDestroyed(Connection c) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001465 if (mConferenceables.remove(c)) {
1466 fireOnConferenceableConnectionsChanged();
1467 }
1468 }
1469 };
1470
1471 private final Conference.Listener mConferenceDeathListener = new Conference.Listener() {
1472 @Override
1473 public void onDestroyed(Conference c) {
1474 if (mConferenceables.remove(c)) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001475 fireOnConferenceableConnectionsChanged();
1476 }
1477 }
1478 };
1479
Jay Shrauner229e3822014-08-15 09:23:07 -07001480 /**
1481 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
1482 * load factor before resizing, 1 means we only expect a single thread to
1483 * access the map so make only a single shard
1484 */
1485 private final Set<Listener> mListeners = Collections.newSetFromMap(
1486 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001487 private final List<Conferenceable> mConferenceables = new ArrayList<>();
1488 private final List<Conferenceable> mUnmodifiableConferenceables =
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001489 Collections.unmodifiableList(mConferenceables);
Santos Cordonb6939982014-06-04 20:20:58 -07001490
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001491 // The internal telecom call ID associated with this connection.
1492 private String mTelecomCallId;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001493 private int mState = STATE_NEW;
Yorke Lee4af59352015-05-13 14:14:54 -07001494 private CallAudioState mCallAudioState;
Andrew Lee100e2932014-09-08 15:34:24 -07001495 private Uri mAddress;
1496 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -07001497 private String mCallerDisplayName;
1498 private int mCallerDisplayNamePresentation;
Andrew Lee100e2932014-09-08 15:34:24 -07001499 private boolean mRingbackRequested = false;
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001500 private int mConnectionCapabilities;
Tyler Gunn720c6642016-03-22 09:02:47 -07001501 private int mConnectionProperties;
Christine Hallstrom2830ce92016-11-30 16:06:42 -08001502 private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001503 private VideoProvider mVideoProvider;
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001504 private boolean mAudioModeIsVoip;
Roshan Piuse927ec02015-07-15 15:47:21 -07001505 private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001506 private StatusHints mStatusHints;
Tyler Gunnaa07df82014-07-17 07:50:22 -07001507 private int mVideoState;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001508 private DisconnectCause mDisconnectCause;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001509 private Conference mConference;
1510 private ConnectionService mConnectionService;
Santos Cordon6b7f9552015-05-27 17:21:45 -07001511 private Bundle mExtras;
Brad Ebinger4fa6a012016-06-14 17:04:01 -07001512 private final Object mExtrasLock = new Object();
Ihab Awad542e0ea2014-05-16 10:22:16 -07001513
1514 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07001515 * Tracks the key set for the extras bundle provided on the last invocation of
1516 * {@link #setExtras(Bundle)}. Used so that on subsequent invocations we can remove any extras
1517 * keys which were set previously but are no longer present in the replacement Bundle.
1518 */
1519 private Set<String> mPreviousExtraKeys;
1520
1521 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001522 * Create a new Connection.
1523 */
Santos Cordonf2951102014-07-20 19:06:29 -07001524 public Connection() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07001525
1526 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001527 * Returns the Telecom internal call ID associated with this connection. Should only be used
1528 * for debugging and tracing purposes.
1529 *
1530 * @return The Telecom call ID.
1531 * @hide
1532 */
1533 public final String getTelecomCallId() {
1534 return mTelecomCallId;
1535 }
1536
1537 /**
Andrew Lee100e2932014-09-08 15:34:24 -07001538 * @return The address (e.g., phone number) to which this Connection is currently communicating.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001539 */
Andrew Lee100e2932014-09-08 15:34:24 -07001540 public final Uri getAddress() {
1541 return mAddress;
Ihab Awad542e0ea2014-05-16 10:22:16 -07001542 }
1543
1544 /**
Andrew Lee100e2932014-09-08 15:34:24 -07001545 * @return The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001546 * See {@link TelecomManager} for valid values.
Sailesh Nepal61203862014-07-11 14:50:13 -07001547 */
Andrew Lee100e2932014-09-08 15:34:24 -07001548 public final int getAddressPresentation() {
1549 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -07001550 }
1551
1552 /**
1553 * @return The caller display name (CNAP).
1554 */
1555 public final String getCallerDisplayName() {
1556 return mCallerDisplayName;
1557 }
1558
1559 /**
Nancy Chen9d568c02014-09-08 14:17:59 -07001560 * @return The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001561 * See {@link TelecomManager} for valid values.
Sailesh Nepal61203862014-07-11 14:50:13 -07001562 */
1563 public final int getCallerDisplayNamePresentation() {
1564 return mCallerDisplayNamePresentation;
1565 }
1566
1567 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001568 * @return The state of this Connection.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001569 */
1570 public final int getState() {
1571 return mState;
1572 }
1573
1574 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001575 * Returns the video state of the connection.
Yorke Lee32f24732015-05-12 16:18:03 -07001576 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
1577 * {@link VideoProfile#STATE_BIDIRECTIONAL},
1578 * {@link VideoProfile#STATE_TX_ENABLED},
1579 * {@link VideoProfile#STATE_RX_ENABLED}.
Tyler Gunnaa07df82014-07-17 07:50:22 -07001580 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001581 * @return The video state of the connection.
Tyler Gunn27d1e252014-08-21 16:38:40 -07001582 * @hide
Tyler Gunnaa07df82014-07-17 07:50:22 -07001583 */
1584 public final int getVideoState() {
1585 return mVideoState;
1586 }
1587
1588 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001589 * @return The audio state of the connection, describing how its audio is currently
Ihab Awad542e0ea2014-05-16 10:22:16 -07001590 * being routed by the system. This is {@code null} if this Connection
1591 * does not directly know about its audio state.
Yorke Lee4af59352015-05-13 14:14:54 -07001592 * @deprecated Use {@link #getCallAudioState()} instead.
1593 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -07001594 */
Yorke Lee4af59352015-05-13 14:14:54 -07001595 @SystemApi
1596 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001597 public final AudioState getAudioState() {
Sailesh Nepal000d38a2015-06-21 10:25:13 -07001598 if (mCallAudioState == null) {
1599 return null;
1600 }
Yorke Lee4af59352015-05-13 14:14:54 -07001601 return new AudioState(mCallAudioState);
1602 }
1603
1604 /**
1605 * @return The audio state of the connection, describing how its audio is currently
1606 * being routed by the system. This is {@code null} if this Connection
1607 * does not directly know about its audio state.
1608 */
1609 public final CallAudioState getCallAudioState() {
1610 return mCallAudioState;
Ihab Awad542e0ea2014-05-16 10:22:16 -07001611 }
1612
1613 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07001614 * @return The conference that this connection is a part of. Null if it is not part of any
1615 * conference.
1616 */
1617 public final Conference getConference() {
1618 return mConference;
1619 }
1620
1621 /**
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001622 * Returns whether this connection is requesting that the system play a ringback tone
1623 * on its behalf.
1624 */
Andrew Lee100e2932014-09-08 15:34:24 -07001625 public final boolean isRingbackRequested() {
1626 return mRingbackRequested;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001627 }
1628
1629 /**
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001630 * @return True if the connection's audio mode is VOIP.
1631 */
1632 public final boolean getAudioModeIsVoip() {
1633 return mAudioModeIsVoip;
1634 }
1635
1636 /**
Roshan Piuse927ec02015-07-15 15:47:21 -07001637 * Retrieves the connection start time of the {@code Connnection}, if specified. A value of
1638 * {@link Conference#CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the
1639 * start time of the conference.
1640 *
1641 * @return The time at which the {@code Connnection} was connected.
1642 *
1643 * @hide
1644 */
1645 public final long getConnectTimeMillis() {
1646 return mConnectTimeMillis;
1647 }
1648
1649 /**
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001650 * @return The status hints for this connection.
1651 */
1652 public final StatusHints getStatusHints() {
1653 return mStatusHints;
1654 }
1655
1656 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07001657 * Returns the extras associated with this connection.
Tyler Gunn2cbe2b52016-05-04 15:48:10 +00001658 * <p>
1659 * Extras should be updated using {@link #putExtras(Bundle)}.
1660 * <p>
1661 * Telecom or an {@link InCallService} can also update the extras via
1662 * {@link android.telecom.Call#putExtras(Bundle)}, and
1663 * {@link Call#removeExtras(List)}.
1664 * <p>
1665 * The connection is notified of changes to the extras made by Telecom or an
1666 * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
Tyler Gunndee56a82016-03-23 16:06:34 -07001667 *
Santos Cordon6b7f9552015-05-27 17:21:45 -07001668 * @return The extras associated with this connection.
1669 */
1670 public final Bundle getExtras() {
Brad Ebinger4fa6a012016-06-14 17:04:01 -07001671 Bundle extras = null;
1672 synchronized (mExtrasLock) {
1673 if (mExtras != null) {
1674 extras = new Bundle(mExtras);
1675 }
1676 }
1677 return extras;
Santos Cordon6b7f9552015-05-27 17:21:45 -07001678 }
1679
1680 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001681 * Assign a listener to be notified of state changes.
1682 *
1683 * @param l A listener.
1684 * @return This Connection.
1685 *
1686 * @hide
1687 */
1688 public final Connection addConnectionListener(Listener l) {
Santos Cordond34e5712014-08-05 18:54:03 +00001689 mListeners.add(l);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001690 return this;
1691 }
1692
1693 /**
1694 * Remove a previously assigned listener that was being notified of state changes.
1695 *
1696 * @param l A Listener.
1697 * @return This Connection.
1698 *
1699 * @hide
1700 */
1701 public final Connection removeConnectionListener(Listener l) {
Jay Shrauner229e3822014-08-15 09:23:07 -07001702 if (l != null) {
1703 mListeners.remove(l);
1704 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001705 return this;
1706 }
1707
1708 /**
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001709 * @return The {@link DisconnectCause} for this connection.
Evan Charltonbf11f982014-07-20 22:06:28 -07001710 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001711 public final DisconnectCause getDisconnectCause() {
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001712 return mDisconnectCause;
Evan Charltonbf11f982014-07-20 22:06:28 -07001713 }
1714
1715 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001716 * Sets the telecom call ID associated with this Connection. The Telecom Call ID should be used
1717 * ONLY for debugging purposes.
1718 *
1719 * @param callId The telecom call ID.
1720 * @hide
1721 */
1722 public void setTelecomCallId(String callId) {
1723 mTelecomCallId = callId;
1724 }
1725
1726 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001727 * Inform this Connection that the state of its audio output has been changed externally.
1728 *
1729 * @param state The new audio state.
Sailesh Nepal400cc482014-06-26 12:04:00 -07001730 * @hide
Ihab Awad542e0ea2014-05-16 10:22:16 -07001731 */
Yorke Lee4af59352015-05-13 14:14:54 -07001732 final void setCallAudioState(CallAudioState state) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001733 checkImmutable();
Ihab Awad60ac30b2014-05-20 22:32:12 -07001734 Log.d(this, "setAudioState %s", state);
Yorke Lee4af59352015-05-13 14:14:54 -07001735 mCallAudioState = state;
1736 onAudioStateChanged(getAudioState());
1737 onCallAudioStateChanged(state);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001738 }
1739
1740 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001741 * @param state An integer value of a {@code STATE_*} constant.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001742 * @return A string representation of the value.
1743 */
1744 public static String stateToString(int state) {
1745 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001746 case STATE_INITIALIZING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001747 return "INITIALIZING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001748 case STATE_NEW:
Yorke Leee911c8d2015-07-14 11:39:36 -07001749 return "NEW";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001750 case STATE_RINGING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001751 return "RINGING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001752 case STATE_DIALING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001753 return "DIALING";
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001754 case STATE_PULLING_CALL:
1755 return "PULLING_CALL";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001756 case STATE_ACTIVE:
Yorke Leee911c8d2015-07-14 11:39:36 -07001757 return "ACTIVE";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001758 case STATE_HOLDING:
Yorke Leee911c8d2015-07-14 11:39:36 -07001759 return "HOLDING";
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001760 case STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001761 return "DISCONNECTED";
1762 default:
Ihab Awad60ac30b2014-05-20 22:32:12 -07001763 Log.wtf(Connection.class, "Unknown state %d", state);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001764 return "UNKNOWN";
1765 }
1766 }
1767
1768 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001769 * Returns the connection's capabilities, as a bit mask of the {@code CAPABILITY_*} constants.
Ihab Awad52a28f62014-06-18 10:26:34 -07001770 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001771 public final int getConnectionCapabilities() {
1772 return mConnectionCapabilities;
Ihab Awad52a28f62014-06-18 10:26:34 -07001773 }
1774
1775 /**
Tyler Gunn720c6642016-03-22 09:02:47 -07001776 * Returns the connection's properties, as a bit mask of the {@code PROPERTY_*} constants.
1777 */
1778 public final int getConnectionProperties() {
1779 return mConnectionProperties;
1780 }
1781
1782 /**
Christine Hallstrom2830ce92016-11-30 16:06:42 -08001783 * Returns the connection's supported audio routes.
1784 *
1785 * @hide
1786 */
1787 public final int getSupportedAudioRoutes() {
1788 return mSupportedAudioRoutes;
1789 }
1790
1791 /**
Andrew Lee100e2932014-09-08 15:34:24 -07001792 * Sets the value of the {@link #getAddress()} property.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001793 *
Andrew Lee100e2932014-09-08 15:34:24 -07001794 * @param address The new address.
1795 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001796 * See {@link TelecomManager} for valid values.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001797 */
Andrew Lee100e2932014-09-08 15:34:24 -07001798 public final void setAddress(Uri address, int presentation) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001799 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001800 Log.d(this, "setAddress %s", address);
1801 mAddress = address;
1802 mAddressPresentation = presentation;
Santos Cordond34e5712014-08-05 18:54:03 +00001803 for (Listener l : mListeners) {
Andrew Lee100e2932014-09-08 15:34:24 -07001804 l.onAddressChanged(this, address, presentation);
Santos Cordond34e5712014-08-05 18:54:03 +00001805 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001806 }
1807
1808 /**
Sailesh Nepal61203862014-07-11 14:50:13 -07001809 * Sets the caller display name (CNAP).
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001810 *
Sailesh Nepal61203862014-07-11 14:50:13 -07001811 * @param callerDisplayName The new display name.
Nancy Chen9d568c02014-09-08 14:17:59 -07001812 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001813 * See {@link TelecomManager} for valid values.
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001814 */
Sailesh Nepal61203862014-07-11 14:50:13 -07001815 public final void setCallerDisplayName(String callerDisplayName, int presentation) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001816 checkImmutable();
Sailesh Nepal61203862014-07-11 14:50:13 -07001817 Log.d(this, "setCallerDisplayName %s", callerDisplayName);
Santos Cordond34e5712014-08-05 18:54:03 +00001818 mCallerDisplayName = callerDisplayName;
1819 mCallerDisplayNamePresentation = presentation;
1820 for (Listener l : mListeners) {
1821 l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
1822 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001823 }
1824
1825 /**
Tyler Gunnaa07df82014-07-17 07:50:22 -07001826 * Set the video state for the connection.
Yorke Lee32f24732015-05-12 16:18:03 -07001827 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
1828 * {@link VideoProfile#STATE_BIDIRECTIONAL},
1829 * {@link VideoProfile#STATE_TX_ENABLED},
1830 * {@link VideoProfile#STATE_RX_ENABLED}.
Tyler Gunnaa07df82014-07-17 07:50:22 -07001831 *
1832 * @param videoState The new video state.
1833 */
1834 public final void setVideoState(int videoState) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001835 checkImmutable();
Tyler Gunnaa07df82014-07-17 07:50:22 -07001836 Log.d(this, "setVideoState %d", videoState);
Santos Cordond34e5712014-08-05 18:54:03 +00001837 mVideoState = videoState;
1838 for (Listener l : mListeners) {
1839 l.onVideoStateChanged(this, mVideoState);
1840 }
Tyler Gunnaa07df82014-07-17 07:50:22 -07001841 }
1842
1843 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001844 * Sets state to active (e.g., an ongoing connection where two or more parties can actively
Ihab Awad542e0ea2014-05-16 10:22:16 -07001845 * communicate).
1846 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001847 public final void setActive() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001848 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001849 setRingbackRequested(false);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001850 setState(STATE_ACTIVE);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001851 }
1852
1853 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001854 * Sets state to ringing (e.g., an inbound ringing connection).
Ihab Awad542e0ea2014-05-16 10:22:16 -07001855 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001856 public final void setRinging() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001857 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001858 setState(STATE_RINGING);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001859 }
1860
1861 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07001862 * Sets state to initializing (this Connection is not yet ready to be used).
1863 */
1864 public final void setInitializing() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001865 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001866 setState(STATE_INITIALIZING);
Evan Charltonbf11f982014-07-20 22:06:28 -07001867 }
1868
1869 /**
1870 * Sets state to initialized (the Connection has been set up and is now ready to be used).
1871 */
1872 public final void setInitialized() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001873 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001874 setState(STATE_NEW);
Evan Charltonbf11f982014-07-20 22:06:28 -07001875 }
1876
1877 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001878 * Sets state to dialing (e.g., dialing an outbound connection).
Ihab Awad542e0ea2014-05-16 10:22:16 -07001879 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001880 public final void setDialing() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001881 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001882 setState(STATE_DIALING);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001883 }
1884
1885 /**
Tyler Gunnc242ceb2016-06-29 22:35:45 -07001886 * Sets state to pulling (e.g. the connection is being pulled to the local device from another
1887 * device). Only applicable for {@link Connection}s with
1888 * {@link Connection#PROPERTY_IS_EXTERNAL_CALL} and {@link Connection#CAPABILITY_CAN_PULL_CALL}.
1889 */
1890 public final void setPulling() {
1891 checkImmutable();
1892 setState(STATE_PULLING_CALL);
1893 }
1894
1895 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07001896 * Sets state to be on hold.
1897 */
Sailesh Nepal400cc482014-06-26 12:04:00 -07001898 public final void setOnHold() {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001899 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001900 setState(STATE_HOLDING);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001901 }
1902
1903 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001904 * Sets the video connection provider.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001905 * @param videoProvider The video provider.
Andrew Lee5ffbe8b2014-06-20 16:29:33 -07001906 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001907 public final void setVideoProvider(VideoProvider videoProvider) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001908 checkImmutable();
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001909 mVideoProvider = videoProvider;
Santos Cordond34e5712014-08-05 18:54:03 +00001910 for (Listener l : mListeners) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001911 l.onVideoProviderChanged(this, videoProvider);
Santos Cordond34e5712014-08-05 18:54:03 +00001912 }
Andrew Lee5ffbe8b2014-06-20 16:29:33 -07001913 }
1914
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001915 public final VideoProvider getVideoProvider() {
1916 return mVideoProvider;
Andrew Leea27a1932014-07-09 17:07:13 -07001917 }
1918
Andrew Lee5ffbe8b2014-06-20 16:29:33 -07001919 /**
Sailesh Nepal091768c2014-06-30 15:15:23 -07001920 * Sets state to disconnected.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001921 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001922 * @param disconnectCause The reason for the disconnection, as specified by
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001923 * {@link DisconnectCause}.
Ihab Awad542e0ea2014-05-16 10:22:16 -07001924 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001925 public final void setDisconnected(DisconnectCause disconnectCause) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001926 checkImmutable();
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001927 mDisconnectCause = disconnectCause;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001928 setState(STATE_DISCONNECTED);
mike dooleyf34519b2014-09-16 17:33:40 -07001929 Log.d(this, "Disconnected with cause %s", disconnectCause);
Santos Cordond34e5712014-08-05 18:54:03 +00001930 for (Listener l : mListeners) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001931 l.onDisconnected(this, disconnectCause);
Santos Cordond34e5712014-08-05 18:54:03 +00001932 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001933 }
1934
1935 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001936 * Informs listeners that this {@code Connection} is in a post-dial wait state. This is done
1937 * when (a) the {@code Connection} is issuing a DTMF sequence; (b) it has encountered a "wait"
1938 * character; and (c) it wishes to inform the In-Call app that it is waiting for the end-user
1939 * to send an {@link #onPostDialContinue(boolean)} signal.
1940 *
1941 * @param remaining The DTMF character sequence remaining to be emitted once the
1942 * {@link #onPostDialContinue(boolean)} is received, including any "wait" characters
1943 * that remaining sequence may contain.
Sailesh Nepal091768c2014-06-30 15:15:23 -07001944 */
1945 public final void setPostDialWait(String remaining) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001946 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00001947 for (Listener l : mListeners) {
1948 l.onPostDialWait(this, remaining);
1949 }
Sailesh Nepal091768c2014-06-30 15:15:23 -07001950 }
1951
1952 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001953 * Informs listeners that this {@code Connection} has processed a character in the post-dial
1954 * started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence;
Sailesh Nepal1ed85612015-01-31 15:17:19 -08001955 * and (b) it wishes to signal Telecom to play the corresponding DTMF tone locally.
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001956 *
1957 * @param nextChar The DTMF character that was just processed by the {@code Connection}.
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001958 */
Sailesh Nepal1ed85612015-01-31 15:17:19 -08001959 public final void setNextPostDialChar(char nextChar) {
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001960 checkImmutable();
1961 for (Listener l : mListeners) {
1962 l.onPostDialChar(this, nextChar);
1963 }
1964 }
1965
1966 /**
Ihab Awadf8358972014-05-28 16:46:42 -07001967 * Requests that the framework play a ringback tone. This is to be invoked by implementations
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001968 * that do not play a ringback tone themselves in the connection's audio stream.
Ihab Awadf8358972014-05-28 16:46:42 -07001969 *
1970 * @param ringback Whether the ringback tone is to be played.
1971 */
Andrew Lee100e2932014-09-08 15:34:24 -07001972 public final void setRingbackRequested(boolean ringback) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001973 checkImmutable();
Andrew Lee100e2932014-09-08 15:34:24 -07001974 if (mRingbackRequested != ringback) {
1975 mRingbackRequested = ringback;
Santos Cordond34e5712014-08-05 18:54:03 +00001976 for (Listener l : mListeners) {
Andrew Lee100e2932014-09-08 15:34:24 -07001977 l.onRingbackRequested(this, ringback);
Santos Cordond34e5712014-08-05 18:54:03 +00001978 }
1979 }
Ihab Awadf8358972014-05-28 16:46:42 -07001980 }
1981
1982 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001983 * Sets the connection's capabilities as a bit mask of the {@code CAPABILITY_*} constants.
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001984 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001985 * @param connectionCapabilities The new connection capabilities.
Santos Cordonb6939982014-06-04 20:20:58 -07001986 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001987 public final void setConnectionCapabilities(int connectionCapabilities) {
1988 checkImmutable();
1989 if (mConnectionCapabilities != connectionCapabilities) {
1990 mConnectionCapabilities = connectionCapabilities;
Santos Cordond34e5712014-08-05 18:54:03 +00001991 for (Listener l : mListeners) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001992 l.onConnectionCapabilitiesChanged(this, mConnectionCapabilities);
Santos Cordond34e5712014-08-05 18:54:03 +00001993 }
1994 }
Santos Cordonb6939982014-06-04 20:20:58 -07001995 }
1996
1997 /**
Tyler Gunn720c6642016-03-22 09:02:47 -07001998 * Sets the connection's properties as a bit mask of the {@code PROPERTY_*} constants.
1999 *
2000 * @param connectionProperties The new connection properties.
2001 */
2002 public final void setConnectionProperties(int connectionProperties) {
2003 checkImmutable();
2004 if (mConnectionProperties != connectionProperties) {
2005 mConnectionProperties = connectionProperties;
2006 for (Listener l : mListeners) {
2007 l.onConnectionPropertiesChanged(this, mConnectionProperties);
2008 }
2009 }
2010 }
2011
2012 /**
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002013 * Sets the supported audio routes.
2014 *
2015 * @param supportedAudioRoutes the supported audio routes as a bitmask.
2016 * See {@link CallAudioState}
2017 * @hide
2018 */
2019 public final void setSupportedAudioRoutes(int supportedAudioRoutes) {
2020 if ((supportedAudioRoutes
2021 & (CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER)) == 0) {
2022 throw new IllegalArgumentException(
2023 "supported audio routes must include either speaker or earpiece");
2024 }
2025
2026 if (mSupportedAudioRoutes != supportedAudioRoutes) {
2027 mSupportedAudioRoutes = supportedAudioRoutes;
2028 for (Listener l : mListeners) {
2029 l.onSupportedAudioRoutesChanged(this, mSupportedAudioRoutes);
2030 }
2031 }
2032 }
2033
2034 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002035 * Tears down the Connection object.
Santos Cordonb6939982014-06-04 20:20:58 -07002036 */
Evan Charlton36a71342014-07-19 16:31:02 -07002037 public final void destroy() {
Jay Shrauner229e3822014-08-15 09:23:07 -07002038 for (Listener l : mListeners) {
2039 l.onDestroyed(this);
Santos Cordond34e5712014-08-05 18:54:03 +00002040 }
Santos Cordonb6939982014-06-04 20:20:58 -07002041 }
2042
2043 /**
Sailesh Nepal33aaae42014-07-07 22:49:44 -07002044 * Requests that the framework use VOIP audio mode for this connection.
2045 *
2046 * @param isVoip True if the audio mode is VOIP.
2047 */
2048 public final void setAudioModeIsVoip(boolean isVoip) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002049 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00002050 mAudioModeIsVoip = isVoip;
2051 for (Listener l : mListeners) {
2052 l.onAudioModeIsVoipChanged(this, isVoip);
2053 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07002054 }
2055
2056 /**
Roshan Piuse927ec02015-07-15 15:47:21 -07002057 * Sets the time at which a call became active on this Connection. This is set only
2058 * when a conference call becomes active on this connection.
2059 *
2060 * @param connectionTimeMillis The connection time, in milliseconds.
2061 *
2062 * @hide
2063 */
2064 public final void setConnectTimeMillis(long connectTimeMillis) {
2065 mConnectTimeMillis = connectTimeMillis;
2066 }
2067
2068 /**
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07002069 * Sets the label and icon status to display in the in-call UI.
2070 *
2071 * @param statusHints The status label and icon to set.
2072 */
2073 public final void setStatusHints(StatusHints statusHints) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002074 checkImmutable();
Santos Cordond34e5712014-08-05 18:54:03 +00002075 mStatusHints = statusHints;
2076 for (Listener l : mListeners) {
2077 l.onStatusHintsChanged(this, statusHints);
2078 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07002079 }
2080
2081 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002082 * Sets the connections with which this connection can be conferenced.
2083 *
2084 * @param conferenceableConnections The set of connections this connection can conference with.
2085 */
2086 public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002087 checkImmutable();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002088 clearConferenceableList();
2089 for (Connection c : conferenceableConnections) {
2090 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
2091 // small amount of items here.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002092 if (!mConferenceables.contains(c)) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002093 c.addConnectionListener(mConnectionDeathListener);
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002094 mConferenceables.add(c);
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002095 }
2096 }
2097 fireOnConferenceableConnectionsChanged();
2098 }
2099
2100 /**
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002101 * Similar to {@link #setConferenceableConnections(java.util.List)}, sets a list of connections
2102 * or conferences with which this connection can be conferenced.
2103 *
2104 * @param conferenceables The conferenceables.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002105 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07002106 public final void setConferenceables(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002107 clearConferenceableList();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07002108 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002109 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
2110 // small amount of items here.
2111 if (!mConferenceables.contains(c)) {
2112 if (c instanceof Connection) {
2113 Connection connection = (Connection) c;
2114 connection.addConnectionListener(mConnectionDeathListener);
2115 } else if (c instanceof Conference) {
2116 Conference conference = (Conference) c;
2117 conference.addListener(mConferenceDeathListener);
2118 }
2119 mConferenceables.add(c);
2120 }
2121 }
2122 fireOnConferenceableConnectionsChanged();
2123 }
2124
2125 /**
2126 * Returns the connections or conferences with which this connection can be conferenced.
2127 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07002128 public final List<Conferenceable> getConferenceables() {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002129 return mUnmodifiableConferenceables;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002130 }
2131
Yorke Lee53463962015-08-04 16:07:19 -07002132 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002133 * @hide
2134 */
2135 public final void setConnectionService(ConnectionService connectionService) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002136 checkImmutable();
Santos Cordon823fd3c2014-08-07 18:35:18 -07002137 if (mConnectionService != null) {
2138 Log.e(this, new Exception(), "Trying to set ConnectionService on a connection " +
2139 "which is already associated with another ConnectionService.");
2140 } else {
2141 mConnectionService = connectionService;
2142 }
2143 }
2144
2145 /**
2146 * @hide
2147 */
2148 public final void unsetConnectionService(ConnectionService connectionService) {
2149 if (mConnectionService != connectionService) {
2150 Log.e(this, new Exception(), "Trying to remove ConnectionService from a Connection " +
2151 "that does not belong to the ConnectionService.");
2152 } else {
2153 mConnectionService = null;
2154 }
2155 }
2156
2157 /**
Santos Cordonaf1b2962014-10-16 19:23:54 -07002158 * @hide
2159 */
2160 public final ConnectionService getConnectionService() {
2161 return mConnectionService;
2162 }
2163
2164 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002165 * Sets the conference that this connection is a part of. This will fail if the connection is
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002166 * already part of a conference. {@link #resetConference} to un-set the conference first.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002167 *
2168 * @param conference The conference.
2169 * @return {@code true} if the conference was successfully set.
2170 * @hide
2171 */
2172 public final boolean setConference(Conference conference) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002173 checkImmutable();
Santos Cordon823fd3c2014-08-07 18:35:18 -07002174 // We check to see if it is already part of another conference.
Santos Cordon0159ac02014-08-21 14:28:11 -07002175 if (mConference == null) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07002176 mConference = conference;
Santos Cordon0159ac02014-08-21 14:28:11 -07002177 if (mConnectionService != null && mConnectionService.containsConference(conference)) {
2178 fireConferenceChanged();
2179 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002180 return true;
2181 }
2182 return false;
2183 }
2184
2185 /**
2186 * Resets the conference that this connection is a part of.
2187 * @hide
2188 */
2189 public final void resetConference() {
2190 if (mConference != null) {
Santos Cordon0159ac02014-08-21 14:28:11 -07002191 Log.d(this, "Conference reset");
Santos Cordon823fd3c2014-08-07 18:35:18 -07002192 mConference = null;
2193 fireConferenceChanged();
2194 }
2195 }
2196
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002197 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002198 * Set some extras that can be associated with this {@code Connection}.
2199 * <p>
2200 * New or existing keys are replaced in the {@code Connection} extras. Keys which are no longer
2201 * in the new extras, but were present the last time {@code setExtras} was called are removed.
2202 * <p>
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07002203 * Alternatively you may use the {@link #putExtras(Bundle)}, and
2204 * {@link #removeExtras(String...)} methods to modify the extras.
2205 * <p>
Tyler Gunndee56a82016-03-23 16:06:34 -07002206 * No assumptions should be made as to how an In-Call UI or service will handle these extras.
Santos Cordon6b7f9552015-05-27 17:21:45 -07002207 * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
2208 *
2209 * @param extras The extras associated with this {@code Connection}.
2210 */
2211 public final void setExtras(@Nullable Bundle extras) {
2212 checkImmutable();
Tyler Gunndee56a82016-03-23 16:06:34 -07002213
2214 // Add/replace any new or changed extras values.
2215 putExtras(extras);
2216
2217 // If we have used "setExtras" in the past, compare the key set from the last invocation to
2218 // the current one and remove any keys that went away.
2219 if (mPreviousExtraKeys != null) {
2220 List<String> toRemove = new ArrayList<String>();
2221 for (String oldKey : mPreviousExtraKeys) {
Tyler Gunna8fb8ab2016-03-29 10:24:22 -07002222 if (extras == null || !extras.containsKey(oldKey)) {
Tyler Gunndee56a82016-03-23 16:06:34 -07002223 toRemove.add(oldKey);
2224 }
2225 }
2226 if (!toRemove.isEmpty()) {
2227 removeExtras(toRemove);
2228 }
2229 }
2230
2231 // Track the keys the last time set called setExtras. This way, the next time setExtras is
2232 // called we can see if the caller has removed any extras values.
2233 if (mPreviousExtraKeys == null) {
2234 mPreviousExtraKeys = new ArraySet<String>();
2235 }
2236 mPreviousExtraKeys.clear();
Tyler Gunna8fb8ab2016-03-29 10:24:22 -07002237 if (extras != null) {
2238 mPreviousExtraKeys.addAll(extras.keySet());
2239 }
Tyler Gunndee56a82016-03-23 16:06:34 -07002240 }
2241
2242 /**
2243 * Adds some extras to this {@code Connection}. Existing keys are replaced and new ones are
2244 * added.
2245 * <p>
2246 * No assumptions should be made as to how an In-Call UI or service will handle these extras.
2247 * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
2248 *
2249 * @param extras The extras to add.
2250 */
2251 public final void putExtras(@NonNull Bundle extras) {
2252 checkImmutable();
2253 if (extras == null) {
2254 return;
2255 }
Brad Ebinger4fa6a012016-06-14 17:04:01 -07002256 // Creating a duplicate bundle so we don't have to synchronize on mExtrasLock while calling
2257 // the listeners.
2258 Bundle listenerExtras;
2259 synchronized (mExtrasLock) {
2260 if (mExtras == null) {
2261 mExtras = new Bundle();
2262 }
2263 mExtras.putAll(extras);
2264 listenerExtras = new Bundle(mExtras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002265 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07002266 for (Listener l : mListeners) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -07002267 // Create a new clone of the extras for each listener so that they don't clobber
2268 // each other
2269 l.onExtrasChanged(this, new Bundle(listenerExtras));
Santos Cordon6b7f9552015-05-27 17:21:45 -07002270 }
2271 }
2272
2273 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002274 * Adds a boolean extra to this {@code Connection}.
2275 *
2276 * @param key The extra key.
2277 * @param value The value.
2278 * @hide
2279 */
2280 public final void putExtra(String key, boolean value) {
2281 Bundle newExtras = new Bundle();
2282 newExtras.putBoolean(key, value);
2283 putExtras(newExtras);
2284 }
2285
2286 /**
2287 * Adds an integer extra to this {@code Connection}.
2288 *
2289 * @param key The extra key.
2290 * @param value The value.
2291 * @hide
2292 */
2293 public final void putExtra(String key, int value) {
2294 Bundle newExtras = new Bundle();
2295 newExtras.putInt(key, value);
2296 putExtras(newExtras);
2297 }
2298
2299 /**
2300 * Adds a string extra to this {@code Connection}.
2301 *
2302 * @param key The extra key.
2303 * @param value The value.
2304 * @hide
2305 */
2306 public final void putExtra(String key, String value) {
2307 Bundle newExtras = new Bundle();
2308 newExtras.putString(key, value);
2309 putExtras(newExtras);
2310 }
2311
2312 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07002313 * Removes extras from this {@code Connection}.
Tyler Gunndee56a82016-03-23 16:06:34 -07002314 *
Tyler Gunn071be6f2016-05-10 14:52:33 -07002315 * @param keys The keys of the extras to remove.
Tyler Gunndee56a82016-03-23 16:06:34 -07002316 */
2317 public final void removeExtras(List<String> keys) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -07002318 synchronized (mExtrasLock) {
2319 if (mExtras != null) {
2320 for (String key : keys) {
2321 mExtras.remove(key);
2322 }
Tyler Gunndee56a82016-03-23 16:06:34 -07002323 }
2324 }
Brad Ebinger4fa6a012016-06-14 17:04:01 -07002325 List<String> unmodifiableKeys = Collections.unmodifiableList(keys);
Tyler Gunndee56a82016-03-23 16:06:34 -07002326 for (Listener l : mListeners) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -07002327 l.onExtrasRemoved(this, unmodifiableKeys);
Tyler Gunndee56a82016-03-23 16:06:34 -07002328 }
2329 }
2330
2331 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -07002332 * Removes extras from this {@code Connection}.
2333 *
2334 * @param keys The keys of the extras to remove.
2335 */
2336 public final void removeExtras(String ... keys) {
2337 removeExtras(Arrays.asList(keys));
2338 }
2339
2340 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002341 * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will
2342 * be change to the {@link #getCallAudioState()}.
2343 * <p>
2344 * Used by self-managed {@link ConnectionService}s which wish to change the audio route for a
2345 * self-managed {@link Connection} (see {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.)
2346 * <p>
2347 * See also {@link InCallService#setAudioRoute(int)}.
2348 *
2349 * @param route The audio route to use (one of {@link CallAudioState#ROUTE_BLUETOOTH},
2350 * {@link CallAudioState#ROUTE_EARPIECE}, {@link CallAudioState#ROUTE_SPEAKER}, or
2351 * {@link CallAudioState#ROUTE_WIRED_HEADSET}).
2352 */
2353 public final void setAudioRoute(int route) {
2354 for (Listener l : mListeners) {
2355 l.onAudioRouteChanged(this, route);
2356 }
2357 }
2358
2359 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002360 * Notifies this Connection that the {@link #getAudioState()} property has a new value.
Sailesh Nepal400cc482014-06-26 12:04:00 -07002361 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002362 * @param state The new connection audio state.
Yorke Lee4af59352015-05-13 14:14:54 -07002363 * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead.
2364 * @hide
Sailesh Nepal400cc482014-06-26 12:04:00 -07002365 */
Yorke Lee4af59352015-05-13 14:14:54 -07002366 @SystemApi
2367 @Deprecated
Nancy Chen354b2bd2014-09-08 18:27:26 -07002368 public void onAudioStateChanged(AudioState state) {}
Sailesh Nepal400cc482014-06-26 12:04:00 -07002369
2370 /**
Yorke Lee4af59352015-05-13 14:14:54 -07002371 * Notifies this Connection that the {@link #getCallAudioState()} property has a new value.
2372 *
2373 * @param state The new connection audio state.
2374 */
2375 public void onCallAudioStateChanged(CallAudioState state) {}
2376
2377 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07002378 * Notifies this Connection of an internal state change. This method is called after the
2379 * state is changed.
Ihab Awadf8358972014-05-28 16:46:42 -07002380 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002381 * @param state The new state, one of the {@code STATE_*} constants.
Ihab Awadf8358972014-05-28 16:46:42 -07002382 */
Nancy Chen354b2bd2014-09-08 18:27:26 -07002383 public void onStateChanged(int state) {}
Ihab Awadf8358972014-05-28 16:46:42 -07002384
2385 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07002386 * Notifies this Connection of a request to play a DTMF tone.
2387 *
2388 * @param c A DTMF character.
2389 */
Santos Cordonf2951102014-07-20 19:06:29 -07002390 public void onPlayDtmfTone(char c) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002391
2392 /**
2393 * Notifies this Connection of a request to stop any currently playing DTMF tones.
2394 */
Santos Cordonf2951102014-07-20 19:06:29 -07002395 public void onStopDtmfTone() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002396
2397 /**
2398 * Notifies this Connection of a request to disconnect.
2399 */
Santos Cordonf2951102014-07-20 19:06:29 -07002400 public void onDisconnect() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002401
2402 /**
Tyler Gunn3b4b1dc2014-11-04 14:53:37 -08002403 * Notifies this Connection of a request to disconnect a participant of the conference managed
2404 * by the connection.
2405 *
2406 * @param endpoint the {@link Uri} of the participant to disconnect.
2407 * @hide
2408 */
2409 public void onDisconnectConferenceParticipant(Uri endpoint) {}
2410
2411 /**
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002412 * Notifies this Connection of a request to separate from its parent conference.
Santos Cordonb6939982014-06-04 20:20:58 -07002413 */
Santos Cordonf2951102014-07-20 19:06:29 -07002414 public void onSeparate() {}
Santos Cordonb6939982014-06-04 20:20:58 -07002415
2416 /**
Ihab Awad542e0ea2014-05-16 10:22:16 -07002417 * Notifies this Connection of a request to abort.
2418 */
Santos Cordonf2951102014-07-20 19:06:29 -07002419 public void onAbort() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002420
2421 /**
2422 * Notifies this Connection of a request to hold.
2423 */
Santos Cordonf2951102014-07-20 19:06:29 -07002424 public void onHold() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002425
2426 /**
2427 * Notifies this Connection of a request to exit a hold state.
2428 */
Santos Cordonf2951102014-07-20 19:06:29 -07002429 public void onUnhold() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002430
2431 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002432 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Santos Cordond34e5712014-08-05 18:54:03 +00002433 * a request to accept.
Andrew Lee8da4c3c2014-07-16 10:11:42 -07002434 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002435 * @param videoState The video state in which to answer the connection.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002436 */
Santos Cordonf2951102014-07-20 19:06:29 -07002437 public void onAnswer(int videoState) {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002438
2439 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002440 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Tyler Gunnbe74de02014-08-29 14:51:48 -07002441 * a request to accept.
2442 */
2443 public void onAnswer() {
Tyler Gunn87b73f32015-06-03 10:09:59 -07002444 onAnswer(VideoProfile.STATE_AUDIO_ONLY);
Tyler Gunnbe74de02014-08-29 14:51:48 -07002445 }
2446
2447 /**
2448 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
Santos Cordond34e5712014-08-05 18:54:03 +00002449 * a request to reject.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002450 */
Santos Cordonf2951102014-07-20 19:06:29 -07002451 public void onReject() {}
Ihab Awad542e0ea2014-05-16 10:22:16 -07002452
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002453 /**
Hall Liu712acbe2016-03-14 16:38:56 -07002454 * Notifies this Connection, which is in {@link #STATE_RINGING}, of
2455 * a request to reject with a message.
Bryce Lee81901682015-08-28 16:38:02 -07002456 */
2457 public void onReject(String replyMessage) {}
2458
2459 /**
Bryce Leecac50772015-11-17 15:13:29 -08002460 * Notifies the Connection of a request to silence the ringer.
2461 *
2462 * @hide
2463 */
2464 public void onSilence() {}
2465
2466 /**
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002467 * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
2468 */
Santos Cordonf2951102014-07-20 19:06:29 -07002469 public void onPostDialContinue(boolean proceed) {}
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002470
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002471 /**
2472 * Notifies this Connection of a request to pull an external call to the local device.
2473 * <p>
2474 * The {@link InCallService} issues a request to pull an external call to the local device via
2475 * {@link Call#pullExternalCall()}.
2476 * <p>
Tyler Gunn720c6642016-03-22 09:02:47 -07002477 * For a Connection to be pulled, both the {@link Connection#CAPABILITY_CAN_PULL_CALL}
2478 * capability and {@link Connection#PROPERTY_IS_EXTERNAL_CALL} property bits must be set.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002479 * <p>
Tyler Gunn720c6642016-03-22 09:02:47 -07002480 * For more information on external calls, see {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002481 */
2482 public void onPullExternalCall() {}
2483
2484 /**
2485 * Notifies this Connection of a {@link Call} event initiated from an {@link InCallService}.
2486 * <p>
2487 * The {@link InCallService} issues a Call event via {@link Call#sendCallEvent(String, Bundle)}.
2488 * <p>
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07002489 * Where possible, the Connection should make an attempt to handle {@link Call} events which
2490 * are part of the {@code android.telecom.*} namespace. The Connection should ignore any events
2491 * it does not wish to handle. Unexpected events should be handled gracefully, as it is
2492 * possible that a {@link InCallService} has defined its own Call events which a Connection is
2493 * not aware of.
2494 * <p>
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002495 * See also {@link Call#sendCallEvent(String, Bundle)}.
2496 *
2497 * @param event The call event.
2498 * @param extras Extras associated with the call event.
2499 */
2500 public void onCallEvent(String event, Bundle extras) {}
2501
Tyler Gunndee56a82016-03-23 16:06:34 -07002502 /**
2503 * Notifies this {@link Connection} of a change to the extras made outside the
2504 * {@link ConnectionService}.
2505 * <p>
2506 * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
2507 * the {@link android.telecom.Call#putExtras(Bundle)} and
2508 * {@link Call#removeExtras(List)}.
2509 *
2510 * @param extras The new extras bundle.
2511 */
2512 public void onExtrasChanged(Bundle extras) {}
2513
Tyler Gunnf5035432017-01-09 09:43:12 -08002514 /**
2515 * Notifies this {@link Connection} that its {@link ConnectionService} is responsible for
2516 * displaying its incoming call user interface for the {@link Connection}.
2517 * <p>
2518 * Will only be called for incoming calls added via a self-managed {@link ConnectionService}
2519 * (see {@link PhoneAccount#CAPABILITY_SELF_MANAGED}), where the {@link ConnectionService}
2520 * should show its own incoming call user interface.
2521 * <p>
2522 * Where there are ongoing calls in other self-managed {@link ConnectionService}s, or in a
2523 * regular {@link ConnectionService}, the Telecom framework will display its own incoming call
2524 * user interface to allow the user to choose whether to answer the new incoming call and
2525 * disconnect other ongoing calls, or to reject the new incoming call.
2526 */
2527 public void onShowIncomingCallUi() {}
2528
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002529 static String toLogSafePhoneNumber(String number) {
2530 // For unknown number, log empty string.
2531 if (number == null) {
2532 return "";
2533 }
2534
2535 if (PII_DEBUG) {
2536 // When PII_DEBUG is true we emit PII.
2537 return number;
2538 }
2539
2540 // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
2541 // sanitized phone numbers.
2542 StringBuilder builder = new StringBuilder();
2543 for (int i = 0; i < number.length(); i++) {
2544 char c = number.charAt(i);
2545 if (c == '-' || c == '@' || c == '.') {
2546 builder.append(c);
2547 } else {
2548 builder.append('x');
2549 }
2550 }
2551 return builder.toString();
2552 }
2553
Ihab Awad542e0ea2014-05-16 10:22:16 -07002554 private void setState(int state) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002555 checkImmutable();
Ihab Awad6107bab2014-08-18 09:23:25 -07002556 if (mState == STATE_DISCONNECTED && mState != state) {
2557 Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
Evan Charltonbf11f982014-07-20 22:06:28 -07002558 return;
Sailesh Nepal400cc482014-06-26 12:04:00 -07002559 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002560 if (mState != state) {
2561 Log.d(this, "setState: %s", stateToString(state));
2562 mState = state;
Nancy Chen354b2bd2014-09-08 18:27:26 -07002563 onStateChanged(state);
Evan Charltonbf11f982014-07-20 22:06:28 -07002564 for (Listener l : mListeners) {
2565 l.onStateChanged(this, state);
2566 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002567 }
2568 }
2569
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002570 private static class FailureSignalingConnection extends Connection {
Ihab Awad90e34e32014-12-01 16:23:17 -08002571 private boolean mImmutable = false;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002572 public FailureSignalingConnection(DisconnectCause disconnectCause) {
2573 setDisconnected(disconnectCause);
Ihab Awad90e34e32014-12-01 16:23:17 -08002574 mImmutable = true;
Ihab Awad6107bab2014-08-18 09:23:25 -07002575 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002576
2577 public void checkImmutable() {
Ihab Awad90e34e32014-12-01 16:23:17 -08002578 if (mImmutable) {
2579 throw new UnsupportedOperationException("Connection is immutable");
2580 }
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002581 }
Ihab Awad6107bab2014-08-18 09:23:25 -07002582 }
2583
Evan Charltonbf11f982014-07-20 22:06:28 -07002584 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07002585 * Return a {@code Connection} which represents a failed connection attempt. The returned
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002586 * {@code Connection} will have a {@link android.telecom.DisconnectCause} and as specified,
2587 * and a {@link #getState()} of {@link #STATE_DISCONNECTED}.
Ihab Awad6107bab2014-08-18 09:23:25 -07002588 * <p>
2589 * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
2590 * so users of this method need not maintain a reference to its return value to destroy it.
Evan Charltonbf11f982014-07-20 22:06:28 -07002591 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002592 * @param disconnectCause The disconnect cause, ({@see android.telecomm.DisconnectCause}).
Ihab Awad6107bab2014-08-18 09:23:25 -07002593 * @return A {@code Connection} which indicates failure.
Evan Charltonbf11f982014-07-20 22:06:28 -07002594 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002595 public static Connection createFailedConnection(DisconnectCause disconnectCause) {
2596 return new FailureSignalingConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07002597 }
2598
Evan Charltonbf11f982014-07-20 22:06:28 -07002599 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002600 * Override to throw an {@link UnsupportedOperationException} if this {@code Connection} is
2601 * not intended to be mutated, e.g., if it is a marker for failure. Only for framework use;
2602 * this should never be un-@hide-den.
2603 *
2604 * @hide
2605 */
2606 public void checkImmutable() {}
2607
2608 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07002609 * Return a {@code Connection} which represents a canceled connection attempt. The returned
2610 * {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
2611 * that state. This connection should not be used for anything, and no other
2612 * {@code Connection}s should be attempted.
2613 * <p>
Ihab Awad6107bab2014-08-18 09:23:25 -07002614 * so users of this method need not maintain a reference to its return value to destroy it.
Evan Charltonbf11f982014-07-20 22:06:28 -07002615 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002616 * @return A {@code Connection} which indicates that the underlying connection should
2617 * be canceled.
Evan Charltonbf11f982014-07-20 22:06:28 -07002618 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002619 public static Connection createCanceledConnection() {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002620 return new FailureSignalingConnection(new DisconnectCause(DisconnectCause.CANCELED));
Ihab Awad542e0ea2014-05-16 10:22:16 -07002621 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002622
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002623 private final void fireOnConferenceableConnectionsChanged() {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002624 for (Listener l : mListeners) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002625 l.onConferenceablesChanged(this, getConferenceables());
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002626 }
2627 }
2628
Santos Cordon823fd3c2014-08-07 18:35:18 -07002629 private final void fireConferenceChanged() {
2630 for (Listener l : mListeners) {
2631 l.onConferenceChanged(this, mConference);
2632 }
2633 }
2634
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002635 private final void clearConferenceableList() {
Tyler Gunndf2cbc82015-04-20 09:13:01 -07002636 for (Conferenceable c : mConferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002637 if (c instanceof Connection) {
2638 Connection connection = (Connection) c;
2639 connection.removeConnectionListener(mConnectionDeathListener);
2640 } else if (c instanceof Conference) {
2641 Conference conference = (Conference) c;
2642 conference.removeListener(mConferenceDeathListener);
2643 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002644 }
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002645 mConferenceables.clear();
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002646 }
Tyler Gunn3bffcf72014-10-28 13:51:27 -07002647
2648 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002649 * Handles a change to extras received from Telecom.
2650 *
2651 * @param extras The new extras.
2652 * @hide
2653 */
2654 final void handleExtrasChanged(Bundle extras) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -07002655 Bundle b = null;
2656 synchronized (mExtrasLock) {
2657 mExtras = extras;
2658 if (mExtras != null) {
2659 b = new Bundle(mExtras);
2660 }
2661 }
2662 onExtrasChanged(b);
Tyler Gunndee56a82016-03-23 16:06:34 -07002663 }
2664
2665 /**
Anthony Lee17455a32015-04-24 15:25:29 -07002666 * Notifies listeners that the merge request failed.
2667 *
2668 * @hide
2669 */
2670 protected final void notifyConferenceMergeFailed() {
2671 for (Listener l : mListeners) {
2672 l.onConferenceMergeFailed(this);
2673 }
2674 }
2675
2676 /**
Tyler Gunnab4650c2014-11-06 20:06:23 -08002677 * Notifies listeners of a change to conference participant(s).
Tyler Gunn3bffcf72014-10-28 13:51:27 -07002678 *
Tyler Gunnab4650c2014-11-06 20:06:23 -08002679 * @param conferenceParticipants The participants.
Tyler Gunn3bffcf72014-10-28 13:51:27 -07002680 * @hide
2681 */
Tyler Gunnab4650c2014-11-06 20:06:23 -08002682 protected final void updateConferenceParticipants(
2683 List<ConferenceParticipant> conferenceParticipants) {
Tyler Gunn3bffcf72014-10-28 13:51:27 -07002684 for (Listener l : mListeners) {
Tyler Gunnab4650c2014-11-06 20:06:23 -08002685 l.onConferenceParticipantsChanged(this, conferenceParticipants);
Tyler Gunn3bffcf72014-10-28 13:51:27 -07002686 }
2687 }
Tyler Gunn8a2b1192015-01-29 11:47:24 -08002688
2689 /**
2690 * Notifies listeners that a conference call has been started.
Jay Shrauner55b97522015-04-09 15:15:43 -07002691 * @hide
Tyler Gunn8a2b1192015-01-29 11:47:24 -08002692 */
2693 protected void notifyConferenceStarted() {
2694 for (Listener l : mListeners) {
2695 l.onConferenceStarted();
2696 }
2697 }
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002698
2699 /**
Tyler Gunn7d633d32016-06-24 07:30:10 -07002700 * Notifies listeners when a change has occurred to the Connection which impacts its ability to
2701 * be a part of a conference call.
2702 * @param isConferenceSupported {@code true} if the connection supports being part of a
2703 * conference call, {@code false} otherwise.
2704 * @hide
2705 */
2706 protected void notifyConferenceSupportedChanged(boolean isConferenceSupported) {
2707 for (Listener l : mListeners) {
2708 l.onConferenceSupportedChanged(this, isConferenceSupported);
2709 }
2710 }
2711
2712 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07002713 * Sends an event associated with this {@code Connection} with associated event extras to the
2714 * {@link InCallService}.
2715 * <p>
2716 * Connection events are used to communicate point in time information from a
2717 * {@link ConnectionService} to a {@link InCallService} implementations. An example of a
2718 * custom connection event includes notifying the UI when a WIFI call has been handed over to
2719 * LTE, which the InCall UI might use to inform the user that billing charges may apply. The
2720 * Android Telephony framework will send the {@link #EVENT_CALL_MERGE_FAILED} connection event
2721 * when a call to {@link Call#mergeConference()} has failed to complete successfully. A
2722 * connection event could also be used to trigger UI in the {@link InCallService} which prompts
2723 * the user to make a choice (e.g. whether they want to incur roaming costs for making a call),
2724 * which is communicated back via {@link Call#sendCallEvent(String, Bundle)}.
2725 * <p>
2726 * Events are exposed to {@link InCallService} implementations via
2727 * {@link Call.Callback#onConnectionEvent(Call, String, Bundle)}.
2728 * <p>
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002729 * No assumptions should be made as to how an In-Call UI or service will handle these events.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07002730 * The {@link ConnectionService} must assume that the In-Call UI could even chose to ignore
2731 * some events altogether.
2732 * <p>
2733 * Events should be fully qualified (e.g. {@code com.example.event.MY_EVENT}) to avoid
2734 * conflicts between {@link ConnectionService} implementations. Further, custom
2735 * {@link ConnectionService} implementations shall not re-purpose events in the
2736 * {@code android.*} namespace, nor shall they define new event types in this namespace. When
2737 * defining a custom event type, ensure the contents of the extras {@link Bundle} is clearly
2738 * defined. Extra keys for this bundle should be named similar to the event type (e.g.
2739 * {@code com.example.extra.MY_EXTRA}).
2740 * <p>
2741 * When defining events and the associated extras, it is important to keep their behavior
2742 * consistent when the associated {@link ConnectionService} is updated. Support for deprecated
2743 * events/extras should me maintained to ensure backwards compatibility with older
2744 * {@link InCallService} implementations which were built to support the older behavior.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002745 *
2746 * @param event The connection event.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -07002747 * @param extras Optional bundle containing extra information associated with the event.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002748 */
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002749 public void sendConnectionEvent(String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002750 for (Listener l : mListeners) {
Tyler Gunna8fb8ab2016-03-29 10:24:22 -07002751 l.onConnectionEvent(this, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002752 }
2753 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002754}