blob: 502b7c01b0c0dc3b2e5b88e9843e8223bd8defa7 [file] [log] [blame]
Ihab Awadb8e85c72014-08-23 20:34:57 -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 Awadb8e85c72014-08-23 20:34:57 -070018
Tyler Gunnef9f6f92014-09-12 22:16:17 -070019import com.android.internal.telecom.IConnectionService;
Ihab Awadb8e85c72014-08-23 20:34:57 -070020
Santos Cordon6b7f9552015-05-27 17:21:45 -070021import android.annotation.Nullable;
Yorke Lee4af59352015-05-13 14:14:54 -070022import android.annotation.SystemApi;
Santos Cordon6b7f9552015-05-27 17:21:45 -070023import android.os.Bundle;
Andrew Lee011728f2015-04-23 15:47:06 -070024import android.os.Handler;
Ihab Awadb8e85c72014-08-23 20:34:57 -070025import android.os.RemoteException;
Ihab Awadb8e85c72014-08-23 20:34:57 -070026
Ihab Awad50e35062014-09-30 09:17:03 -070027import java.util.ArrayList;
Ihab Awadb8e85c72014-08-23 20:34:57 -070028import java.util.Collections;
29import java.util.List;
30import java.util.Set;
31import java.util.concurrent.CopyOnWriteArrayList;
32import java.util.concurrent.CopyOnWriteArraySet;
33
34/**
Santos Cordon895d4b82015-06-25 16:41:48 -070035 * A conference provided to a {@link ConnectionService} by another {@code ConnectionService} through
36 * {@link ConnectionService#conferenceRemoteConnections}. Once created, a {@code RemoteConference}
37 * can be used to control the conference call or monitor changes through
38 * {@link RemoteConnection.Callback}.
Santos Cordonb804f8d2015-05-12 12:09:47 -070039 *
40 * @see ConnectionService#onRemoteConferenceAdded
Ihab Awadb8e85c72014-08-23 20:34:57 -070041 */
42public final class RemoteConference {
43
Santos Cordon895d4b82015-06-25 16:41:48 -070044 /**
45 * Callback base class for {@link RemoteConference}.
46 */
Nancy Chen1d834f52014-09-05 11:03:21 -070047 public abstract static class Callback {
Santos Cordon895d4b82015-06-25 16:41:48 -070048 /**
49 * Invoked when the state of this {@code RemoteConferece} has changed. See
50 * {@link #getState()}.
51 *
52 * @param conference The {@code RemoteConference} invoking this method.
53 * @param oldState The previous state of the {@code RemoteConference}.
54 * @param newState The new state of the {@code RemoteConference}.
55 */
Ihab Awadb8e85c72014-08-23 20:34:57 -070056 public void onStateChanged(RemoteConference conference, int oldState, int newState) {}
Santos Cordon895d4b82015-06-25 16:41:48 -070057
58 /**
59 * Invoked when this {@code RemoteConference} is disconnected.
60 *
61 * @param conference The {@code RemoteConference} invoking this method.
62 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
63 * conference.
64 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -070065 public void onDisconnected(RemoteConference conference, DisconnectCause disconnectCause) {}
Santos Cordon895d4b82015-06-25 16:41:48 -070066
67 /**
68 * Invoked when a {@link RemoteConnection} is added to the conference call.
69 *
70 * @param conference The {@code RemoteConference} invoking this method.
71 * @param connection The {@link RemoteConnection} being added.
72 */
Ihab Awadb8e85c72014-08-23 20:34:57 -070073 public void onConnectionAdded(RemoteConference conference, RemoteConnection connection) {}
Santos Cordon895d4b82015-06-25 16:41:48 -070074
75 /**
76 * Invoked when a {@link RemoteConnection} is removed from the conference call.
77 *
78 * @param conference The {@code RemoteConference} invoking this method.
79 * @param connection The {@link RemoteConnection} being removed.
80 */
Ihab Awadb8e85c72014-08-23 20:34:57 -070081 public void onConnectionRemoved(RemoteConference conference, RemoteConnection connection) {}
Santos Cordon895d4b82015-06-25 16:41:48 -070082
83 /**
84 * Indicates that the call capabilities of this {@code RemoteConference} have changed.
85 * See {@link #getConnectionCapabilities()}.
86 *
87 * @param conference The {@code RemoteConference} invoking this method.
88 * @param connectionCapabilities The new capabilities of the {@code RemoteConference}.
89 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080090 public void onConnectionCapabilitiesChanged(
91 RemoteConference conference,
92 int connectionCapabilities) {}
Santos Cordon895d4b82015-06-25 16:41:48 -070093
94 /**
Tyler Gunn720c6642016-03-22 09:02:47 -070095 * Indicates that the call properties of this {@code RemoteConference} have changed.
96 * See {@link #getConnectionProperties()}.
97 *
98 * @param conference The {@code RemoteConference} invoking this method.
99 * @param connectionProperties The new properties of the {@code RemoteConference}.
100 */
101 public void onConnectionPropertiesChanged(
102 RemoteConference conference,
103 int connectionProperties) {}
104
105
106 /**
Santos Cordon895d4b82015-06-25 16:41:48 -0700107 * Invoked when the set of {@link RemoteConnection}s which can be added to this conference
108 * call have changed.
109 *
110 * @param conference The {@code RemoteConference} invoking this method.
111 * @param conferenceableConnections The list of conferenceable {@link RemoteConnection}s.
112 */
Ihab Awad50e35062014-09-30 09:17:03 -0700113 public void onConferenceableConnectionsChanged(
114 RemoteConference conference,
115 List<RemoteConnection> conferenceableConnections) {}
Santos Cordon895d4b82015-06-25 16:41:48 -0700116
117 /**
118 * Indicates that this {@code RemoteConference} has been destroyed. No further requests
119 * should be made to the {@code RemoteConference}, and references to it should be cleared.
120 *
121 * @param conference The {@code RemoteConference} invoking this method.
122 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700123 public void onDestroyed(RemoteConference conference) {}
Santos Cordon895d4b82015-06-25 16:41:48 -0700124
125 /**
126 * Handles changes to the {@code RemoteConference} extras.
127 *
128 * @param conference The {@code RemoteConference} invoking this method.
129 * @param extras The extras containing other information associated with the conference.
130 */
Santos Cordon6b7f9552015-05-27 17:21:45 -0700131 public void onExtrasChanged(RemoteConference conference, @Nullable Bundle extras) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700132 }
133
134 private final String mId;
135 private final IConnectionService mConnectionService;
136
Andrew Lee011728f2015-04-23 15:47:06 -0700137 private final Set<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArraySet<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700138 private final List<RemoteConnection> mChildConnections = new CopyOnWriteArrayList<>();
139 private final List<RemoteConnection> mUnmodifiableChildConnections =
140 Collections.unmodifiableList(mChildConnections);
Ihab Awad50e35062014-09-30 09:17:03 -0700141 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
142 private final List<RemoteConnection> mUnmodifiableConferenceableConnections =
143 Collections.unmodifiableList(mConferenceableConnections);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700144
145 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700146 private DisconnectCause mDisconnectCause;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800147 private int mConnectionCapabilities;
Tyler Gunn720c6642016-03-22 09:02:47 -0700148 private int mConnectionProperties;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700149 private Bundle mExtras;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700150
Santos Cordonb804f8d2015-05-12 12:09:47 -0700151 /** @hide */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700152 RemoteConference(String id, IConnectionService connectionService) {
153 mId = id;
154 mConnectionService = connectionService;
155 }
156
Santos Cordonb804f8d2015-05-12 12:09:47 -0700157 /** @hide */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700158 String getId() {
159 return mId;
160 }
161
Santos Cordonb804f8d2015-05-12 12:09:47 -0700162 /** @hide */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700163 void setDestroyed() {
164 for (RemoteConnection connection : mChildConnections) {
165 connection.setConference(null);
166 }
Andrew Lee011728f2015-04-23 15:47:06 -0700167 for (CallbackRecord<Callback> record : mCallbackRecords) {
168 final RemoteConference conference = this;
169 final Callback callback = record.getCallback();
170 record.getHandler().post(new Runnable() {
171 @Override
172 public void run() {
173 callback.onDestroyed(conference);
174 }
175 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700176 }
177 }
178
Santos Cordonb804f8d2015-05-12 12:09:47 -0700179 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700180 void setState(final int newState) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700181 if (newState != Connection.STATE_ACTIVE &&
182 newState != Connection.STATE_HOLDING &&
183 newState != Connection.STATE_DISCONNECTED) {
184 Log.w(this, "Unsupported state transition for Conference call.",
185 Connection.stateToString(newState));
186 return;
187 }
188
189 if (mState != newState) {
Andrew Lee011728f2015-04-23 15:47:06 -0700190 final int oldState = mState;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700191 mState = newState;
Andrew Lee011728f2015-04-23 15:47:06 -0700192 for (CallbackRecord<Callback> record : mCallbackRecords) {
193 final RemoteConference conference = this;
194 final Callback callback = record.getCallback();
195 record.getHandler().post(new Runnable() {
196 @Override
197 public void run() {
198 callback.onStateChanged(conference, oldState, newState);
199 }
200 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700201 }
202 }
203 }
204
Santos Cordonb804f8d2015-05-12 12:09:47 -0700205 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700206 void addConnection(final RemoteConnection connection) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700207 if (!mChildConnections.contains(connection)) {
208 mChildConnections.add(connection);
209 connection.setConference(this);
Andrew Lee011728f2015-04-23 15:47:06 -0700210 for (CallbackRecord<Callback> record : mCallbackRecords) {
211 final RemoteConference conference = this;
212 final Callback callback = record.getCallback();
213 record.getHandler().post(new Runnable() {
214 @Override
215 public void run() {
216 callback.onConnectionAdded(conference, connection);
217 }
218 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700219 }
220 }
221 }
222
Santos Cordonb804f8d2015-05-12 12:09:47 -0700223 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700224 void removeConnection(final RemoteConnection connection) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700225 if (mChildConnections.contains(connection)) {
226 mChildConnections.remove(connection);
227 connection.setConference(null);
Andrew Lee011728f2015-04-23 15:47:06 -0700228 for (CallbackRecord<Callback> record : mCallbackRecords) {
229 final RemoteConference conference = this;
230 final Callback callback = record.getCallback();
231 record.getHandler().post(new Runnable() {
232 @Override
233 public void run() {
234 callback.onConnectionRemoved(conference, connection);
235 }
236 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700237 }
238 }
239 }
240
Santos Cordonb804f8d2015-05-12 12:09:47 -0700241 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700242 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800243 if (mConnectionCapabilities != connectionCapabilities) {
244 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -0700245 for (CallbackRecord<Callback> record : mCallbackRecords) {
246 final RemoteConference conference = this;
247 final Callback callback = record.getCallback();
248 record.getHandler().post(new Runnable() {
249 @Override
250 public void run() {
251 callback.onConnectionCapabilitiesChanged(
252 conference, mConnectionCapabilities);
253 }
254 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700255 }
256 }
257 }
258
Ihab Awad50e35062014-09-30 09:17:03 -0700259 /** @hide */
Tyler Gunn720c6642016-03-22 09:02:47 -0700260 void setConnectionProperties(final int connectionProperties) {
261 if (mConnectionProperties != connectionProperties) {
262 mConnectionProperties = connectionProperties;
263 for (CallbackRecord<Callback> record : mCallbackRecords) {
264 final RemoteConference conference = this;
265 final Callback callback = record.getCallback();
266 record.getHandler().post(new Runnable() {
267 @Override
268 public void run() {
269 callback.onConnectionPropertiesChanged(
270 conference, mConnectionProperties);
271 }
272 });
273 }
274 }
275 }
276
277 /** @hide */
Ihab Awad50e35062014-09-30 09:17:03 -0700278 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
279 mConferenceableConnections.clear();
280 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -0700281 for (CallbackRecord<Callback> record : mCallbackRecords) {
282 final RemoteConference conference = this;
283 final Callback callback = record.getCallback();
284 record.getHandler().post(new Runnable() {
285 @Override
286 public void run() {
287 callback.onConferenceableConnectionsChanged(
288 conference, mUnmodifiableConferenceableConnections);
289 }
290 });
Ihab Awad50e35062014-09-30 09:17:03 -0700291 }
292 }
293
Santos Cordonb804f8d2015-05-12 12:09:47 -0700294 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700295 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700296 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700297 mDisconnectCause = disconnectCause;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700298 setState(Connection.STATE_DISCONNECTED);
Andrew Lee011728f2015-04-23 15:47:06 -0700299 for (CallbackRecord<Callback> record : mCallbackRecords) {
300 final RemoteConference conference = this;
301 final Callback callback = record.getCallback();
302 record.getHandler().post(new Runnable() {
303 @Override
304 public void run() {
305 callback.onDisconnected(conference, disconnectCause);
306 }
307 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700308 }
309 }
310 }
311
Santos Cordon6b7f9552015-05-27 17:21:45 -0700312 /** @hide */
Tyler Gunndee56a82016-03-23 16:06:34 -0700313 void putExtras(final Bundle extras) {
Tyler Gunn2282bb92016-10-17 15:48:19 -0700314 if (extras == null) {
315 return;
316 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700317 if (mExtras == null) {
318 mExtras = new Bundle();
319 }
320 mExtras.putAll(extras);
321
322 notifyExtrasChanged();
323 }
324
325 /** @hide */
326 void removeExtras(List<String> keys) {
327 if (mExtras == null || keys == null || keys.isEmpty()) {
328 return;
329 }
330 for (String key : keys) {
331 mExtras.remove(key);
332 }
333
334 notifyExtrasChanged();
335 }
336
337 private void notifyExtrasChanged() {
Santos Cordon6b7f9552015-05-27 17:21:45 -0700338 for (CallbackRecord<Callback> record : mCallbackRecords) {
339 final RemoteConference conference = this;
340 final Callback callback = record.getCallback();
341 record.getHandler().post(new Runnable() {
342 @Override
343 public void run() {
Tyler Gunndee56a82016-03-23 16:06:34 -0700344 callback.onExtrasChanged(conference, mExtras);
Santos Cordon6b7f9552015-05-27 17:21:45 -0700345 }
346 });
347 }
348 }
349
Santos Cordonb804f8d2015-05-12 12:09:47 -0700350 /**
351 * Returns the list of {@link RemoteConnection}s contained in this conference.
352 *
353 * @return A list of child connections.
354 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700355 public final List<RemoteConnection> getConnections() {
356 return mUnmodifiableChildConnections;
357 }
358
Santos Cordonb804f8d2015-05-12 12:09:47 -0700359 /**
360 * Gets the state of the conference call. See {@link Connection} for valid values.
361 *
362 * @return A constant representing the state the conference call is currently in.
363 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700364 public final int getState() {
365 return mState;
366 }
367
Santos Cordonb804f8d2015-05-12 12:09:47 -0700368 /**
369 * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class
370 * {@link Connection} for valid values.
371 *
372 * @return A bitmask of the capabilities of the conference call.
373 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800374 public final int getConnectionCapabilities() {
375 return mConnectionCapabilities;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700376 }
377
Santos Cordonb804f8d2015-05-12 12:09:47 -0700378 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700379 * Returns the properties of the conference. See {@code PROPERTY_*} constants in class
380 * {@link Connection} for valid values.
381 *
382 * @return A bitmask of the properties of the conference call.
383 */
384 public final int getConnectionProperties() {
385 return mConnectionProperties;
386 }
387
388 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700389 * Obtain the extras associated with this {@code RemoteConnection}.
390 *
391 * @return The extras for this connection.
392 */
393 public final Bundle getExtras() {
394 return mExtras;
395 }
396
397 /**
Santos Cordonb804f8d2015-05-12 12:09:47 -0700398 * Disconnects the conference call as well as the child {@link RemoteConnection}s.
399 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700400 public void disconnect() {
401 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700402 mConnectionService.disconnect(mId, null /*Session.Info*/);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700403 } catch (RemoteException e) {
404 }
405 }
406
Santos Cordonb804f8d2015-05-12 12:09:47 -0700407 /**
408 * Removes the specified {@link RemoteConnection} from the conference. This causes the
409 * {@link RemoteConnection} to become a standalone connection. This is a no-op if the
410 * {@link RemoteConnection} does not belong to this conference.
411 *
412 * @param connection The remote-connection to remove.
413 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700414 public void separate(RemoteConnection connection) {
415 if (mChildConnections.contains(connection)) {
416 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700417 mConnectionService.splitFromConference(connection.getId(), null /*Session.Info*/);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700418 } catch (RemoteException e) {
419 }
420 }
421 }
422
Santos Cordonb804f8d2015-05-12 12:09:47 -0700423 /**
424 * Merges all {@link RemoteConnection}s of this conference into a single call. This should be
425 * invoked only if the conference contains the capability
426 * {@link Connection#CAPABILITY_MERGE_CONFERENCE}, otherwise it is a no-op. The presence of said
427 * capability indicates that the connections of this conference, despite being part of the
428 * same conference object, are yet to have their audio streams merged; this is a common pattern
429 * for CDMA conference calls, but the capability is not used for GSM and SIP conference calls.
430 * Invoking this method will cause the unmerged child connections to merge their audio
431 * streams.
432 */
mike dooley95ea5762014-09-25 14:49:21 -0700433 public void merge() {
434 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700435 mConnectionService.mergeConference(mId, null /*Session.Info*/);
mike dooley95ea5762014-09-25 14:49:21 -0700436 } catch (RemoteException e) {
437 }
438 }
439
Santos Cordonb804f8d2015-05-12 12:09:47 -0700440 /**
441 * Swaps the active audio stream between the conference's child {@link RemoteConnection}s.
442 * This should be invoked only if the conference contains the capability
443 * {@link Connection#CAPABILITY_SWAP_CONFERENCE}, otherwise it is a no-op. This is only used by
444 * {@link ConnectionService}s that create conferences for connections that do not yet have
445 * their audio streams merged; this is a common pattern for CDMA conference calls, but the
446 * capability is not used for GSM and SIP conference calls. Invoking this method will change the
447 * active audio stream to a different child connection.
448 */
mike dooley95ea5762014-09-25 14:49:21 -0700449 public void swap() {
450 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700451 mConnectionService.swapConference(mId, null /*Session.Info*/);
mike dooley95ea5762014-09-25 14:49:21 -0700452 } catch (RemoteException e) {
453 }
454 }
455
Santos Cordonb804f8d2015-05-12 12:09:47 -0700456 /**
457 * Puts the conference on hold.
458 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700459 public void hold() {
460 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700461 mConnectionService.hold(mId, null /*Session.Info*/);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700462 } catch (RemoteException e) {
463 }
464 }
465
Santos Cordonb804f8d2015-05-12 12:09:47 -0700466 /**
467 * Unholds the conference call.
468 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700469 public void unhold() {
470 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700471 mConnectionService.unhold(mId, null /*Session.Info*/);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700472 } catch (RemoteException e) {
473 }
474 }
475
Santos Cordonb804f8d2015-05-12 12:09:47 -0700476 /**
477 * Returns the {@link DisconnectCause} for the conference if it is in the state
478 * {@link Connection#STATE_DISCONNECTED}. If the conference is not disconnected, this will
479 * return null.
480 *
481 * @return The disconnect cause.
482 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700483 public DisconnectCause getDisconnectCause() {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700484 return mDisconnectCause;
485 }
486
Santos Cordonb804f8d2015-05-12 12:09:47 -0700487 /**
488 * Requests that the conference start playing the specified DTMF tone.
489 *
490 * @param digit The digit for which to play a DTMF tone.
491 */
Yorke Lee58bacc52014-09-16 10:43:06 -0700492 public void playDtmfTone(char digit) {
493 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700494 mConnectionService.playDtmfTone(mId, digit, null /*Session.Info*/);
Yorke Lee58bacc52014-09-16 10:43:06 -0700495 } catch (RemoteException e) {
496 }
497 }
498
Santos Cordonb804f8d2015-05-12 12:09:47 -0700499 /**
500 * Stops the most recent request to play a DTMF tone.
501 *
502 * @see #playDtmfTone
503 */
Yorke Lee58bacc52014-09-16 10:43:06 -0700504 public void stopDtmfTone() {
505 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700506 mConnectionService.stopDtmfTone(mId, null /*Session.Info*/);
Yorke Lee58bacc52014-09-16 10:43:06 -0700507 } catch (RemoteException e) {
508 }
509 }
510
Santos Cordonb804f8d2015-05-12 12:09:47 -0700511 /**
512 * Request to change the conference's audio routing to the specified state. The specified state
513 * can include audio routing (Bluetooth, Speaker, etc) and muting state.
514 *
515 * @see android.telecom.AudioState
Yorke Lee4af59352015-05-13 14:14:54 -0700516 * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead.
517 * @hide
Santos Cordonb804f8d2015-05-12 12:09:47 -0700518 */
Yorke Lee4af59352015-05-13 14:14:54 -0700519 @SystemApi
520 @Deprecated
Yorke Lee58bacc52014-09-16 10:43:06 -0700521 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -0700522 setCallAudioState(new CallAudioState(state));
523 }
524
525 /**
526 * Request to change the conference's audio routing to the specified state. The specified state
527 * can include audio routing (Bluetooth, Speaker, etc) and muting state.
528 */
529 public void setCallAudioState(CallAudioState state) {
Yorke Lee58bacc52014-09-16 10:43:06 -0700530 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700531 mConnectionService.onCallAudioStateChanged(mId, state, null /*Session.Info*/);
Yorke Lee58bacc52014-09-16 10:43:06 -0700532 } catch (RemoteException e) {
533 }
534 }
535
Yorke Lee4af59352015-05-13 14:14:54 -0700536
Santos Cordonb804f8d2015-05-12 12:09:47 -0700537 /**
538 * Returns a list of independent connections that can me merged with this conference.
539 *
540 * @return A list of conferenceable connections.
541 */
Ihab Awad50e35062014-09-30 09:17:03 -0700542 public List<RemoteConnection> getConferenceableConnections() {
543 return mUnmodifiableConferenceableConnections;
544 }
545
Santos Cordonb804f8d2015-05-12 12:09:47 -0700546 /**
547 * Register a callback through which to receive state updates for this conference.
548 *
549 * @param callback The callback to notify of state changes.
550 */
Andrew Lee100e2932014-09-08 15:34:24 -0700551 public final void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700552 registerCallback(callback, new Handler());
553 }
554
Santos Cordonb804f8d2015-05-12 12:09:47 -0700555 /**
556 * Registers a callback through which to receive state updates for this conference.
557 * Callbacks will be notified using the specified handler, if provided.
558 *
559 * @param callback The callback to notify of state changes.
560 * @param handler The handler on which to execute the callbacks.
561 */
Andrew Lee011728f2015-04-23 15:47:06 -0700562 public final void registerCallback(Callback callback, Handler handler) {
563 unregisterCallback(callback);
564 if (callback != null && handler != null) {
565 mCallbackRecords.add(new CallbackRecord(callback, handler));
566 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700567 }
568
Santos Cordonb804f8d2015-05-12 12:09:47 -0700569 /**
570 * Unregisters a previously registered callback.
571 *
572 * @see #registerCallback
573 *
574 * @param callback The callback to unregister.
575 */
Andrew Lee100e2932014-09-08 15:34:24 -0700576 public final void unregisterCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700577 if (callback != null) {
578 for (CallbackRecord<Callback> record : mCallbackRecords) {
579 if (record.getCallback() == callback) {
580 mCallbackRecords.remove(record);
581 break;
582 }
583 }
584 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700585 }
586}