blob: 1d6e15c1282b92756a7fa658ceeaf6382a91a461 [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
Yorke Lee4af59352015-05-13 14:14:54 -070023import android.annotation.SystemApi;
Santos Cordon52d8a152014-06-17 19:08:45 -070024import android.net.Uri;
Andrew Lee011728f2015-04-23 15:47:06 -070025import android.os.Handler;
Ihab Awada64627c2014-08-20 09:36:40 -070026import android.os.IBinder;
Santos Cordon52d8a152014-06-17 19:08:45 -070027import android.os.RemoteException;
Ihab Awada64627c2014-08-20 09:36:40 -070028import android.view.Surface;
Santos Cordon52d8a152014-06-17 19:08:45 -070029
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070030import java.util.ArrayList;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070031import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070032import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070033import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070034import java.util.concurrent.ConcurrentHashMap;
Santos Cordon52d8a152014-06-17 19:08:45 -070035
36/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070037 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
38 * running in a different process.
39 *
40 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
41 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070042 */
43public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070044
Andrew Lee100e2932014-09-08 15:34:24 -070045 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070046 /**
47 * Invoked when the state of this {@code RemoteConnection} has changed. See
48 * {@link #getState()}.
49 *
50 * @param connection The {@code RemoteConnection} invoking this method.
51 * @param state The new state of the {@code RemoteConnection}.
52 */
Evan Charltonbf11f982014-07-20 22:06:28 -070053 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070054
55 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070056 * Invoked when this {@code RemoteConnection} is disconnected.
57 *
58 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070059 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
60 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070061 */
62 public void onDisconnected(
63 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070064 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070065
66 /**
67 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070068 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070069 *
70 * @param connection The {@code RemoteConnection} invoking this method.
71 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
72 */
Andrew Lee100e2932014-09-08 15:34:24 -070073 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070074
75 /**
76 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080077 * See {@link #getConnectionCapabilities()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070078 *
79 * @param connection The {@code RemoteConnection} invoking this method.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080080 * @param connectionCapabilities The new capabilities of the {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070081 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080082 public void onConnectionCapabilitiesChanged(
83 RemoteConnection connection,
84 int connectionCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070085
86 /**
87 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
88 * pause character. This causes the post-dial signals to stop pending user confirmation. An
89 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -070090 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -070091 *
92 * @param connection The {@code RemoteConnection} invoking this method.
93 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
94 */
95 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
96
97 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -080098 * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
99 * a character.
100 *
101 * @param connection The {@code RemoteConnection} invoking this method.
102 * @param nextChar The character being processed.
103 */
104 public void onPostDialChar(RemoteConnection connection, char nextChar) {}
105
106 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700107 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -0700108 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700109 *
110 * @param connection The {@code RemoteConnection} invoking this method.
111 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
112 */
Andrew Lee100e2932014-09-08 15:34:24 -0700113 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700114
115 /**
116 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
117 * {@link #getStatusHints()} ()}.
118 *
119 * @param connection The {@code RemoteConnection} invoking this method.
120 * @param statusHints The new status hints of the {@code RemoteConnection}.
121 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700122 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700123
124 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700125 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
126 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700127 *
128 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700129 * @param address The new address of the {@code RemoteConnection}.
130 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700131 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700132 */
Andrew Lee100e2932014-09-08 15:34:24 -0700133 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700134
135 /**
136 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
137 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
138 *
139 * @param connection The {@code RemoteConnection} invoking this method.
140 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700141 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700142 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700143 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700144 public void onCallerDisplayNameChanged(
145 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700146
147 /**
148 * Indicates that the video state of this {@code RemoteConnection} has changed.
149 * See {@link #getVideoState()}.
150 *
151 * @param connection The {@code RemoteConnection} invoking this method.
152 * @param videoState The new video state of the {@code RemoteConnection}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700153 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700154 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700155 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700156
157 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700158 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
159 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
160 *
161 * @param connection The {@code RemoteConnection} invoking this method.
162 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700163 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700164
165 /**
166 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
167 * may be asked to create a conference has changed.
168 *
169 * @param connection The {@code RemoteConnection} invoking this method.
170 * @param conferenceableConnections The {@code RemoteConnection}s with which this
171 * {@code RemoteConnection} may be asked to create a conference.
172 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700173 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700174 RemoteConnection connection,
175 List<RemoteConnection> conferenceableConnections) {}
176
177 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700178 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
179 * has changed.
180 *
181 * @param connection The {@code RemoteConnection} invoking this method.
182 * @param videoProvider The new {@code VideoProvider} associated with this
183 * {@code RemoteConnection}.
184 * @hide
185 */
186 public void onVideoProviderChanged(
187 RemoteConnection connection, VideoProvider videoProvider) {}
188
189 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700190 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
191 * of has changed.
192 *
193 * @param connection The {@code RemoteConnection} invoking this method.
194 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
195 * a part, which may be {@code null}.
196 */
197 public void onConferenceChanged(
198 RemoteConnection connection,
199 RemoteConference conference) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700200 }
201
Ihab Awada64627c2014-08-20 09:36:40 -0700202 /** {@hide} */
203 public static class VideoProvider {
204
205 public abstract static class Listener {
206 public void onReceiveSessionModifyRequest(
207 VideoProvider videoProvider,
208 VideoProfile videoProfile) {}
209
210 public void onReceiveSessionModifyResponse(
211 VideoProvider videoProvider,
212 int status,
213 VideoProfile requestedProfile,
214 VideoProfile responseProfile) {}
215
216 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {}
217
218 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {}
219
Rekha Kumar07366812015-03-24 16:42:31 -0700220 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700221
222 public void onCameraCapabilitiesChanged(
223 VideoProvider videoProvider,
Yorke Lee400470f2015-05-12 13:31:25 -0700224 VideoProfile.CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700225
226 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700227 }
228
229 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
230 @Override
231 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
232 for (Listener l : mListeners) {
233 l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile);
234 }
235 }
236
237 @Override
238 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
239 VideoProfile responseProfile) {
240 for (Listener l : mListeners) {
241 l.onReceiveSessionModifyResponse(
242 VideoProvider.this,
243 status,
244 requestedProfile,
245 responseProfile);
246 }
247 }
248
249 @Override
250 public void handleCallSessionEvent(int event) {
251 for (Listener l : mListeners) {
252 l.onHandleCallSessionEvent(VideoProvider.this, event);
253 }
254 }
255
256 @Override
257 public void changePeerDimensions(int width, int height) {
258 for (Listener l : mListeners) {
259 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
260 }
261 }
262
263 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700264 public void changeCallDataUsage(long dataUsage) {
Ihab Awada64627c2014-08-20 09:36:40 -0700265 for (Listener l : mListeners) {
266 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
267 }
268 }
269
270 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700271 public void changeCameraCapabilities(
272 VideoProfile.CameraCapabilities cameraCapabilities) {
Ihab Awada64627c2014-08-20 09:36:40 -0700273 for (Listener l : mListeners) {
274 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
275 }
276 }
277
278 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700279 public void changeVideoQuality(int videoQuality) {
280 for (Listener l : mListeners) {
281 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
282 }
283 }
284
285 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700286 public IBinder asBinder() {
287 return null;
288 }
289 };
290
291 private final VideoCallbackServant mVideoCallbackServant =
292 new VideoCallbackServant(mVideoCallbackDelegate);
293
294 private final IVideoProvider mVideoProviderBinder;
295
296 /**
297 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
298 * load factor before resizing, 1 means we only expect a single thread to
299 * access the map so make only a single shard
300 */
301 private final Set<Listener> mListeners = Collections.newSetFromMap(
302 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
303
304 public VideoProvider(IVideoProvider videoProviderBinder) {
305 mVideoProviderBinder = videoProviderBinder;
306 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700307 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700308 } catch (RemoteException e) {
309 }
310 }
311
312 public void addListener(Listener l) {
313 mListeners.add(l);
314 }
315
316 public void removeListener(Listener l) {
317 mListeners.remove(l);
318 }
319
320 public void setCamera(String cameraId) {
321 try {
322 mVideoProviderBinder.setCamera(cameraId);
323 } catch (RemoteException e) {
324 }
325 }
326
327 public void setPreviewSurface(Surface surface) {
328 try {
329 mVideoProviderBinder.setPreviewSurface(surface);
330 } catch (RemoteException e) {
331 }
332 }
333
334 public void setDisplaySurface(Surface surface) {
335 try {
336 mVideoProviderBinder.setDisplaySurface(surface);
337 } catch (RemoteException e) {
338 }
339 }
340
341 public void setDeviceOrientation(int rotation) {
342 try {
343 mVideoProviderBinder.setDeviceOrientation(rotation);
344 } catch (RemoteException e) {
345 }
346 }
347
348 public void setZoom(float value) {
349 try {
350 mVideoProviderBinder.setZoom(value);
351 } catch (RemoteException e) {
352 }
353 }
354
Tyler Gunn45382162015-05-06 08:52:27 -0700355 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700356 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700357 mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700358 } catch (RemoteException e) {
359 }
360 }
361
362 public void sendSessionModifyResponse(VideoProfile responseProfile) {
363 try {
364 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
365 } catch (RemoteException e) {
366 }
367 }
368
369 public void requestCameraCapabilities() {
370 try {
371 mVideoProviderBinder.requestCameraCapabilities();
372 } catch (RemoteException e) {
373 }
374 }
375
376 public void requestCallDataUsage() {
377 try {
378 mVideoProviderBinder.requestCallDataUsage();
379 } catch (RemoteException e) {
380 }
381 }
382
Yorke Lee32f24732015-05-12 16:18:03 -0700383 public void setPauseImage(Uri uri) {
Ihab Awada64627c2014-08-20 09:36:40 -0700384 try {
385 mVideoProviderBinder.setPauseImage(uri);
386 } catch (RemoteException e) {
387 }
388 }
389 }
390
Evan Charltonbf11f982014-07-20 22:06:28 -0700391 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700392 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700393 /**
394 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
395 * load factor before resizing, 1 means we only expect a single thread to
396 * access the map so make only a single shard
397 */
Andrew Lee011728f2015-04-23 15:47:06 -0700398 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
399 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700400 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
401 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
402 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700403
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700404 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700405 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700406 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700407 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800408 private int mConnectionCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700409 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700410 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700411 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700412 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700413 private Uri mAddress;
414 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700415 private String mCallerDisplayName;
416 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700417 private RemoteConference mConference;
Santos Cordon52d8a152014-06-17 19:08:45 -0700418
419 /**
420 * @hide
421 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700422 RemoteConnection(
423 String id,
424 IConnectionService connectionService,
425 ConnectionRequest request) {
426 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700427 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700428 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700429 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700430 }
431
432 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700433 * @hide
434 */
435 RemoteConnection(String callId, IConnectionService connectionService,
436 ParcelableConnection connection) {
437 mConnectionId = callId;
438 mConnectionService = connectionService;
439 mConnected = true;
440 mState = connection.getState();
441 mDisconnectCause = connection.getDisconnectCause();
442 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800443 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700444 mVideoState = connection.getVideoState();
445 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
446 mIsVoipAudioMode = connection.getIsVoipAudioMode();
447 mStatusHints = connection.getStatusHints();
448 mAddress = connection.getHandle();
449 mAddressPresentation = connection.getHandlePresentation();
450 mCallerDisplayName = connection.getCallerDisplayName();
451 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
452 mConference = null;
453 }
454
455 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700456 * Create a RemoteConnection which is used for failed connections. Note that using it for any
457 * "real" purpose will almost certainly fail. Callers should note the failure and act
458 * accordingly (moving on to another RemoteConnection, for example)
459 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700460 * @param disconnectCause The reason for the failed connection.
461 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700462 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700463 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700464 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700465 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700466 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700467 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700468 }
469
Ihab Awad5d0410f2014-07-30 10:07:40 -0700470 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700471 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700472 *
Andrew Lee100e2932014-09-08 15:34:24 -0700473 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700474 */
Andrew Lee100e2932014-09-08 15:34:24 -0700475 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700476 registerCallback(callback, new Handler());
477 }
478
479 /**
480 * Adds a callback to this {@code RemoteConnection}.
481 *
482 * @param callback A {@code Callback}.
483 * @param handler A {@code Handler} which command and status changes will be delivered to.
484 */
485 public void registerCallback(Callback callback, Handler handler) {
486 unregisterCallback(callback);
487 if (callback != null && handler != null) {
488 mCallbackRecords.add(new CallbackRecord(callback, handler));
489 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700490 }
491
Ihab Awad5d0410f2014-07-30 10:07:40 -0700492 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700493 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700494 *
Andrew Lee100e2932014-09-08 15:34:24 -0700495 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700496 */
Andrew Lee100e2932014-09-08 15:34:24 -0700497 public void unregisterCallback(Callback callback) {
498 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700499 for (CallbackRecord record : mCallbackRecords) {
500 if (record.getCallback() == callback) {
501 mCallbackRecords.remove(record);
502 break;
503 }
504 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700505 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700506 }
507
Ihab Awad5d0410f2014-07-30 10:07:40 -0700508 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700509 * Obtains the state of this {@code RemoteConnection}.
510 *
511 * @return A state value, chosen from the {@code STATE_*} constants.
512 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700513 public int getState() {
514 return mState;
515 }
516
Ihab Awad5d0410f2014-07-30 10:07:40 -0700517 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800518 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
519 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700520 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800521 * disconnect cause expressed as a code chosen from among those declared in
522 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700523 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700524 public DisconnectCause getDisconnectCause() {
525 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700526 }
527
Ihab Awad5d0410f2014-07-30 10:07:40 -0700528 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800529 * Obtains the capabilities of this {@code RemoteConnection}.
530 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700531 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800532 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700533 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800534 public int getConnectionCapabilities() {
535 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700536 }
537
Ihab Awad5d0410f2014-07-30 10:07:40 -0700538 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800539 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
540 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700541 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
542 */
Andrew Lee100e2932014-09-08 15:34:24 -0700543 public boolean isVoipAudioMode() {
544 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700545 }
546
Ihab Awad5d0410f2014-07-30 10:07:40 -0700547 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800548 * Obtains status hints pertaining to this {@code RemoteConnection}.
549 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700550 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800551 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700552 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700553 public StatusHints getStatusHints() {
554 return mStatusHints;
555 }
556
Ihab Awad5d0410f2014-07-30 10:07:40 -0700557 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800558 * Obtains the address of this {@code RemoteConnection}.
559 *
560 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
561 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700562 */
Andrew Lee100e2932014-09-08 15:34:24 -0700563 public Uri getAddress() {
564 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700565 }
566
Ihab Awad5d0410f2014-07-30 10:07:40 -0700567 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800568 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
569 *
570 * @return The presentation requirements for the address. See
571 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700572 */
Andrew Lee100e2932014-09-08 15:34:24 -0700573 public int getAddressPresentation() {
574 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700575 }
576
Ihab Awad5d0410f2014-07-30 10:07:40 -0700577 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800578 * Obtains the display name for this {@code RemoteConnection}'s caller.
579 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700580 * @return The display name for the caller.
581 */
Andrew Lee100e2932014-09-08 15:34:24 -0700582 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700583 return mCallerDisplayName;
584 }
585
Ihab Awad5d0410f2014-07-30 10:07:40 -0700586 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800587 * Obtains the presentation requirements for this {@code RemoteConnection}'s
588 * caller's display name.
589 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700590 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800591 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700592 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700593 public int getCallerDisplayNamePresentation() {
594 return mCallerDisplayNamePresentation;
595 }
596
Ihab Awad5d0410f2014-07-30 10:07:40 -0700597 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800598 * Obtains the video state of this {@code RemoteConnection}.
599 *
600 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile.VideoState}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700601 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700602 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700603 public int getVideoState() {
604 return mVideoState;
605 }
606
Ihab Awad5d0410f2014-07-30 10:07:40 -0700607 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700608 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700609 * @return The video provider associated with this {@code RemoteConnection}.
610 * @hide
611 */
612 public final VideoProvider getVideoProvider() {
613 return mVideoProvider;
614 }
615
616 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800617 * Determines whether this {@code RemoteConnection} is requesting ringback.
618 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700619 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800620 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700621 */
Andrew Lee100e2932014-09-08 15:34:24 -0700622 public boolean isRingbackRequested() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700623 return false;
624 }
625
626 /**
627 * Instructs this {@code RemoteConnection} to abort.
628 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700629 public void abort() {
630 try {
631 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700632 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700633 }
634 } catch (RemoteException ignored) {
635 }
636 }
637
Ihab Awad5d0410f2014-07-30 10:07:40 -0700638 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700639 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700640 */
641 public void answer() {
642 try {
643 if (mConnected) {
644 mConnectionService.answer(mConnectionId);
645 }
646 } catch (RemoteException ignored) {
647 }
648 }
649
650 /**
651 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700652 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700653 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700654 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700655 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700656 try {
657 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700658 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700659 }
660 } catch (RemoteException ignored) {
661 }
662 }
663
Ihab Awad5d0410f2014-07-30 10:07:40 -0700664 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700665 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700666 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700667 public void reject() {
668 try {
669 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700670 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700671 }
672 } catch (RemoteException ignored) {
673 }
674 }
675
Ihab Awad5d0410f2014-07-30 10:07:40 -0700676 /**
677 * Instructs this {@code RemoteConnection} to go on hold.
678 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700679 public void hold() {
680 try {
681 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700682 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700683 }
684 } catch (RemoteException ignored) {
685 }
686 }
687
Ihab Awad5d0410f2014-07-30 10:07:40 -0700688 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700689 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700690 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700691 public void unhold() {
692 try {
693 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700694 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700695 }
696 } catch (RemoteException ignored) {
697 }
698 }
699
Ihab Awad5d0410f2014-07-30 10:07:40 -0700700 /**
701 * Instructs this {@code RemoteConnection} to disconnect.
702 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700703 public void disconnect() {
704 try {
705 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700706 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700707 }
708 } catch (RemoteException ignored) {
709 }
710 }
711
Ihab Awad5d0410f2014-07-30 10:07:40 -0700712 /**
713 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
714 * (DTMF) tone.
715 *
716 * Any other currently playing DTMF tone in the specified call is immediately stopped.
717 *
718 * @param digit A character representing the DTMF digit for which to play the tone. This
719 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
720 */
721 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700722 try {
723 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700724 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700725 }
726 } catch (RemoteException ignored) {
727 }
728 }
729
Ihab Awad5d0410f2014-07-30 10:07:40 -0700730 /**
731 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
732 * (DTMF) tone currently playing.
733 *
734 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
735 * currently playing, this method will do nothing.
736 */
737 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700738 try {
739 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700740 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700741 }
742 } catch (RemoteException ignored) {
743 }
744 }
745
Ihab Awad5d0410f2014-07-30 10:07:40 -0700746 /**
747 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
748 *
749 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700750 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700751 * These digits are immediately sent as DTMF tones to the recipient as soon as the
752 * connection is made.
753 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700754 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700755 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
756 * of time.
757 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700758 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800759 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -0700760 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700761 * should display to the user an indication of this state and an affordance to continue
762 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
763 * app should invoke the {@link #postDialContinue(boolean)} method.
764 *
765 * @param proceed Whether or not to continue with the post-dial sequence.
766 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700767 public void postDialContinue(boolean proceed) {
768 try {
769 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700770 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700771 }
772 } catch (RemoteException ignored) {
773 }
774 }
775
Ihab Awad5d0410f2014-07-30 10:07:40 -0700776 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700777 * Set the audio state of this {@code RemoteConnection}.
778 *
779 * @param state The audio state of this {@code RemoteConnection}.
Yorke Lee4af59352015-05-13 14:14:54 -0700780 * @hide
781 * @deprecated Use {@link #setCallAudioState(CallAudioState) instead.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700782 */
Yorke Lee4af59352015-05-13 14:14:54 -0700783 @SystemApi
784 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700785 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -0700786 setCallAudioState(new CallAudioState(state));
787 }
788
789 /**
790 * Set the audio state of this {@code RemoteConnection}.
791 *
792 * @param state The audio state of this {@code RemoteConnection}.
793 */
794 public void setCallAudioState(CallAudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700795 try {
796 if (mConnected) {
Yorke Lee4af59352015-05-13 14:14:54 -0700797 mConnectionService.onCallAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700798 }
799 } catch (RemoteException ignored) {
800 }
801 }
802
Santos Cordon52d8a152014-06-17 19:08:45 -0700803 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700804 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
805 * successfully asked to create a conference with.
806 *
807 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
808 * merged into a {@link RemoteConference}.
809 */
810 public List<RemoteConnection> getConferenceableConnections() {
811 return mUnmodifiableconferenceableConnections;
812 }
813
814 /**
815 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
816 * of, or {@code null} if there is no such {@code RemoteConference}.
817 *
818 * @return A {@code RemoteConference} or {@code null};
819 */
820 public RemoteConference getConference() {
821 return mConference;
822 }
823
824 /** {@hide} */
825 String getId() {
826 return mConnectionId;
827 }
828
829 /** {@hide} */
830 IConnectionService getConnectionService() {
831 return mConnectionService;
832 }
833
834 /**
Santos Cordon52d8a152014-06-17 19:08:45 -0700835 * @hide
836 */
Andrew Lee011728f2015-04-23 15:47:06 -0700837 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700838 if (mState != state) {
839 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -0700840 for (CallbackRecord record: mCallbackRecords) {
841 final RemoteConnection connection = this;
842 final Callback callback = record.getCallback();
843 record.getHandler().post(new Runnable() {
844 @Override
845 public void run() {
846 callback.onStateChanged(connection, state);
847 }
848 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700849 }
850 }
851 }
852
853 /**
854 * @hide
855 */
Andrew Lee011728f2015-04-23 15:47:06 -0700856 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700857 if (mState != Connection.STATE_DISCONNECTED) {
858 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700859 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700860
Andrew Lee011728f2015-04-23 15:47:06 -0700861 for (CallbackRecord record : mCallbackRecords) {
862 final RemoteConnection connection = this;
863 final Callback callback = record.getCallback();
864 record.getHandler().post(new Runnable() {
865 @Override
866 public void run() {
867 callback.onDisconnected(connection, disconnectCause);
868 }
869 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700870 }
871 }
872 }
873
874 /**
875 * @hide
876 */
Andrew Lee011728f2015-04-23 15:47:06 -0700877 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -0700878 if (mRingbackRequested != ringback) {
879 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -0700880 for (CallbackRecord record : mCallbackRecords) {
881 final RemoteConnection connection = this;
882 final Callback callback = record.getCallback();
883 record.getHandler().post(new Runnable() {
884 @Override
885 public void run() {
886 callback.onRingbackRequested(connection, ringback);
887 }
888 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700889 }
890 }
891 }
892
893 /**
894 * @hide
895 */
Andrew Lee011728f2015-04-23 15:47:06 -0700896 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800897 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -0700898 for (CallbackRecord record : mCallbackRecords) {
899 final RemoteConnection connection = this;
900 final Callback callback = record.getCallback();
901 record.getHandler().post(new Runnable() {
902 @Override
903 public void run() {
904 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
905 }
906 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700907 }
908 }
909
910 /**
911 * @hide
912 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700913 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -0700914 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -0700915 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700916 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700917 setDisconnected(
918 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -0700919 }
920
Andrew Lee011728f2015-04-23 15:47:06 -0700921 for (CallbackRecord record : mCallbackRecords) {
922 final RemoteConnection connection = this;
923 final Callback callback = record.getCallback();
924 record.getHandler().post(new Runnable() {
925 @Override
926 public void run() {
927 callback.onDestroyed(connection);
928 }
929 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700930 }
Andrew Lee011728f2015-04-23 15:47:06 -0700931 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -0700932
933 mConnected = false;
934 }
935 }
936
937 /**
938 * @hide
939 */
Andrew Lee011728f2015-04-23 15:47:06 -0700940 void setPostDialWait(final String remainingDigits) {
941 for (CallbackRecord record : mCallbackRecords) {
942 final RemoteConnection connection = this;
943 final Callback callback = record.getCallback();
944 record.getHandler().post(new Runnable() {
945 @Override
946 public void run() {
947 callback.onPostDialWait(connection, remainingDigits);
948 }
949 });
Santos Cordon52d8a152014-06-17 19:08:45 -0700950 }
951 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700952
Tyler Gunnaa07df82014-07-17 07:50:22 -0700953 /**
954 * @hide
955 */
Andrew Lee011728f2015-04-23 15:47:06 -0700956 void onPostDialChar(final char nextChar) {
957 for (CallbackRecord record : mCallbackRecords) {
958 final RemoteConnection connection = this;
959 final Callback callback = record.getCallback();
960 record.getHandler().post(new Runnable() {
961 @Override
962 public void run() {
Sailesh Nepal40451b32015-05-14 17:39:41 -0700963 callback.onPostDialChar(connection, nextChar);
Andrew Lee011728f2015-04-23 15:47:06 -0700964 }
965 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800966 }
967 }
968
969 /**
970 * @hide
971 */
Andrew Lee011728f2015-04-23 15:47:06 -0700972 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -0700973 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -0700974 for (CallbackRecord record : mCallbackRecords) {
975 final RemoteConnection connection = this;
976 final Callback callback = record.getCallback();
977 record.getHandler().post(new Runnable() {
978 @Override
979 public void run() {
980 callback.onVideoStateChanged(connection, videoState);
981 }
982 });
Tyler Gunnaa07df82014-07-17 07:50:22 -0700983 }
984 }
985
Ihab Awada64627c2014-08-20 09:36:40 -0700986 /**
987 * @hide
988 */
Andrew Lee011728f2015-04-23 15:47:06 -0700989 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -0700990 mVideoProvider = videoProvider;
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.onVideoProviderChanged(connection, videoProvider);
998 }
999 });
Ihab Awada64627c2014-08-20 09:36:40 -07001000 }
1001 }
1002
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001003 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001004 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -07001005 mIsVoipAudioMode = isVoip;
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.onVoipAudioChanged(connection, isVoip);
1013 }
1014 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001015 }
1016 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001017
1018 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001019 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001020 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001021 for (CallbackRecord record : mCallbackRecords) {
1022 final RemoteConnection connection = this;
1023 final Callback callback = record.getCallback();
1024 record.getHandler().post(new Runnable() {
1025 @Override
1026 public void run() {
1027 callback.onStatusHintsChanged(connection, statusHints);
1028 }
1029 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001030 }
1031 }
1032
1033 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001034 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001035 mAddress = address;
1036 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001037 for (CallbackRecord record : mCallbackRecords) {
1038 final RemoteConnection connection = this;
1039 final Callback callback = record.getCallback();
1040 record.getHandler().post(new Runnable() {
1041 @Override
1042 public void run() {
1043 callback.onAddressChanged(connection, address, presentation);
1044 }
1045 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001046 }
1047 }
1048
1049 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001050 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001051 mCallerDisplayName = callerDisplayName;
1052 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001053 for (CallbackRecord record : mCallbackRecords) {
1054 final RemoteConnection connection = this;
1055 final Callback callback = record.getCallback();
1056 record.getHandler().post(new Runnable() {
1057 @Override
1058 public void run() {
1059 callback.onCallerDisplayNameChanged(
1060 connection, callerDisplayName, presentation);
1061 }
1062 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001063 }
1064 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001065
1066 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001067 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001068 mConferenceableConnections.clear();
1069 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001070 for (CallbackRecord record : mCallbackRecords) {
1071 final RemoteConnection connection = this;
1072 final Callback callback = record.getCallback();
1073 record.getHandler().post(new Runnable() {
1074 @Override
1075 public void run() {
1076 callback.onConferenceableConnectionsChanged(
1077 connection, mUnmodifiableconferenceableConnections);
1078 }
1079 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001080 }
1081 }
1082
1083 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001084 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001085 if (mConference != conference) {
1086 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001087 for (CallbackRecord record : mCallbackRecords) {
1088 final RemoteConnection connection = this;
1089 final Callback callback = record.getCallback();
1090 record.getHandler().post(new Runnable() {
1091 @Override
1092 public void run() {
1093 callback.onConferenceChanged(connection, conference);
1094 }
1095 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001096 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001097 }
1098 }
1099
Evan Charltonbf11f982014-07-20 22:06:28 -07001100 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001101 * Create a RemoteConnection represents a failure, and which will be in
1102 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1103 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001104 *
1105 * @return a failed {@link RemoteConnection}
1106 *
1107 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001108 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001109 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1110 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001111 }
Andrew Lee011728f2015-04-23 15:47:06 -07001112
1113 private static final class CallbackRecord extends Callback {
1114 private final Callback mCallback;
1115 private final Handler mHandler;
1116
1117 public CallbackRecord(Callback callback, Handler handler) {
1118 mCallback = callback;
1119 mHandler = handler;
1120 }
1121
1122 public Callback getCallback() {
1123 return mCallback;
1124 }
1125
1126 public Handler getHandler() {
1127 return mHandler;
1128 }
1129 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001130}