blob: 58abf0051539a736bb93d420f43e12ba6ac661da [file] [log] [blame]
Santos Cordon823fd3c2014-08-07 18:35:18 -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;
Santos Cordon823fd3c2014-08-07 18:35:18 -070018
Tyler Gunndee56a82016-03-23 16:06:34 -070019import android.annotation.NonNull;
Santos Cordon6b7f9552015-05-27 17:21:45 -070020import android.annotation.Nullable;
Santos Cordon5d2e4f22015-05-12 12:32:51 -070021import android.annotation.SystemApi;
Tyler Gunn6c14a6992019-02-04 15:12:06 -080022import android.annotation.TestApi;
Tyler Gunn68a73a42018-10-03 15:38:57 -070023import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070024import android.os.Bundle;
Tyler Gunn3fa819c2017-08-04 09:27:26 -070025import android.os.SystemClock;
Rekha Kumar07366812015-03-24 16:42:31 -070026import android.telecom.Connection.VideoProvider;
Chen Xub6d13192019-10-02 00:20:43 -070027import android.telephony.Annotation.RilRadioTechnology;
Wei Huang7f7f72e2018-05-30 19:21:36 +080028import android.telephony.ServiceState;
29import android.telephony.TelephonyManager;
Tyler Gunndee56a82016-03-23 16:06:34 -070030import android.util.ArraySet;
Evan Charlton0e094d92014-11-08 15:49:16 -080031
Ihab Awad50e35062014-09-30 09:17:03 -070032import java.util.ArrayList;
Tyler Gunn071be6f2016-05-10 14:52:33 -070033import java.util.Arrays;
Santos Cordon823fd3c2014-08-07 18:35:18 -070034import java.util.Collections;
Santos Cordon823fd3c2014-08-07 18:35:18 -070035import java.util.List;
Rekha Kumar07366812015-03-24 16:42:31 -070036import java.util.Locale;
Santos Cordon823fd3c2014-08-07 18:35:18 -070037import java.util.Set;
38import java.util.concurrent.CopyOnWriteArrayList;
39import java.util.concurrent.CopyOnWriteArraySet;
40
41/**
42 * Represents a conference call which can contain any number of {@link Connection} objects.
43 */
Yorke Leeabfcfdc2015-05-13 18:55:18 -070044public abstract class Conference extends Conferenceable {
Santos Cordon823fd3c2014-08-07 18:35:18 -070045
Tyler Gunncd5d33c2015-01-12 09:02:01 -080046 /**
47 * Used to indicate that the conference connection time is not specified. If not specified,
48 * Telecom will set the connect time.
49 */
Jay Shrauner164a0ac2015-04-14 18:16:10 -070050 public static final long CONNECT_TIME_NOT_SPECIFIED = 0;
Tyler Gunncd5d33c2015-01-12 09:02:01 -080051
Santos Cordon823fd3c2014-08-07 18:35:18 -070052 /** @hide */
Tyler Gunn5567d742019-10-31 13:04:37 -070053 abstract static class Listener {
Santos Cordon823fd3c2014-08-07 18:35:18 -070054 public void onStateChanged(Conference conference, int oldState, int newState) {}
Andrew Lee7f3d41f2014-09-11 17:33:16 -070055 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {}
Santos Cordon823fd3c2014-08-07 18:35:18 -070056 public void onConnectionAdded(Conference conference, Connection connection) {}
57 public void onConnectionRemoved(Conference conference, Connection connection) {}
Ihab Awad50e35062014-09-30 09:17:03 -070058 public void onConferenceableConnectionsChanged(
59 Conference conference, List<Connection> conferenceableConnections) {}
Santos Cordon823fd3c2014-08-07 18:35:18 -070060 public void onDestroyed(Conference conference) {}
Ihab Awad5c9c86e2014-11-12 13:41:16 -080061 public void onConnectionCapabilitiesChanged(
62 Conference conference, int connectionCapabilities) {}
Tyler Gunn720c6642016-03-22 09:02:47 -070063 public void onConnectionPropertiesChanged(
64 Conference conference, int connectionProperties) {}
Rekha Kumar07366812015-03-24 16:42:31 -070065 public void onVideoStateChanged(Conference c, int videoState) { }
66 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {}
Andrew Leeedc625f2015-04-14 13:38:12 -070067 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {}
Tyler Gunndee56a82016-03-23 16:06:34 -070068 public void onExtrasChanged(Conference c, Bundle extras) {}
69 public void onExtrasRemoved(Conference c, List<String> keys) {}
Tyler Gunn68a73a42018-10-03 15:38:57 -070070 public void onConferenceStateChanged(Conference c, boolean isConference) {}
71 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {}
Hall Liuc9bc1c62019-04-16 14:00:55 -070072 public void onConnectionEvent(Conference c, String event, Bundle extras) {}
Tyler Gunn68a73a42018-10-03 15:38:57 -070073 public void onCallerDisplayNameChanged(
74 Conference c, String callerDisplayName, int presentation) {}
Santos Cordon823fd3c2014-08-07 18:35:18 -070075 }
76
77 private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
78 private final List<Connection> mChildConnections = new CopyOnWriteArrayList<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -070079 private final List<Connection> mUnmodifiableChildConnections =
Santos Cordon823fd3c2014-08-07 18:35:18 -070080 Collections.unmodifiableList(mChildConnections);
Ihab Awad50e35062014-09-30 09:17:03 -070081 private final List<Connection> mConferenceableConnections = new ArrayList<>();
82 private final List<Connection> mUnmodifiableConferenceableConnections =
83 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon823fd3c2014-08-07 18:35:18 -070084
Jack Yu67140302015-12-10 12:27:58 -080085 private String mTelecomCallId;
Jay Shrauner164a0ac2015-04-14 18:16:10 -070086 private PhoneAccountHandle mPhoneAccount;
Yorke Lee4af59352015-05-13 14:14:54 -070087 private CallAudioState mCallAudioState;
Santos Cordon823fd3c2014-08-07 18:35:18 -070088 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -070089 private DisconnectCause mDisconnectCause;
Ihab Awad5c9c86e2014-11-12 13:41:16 -080090 private int mConnectionCapabilities;
Tyler Gunn720c6642016-03-22 09:02:47 -070091 private int mConnectionProperties;
Santos Cordon823fd3c2014-08-07 18:35:18 -070092 private String mDisconnectMessage;
Tyler Gunncd5d33c2015-01-12 09:02:01 -080093 private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
Tyler Gunn17541392018-02-01 08:58:38 -080094 private long mConnectionStartElapsedRealTime = CONNECT_TIME_NOT_SPECIFIED;
Andrew Leeedc625f2015-04-14 13:38:12 -070095 private StatusHints mStatusHints;
Santos Cordon6b7f9552015-05-27 17:21:45 -070096 private Bundle mExtras;
Tyler Gunndee56a82016-03-23 16:06:34 -070097 private Set<String> mPreviousExtraKeys;
Brad Ebinger4fa6a012016-06-14 17:04:01 -070098 private final Object mExtrasLock = new Object();
Tyler Gunnac60f952019-05-31 07:23:16 -070099 private Uri mAddress;
100 private int mAddressPresentation;
101 private String mCallerDisplayName;
102 private int mCallerDisplayNamePresentation;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700103
Ihab Awad50e35062014-09-30 09:17:03 -0700104 private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
105 @Override
106 public void onDestroyed(Connection c) {
107 if (mConferenceableConnections.remove(c)) {
108 fireOnConferenceableConnectionsChanged();
109 }
110 }
111 };
112
Nancy Chen56fc25d2014-09-09 12:24:51 -0700113 /**
114 * Constructs a new Conference with a mandatory {@link PhoneAccountHandle}
115 *
116 * @param phoneAccount The {@code PhoneAccountHandle} associated with the conference.
117 */
Santos Cordon823fd3c2014-08-07 18:35:18 -0700118 public Conference(PhoneAccountHandle phoneAccount) {
119 mPhoneAccount = phoneAccount;
120 }
121
Nancy Chen56fc25d2014-09-09 12:24:51 -0700122 /**
Jack Yu67140302015-12-10 12:27:58 -0800123 * Returns the telecom internal call ID associated with this conference.
Tyler Gunn5567d742019-10-31 13:04:37 -0700124 * <p>
125 * Note: This is ONLY used for debugging purposes so that the Telephony stack can better
126 * associate logs in Telephony with those in Telecom.
127 * The ID returned should not be used for any other purpose.
Jack Yu67140302015-12-10 12:27:58 -0800128 *
129 * @return The telecom call ID.
130 * @hide
131 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700132 @SystemApi
133 @TestApi
134 public final @NonNull String getTelecomCallId() {
Jack Yu67140302015-12-10 12:27:58 -0800135 return mTelecomCallId;
136 }
137
138 /**
139 * Sets the telecom internal call ID associated with this conference.
140 *
141 * @param telecomCallId The telecom call ID.
142 * @hide
143 */
144 public final void setTelecomCallId(String telecomCallId) {
145 mTelecomCallId = telecomCallId;
146 }
147
148 /**
Nancy Chen56fc25d2014-09-09 12:24:51 -0700149 * Returns the {@link PhoneAccountHandle} the conference call is being placed through.
150 *
151 * @return A {@code PhoneAccountHandle} object representing the PhoneAccount of the conference.
152 */
Nancy Chenea38cca2014-09-05 16:38:49 -0700153 public final PhoneAccountHandle getPhoneAccountHandle() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700154 return mPhoneAccount;
155 }
156
Nancy Chen56fc25d2014-09-09 12:24:51 -0700157 /**
158 * Returns the list of connections currently associated with the conference call.
159 *
160 * @return A list of {@code Connection} objects which represent the children of the conference.
161 */
Santos Cordon823fd3c2014-08-07 18:35:18 -0700162 public final List<Connection> getConnections() {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700163 return mUnmodifiableChildConnections;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700164 }
165
Nancy Chen56fc25d2014-09-09 12:24:51 -0700166 /**
167 * Gets the state of the conference call. See {@link Connection} for valid values.
168 *
169 * @return A constant representing the state the conference call is currently in.
170 */
Santos Cordon823fd3c2014-08-07 18:35:18 -0700171 public final int getState() {
172 return mState;
173 }
174
Nancy Chen56fc25d2014-09-09 12:24:51 -0700175 /**
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700176 * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800177 * {@link Connection} for valid values.
Nancy Chen56fc25d2014-09-09 12:24:51 -0700178 *
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800179 * @return A bitmask of the capabilities of the conference call.
Nancy Chen56fc25d2014-09-09 12:24:51 -0700180 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800181 public final int getConnectionCapabilities() {
182 return mConnectionCapabilities;
183 }
184
185 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700186 * Returns the properties of the conference. See {@code PROPERTY_*} constants in class
187 * {@link Connection} for valid values.
188 *
189 * @return A bitmask of the properties of the conference call.
190 */
191 public final int getConnectionProperties() {
192 return mConnectionProperties;
193 }
194
195 /**
Yorke Leea0d3ca92014-09-15 19:18:13 -0700196 * @return The audio state of the conference, describing how its audio is currently
197 * being routed by the system. This is {@code null} if this Conference
198 * does not directly know about its audio state.
Yorke Lee4af59352015-05-13 14:14:54 -0700199 * @deprecated Use {@link #getCallAudioState()} instead.
200 * @hide
Yorke Leea0d3ca92014-09-15 19:18:13 -0700201 */
Yorke Lee4af59352015-05-13 14:14:54 -0700202 @Deprecated
203 @SystemApi
Yorke Leea0d3ca92014-09-15 19:18:13 -0700204 public final AudioState getAudioState() {
Yorke Lee4af59352015-05-13 14:14:54 -0700205 return new AudioState(mCallAudioState);
206 }
207
208 /**
209 * @return The audio state of the conference, describing how its audio is currently
210 * being routed by the system. This is {@code null} if this Conference
211 * does not directly know about its audio state.
212 */
213 public final CallAudioState getCallAudioState() {
214 return mCallAudioState;
Yorke Leea0d3ca92014-09-15 19:18:13 -0700215 }
216
217 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700218 * Returns VideoProvider of the primary call. This can be null.
Rekha Kumar07366812015-03-24 16:42:31 -0700219 */
220 public VideoProvider getVideoProvider() {
221 return null;
222 }
223
224 /**
225 * Returns video state of the primary call.
Rekha Kumar07366812015-03-24 16:42:31 -0700226 */
227 public int getVideoState() {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700228 return VideoProfile.STATE_AUDIO_ONLY;
Rekha Kumar07366812015-03-24 16:42:31 -0700229 }
230
231 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700232 * Notifies the {@link Conference} when the Conference and all it's {@link Connection}s should
233 * be disconnected.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700234 */
235 public void onDisconnect() {}
236
237 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700238 * Notifies the {@link Conference} when the specified {@link Connection} should be separated
239 * from the conference call.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700240 *
241 * @param connection The connection to separate.
242 */
243 public void onSeparate(Connection connection) {}
244
245 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700246 * Notifies the {@link Conference} when the specified {@link Connection} should merged with the
247 * conference call.
Ihab Awad50e35062014-09-30 09:17:03 -0700248 *
249 * @param connection The {@code Connection} to merge.
250 */
251 public void onMerge(Connection connection) {}
252
253 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700254 * Notifies the {@link Conference} when it should be put on hold.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700255 */
256 public void onHold() {}
257
258 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700259 * Notifies the {@link Conference} when it should be moved from a held to active state.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700260 */
261 public void onUnhold() {}
262
263 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700264 * Notifies the {@link Conference} when the child calls should be merged. Only invoked if the
265 * conference contains the capability {@link Connection#CAPABILITY_MERGE_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700266 */
267 public void onMerge() {}
268
269 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700270 * Notifies the {@link Conference} when the child calls should be swapped. Only invoked if the
271 * conference contains the capability {@link Connection#CAPABILITY_SWAP_CONFERENCE}.
Santos Cordona4868042014-09-04 17:39:22 -0700272 */
273 public void onSwap() {}
274
275 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700276 * Notifies the {@link Conference} of a request to play a DTMF tone.
Yorke Leea0d3ca92014-09-15 19:18:13 -0700277 *
278 * @param c A DTMF character.
279 */
280 public void onPlayDtmfTone(char c) {}
281
282 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700283 * Notifies the {@link Conference} of a request to stop any currently playing DTMF tones.
Yorke Leea0d3ca92014-09-15 19:18:13 -0700284 */
285 public void onStopDtmfTone() {}
286
287 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700288 * Notifies the {@link Conference} that the {@link #getAudioState()} property has a new value.
Yorke Leea0d3ca92014-09-15 19:18:13 -0700289 *
290 * @param state The new call audio state.
Yorke Lee4af59352015-05-13 14:14:54 -0700291 * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead.
292 * @hide
Yorke Leea0d3ca92014-09-15 19:18:13 -0700293 */
Yorke Lee4af59352015-05-13 14:14:54 -0700294 @SystemApi
295 @Deprecated
Yorke Leea0d3ca92014-09-15 19:18:13 -0700296 public void onAudioStateChanged(AudioState state) {}
297
298 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700299 * Notifies the {@link Conference} that the {@link #getCallAudioState()} property has a new
300 * value.
Yorke Lee4af59352015-05-13 14:14:54 -0700301 *
302 * @param state The new call audio state.
303 */
304 public void onCallAudioStateChanged(CallAudioState state) {}
305
306 /**
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700307 * Notifies the {@link Conference} that a {@link Connection} has been added to it.
Andrew Lee46f7f5d2014-11-06 17:00:25 -0800308 *
309 * @param connection The newly added connection.
310 */
311 public void onConnectionAdded(Connection connection) {}
312
313 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -0700314 * Sets state to be on hold.
315 */
316 public final void setOnHold() {
317 setState(Connection.STATE_HOLDING);
318 }
319
320 /**
Tyler Gunnd46595a2015-06-01 14:29:11 -0700321 * Sets state to be dialing.
322 */
323 public final void setDialing() {
324 setState(Connection.STATE_DIALING);
325 }
326
327 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -0700328 * Sets state to be active.
329 */
330 public final void setActive() {
331 setState(Connection.STATE_ACTIVE);
332 }
333
334 /**
335 * Sets state to disconnected.
336 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700337 * @param disconnectCause The reason for the disconnection, as described by
338 * {@link android.telecom.DisconnectCause}.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700339 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700340 public final void setDisconnected(DisconnectCause disconnectCause) {
341 mDisconnectCause = disconnectCause;;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700342 setState(Connection.STATE_DISCONNECTED);
343 for (Listener l : mListeners) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700344 l.onDisconnected(this, mDisconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700345 }
346 }
347
348 /**
mike dooley1cf14ac2014-11-04 10:59:53 -0800349 * @return The {@link DisconnectCause} for this connection.
350 */
351 public final DisconnectCause getDisconnectCause() {
352 return mDisconnectCause;
353 }
354
355 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800356 * Sets the capabilities of a conference. See {@code CAPABILITY_*} constants of class
357 * {@link Connection} for valid values.
Nancy Chen56fc25d2014-09-09 12:24:51 -0700358 *
Tyler Gunn720c6642016-03-22 09:02:47 -0700359 * @param connectionCapabilities A bitmask of the {@code Capabilities} of the conference call.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700360 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800361 public final void setConnectionCapabilities(int connectionCapabilities) {
362 if (connectionCapabilities != mConnectionCapabilities) {
363 mConnectionCapabilities = connectionCapabilities;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700364
365 for (Listener l : mListeners) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800366 l.onConnectionCapabilitiesChanged(this, mConnectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700367 }
368 }
369 }
370
371 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700372 * Sets the properties of a conference. See {@code PROPERTY_*} constants of class
373 * {@link Connection} for valid values.
374 *
375 * @param connectionProperties A bitmask of the {@code Properties} of the conference call.
376 */
377 public final void setConnectionProperties(int connectionProperties) {
378 if (connectionProperties != mConnectionProperties) {
379 mConnectionProperties = connectionProperties;
380
381 for (Listener l : mListeners) {
382 l.onConnectionPropertiesChanged(this, mConnectionProperties);
383 }
384 }
385 }
386
387 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -0700388 * Adds the specified connection as a child of this conference.
389 *
390 * @param connection The connection to add.
391 * @return True if the connection was successfully added.
392 */
Santos Cordona4868042014-09-04 17:39:22 -0700393 public final boolean addConnection(Connection connection) {
Rekha Kumar07366812015-03-24 16:42:31 -0700394 Log.d(this, "Connection=%s, connection=", connection);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700395 if (connection != null && !mChildConnections.contains(connection)) {
396 if (connection.setConference(this)) {
397 mChildConnections.add(connection);
Andrew Lee46f7f5d2014-11-06 17:00:25 -0800398 onConnectionAdded(connection);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700399 for (Listener l : mListeners) {
400 l.onConnectionAdded(this, connection);
401 }
402 return true;
403 }
404 }
405 return false;
406 }
407
408 /**
409 * Removes the specified connection as a child of this conference.
410 *
411 * @param connection The connection to remove.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700412 */
Santos Cordona4868042014-09-04 17:39:22 -0700413 public final void removeConnection(Connection connection) {
Santos Cordon0159ac02014-08-21 14:28:11 -0700414 Log.d(this, "removing %s from %s", connection, mChildConnections);
Santos Cordon823fd3c2014-08-07 18:35:18 -0700415 if (connection != null && mChildConnections.remove(connection)) {
416 connection.resetConference();
417 for (Listener l : mListeners) {
418 l.onConnectionRemoved(this, connection);
419 }
420 }
421 }
422
423 /**
Ihab Awad50e35062014-09-30 09:17:03 -0700424 * Sets the connections with which this connection can be conferenced.
425 *
426 * @param conferenceableConnections The set of connections this connection can conference with.
427 */
428 public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
429 clearConferenceableList();
430 for (Connection c : conferenceableConnections) {
431 // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
432 // small amount of items here.
433 if (!mConferenceableConnections.contains(c)) {
434 c.addConnectionListener(mConnectionDeathListener);
435 mConferenceableConnections.add(c);
436 }
437 }
438 fireOnConferenceableConnectionsChanged();
439 }
440
Rekha Kumar07366812015-03-24 16:42:31 -0700441 /**
442 * Set the video state for the conference.
Yorke Lee32f24732015-05-12 16:18:03 -0700443 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
444 * {@link VideoProfile#STATE_BIDIRECTIONAL},
445 * {@link VideoProfile#STATE_TX_ENABLED},
446 * {@link VideoProfile#STATE_RX_ENABLED}.
Rekha Kumar07366812015-03-24 16:42:31 -0700447 *
448 * @param videoState The new video state.
Rekha Kumar07366812015-03-24 16:42:31 -0700449 */
450 public final void setVideoState(Connection c, int videoState) {
451 Log.d(this, "setVideoState Conference: %s Connection: %s VideoState: %s",
452 this, c, videoState);
453 for (Listener l : mListeners) {
454 l.onVideoStateChanged(this, videoState);
455 }
456 }
457
458 /**
459 * Sets the video connection provider.
460 *
461 * @param videoProvider The video provider.
Rekha Kumar07366812015-03-24 16:42:31 -0700462 */
463 public final void setVideoProvider(Connection c, Connection.VideoProvider videoProvider) {
464 Log.d(this, "setVideoProvider Conference: %s Connection: %s VideoState: %s",
465 this, c, videoProvider);
466 for (Listener l : mListeners) {
467 l.onVideoProviderChanged(this, videoProvider);
468 }
469 }
470
Ihab Awad50e35062014-09-30 09:17:03 -0700471 private final void fireOnConferenceableConnectionsChanged() {
472 for (Listener l : mListeners) {
473 l.onConferenceableConnectionsChanged(this, getConferenceableConnections());
474 }
475 }
476
477 /**
478 * Returns the connections with which this connection can be conferenced.
479 */
480 public final List<Connection> getConferenceableConnections() {
481 return mUnmodifiableConferenceableConnections;
482 }
483
484 /**
Nancy Chenea38cca2014-09-05 16:38:49 -0700485 * Tears down the conference object and any of its current connections.
Santos Cordon823fd3c2014-08-07 18:35:18 -0700486 */
Santos Cordona4868042014-09-04 17:39:22 -0700487 public final void destroy() {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700488 Log.d(this, "destroying conference : %s", this);
489 // Tear down the children.
Santos Cordon0159ac02014-08-21 14:28:11 -0700490 for (Connection connection : mChildConnections) {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700491 Log.d(this, "removing connection %s", connection);
492 removeConnection(connection);
493 }
494
495 // If not yet disconnected, set the conference call as disconnected first.
496 if (mState != Connection.STATE_DISCONNECTED) {
497 Log.d(this, "setting to disconnected");
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700498 setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
Santos Cordon823fd3c2014-08-07 18:35:18 -0700499 }
500
501 // ...and notify.
502 for (Listener l : mListeners) {
503 l.onDestroyed(this);
504 }
505 }
506
507 /**
508 * Add a listener to be notified of a state change.
509 *
510 * @param listener The new listener.
511 * @return This conference.
512 * @hide
513 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700514 final Conference addListener(Listener listener) {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700515 mListeners.add(listener);
516 return this;
517 }
518
519 /**
520 * Removes the specified listener.
521 *
522 * @param listener The listener to remove.
523 * @return This conference.
524 * @hide
525 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700526 final Conference removeListener(Listener listener) {
Santos Cordon823fd3c2014-08-07 18:35:18 -0700527 mListeners.remove(listener);
528 return this;
529 }
530
Yorke Leea0d3ca92014-09-15 19:18:13 -0700531 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700532 * Retrieves the primary connection associated with the conference. The primary connection is
533 * the connection from which the conference will retrieve its current state.
534 *
535 * @return The primary connection.
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700536 * @hide
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700537 */
Tyler Gunn6c14a6992019-02-04 15:12:06 -0800538 @TestApi
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700539 @SystemApi
Santos Cordon4055d642015-05-12 14:19:24 -0700540 public Connection getPrimaryConnection() {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700541 if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) {
542 return null;
543 }
544 return mUnmodifiableChildConnections.get(0);
545 }
546
547 /**
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700548 * @hide
549 * @deprecated Use {@link #setConnectionTime}.
Tyler Gunncd5d33c2015-01-12 09:02:01 -0800550 */
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700551 @Deprecated
552 @SystemApi
553 public final void setConnectTimeMillis(long connectTimeMillis) {
554 setConnectionTime(connectTimeMillis);
Tyler Gunncd5d33c2015-01-12 09:02:01 -0800555 }
556
557 /**
Tyler Gunn17541392018-02-01 08:58:38 -0800558 * Sets the connection start time of the {@code Conference}. This is used in the call log to
559 * indicate the date and time when the conference took place.
560 * <p>
561 * Should be specified in wall-clock time returned by {@link System#currentTimeMillis()}.
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700562 * <p>
563 * When setting the connection time, you should always set the connection elapsed time via
Tyler Gunn17541392018-02-01 08:58:38 -0800564 * {@link #setConnectionStartElapsedRealTime(long)} to ensure the duration is reflected.
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700565 *
Tyler Gunn17541392018-02-01 08:58:38 -0800566 * @param connectionTimeMillis The connection time, in milliseconds, as returned by
567 * {@link System#currentTimeMillis()}.
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700568 */
569 public final void setConnectionTime(long connectionTimeMillis) {
570 mConnectTimeMillis = connectionTimeMillis;
571 }
572
573 /**
Tyler Gunn17541392018-02-01 08:58:38 -0800574 * Sets the start time of the {@link Conference} which is the basis for the determining the
575 * duration of the {@link Conference}.
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700576 * <p>
Tyler Gunn17541392018-02-01 08:58:38 -0800577 * You should use a value returned by {@link SystemClock#elapsedRealtime()} to ensure that time
578 * zone changes do not impact the conference duration.
579 * <p>
580 * When setting this, you should also set the connection time via
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700581 * {@link #setConnectionTime(long)}.
582 *
Tyler Gunn17541392018-02-01 08:58:38 -0800583 * @param connectionStartElapsedRealTime The connection time, as measured by
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700584 * {@link SystemClock#elapsedRealtime()}.
585 */
Tyler Gunn17541392018-02-01 08:58:38 -0800586 public final void setConnectionStartElapsedRealTime(long connectionStartElapsedRealTime) {
587 mConnectionStartElapsedRealTime = connectionStartElapsedRealTime;
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700588 }
589
590 /**
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700591 * @hide
592 * @deprecated Use {@link #getConnectionTime}.
593 */
594 @Deprecated
595 @SystemApi
596 public final long getConnectTimeMillis() {
597 return getConnectionTime();
598 }
599
600 /**
601 * Retrieves the connection start time of the {@code Conference}, if specified. A value of
Tyler Gunncd5d33c2015-01-12 09:02:01 -0800602 * {@link #CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the start time
603 * of the conference.
604 *
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700605 * @return The time at which the {@code Conference} was connected.
Tyler Gunncd5d33c2015-01-12 09:02:01 -0800606 */
Santos Cordon5d2e4f22015-05-12 12:32:51 -0700607 public final long getConnectionTime() {
Tyler Gunncd5d33c2015-01-12 09:02:01 -0800608 return mConnectTimeMillis;
609 }
610
611 /**
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700612 * Retrieves the connection start time of the {@link Conference}, if specified. A value of
613 * {@link #CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the start time
614 * of the conference.
Tyler Gunn5567d742019-10-31 13:04:37 -0700615 * <p>
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700616 * This is based on the value of {@link SystemClock#elapsedRealtime()} to ensure that it is not
617 * impacted by wall clock changes (user initiated, network initiated, time zone change, etc).
Tyler Gunn5567d742019-10-31 13:04:37 -0700618 * <p>
619 * Note: This is only exposed for use by the Telephony framework which needs it to copy
620 * conference start times among conference participants. It is exposed as a system API since it
621 * has no general use other than to the Telephony framework.
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700622 *
623 * @return The elapsed time at which the {@link Conference} was connected.
624 * @hide
625 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700626 @SystemApi
627 @TestApi
Tyler Gunn17541392018-02-01 08:58:38 -0800628 public final long getConnectionStartElapsedRealTime() {
629 return mConnectionStartElapsedRealTime;
Tyler Gunn3fa819c2017-08-04 09:27:26 -0700630 }
631
632 /**
Yorke Leea0d3ca92014-09-15 19:18:13 -0700633 * Inform this Conference that the state of its audio output has been changed externally.
634 *
635 * @param state The new audio state.
636 * @hide
637 */
Yorke Lee4af59352015-05-13 14:14:54 -0700638 final void setCallAudioState(CallAudioState state) {
639 Log.d(this, "setCallAudioState %s", state);
640 mCallAudioState = state;
641 onAudioStateChanged(getAudioState());
642 onCallAudioStateChanged(state);
Yorke Leea0d3ca92014-09-15 19:18:13 -0700643 }
644
Santos Cordon823fd3c2014-08-07 18:35:18 -0700645 private void setState(int newState) {
646 if (newState != Connection.STATE_ACTIVE &&
647 newState != Connection.STATE_HOLDING &&
648 newState != Connection.STATE_DISCONNECTED) {
649 Log.w(this, "Unsupported state transition for Conference call.",
650 Connection.stateToString(newState));
651 return;
652 }
653
654 if (mState != newState) {
655 int oldState = mState;
656 mState = newState;
657 for (Listener l : mListeners) {
658 l.onStateChanged(this, oldState, newState);
659 }
660 }
661 }
Ihab Awad50e35062014-09-30 09:17:03 -0700662
663 private final void clearConferenceableList() {
664 for (Connection c : mConferenceableConnections) {
665 c.removeConnectionListener(mConnectionDeathListener);
666 }
667 mConferenceableConnections.clear();
668 }
Rekha Kumar07366812015-03-24 16:42:31 -0700669
670 @Override
671 public String toString() {
672 return String.format(Locale.US,
673 "[State: %s,Capabilites: %s, VideoState: %s, VideoProvider: %s, ThisObject %s]",
674 Connection.stateToString(mState),
675 Call.Details.capabilitiesToString(mConnectionCapabilities),
676 getVideoState(),
677 getVideoProvider(),
678 super.toString());
679 }
Andrew Lee0f51da32015-04-16 13:11:55 -0700680
Andrew Leeedc625f2015-04-14 13:38:12 -0700681 /**
682 * Sets the label and icon status to display in the InCall UI.
683 *
684 * @param statusHints The status label and icon to set.
685 */
686 public final void setStatusHints(StatusHints statusHints) {
687 mStatusHints = statusHints;
688 for (Listener l : mListeners) {
689 l.onStatusHintsChanged(this, statusHints);
690 }
691 }
692
693 /**
694 * @return The status hints for this conference.
695 */
696 public final StatusHints getStatusHints() {
697 return mStatusHints;
698 }
Santos Cordon6b7f9552015-05-27 17:21:45 -0700699
700 /**
Tyler Gunndee56a82016-03-23 16:06:34 -0700701 * Replaces all the extras associated with this {@code Conference}.
702 * <p>
703 * New or existing keys are replaced in the {@code Conference} extras. Keys which are no longer
704 * in the new extras, but were present the last time {@code setExtras} was called are removed.
705 * <p>
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700706 * Alternatively you may use the {@link #putExtras(Bundle)}, and
707 * {@link #removeExtras(String...)} methods to modify the extras.
708 * <p>
Tyler Gunndee56a82016-03-23 16:06:34 -0700709 * No assumptions should be made as to how an In-Call UI or service will handle these extras.
Tyler Gunn9c0eb0b2016-06-29 11:23:25 -0700710 * Keys should be fully qualified (e.g., com.example.extras.MY_EXTRA) to avoid conflicts.
Santos Cordon6b7f9552015-05-27 17:21:45 -0700711 *
Tyler Gunndee56a82016-03-23 16:06:34 -0700712 * @param extras The extras associated with this {@code Conference}.
Santos Cordon6b7f9552015-05-27 17:21:45 -0700713 */
714 public final void setExtras(@Nullable Bundle extras) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700715 // Keeping putExtras and removeExtras in the same lock so that this operation happens as a
716 // block instead of letting other threads put/remove while this method is running.
717 synchronized (mExtrasLock) {
718 // Add/replace any new or changed extras values.
719 putExtras(extras);
720 // If we have used "setExtras" in the past, compare the key set from the last invocation
721 // to the current one and remove any keys that went away.
722 if (mPreviousExtraKeys != null) {
723 List<String> toRemove = new ArrayList<String>();
724 for (String oldKey : mPreviousExtraKeys) {
725 if (extras == null || !extras.containsKey(oldKey)) {
726 toRemove.add(oldKey);
727 }
728 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700729
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700730 if (!toRemove.isEmpty()) {
731 removeExtras(toRemove);
Tyler Gunndee56a82016-03-23 16:06:34 -0700732 }
733 }
734
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700735 // Track the keys the last time set called setExtras. This way, the next time setExtras
736 // is called we can see if the caller has removed any extras values.
737 if (mPreviousExtraKeys == null) {
738 mPreviousExtraKeys = new ArraySet<String>();
Tyler Gunndee56a82016-03-23 16:06:34 -0700739 }
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700740 mPreviousExtraKeys.clear();
741 if (extras != null) {
742 mPreviousExtraKeys.addAll(extras.keySet());
743 }
Tyler Gunna8fb8ab2016-03-29 10:24:22 -0700744 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700745 }
746
747 /**
748 * Adds some extras to this {@link Conference}. Existing keys are replaced and new ones are
749 * added.
750 * <p>
751 * No assumptions should be made as to how an In-Call UI or service will handle these extras.
752 * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
753 *
754 * @param extras The extras to add.
755 */
756 public final void putExtras(@NonNull Bundle extras) {
757 if (extras == null) {
758 return;
759 }
760
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700761 // Creating a Bundle clone so we don't have to synchronize on mExtrasLock while calling
762 // onExtrasChanged.
763 Bundle listenersBundle;
764 synchronized (mExtrasLock) {
765 if (mExtras == null) {
766 mExtras = new Bundle();
767 }
768 mExtras.putAll(extras);
769 listenersBundle = new Bundle(mExtras);
Tyler Gunndee56a82016-03-23 16:06:34 -0700770 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700771
Santos Cordon6b7f9552015-05-27 17:21:45 -0700772 for (Listener l : mListeners) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700773 l.onExtrasChanged(this, new Bundle(listenersBundle));
Santos Cordon6b7f9552015-05-27 17:21:45 -0700774 }
775 }
776
777 /**
Tyler Gunndee56a82016-03-23 16:06:34 -0700778 * Adds a boolean extra to this {@link Conference}.
779 *
780 * @param key The extra key.
781 * @param value The value.
782 * @hide
783 */
784 public final void putExtra(String key, boolean value) {
785 Bundle newExtras = new Bundle();
786 newExtras.putBoolean(key, value);
787 putExtras(newExtras);
788 }
789
790 /**
791 * Adds an integer extra to this {@link Conference}.
792 *
793 * @param key The extra key.
794 * @param value The value.
795 * @hide
796 */
797 public final void putExtra(String key, int value) {
798 Bundle newExtras = new Bundle();
799 newExtras.putInt(key, value);
800 putExtras(newExtras);
801 }
802
803 /**
804 * Adds a string extra to this {@link Conference}.
805 *
806 * @param key The extra key.
807 * @param value The value.
808 * @hide
809 */
810 public final void putExtra(String key, String value) {
811 Bundle newExtras = new Bundle();
812 newExtras.putString(key, value);
813 putExtras(newExtras);
814 }
815
816 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -0700817 * Removes extras from this {@link Conference}.
Tyler Gunndee56a82016-03-23 16:06:34 -0700818 *
Tyler Gunn071be6f2016-05-10 14:52:33 -0700819 * @param keys The keys of the extras to remove.
Tyler Gunndee56a82016-03-23 16:06:34 -0700820 */
821 public final void removeExtras(List<String> keys) {
822 if (keys == null || keys.isEmpty()) {
823 return;
824 }
825
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700826 synchronized (mExtrasLock) {
827 if (mExtras != null) {
828 for (String key : keys) {
829 mExtras.remove(key);
830 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700831 }
832 }
833
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700834 List<String> unmodifiableKeys = Collections.unmodifiableList(keys);
Tyler Gunndee56a82016-03-23 16:06:34 -0700835 for (Listener l : mListeners) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -0700836 l.onExtrasRemoved(this, unmodifiableKeys);
Tyler Gunndee56a82016-03-23 16:06:34 -0700837 }
838 }
839
840 /**
Tyler Gunn071be6f2016-05-10 14:52:33 -0700841 * Removes extras from this {@link Conference}.
842 *
843 * @param keys The keys of the extras to remove.
844 */
845 public final void removeExtras(String ... keys) {
846 removeExtras(Arrays.asList(keys));
847 }
848
849 /**
Tyler Gunndee56a82016-03-23 16:06:34 -0700850 * Returns the extras associated with this conference.
Tyler Gunn2cbe2b52016-05-04 15:48:10 +0000851 * <p>
852 * Extras should be updated using {@link #putExtras(Bundle)} and {@link #removeExtras(List)}.
853 * <p>
854 * Telecom or an {@link InCallService} can also update the extras via
855 * {@link android.telecom.Call#putExtras(Bundle)}, and
856 * {@link Call#removeExtras(List)}.
857 * <p>
858 * The conference is notified of changes to the extras made by Telecom or an
859 * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
Tyler Gunndee56a82016-03-23 16:06:34 -0700860 *
861 * @return The extras associated with this connection.
Santos Cordon6b7f9552015-05-27 17:21:45 -0700862 */
863 public final Bundle getExtras() {
864 return mExtras;
865 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700866
867 /**
868 * Notifies this {@link Conference} of a change to the extras made outside the
869 * {@link ConnectionService}.
870 * <p>
871 * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
872 * {@link android.telecom.Call#putExtras(Bundle)}, and
873 * {@link Call#removeExtras(List)}.
874 *
875 * @param extras The new extras bundle.
876 */
877 public void onExtrasChanged(Bundle extras) {}
878
879 /**
Tyler Gunn68a73a42018-10-03 15:38:57 -0700880 * Set whether Telecom should treat this {@link Conference} as a conference call or if it
881 * should treat it as a single-party call.
882 * This method is used as part of a workaround regarding IMS conference calls and user
883 * expectation. In IMS, once a conference is formed, the UE is connected to an IMS conference
884 * server. If all participants of the conference drop out of the conference except for one, the
885 * UE is still connected to the IMS conference server. At this point, the user logically
886 * assumes they're no longer in a conference, yet the underlying network actually is.
887 * To help provide a better user experiece, IMS conference calls can pretend to actually be a
888 * single-party call when the participant count drops to 1. Although the dialer/phone app
889 * could perform this trickery, it makes sense to do this in Telephony since a fix there will
890 * ensure that bluetooth head units, auto and wearable apps all behave consistently.
Tyler Gunn5567d742019-10-31 13:04:37 -0700891 * <p>
892 * This API is intended for use by the platform Telephony stack only.
Tyler Gunn68a73a42018-10-03 15:38:57 -0700893 *
894 * @param isConference {@code true} if this {@link Conference} should be treated like a
895 * conference call, {@code false} if it should be treated like a single-party call.
896 * @hide
897 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700898 @SystemApi
899 @TestApi
Tyler Gunn68a73a42018-10-03 15:38:57 -0700900 public void setConferenceState(boolean isConference) {
901 for (Listener l : mListeners) {
902 l.onConferenceStateChanged(this, isConference);
903 }
904 }
905
906 /**
907 * Sets the address of this {@link Conference}. Used when {@link #setConferenceState(boolean)}
908 * is called to mark a conference temporarily as NOT a conference.
Tyler Gunn5567d742019-10-31 13:04:37 -0700909 * <p>
910 * Note: This is a Telephony-specific implementation detail related to IMS conferences. It is
911 * not intended for use outside of the Telephony stack.
Tyler Gunn68a73a42018-10-03 15:38:57 -0700912 *
913 * @param address The new address.
914 * @param presentation The presentation requirements for the address.
915 * See {@link TelecomManager} for valid values.
916 * @hide
917 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700918 @SystemApi
919 @TestApi
920 public final void setAddress(@NonNull Uri address,
921 @TelecomManager.Presentation int presentation) {
Tyler Gunn68a73a42018-10-03 15:38:57 -0700922 Log.d(this, "setAddress %s", address);
Tyler Gunnac60f952019-05-31 07:23:16 -0700923 mAddress = address;
924 mAddressPresentation = presentation;
Tyler Gunn68a73a42018-10-03 15:38:57 -0700925 for (Listener l : mListeners) {
926 l.onAddressChanged(this, address, presentation);
927 }
928 }
929
930 /**
Tyler Gunnac60f952019-05-31 07:23:16 -0700931 * Returns the "address" associated with the conference. This is applicable in two cases:
932 * <ol>
933 * <li>When {@link #setConferenceState(boolean)} is used to mark a conference as
934 * temporarily "not a conference"; we need to present the correct address in the in-call
935 * UI.</li>
936 * <li>When the conference is not hosted on the current device, we need to know the address
937 * information for the purpose of showing the original address to the user, as well as for
938 * logging to the call log.</li>
939 * </ol>
940 * @return The address of the conference, or {@code null} if not applicable.
941 * @hide
942 */
943 public final Uri getAddress() {
944 return mAddress;
945 }
946
947 /**
948 * Returns the address presentation associated with the conference.
949 * <p>
950 * This is applicable in two cases:
951 * <ol>
952 * <li>When {@link #setConferenceState(boolean)} is used to mark a conference as
953 * temporarily "not a conference"; we need to present the correct address in the in-call
954 * UI.</li>
955 * <li>When the conference is not hosted on the current device, we need to know the address
956 * information for the purpose of showing the original address to the user, as well as for
957 * logging to the call log.</li>
958 * </ol>
959 * @return The address of the conference, or {@code null} if not applicable.
960 * @hide
961 */
962 public final int getAddressPresentation() {
963 return mAddressPresentation;
964 }
965
966 /**
967 * @return The caller display name (CNAP).
968 * @hide
969 */
970 public final String getCallerDisplayName() {
971 return mCallerDisplayName;
972 }
973
974 /**
975 * @return The presentation requirements for the handle.
976 * See {@link TelecomManager} for valid values.
977 * @hide
978 */
979 public final int getCallerDisplayNamePresentation() {
980 return mCallerDisplayNamePresentation;
981 }
982
983 /**
Tyler Gunn68a73a42018-10-03 15:38:57 -0700984 * Sets the caller display name (CNAP) of this {@link Conference}. Used when
985 * {@link #setConferenceState(boolean)} is called to mark a conference temporarily as NOT a
986 * conference.
Tyler Gunn5567d742019-10-31 13:04:37 -0700987 * <p>
988 * Note: This is a Telephony-specific implementation detail related to IMS conferences. It is
989 * not intended for use outside of the Telephony stack.
Tyler Gunn68a73a42018-10-03 15:38:57 -0700990 *
991 * @param callerDisplayName The new display name.
992 * @param presentation The presentation requirements for the handle.
993 * See {@link TelecomManager} for valid values.
994 * @hide
995 */
Tyler Gunn5567d742019-10-31 13:04:37 -0700996 @SystemApi
997 @TestApi
998 public final void setCallerDisplayName(@NonNull String callerDisplayName,
999 @TelecomManager.Presentation int presentation) {
Tyler Gunn68a73a42018-10-03 15:38:57 -07001000 Log.d(this, "setCallerDisplayName %s", callerDisplayName);
Tyler Gunnac60f952019-05-31 07:23:16 -07001001 mCallerDisplayName = callerDisplayName;
1002 mCallerDisplayNamePresentation = presentation;
Tyler Gunn68a73a42018-10-03 15:38:57 -07001003 for (Listener l : mListeners) {
1004 l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
1005 }
1006 }
1007
1008 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07001009 * Handles a change to extras received from Telecom.
1010 *
1011 * @param extras The new extras.
1012 * @hide
1013 */
1014 final void handleExtrasChanged(Bundle extras) {
Brad Ebinger4fa6a012016-06-14 17:04:01 -07001015 Bundle b = null;
1016 synchronized (mExtrasLock) {
1017 mExtras = extras;
1018 if (mExtras != null) {
1019 b = new Bundle(mExtras);
1020 }
1021 }
1022 onExtrasChanged(b);
Tyler Gunndee56a82016-03-23 16:06:34 -07001023 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001024
1025 /**
Tyler Gunn5567d742019-10-31 13:04:37 -07001026 * Sends an event associated with this {@code Conference} with associated event extras to the
1027 * {@link InCallService} (note: this is identical in concept to
1028 * {@link Connection#sendConnectionEvent(String, Bundle)}).
1029 * @see Connection#sendConnectionEvent(String, Bundle)
1030 *
1031 * @param event The connection event.
1032 * @param extras Optional bundle containing extra information associated with the event.
Hall Liuc9bc1c62019-04-16 14:00:55 -07001033 */
Tyler Gunn5567d742019-10-31 13:04:37 -07001034 public void sendConferenceEvent(@NonNull String event, @Nullable Bundle extras) {
Hall Liuc9bc1c62019-04-16 14:00:55 -07001035 for (Listener l : mListeners) {
1036 l.onConnectionEvent(this, event, extras);
1037 }
1038 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001039}