blob: 1493b208ad69f627815af8e33891fbd8dc8fa8ca [file] [log] [blame]
Santos Cordon52d8a152014-06-17 19:08:45 -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 Cordon52d8a152014-06-17 19:08:45 -070018
Tyler Gunnef9f6f92014-09-12 22:16:17 -070019import com.android.internal.telecom.IConnectionService;
20import com.android.internal.telecom.IVideoCallback;
21import com.android.internal.telecom.IVideoProvider;
Ihab Awadb19a0bc2014-08-07 19:46:01 -070022
Santos Cordon52d8a152014-06-17 19:08:45 -070023import android.net.Uri;
Andrew Lee011728f2015-04-23 15:47:06 -070024import android.os.Handler;
Ihab Awada64627c2014-08-20 09:36:40 -070025import android.os.IBinder;
Santos Cordon52d8a152014-06-17 19:08:45 -070026import android.os.RemoteException;
Ihab Awada64627c2014-08-20 09:36:40 -070027import android.view.Surface;
Santos Cordon52d8a152014-06-17 19:08:45 -070028
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070029import java.util.ArrayList;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070030import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070031import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070032import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070033import java.util.concurrent.ConcurrentHashMap;
Santos Cordon52d8a152014-06-17 19:08:45 -070034
35/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070036 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
37 * running in a different process.
38 *
39 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
40 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070041 */
42public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070043
Andrew Lee100e2932014-09-08 15:34:24 -070044 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070045 /**
46 * Invoked when the state of this {@code RemoteConnection} has changed. See
47 * {@link #getState()}.
48 *
49 * @param connection The {@code RemoteConnection} invoking this method.
50 * @param state The new state of the {@code RemoteConnection}.
51 */
Evan Charltonbf11f982014-07-20 22:06:28 -070052 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070053
54 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070055 * Invoked when this {@code RemoteConnection} is disconnected.
56 *
57 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070058 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
59 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070060 */
61 public void onDisconnected(
62 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070063 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070064
65 /**
66 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070067 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070068 *
69 * @param connection The {@code RemoteConnection} invoking this method.
70 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
71 */
Andrew Lee100e2932014-09-08 15:34:24 -070072 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070073
74 /**
75 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080076 * See {@link #getConnectionCapabilities()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070077 *
78 * @param connection The {@code RemoteConnection} invoking this method.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080079 * @param connectionCapabilities The new capabilities of the {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070080 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080081 public void onConnectionCapabilitiesChanged(
82 RemoteConnection connection,
83 int connectionCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070084
85 /**
86 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
87 * pause character. This causes the post-dial signals to stop pending user confirmation. An
88 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -070089 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -070090 *
91 * @param connection The {@code RemoteConnection} invoking this method.
92 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
93 */
94 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
95
96 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -080097 * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
98 * a character.
99 *
100 * @param connection The {@code RemoteConnection} invoking this method.
101 * @param nextChar The character being processed.
102 */
103 public void onPostDialChar(RemoteConnection connection, char nextChar) {}
104
105 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700106 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -0700107 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700108 *
109 * @param connection The {@code RemoteConnection} invoking this method.
110 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
111 */
Andrew Lee100e2932014-09-08 15:34:24 -0700112 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700113
114 /**
115 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
116 * {@link #getStatusHints()} ()}.
117 *
118 * @param connection The {@code RemoteConnection} invoking this method.
119 * @param statusHints The new status hints of the {@code RemoteConnection}.
120 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700121 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700122
123 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700124 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
125 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700126 *
127 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700128 * @param address The new address of the {@code RemoteConnection}.
129 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700130 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700131 */
Andrew Lee100e2932014-09-08 15:34:24 -0700132 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700133
134 /**
135 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
136 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
137 *
138 * @param connection The {@code RemoteConnection} invoking this method.
139 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700140 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700141 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700142 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700143 public void onCallerDisplayNameChanged(
144 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700145
146 /**
147 * Indicates that the video state of this {@code RemoteConnection} has changed.
148 * See {@link #getVideoState()}.
149 *
150 * @param connection The {@code RemoteConnection} invoking this method.
151 * @param videoState The new video state of the {@code RemoteConnection}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700152 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700153 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700154 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700155
156 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700157 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
158 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
159 *
160 * @param connection The {@code RemoteConnection} invoking this method.
161 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700162 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700163
164 /**
165 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
166 * may be asked to create a conference has changed.
167 *
168 * @param connection The {@code RemoteConnection} invoking this method.
169 * @param conferenceableConnections The {@code RemoteConnection}s with which this
170 * {@code RemoteConnection} may be asked to create a conference.
171 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700172 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700173 RemoteConnection connection,
174 List<RemoteConnection> conferenceableConnections) {}
175
176 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700177 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
178 * has changed.
179 *
180 * @param connection The {@code RemoteConnection} invoking this method.
181 * @param videoProvider The new {@code VideoProvider} associated with this
182 * {@code RemoteConnection}.
183 * @hide
184 */
185 public void onVideoProviderChanged(
186 RemoteConnection connection, VideoProvider videoProvider) {}
187
188 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700189 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
190 * of has changed.
191 *
192 * @param connection The {@code RemoteConnection} invoking this method.
193 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
194 * a part, which may be {@code null}.
195 */
196 public void onConferenceChanged(
197 RemoteConnection connection,
198 RemoteConference conference) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700199 }
200
Ihab Awada64627c2014-08-20 09:36:40 -0700201 /** {@hide} */
202 public static class VideoProvider {
203
204 public abstract static class Listener {
205 public void onReceiveSessionModifyRequest(
206 VideoProvider videoProvider,
207 VideoProfile videoProfile) {}
208
209 public void onReceiveSessionModifyResponse(
210 VideoProvider videoProvider,
211 int status,
212 VideoProfile requestedProfile,
213 VideoProfile responseProfile) {}
214
215 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {}
216
217 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {}
218
Rekha Kumar07366812015-03-24 16:42:31 -0700219 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700220
221 public void onCameraCapabilitiesChanged(
222 VideoProvider videoProvider,
223 CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700224
225 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700226 }
227
228 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
229 @Override
230 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
231 for (Listener l : mListeners) {
232 l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile);
233 }
234 }
235
236 @Override
237 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
238 VideoProfile responseProfile) {
239 for (Listener l : mListeners) {
240 l.onReceiveSessionModifyResponse(
241 VideoProvider.this,
242 status,
243 requestedProfile,
244 responseProfile);
245 }
246 }
247
248 @Override
249 public void handleCallSessionEvent(int event) {
250 for (Listener l : mListeners) {
251 l.onHandleCallSessionEvent(VideoProvider.this, event);
252 }
253 }
254
255 @Override
256 public void changePeerDimensions(int width, int height) {
257 for (Listener l : mListeners) {
258 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
259 }
260 }
261
262 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700263 public void changeCallDataUsage(long dataUsage) {
Ihab Awada64627c2014-08-20 09:36:40 -0700264 for (Listener l : mListeners) {
265 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
266 }
267 }
268
269 @Override
270 public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
271 for (Listener l : mListeners) {
272 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
273 }
274 }
275
276 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700277 public void changeVideoQuality(int videoQuality) {
278 for (Listener l : mListeners) {
279 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
280 }
281 }
282
283 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700284 public IBinder asBinder() {
285 return null;
286 }
287 };
288
289 private final VideoCallbackServant mVideoCallbackServant =
290 new VideoCallbackServant(mVideoCallbackDelegate);
291
292 private final IVideoProvider mVideoProviderBinder;
293
294 /**
295 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
296 * load factor before resizing, 1 means we only expect a single thread to
297 * access the map so make only a single shard
298 */
299 private final Set<Listener> mListeners = Collections.newSetFromMap(
300 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
301
302 public VideoProvider(IVideoProvider videoProviderBinder) {
303 mVideoProviderBinder = videoProviderBinder;
304 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700305 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700306 } catch (RemoteException e) {
307 }
308 }
309
310 public void addListener(Listener l) {
311 mListeners.add(l);
312 }
313
314 public void removeListener(Listener l) {
315 mListeners.remove(l);
316 }
317
318 public void setCamera(String cameraId) {
319 try {
320 mVideoProviderBinder.setCamera(cameraId);
321 } catch (RemoteException e) {
322 }
323 }
324
325 public void setPreviewSurface(Surface surface) {
326 try {
327 mVideoProviderBinder.setPreviewSurface(surface);
328 } catch (RemoteException e) {
329 }
330 }
331
332 public void setDisplaySurface(Surface surface) {
333 try {
334 mVideoProviderBinder.setDisplaySurface(surface);
335 } catch (RemoteException e) {
336 }
337 }
338
339 public void setDeviceOrientation(int rotation) {
340 try {
341 mVideoProviderBinder.setDeviceOrientation(rotation);
342 } catch (RemoteException e) {
343 }
344 }
345
346 public void setZoom(float value) {
347 try {
348 mVideoProviderBinder.setZoom(value);
349 } catch (RemoteException e) {
350 }
351 }
352
353 public void sendSessionModifyRequest(VideoProfile reqProfile) {
354 try {
355 mVideoProviderBinder.sendSessionModifyRequest(reqProfile);
356 } catch (RemoteException e) {
357 }
358 }
359
360 public void sendSessionModifyResponse(VideoProfile responseProfile) {
361 try {
362 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
363 } catch (RemoteException e) {
364 }
365 }
366
367 public void requestCameraCapabilities() {
368 try {
369 mVideoProviderBinder.requestCameraCapabilities();
370 } catch (RemoteException e) {
371 }
372 }
373
374 public void requestCallDataUsage() {
375 try {
376 mVideoProviderBinder.requestCallDataUsage();
377 } catch (RemoteException e) {
378 }
379 }
380
381 public void setPauseImage(String uri) {
382 try {
383 mVideoProviderBinder.setPauseImage(uri);
384 } catch (RemoteException e) {
385 }
386 }
387 }
388
Evan Charltonbf11f982014-07-20 22:06:28 -0700389 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700390 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700391 /**
392 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
393 * load factor before resizing, 1 means we only expect a single thread to
394 * access the map so make only a single shard
395 */
Andrew Lee011728f2015-04-23 15:47:06 -0700396 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
397 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700398 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
399 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
400 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700401
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700402 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700403 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700404 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700405 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800406 private int mConnectionCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700407 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700408 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700409 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700410 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700411 private Uri mAddress;
412 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700413 private String mCallerDisplayName;
414 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700415 private RemoteConference mConference;
Santos Cordon52d8a152014-06-17 19:08:45 -0700416
417 /**
418 * @hide
419 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700420 RemoteConnection(
421 String id,
422 IConnectionService connectionService,
423 ConnectionRequest request) {
424 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700425 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700426 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700427 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700428 }
429
430 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700431 * @hide
432 */
433 RemoteConnection(String callId, IConnectionService connectionService,
434 ParcelableConnection connection) {
435 mConnectionId = callId;
436 mConnectionService = connectionService;
437 mConnected = true;
438 mState = connection.getState();
439 mDisconnectCause = connection.getDisconnectCause();
440 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800441 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700442 mVideoState = connection.getVideoState();
443 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
444 mIsVoipAudioMode = connection.getIsVoipAudioMode();
445 mStatusHints = connection.getStatusHints();
446 mAddress = connection.getHandle();
447 mAddressPresentation = connection.getHandlePresentation();
448 mCallerDisplayName = connection.getCallerDisplayName();
449 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
450 mConference = null;
451 }
452
453 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700454 * Create a RemoteConnection which is used for failed connections. Note that using it for any
455 * "real" purpose will almost certainly fail. Callers should note the failure and act
456 * accordingly (moving on to another RemoteConnection, for example)
457 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700458 * @param disconnectCause The reason for the failed connection.
459 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700460 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700461 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700462 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700463 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700464 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700465 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700466 }
467
Ihab Awad5d0410f2014-07-30 10:07:40 -0700468 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700469 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700470 *
Andrew Lee100e2932014-09-08 15:34:24 -0700471 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700472 */
Andrew Lee100e2932014-09-08 15:34:24 -0700473 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700474 registerCallback(callback, new Handler());
475 }
476
477 /**
478 * Adds a callback to this {@code RemoteConnection}.
479 *
480 * @param callback A {@code Callback}.
481 * @param handler A {@code Handler} which command and status changes will be delivered to.
482 */
483 public void registerCallback(Callback callback, Handler handler) {
484 unregisterCallback(callback);
485 if (callback != null && handler != null) {
486 mCallbackRecords.add(new CallbackRecord(callback, handler));
487 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700488 }
489
Ihab Awad5d0410f2014-07-30 10:07:40 -0700490 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700491 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700492 *
Andrew Lee100e2932014-09-08 15:34:24 -0700493 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700494 */
Andrew Lee100e2932014-09-08 15:34:24 -0700495 public void unregisterCallback(Callback callback) {
496 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700497 for (CallbackRecord record : mCallbackRecords) {
498 if (record.getCallback() == callback) {
499 mCallbackRecords.remove(record);
500 break;
501 }
502 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700503 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700504 }
505
Ihab Awad5d0410f2014-07-30 10:07:40 -0700506 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700507 * Obtains the state of this {@code RemoteConnection}.
508 *
509 * @return A state value, chosen from the {@code STATE_*} constants.
510 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700511 public int getState() {
512 return mState;
513 }
514
Ihab Awad5d0410f2014-07-30 10:07:40 -0700515 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800516 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
517 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700518 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800519 * disconnect cause expressed as a code chosen from among those declared in
520 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700521 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700522 public DisconnectCause getDisconnectCause() {
523 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700524 }
525
Ihab Awad5d0410f2014-07-30 10:07:40 -0700526 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800527 * Obtains the capabilities of this {@code RemoteConnection}.
528 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700529 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800530 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700531 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800532 public int getConnectionCapabilities() {
533 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700534 }
535
Ihab Awad5d0410f2014-07-30 10:07:40 -0700536 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800537 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
538 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700539 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
540 */
Andrew Lee100e2932014-09-08 15:34:24 -0700541 public boolean isVoipAudioMode() {
542 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700543 }
544
Ihab Awad5d0410f2014-07-30 10:07:40 -0700545 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800546 * Obtains status hints pertaining to this {@code RemoteConnection}.
547 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700548 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800549 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700550 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700551 public StatusHints getStatusHints() {
552 return mStatusHints;
553 }
554
Ihab Awad5d0410f2014-07-30 10:07:40 -0700555 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800556 * Obtains the address of this {@code RemoteConnection}.
557 *
558 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
559 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700560 */
Andrew Lee100e2932014-09-08 15:34:24 -0700561 public Uri getAddress() {
562 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700563 }
564
Ihab Awad5d0410f2014-07-30 10:07:40 -0700565 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800566 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
567 *
568 * @return The presentation requirements for the address. See
569 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700570 */
Andrew Lee100e2932014-09-08 15:34:24 -0700571 public int getAddressPresentation() {
572 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700573 }
574
Ihab Awad5d0410f2014-07-30 10:07:40 -0700575 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800576 * Obtains the display name for this {@code RemoteConnection}'s caller.
577 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700578 * @return The display name for the caller.
579 */
Andrew Lee100e2932014-09-08 15:34:24 -0700580 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700581 return mCallerDisplayName;
582 }
583
Ihab Awad5d0410f2014-07-30 10:07:40 -0700584 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800585 * Obtains the presentation requirements for this {@code RemoteConnection}'s
586 * caller's display name.
587 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700588 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800589 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700590 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700591 public int getCallerDisplayNamePresentation() {
592 return mCallerDisplayNamePresentation;
593 }
594
Ihab Awad5d0410f2014-07-30 10:07:40 -0700595 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800596 * Obtains the video state of this {@code RemoteConnection}.
597 *
598 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile.VideoState}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700599 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700600 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700601 public int getVideoState() {
602 return mVideoState;
603 }
604
Ihab Awad5d0410f2014-07-30 10:07:40 -0700605 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700606 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700607 * @return The video provider associated with this {@code RemoteConnection}.
608 * @hide
609 */
610 public final VideoProvider getVideoProvider() {
611 return mVideoProvider;
612 }
613
614 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800615 * Determines whether this {@code RemoteConnection} is requesting ringback.
616 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700617 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800618 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700619 */
Andrew Lee100e2932014-09-08 15:34:24 -0700620 public boolean isRingbackRequested() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700621 return false;
622 }
623
624 /**
625 * Instructs this {@code RemoteConnection} to abort.
626 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700627 public void abort() {
628 try {
629 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700630 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700631 }
632 } catch (RemoteException ignored) {
633 }
634 }
635
Ihab Awad5d0410f2014-07-30 10:07:40 -0700636 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700637 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700638 */
639 public void answer() {
640 try {
641 if (mConnected) {
642 mConnectionService.answer(mConnectionId);
643 }
644 } catch (RemoteException ignored) {
645 }
646 }
647
648 /**
649 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700650 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700651 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700652 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700653 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700654 try {
655 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700656 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700657 }
658 } catch (RemoteException ignored) {
659 }
660 }
661
Ihab Awad5d0410f2014-07-30 10:07:40 -0700662 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700663 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700664 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700665 public void reject() {
666 try {
667 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700668 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700669 }
670 } catch (RemoteException ignored) {
671 }
672 }
673
Ihab Awad5d0410f2014-07-30 10:07:40 -0700674 /**
675 * Instructs this {@code RemoteConnection} to go on hold.
676 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700677 public void hold() {
678 try {
679 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700680 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700681 }
682 } catch (RemoteException ignored) {
683 }
684 }
685
Ihab Awad5d0410f2014-07-30 10:07:40 -0700686 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700687 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700688 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700689 public void unhold() {
690 try {
691 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700692 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700693 }
694 } catch (RemoteException ignored) {
695 }
696 }
697
Ihab Awad5d0410f2014-07-30 10:07:40 -0700698 /**
699 * Instructs this {@code RemoteConnection} to disconnect.
700 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700701 public void disconnect() {
702 try {
703 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700704 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700705 }
706 } catch (RemoteException ignored) {
707 }
708 }
709
Ihab Awad5d0410f2014-07-30 10:07:40 -0700710 /**
711 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
712 * (DTMF) tone.
713 *
714 * Any other currently playing DTMF tone in the specified call is immediately stopped.
715 *
716 * @param digit A character representing the DTMF digit for which to play the tone. This
717 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
718 */
719 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700720 try {
721 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700722 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700723 }
724 } catch (RemoteException ignored) {
725 }
726 }
727
Ihab Awad5d0410f2014-07-30 10:07:40 -0700728 /**
729 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
730 * (DTMF) tone currently playing.
731 *
732 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
733 * currently playing, this method will do nothing.
734 */
735 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700736 try {
737 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700738 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700739 }
740 } catch (RemoteException ignored) {
741 }
742 }
743
Ihab Awad5d0410f2014-07-30 10:07:40 -0700744 /**
745 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
746 *
747 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700748 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700749 * These digits are immediately sent as DTMF tones to the recipient as soon as the
750 * connection is made.
751 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700752 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700753 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
754 * of time.
755 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700756 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800757 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -0700758 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700759 * should display to the user an indication of this state and an affordance to continue
760 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
761 * app should invoke the {@link #postDialContinue(boolean)} method.
762 *
763 * @param proceed Whether or not to continue with the post-dial sequence.
764 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700765 public void postDialContinue(boolean proceed) {
766 try {
767 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700768 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700769 }
770 } catch (RemoteException ignored) {
771 }
772 }
773
Ihab Awad5d0410f2014-07-30 10:07:40 -0700774 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700775 * Set the audio state of this {@code RemoteConnection}.
776 *
777 * @param state The audio state of this {@code RemoteConnection}.
778 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700779 public void setAudioState(AudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700780 try {
781 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700782 mConnectionService.onAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700783 }
784 } catch (RemoteException ignored) {
785 }
786 }
787
Santos Cordon52d8a152014-06-17 19:08:45 -0700788 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700789 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
790 * successfully asked to create a conference with.
791 *
792 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
793 * merged into a {@link RemoteConference}.
794 */
795 public List<RemoteConnection> getConferenceableConnections() {
796 return mUnmodifiableconferenceableConnections;
797 }
798
799 /**
800 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
801 * of, or {@code null} if there is no such {@code RemoteConference}.
802 *
803 * @return A {@code RemoteConference} or {@code null};
804 */
805 public RemoteConference getConference() {
806 return mConference;
807 }
808
809 /** {@hide} */
810 String getId() {
811 return mConnectionId;
812 }
813
814 /** {@hide} */
815 IConnectionService getConnectionService() {
816 return mConnectionService;
817 }
818
819 /**
Santos Cordon52d8a152014-06-17 19:08:45 -0700820 * @hide
821 */
Andrew Lee011728f2015-04-23 15:47:06 -0700822 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700823 if (mState != state) {
824 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -0700825 for (CallbackRecord record: mCallbackRecords) {
826 final RemoteConnection connection = this;
827 final Callback callback = record.getCallback();
828 record.getHandler().post(new Runnable() {
829 @Override
830 public void run() {
831 callback.onStateChanged(connection, state);
832 }
833 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700834 }
835 }
836 }
837
838 /**
839 * @hide
840 */
Andrew Lee011728f2015-04-23 15:47:06 -0700841 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700842 if (mState != Connection.STATE_DISCONNECTED) {
843 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700844 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700845
Andrew Lee011728f2015-04-23 15:47:06 -0700846 for (CallbackRecord record : mCallbackRecords) {
847 final RemoteConnection connection = this;
848 final Callback callback = record.getCallback();
849 record.getHandler().post(new Runnable() {
850 @Override
851 public void run() {
852 callback.onDisconnected(connection, disconnectCause);
853 }
854 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700855 }
856 }
857 }
858
859 /**
860 * @hide
861 */
Andrew Lee011728f2015-04-23 15:47:06 -0700862 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -0700863 if (mRingbackRequested != ringback) {
864 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -0700865 for (CallbackRecord record : mCallbackRecords) {
866 final RemoteConnection connection = this;
867 final Callback callback = record.getCallback();
868 record.getHandler().post(new Runnable() {
869 @Override
870 public void run() {
871 callback.onRingbackRequested(connection, ringback);
872 }
873 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700874 }
875 }
876 }
877
878 /**
879 * @hide
880 */
Andrew Lee011728f2015-04-23 15:47:06 -0700881 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800882 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -0700883 for (CallbackRecord record : mCallbackRecords) {
884 final RemoteConnection connection = this;
885 final Callback callback = record.getCallback();
886 record.getHandler().post(new Runnable() {
887 @Override
888 public void run() {
889 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
890 }
891 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700892 }
893 }
894
895 /**
896 * @hide
897 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700898 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -0700899 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -0700900 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700901 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700902 setDisconnected(
903 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -0700904 }
905
Andrew Lee011728f2015-04-23 15:47:06 -0700906 for (CallbackRecord record : mCallbackRecords) {
907 final RemoteConnection connection = this;
908 final Callback callback = record.getCallback();
909 record.getHandler().post(new Runnable() {
910 @Override
911 public void run() {
912 callback.onDestroyed(connection);
913 }
914 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700915 }
Andrew Lee011728f2015-04-23 15:47:06 -0700916 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -0700917
918 mConnected = false;
919 }
920 }
921
922 /**
923 * @hide
924 */
Andrew Lee011728f2015-04-23 15:47:06 -0700925 void setPostDialWait(final String remainingDigits) {
926 for (CallbackRecord record : mCallbackRecords) {
927 final RemoteConnection connection = this;
928 final Callback callback = record.getCallback();
929 record.getHandler().post(new Runnable() {
930 @Override
931 public void run() {
932 callback.onPostDialWait(connection, remainingDigits);
933 }
934 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700935 }
936 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700937
Tyler Gunnaa07df82014-07-17 07:50:22 -0700938 /**
939 * @hide
940 */
Andrew Lee011728f2015-04-23 15:47:06 -0700941 void onPostDialChar(final char nextChar) {
942 for (CallbackRecord record : mCallbackRecords) {
943 final RemoteConnection connection = this;
944 final Callback callback = record.getCallback();
945 record.getHandler().post(new Runnable() {
946 @Override
947 public void run() {
948 callback.onPostDialWait(connection, String.valueOf(nextChar));
949 }
950 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800951 }
952 }
953
954 /**
955 * @hide
956 */
Andrew Lee011728f2015-04-23 15:47:06 -0700957 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -0700958 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -0700959 for (CallbackRecord record : mCallbackRecords) {
960 final RemoteConnection connection = this;
961 final Callback callback = record.getCallback();
962 record.getHandler().post(new Runnable() {
963 @Override
964 public void run() {
965 callback.onVideoStateChanged(connection, videoState);
966 }
967 });
Tyler Gunnaa07df82014-07-17 07:50:22 -0700968 }
969 }
970
Ihab Awada64627c2014-08-20 09:36:40 -0700971 /**
972 * @hide
973 */
Andrew Lee011728f2015-04-23 15:47:06 -0700974 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -0700975 mVideoProvider = videoProvider;
Andrew Lee011728f2015-04-23 15:47:06 -0700976 for (CallbackRecord record : mCallbackRecords) {
977 final RemoteConnection connection = this;
978 final Callback callback = record.getCallback();
979 record.getHandler().post(new Runnable() {
980 @Override
981 public void run() {
982 callback.onVideoProviderChanged(connection, videoProvider);
983 }
984 });
Ihab Awada64627c2014-08-20 09:36:40 -0700985 }
986 }
987
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700988 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -0700989 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -0700990 mIsVoipAudioMode = isVoip;
Andrew Lee011728f2015-04-23 15:47:06 -0700991 for (CallbackRecord record : mCallbackRecords) {
992 final RemoteConnection connection = this;
993 final Callback callback = record.getCallback();
994 record.getHandler().post(new Runnable() {
995 @Override
996 public void run() {
997 callback.onVoipAudioChanged(connection, isVoip);
998 }
999 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001000 }
1001 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001002
1003 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001004 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001005 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001006 for (CallbackRecord record : mCallbackRecords) {
1007 final RemoteConnection connection = this;
1008 final Callback callback = record.getCallback();
1009 record.getHandler().post(new Runnable() {
1010 @Override
1011 public void run() {
1012 callback.onStatusHintsChanged(connection, statusHints);
1013 }
1014 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001015 }
1016 }
1017
1018 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001019 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001020 mAddress = address;
1021 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001022 for (CallbackRecord record : mCallbackRecords) {
1023 final RemoteConnection connection = this;
1024 final Callback callback = record.getCallback();
1025 record.getHandler().post(new Runnable() {
1026 @Override
1027 public void run() {
1028 callback.onAddressChanged(connection, address, presentation);
1029 }
1030 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001031 }
1032 }
1033
1034 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001035 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001036 mCallerDisplayName = callerDisplayName;
1037 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001038 for (CallbackRecord record : mCallbackRecords) {
1039 final RemoteConnection connection = this;
1040 final Callback callback = record.getCallback();
1041 record.getHandler().post(new Runnable() {
1042 @Override
1043 public void run() {
1044 callback.onCallerDisplayNameChanged(
1045 connection, callerDisplayName, presentation);
1046 }
1047 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001048 }
1049 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001050
1051 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001052 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001053 mConferenceableConnections.clear();
1054 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001055 for (CallbackRecord record : mCallbackRecords) {
1056 final RemoteConnection connection = this;
1057 final Callback callback = record.getCallback();
1058 record.getHandler().post(new Runnable() {
1059 @Override
1060 public void run() {
1061 callback.onConferenceableConnectionsChanged(
1062 connection, mUnmodifiableconferenceableConnections);
1063 }
1064 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001065 }
1066 }
1067
1068 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001069 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001070 if (mConference != conference) {
1071 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001072 for (CallbackRecord record : mCallbackRecords) {
1073 final RemoteConnection connection = this;
1074 final Callback callback = record.getCallback();
1075 record.getHandler().post(new Runnable() {
1076 @Override
1077 public void run() {
1078 callback.onConferenceChanged(connection, conference);
1079 }
1080 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001081 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001082 }
1083 }
1084
Evan Charltonbf11f982014-07-20 22:06:28 -07001085 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001086 * Create a RemoteConnection represents a failure, and which will be in
1087 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1088 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001089 *
1090 * @return a failed {@link RemoteConnection}
1091 *
1092 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001093 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001094 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1095 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001096 }
Andrew Lee011728f2015-04-23 15:47:06 -07001097
1098 private static final class CallbackRecord extends Callback {
1099 private final Callback mCallback;
1100 private final Handler mHandler;
1101
1102 public CallbackRecord(Callback callback, Handler handler) {
1103 mCallback = callback;
1104 mHandler = handler;
1105 }
1106
1107 public Callback getCallback() {
1108 return mCallback;
1109 }
1110
1111 public Handler getHandler() {
1112 return mHandler;
1113 }
1114 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001115}