blob: b03cb51277b540f8e101262fc7cc4cd7c4b9ee46 [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 /**
95 * Invoked when the set of {@link RemoteConnection}s which can be added to this conference
96 * call have changed.
97 *
98 * @param conference The {@code RemoteConference} invoking this method.
99 * @param conferenceableConnections The list of conferenceable {@link RemoteConnection}s.
100 */
Ihab Awad50e35062014-09-30 09:17:03 -0700101 public void onConferenceableConnectionsChanged(
102 RemoteConference conference,
103 List<RemoteConnection> conferenceableConnections) {}
Santos Cordon895d4b82015-06-25 16:41:48 -0700104
105 /**
106 * Indicates that this {@code RemoteConference} has been destroyed. No further requests
107 * should be made to the {@code RemoteConference}, and references to it should be cleared.
108 *
109 * @param conference The {@code RemoteConference} invoking this method.
110 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700111 public void onDestroyed(RemoteConference conference) {}
Santos Cordon895d4b82015-06-25 16:41:48 -0700112
113 /**
114 * Handles changes to the {@code RemoteConference} extras.
115 *
116 * @param conference The {@code RemoteConference} invoking this method.
117 * @param extras The extras containing other information associated with the conference.
118 */
Santos Cordon6b7f9552015-05-27 17:21:45 -0700119 public void onExtrasChanged(RemoteConference conference, @Nullable Bundle extras) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700120 }
121
122 private final String mId;
123 private final IConnectionService mConnectionService;
124
Andrew Lee011728f2015-04-23 15:47:06 -0700125 private final Set<CallbackRecord<Callback>> mCallbackRecords = new CopyOnWriteArraySet<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700126 private final List<RemoteConnection> mChildConnections = new CopyOnWriteArrayList<>();
127 private final List<RemoteConnection> mUnmodifiableChildConnections =
128 Collections.unmodifiableList(mChildConnections);
Ihab Awad50e35062014-09-30 09:17:03 -0700129 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
130 private final List<RemoteConnection> mUnmodifiableConferenceableConnections =
131 Collections.unmodifiableList(mConferenceableConnections);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700132
133 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700134 private DisconnectCause mDisconnectCause;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800135 private int mConnectionCapabilities;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700136 private Bundle mExtras;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700137
Santos Cordonb804f8d2015-05-12 12:09:47 -0700138 /** @hide */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700139 RemoteConference(String id, IConnectionService connectionService) {
140 mId = id;
141 mConnectionService = connectionService;
142 }
143
Santos Cordonb804f8d2015-05-12 12:09:47 -0700144 /** @hide */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700145 String getId() {
146 return mId;
147 }
148
Santos Cordonb804f8d2015-05-12 12:09:47 -0700149 /** @hide */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700150 void setDestroyed() {
151 for (RemoteConnection connection : mChildConnections) {
152 connection.setConference(null);
153 }
Andrew Lee011728f2015-04-23 15:47:06 -0700154 for (CallbackRecord<Callback> record : mCallbackRecords) {
155 final RemoteConference conference = this;
156 final Callback callback = record.getCallback();
157 record.getHandler().post(new Runnable() {
158 @Override
159 public void run() {
160 callback.onDestroyed(conference);
161 }
162 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700163 }
164 }
165
Santos Cordonb804f8d2015-05-12 12:09:47 -0700166 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700167 void setState(final int newState) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700168 if (newState != Connection.STATE_ACTIVE &&
169 newState != Connection.STATE_HOLDING &&
170 newState != Connection.STATE_DISCONNECTED) {
171 Log.w(this, "Unsupported state transition for Conference call.",
172 Connection.stateToString(newState));
173 return;
174 }
175
176 if (mState != newState) {
Andrew Lee011728f2015-04-23 15:47:06 -0700177 final int oldState = mState;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700178 mState = newState;
Andrew Lee011728f2015-04-23 15:47:06 -0700179 for (CallbackRecord<Callback> record : mCallbackRecords) {
180 final RemoteConference conference = this;
181 final Callback callback = record.getCallback();
182 record.getHandler().post(new Runnable() {
183 @Override
184 public void run() {
185 callback.onStateChanged(conference, oldState, newState);
186 }
187 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700188 }
189 }
190 }
191
Santos Cordonb804f8d2015-05-12 12:09:47 -0700192 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700193 void addConnection(final RemoteConnection connection) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700194 if (!mChildConnections.contains(connection)) {
195 mChildConnections.add(connection);
196 connection.setConference(this);
Andrew Lee011728f2015-04-23 15:47:06 -0700197 for (CallbackRecord<Callback> record : mCallbackRecords) {
198 final RemoteConference conference = this;
199 final Callback callback = record.getCallback();
200 record.getHandler().post(new Runnable() {
201 @Override
202 public void run() {
203 callback.onConnectionAdded(conference, connection);
204 }
205 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700206 }
207 }
208 }
209
Santos Cordonb804f8d2015-05-12 12:09:47 -0700210 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700211 void removeConnection(final RemoteConnection connection) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700212 if (mChildConnections.contains(connection)) {
213 mChildConnections.remove(connection);
214 connection.setConference(null);
Andrew Lee011728f2015-04-23 15:47:06 -0700215 for (CallbackRecord<Callback> record : mCallbackRecords) {
216 final RemoteConference conference = this;
217 final Callback callback = record.getCallback();
218 record.getHandler().post(new Runnable() {
219 @Override
220 public void run() {
221 callback.onConnectionRemoved(conference, connection);
222 }
223 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700224 }
225 }
226 }
227
Santos Cordonb804f8d2015-05-12 12:09:47 -0700228 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700229 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800230 if (mConnectionCapabilities != connectionCapabilities) {
231 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -0700232 for (CallbackRecord<Callback> record : mCallbackRecords) {
233 final RemoteConference conference = this;
234 final Callback callback = record.getCallback();
235 record.getHandler().post(new Runnable() {
236 @Override
237 public void run() {
238 callback.onConnectionCapabilitiesChanged(
239 conference, mConnectionCapabilities);
240 }
241 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700242 }
243 }
244 }
245
Ihab Awad50e35062014-09-30 09:17:03 -0700246 /** @hide */
247 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
248 mConferenceableConnections.clear();
249 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -0700250 for (CallbackRecord<Callback> record : mCallbackRecords) {
251 final RemoteConference conference = this;
252 final Callback callback = record.getCallback();
253 record.getHandler().post(new Runnable() {
254 @Override
255 public void run() {
256 callback.onConferenceableConnectionsChanged(
257 conference, mUnmodifiableConferenceableConnections);
258 }
259 });
Ihab Awad50e35062014-09-30 09:17:03 -0700260 }
261 }
262
Santos Cordonb804f8d2015-05-12 12:09:47 -0700263 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700264 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700265 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700266 mDisconnectCause = disconnectCause;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700267 setState(Connection.STATE_DISCONNECTED);
Andrew Lee011728f2015-04-23 15:47:06 -0700268 for (CallbackRecord<Callback> record : mCallbackRecords) {
269 final RemoteConference conference = this;
270 final Callback callback = record.getCallback();
271 record.getHandler().post(new Runnable() {
272 @Override
273 public void run() {
274 callback.onDisconnected(conference, disconnectCause);
275 }
276 });
Ihab Awadb8e85c72014-08-23 20:34:57 -0700277 }
278 }
279 }
280
Santos Cordon6b7f9552015-05-27 17:21:45 -0700281 /** @hide */
Tyler Gunndee56a82016-03-23 16:06:34 -0700282 void putExtras(final Bundle extras) {
283 if (mExtras == null) {
284 mExtras = new Bundle();
285 }
286 mExtras.putAll(extras);
287
288 notifyExtrasChanged();
289 }
290
291 /** @hide */
292 void removeExtras(List<String> keys) {
293 if (mExtras == null || keys == null || keys.isEmpty()) {
294 return;
295 }
296 for (String key : keys) {
297 mExtras.remove(key);
298 }
299
300 notifyExtrasChanged();
301 }
302
303 private void notifyExtrasChanged() {
Santos Cordon6b7f9552015-05-27 17:21:45 -0700304 for (CallbackRecord<Callback> record : mCallbackRecords) {
305 final RemoteConference conference = this;
306 final Callback callback = record.getCallback();
307 record.getHandler().post(new Runnable() {
308 @Override
309 public void run() {
Tyler Gunndee56a82016-03-23 16:06:34 -0700310 callback.onExtrasChanged(conference, mExtras);
Santos Cordon6b7f9552015-05-27 17:21:45 -0700311 }
312 });
313 }
314 }
315
Santos Cordonb804f8d2015-05-12 12:09:47 -0700316 /**
317 * Returns the list of {@link RemoteConnection}s contained in this conference.
318 *
319 * @return A list of child connections.
320 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700321 public final List<RemoteConnection> getConnections() {
322 return mUnmodifiableChildConnections;
323 }
324
Santos Cordonb804f8d2015-05-12 12:09:47 -0700325 /**
326 * Gets the state of the conference call. See {@link Connection} for valid values.
327 *
328 * @return A constant representing the state the conference call is currently in.
329 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700330 public final int getState() {
331 return mState;
332 }
333
Santos Cordonb804f8d2015-05-12 12:09:47 -0700334 /**
335 * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class
336 * {@link Connection} for valid values.
337 *
338 * @return A bitmask of the capabilities of the conference call.
339 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800340 public final int getConnectionCapabilities() {
341 return mConnectionCapabilities;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700342 }
343
Santos Cordonb804f8d2015-05-12 12:09:47 -0700344 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700345 * Obtain the extras associated with this {@code RemoteConnection}.
346 *
347 * @return The extras for this connection.
348 */
349 public final Bundle getExtras() {
350 return mExtras;
351 }
352
353 /**
Santos Cordonb804f8d2015-05-12 12:09:47 -0700354 * Disconnects the conference call as well as the child {@link RemoteConnection}s.
355 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700356 public void disconnect() {
357 try {
358 mConnectionService.disconnect(mId);
359 } catch (RemoteException e) {
360 }
361 }
362
Santos Cordonb804f8d2015-05-12 12:09:47 -0700363 /**
364 * Removes the specified {@link RemoteConnection} from the conference. This causes the
365 * {@link RemoteConnection} to become a standalone connection. This is a no-op if the
366 * {@link RemoteConnection} does not belong to this conference.
367 *
368 * @param connection The remote-connection to remove.
369 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700370 public void separate(RemoteConnection connection) {
371 if (mChildConnections.contains(connection)) {
372 try {
373 mConnectionService.splitFromConference(connection.getId());
374 } catch (RemoteException e) {
375 }
376 }
377 }
378
Santos Cordonb804f8d2015-05-12 12:09:47 -0700379 /**
380 * Merges all {@link RemoteConnection}s of this conference into a single call. This should be
381 * invoked only if the conference contains the capability
382 * {@link Connection#CAPABILITY_MERGE_CONFERENCE}, otherwise it is a no-op. The presence of said
383 * capability indicates that the connections of this conference, despite being part of the
384 * same conference object, are yet to have their audio streams merged; this is a common pattern
385 * for CDMA conference calls, but the capability is not used for GSM and SIP conference calls.
386 * Invoking this method will cause the unmerged child connections to merge their audio
387 * streams.
388 */
mike dooley95ea5762014-09-25 14:49:21 -0700389 public void merge() {
390 try {
391 mConnectionService.mergeConference(mId);
392 } catch (RemoteException e) {
393 }
394 }
395
Santos Cordonb804f8d2015-05-12 12:09:47 -0700396 /**
397 * Swaps the active audio stream between the conference's child {@link RemoteConnection}s.
398 * This should be invoked only if the conference contains the capability
399 * {@link Connection#CAPABILITY_SWAP_CONFERENCE}, otherwise it is a no-op. This is only used by
400 * {@link ConnectionService}s that create conferences for connections that do not yet have
401 * their audio streams merged; this is a common pattern for CDMA conference calls, but the
402 * capability is not used for GSM and SIP conference calls. Invoking this method will change the
403 * active audio stream to a different child connection.
404 */
mike dooley95ea5762014-09-25 14:49:21 -0700405 public void swap() {
406 try {
407 mConnectionService.swapConference(mId);
408 } catch (RemoteException e) {
409 }
410 }
411
Santos Cordonb804f8d2015-05-12 12:09:47 -0700412 /**
413 * Puts the conference on hold.
414 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700415 public void hold() {
416 try {
417 mConnectionService.hold(mId);
418 } catch (RemoteException e) {
419 }
420 }
421
Santos Cordonb804f8d2015-05-12 12:09:47 -0700422 /**
423 * Unholds the conference call.
424 */
Ihab Awadb8e85c72014-08-23 20:34:57 -0700425 public void unhold() {
426 try {
427 mConnectionService.unhold(mId);
428 } catch (RemoteException e) {
429 }
430 }
431
Santos Cordonb804f8d2015-05-12 12:09:47 -0700432 /**
433 * Returns the {@link DisconnectCause} for the conference if it is in the state
434 * {@link Connection#STATE_DISCONNECTED}. If the conference is not disconnected, this will
435 * return null.
436 *
437 * @return The disconnect cause.
438 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700439 public DisconnectCause getDisconnectCause() {
Ihab Awadb8e85c72014-08-23 20:34:57 -0700440 return mDisconnectCause;
441 }
442
Santos Cordonb804f8d2015-05-12 12:09:47 -0700443 /**
444 * Requests that the conference start playing the specified DTMF tone.
445 *
446 * @param digit The digit for which to play a DTMF tone.
447 */
Yorke Lee58bacc52014-09-16 10:43:06 -0700448 public void playDtmfTone(char digit) {
449 try {
450 mConnectionService.playDtmfTone(mId, digit);
451 } catch (RemoteException e) {
452 }
453 }
454
Santos Cordonb804f8d2015-05-12 12:09:47 -0700455 /**
456 * Stops the most recent request to play a DTMF tone.
457 *
458 * @see #playDtmfTone
459 */
Yorke Lee58bacc52014-09-16 10:43:06 -0700460 public void stopDtmfTone() {
461 try {
462 mConnectionService.stopDtmfTone(mId);
463 } catch (RemoteException e) {
464 }
465 }
466
Santos Cordonb804f8d2015-05-12 12:09:47 -0700467 /**
468 * Request to change the conference's audio routing to the specified state. The specified state
469 * can include audio routing (Bluetooth, Speaker, etc) and muting state.
470 *
471 * @see android.telecom.AudioState
Yorke Lee4af59352015-05-13 14:14:54 -0700472 * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead.
473 * @hide
Santos Cordonb804f8d2015-05-12 12:09:47 -0700474 */
Yorke Lee4af59352015-05-13 14:14:54 -0700475 @SystemApi
476 @Deprecated
Yorke Lee58bacc52014-09-16 10:43:06 -0700477 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -0700478 setCallAudioState(new CallAudioState(state));
479 }
480
481 /**
482 * Request to change the conference's audio routing to the specified state. The specified state
483 * can include audio routing (Bluetooth, Speaker, etc) and muting state.
484 */
485 public void setCallAudioState(CallAudioState state) {
Yorke Lee58bacc52014-09-16 10:43:06 -0700486 try {
Yorke Lee4af59352015-05-13 14:14:54 -0700487 mConnectionService.onCallAudioStateChanged(mId, state);
Yorke Lee58bacc52014-09-16 10:43:06 -0700488 } catch (RemoteException e) {
489 }
490 }
491
Yorke Lee4af59352015-05-13 14:14:54 -0700492
Santos Cordonb804f8d2015-05-12 12:09:47 -0700493 /**
494 * Returns a list of independent connections that can me merged with this conference.
495 *
496 * @return A list of conferenceable connections.
497 */
Ihab Awad50e35062014-09-30 09:17:03 -0700498 public List<RemoteConnection> getConferenceableConnections() {
499 return mUnmodifiableConferenceableConnections;
500 }
501
Santos Cordonb804f8d2015-05-12 12:09:47 -0700502 /**
503 * Register a callback through which to receive state updates for this conference.
504 *
505 * @param callback The callback to notify of state changes.
506 */
Andrew Lee100e2932014-09-08 15:34:24 -0700507 public final void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700508 registerCallback(callback, new Handler());
509 }
510
Santos Cordonb804f8d2015-05-12 12:09:47 -0700511 /**
512 * Registers a callback through which to receive state updates for this conference.
513 * Callbacks will be notified using the specified handler, if provided.
514 *
515 * @param callback The callback to notify of state changes.
516 * @param handler The handler on which to execute the callbacks.
517 */
Andrew Lee011728f2015-04-23 15:47:06 -0700518 public final void registerCallback(Callback callback, Handler handler) {
519 unregisterCallback(callback);
520 if (callback != null && handler != null) {
521 mCallbackRecords.add(new CallbackRecord(callback, handler));
522 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700523 }
524
Santos Cordonb804f8d2015-05-12 12:09:47 -0700525 /**
526 * Unregisters a previously registered callback.
527 *
528 * @see #registerCallback
529 *
530 * @param callback The callback to unregister.
531 */
Andrew Lee100e2932014-09-08 15:34:24 -0700532 public final void unregisterCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700533 if (callback != null) {
534 for (CallbackRecord<Callback> record : mCallbackRecords) {
535 if (record.getCallback() == callback) {
536 mCallbackRecords.remove(record);
537 break;
538 }
539 }
540 }
Ihab Awadb8e85c72014-08-23 20:34:57 -0700541 }
542}