blob: 816e2bf6b41899d1f8cd4db21ef594b35082820d [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;
Ihab Awada64627c2014-08-20 09:36:40 -070024import android.os.IBinder;
Santos Cordon52d8a152014-06-17 19:08:45 -070025import android.os.RemoteException;
Ihab Awada64627c2014-08-20 09:36:40 -070026import android.view.Surface;
Santos Cordon52d8a152014-06-17 19:08:45 -070027
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070028import java.util.ArrayList;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070029import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070030import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070031import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070032import java.util.concurrent.ConcurrentHashMap;
Santos Cordon52d8a152014-06-17 19:08:45 -070033
34/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070035 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
36 * running in a different process.
37 *
38 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
39 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070040 */
41public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070042
Andrew Lee100e2932014-09-08 15:34:24 -070043 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070044 /**
45 * Invoked when the state of this {@code RemoteConnection} has changed. See
46 * {@link #getState()}.
47 *
48 * @param connection The {@code RemoteConnection} invoking this method.
49 * @param state The new state of the {@code RemoteConnection}.
50 */
Evan Charltonbf11f982014-07-20 22:06:28 -070051 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070052
53 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070054 * Invoked when this {@code RemoteConnection} is disconnected.
55 *
56 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070057 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
58 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070059 */
60 public void onDisconnected(
61 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070062 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070063
64 /**
65 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070066 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070067 *
68 * @param connection The {@code RemoteConnection} invoking this method.
69 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
70 */
Andrew Lee100e2932014-09-08 15:34:24 -070071 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070072
73 /**
74 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
75 * See {@link #getCallCapabilities()}.
76 *
77 * @param connection The {@code RemoteConnection} invoking this method.
78 * @param callCapabilities The new call capabilities of the {@code RemoteConnection}.
79 */
Evan Charltonbf11f982014-07-20 22:06:28 -070080 public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070081
82 /**
83 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
84 * pause character. This causes the post-dial signals to stop pending user confirmation. An
85 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -070086 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -070087 *
88 * @param connection The {@code RemoteConnection} invoking this method.
89 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
90 */
91 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
92
93 /**
94 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -070095 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070096 *
97 * @param connection The {@code RemoteConnection} invoking this method.
98 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
99 */
Andrew Lee100e2932014-09-08 15:34:24 -0700100 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700101
102 /**
103 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
104 * {@link #getStatusHints()} ()}.
105 *
106 * @param connection The {@code RemoteConnection} invoking this method.
107 * @param statusHints The new status hints of the {@code RemoteConnection}.
108 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700109 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700110
111 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700112 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
113 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700114 *
115 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700116 * @param address The new address of the {@code RemoteConnection}.
117 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700118 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700119 */
Andrew Lee100e2932014-09-08 15:34:24 -0700120 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700121
122 /**
123 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
124 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
125 *
126 * @param connection The {@code RemoteConnection} invoking this method.
127 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700128 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700129 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700130 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700131 public void onCallerDisplayNameChanged(
132 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700133
134 /**
135 * Indicates that the video state of this {@code RemoteConnection} has changed.
136 * See {@link #getVideoState()}.
137 *
138 * @param connection The {@code RemoteConnection} invoking this method.
139 * @param videoState The new video state of the {@code RemoteConnection}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700140 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700141 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700142 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700143
144 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700145 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
146 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
147 *
148 * @param connection The {@code RemoteConnection} invoking this method.
149 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700150 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700151
152 /**
153 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
154 * may be asked to create a conference has changed.
155 *
156 * @param connection The {@code RemoteConnection} invoking this method.
157 * @param conferenceableConnections The {@code RemoteConnection}s with which this
158 * {@code RemoteConnection} may be asked to create a conference.
159 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700160 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700161 RemoteConnection connection,
162 List<RemoteConnection> conferenceableConnections) {}
163
164 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700165 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
166 * has changed.
167 *
168 * @param connection The {@code RemoteConnection} invoking this method.
169 * @param videoProvider The new {@code VideoProvider} associated with this
170 * {@code RemoteConnection}.
171 * @hide
172 */
173 public void onVideoProviderChanged(
174 RemoteConnection connection, VideoProvider videoProvider) {}
175
176 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700177 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
178 * of has changed.
179 *
180 * @param connection The {@code RemoteConnection} invoking this method.
181 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
182 * a part, which may be {@code null}.
183 */
184 public void onConferenceChanged(
185 RemoteConnection connection,
186 RemoteConference conference) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700187 }
188
Ihab Awada64627c2014-08-20 09:36:40 -0700189 /** {@hide} */
190 public static class VideoProvider {
191
192 public abstract static class Listener {
193 public void onReceiveSessionModifyRequest(
194 VideoProvider videoProvider,
195 VideoProfile videoProfile) {}
196
197 public void onReceiveSessionModifyResponse(
198 VideoProvider videoProvider,
199 int status,
200 VideoProfile requestedProfile,
201 VideoProfile responseProfile) {}
202
203 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {}
204
205 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {}
206
207 public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {}
208
209 public void onCameraCapabilitiesChanged(
210 VideoProvider videoProvider,
211 CameraCapabilities cameraCapabilities) {}
212 }
213
214 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
215 @Override
216 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
217 for (Listener l : mListeners) {
218 l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile);
219 }
220 }
221
222 @Override
223 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
224 VideoProfile responseProfile) {
225 for (Listener l : mListeners) {
226 l.onReceiveSessionModifyResponse(
227 VideoProvider.this,
228 status,
229 requestedProfile,
230 responseProfile);
231 }
232 }
233
234 @Override
235 public void handleCallSessionEvent(int event) {
236 for (Listener l : mListeners) {
237 l.onHandleCallSessionEvent(VideoProvider.this, event);
238 }
239 }
240
241 @Override
242 public void changePeerDimensions(int width, int height) {
243 for (Listener l : mListeners) {
244 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
245 }
246 }
247
248 @Override
249 public void changeCallDataUsage(int dataUsage) {
250 for (Listener l : mListeners) {
251 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
252 }
253 }
254
255 @Override
256 public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
257 for (Listener l : mListeners) {
258 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
259 }
260 }
261
262 @Override
263 public IBinder asBinder() {
264 return null;
265 }
266 };
267
268 private final VideoCallbackServant mVideoCallbackServant =
269 new VideoCallbackServant(mVideoCallbackDelegate);
270
271 private final IVideoProvider mVideoProviderBinder;
272
273 /**
274 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
275 * load factor before resizing, 1 means we only expect a single thread to
276 * access the map so make only a single shard
277 */
278 private final Set<Listener> mListeners = Collections.newSetFromMap(
279 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
280
281 public VideoProvider(IVideoProvider videoProviderBinder) {
282 mVideoProviderBinder = videoProviderBinder;
283 try {
284 mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder());
285 } catch (RemoteException e) {
286 }
287 }
288
289 public void addListener(Listener l) {
290 mListeners.add(l);
291 }
292
293 public void removeListener(Listener l) {
294 mListeners.remove(l);
295 }
296
297 public void setCamera(String cameraId) {
298 try {
299 mVideoProviderBinder.setCamera(cameraId);
300 } catch (RemoteException e) {
301 }
302 }
303
304 public void setPreviewSurface(Surface surface) {
305 try {
306 mVideoProviderBinder.setPreviewSurface(surface);
307 } catch (RemoteException e) {
308 }
309 }
310
311 public void setDisplaySurface(Surface surface) {
312 try {
313 mVideoProviderBinder.setDisplaySurface(surface);
314 } catch (RemoteException e) {
315 }
316 }
317
318 public void setDeviceOrientation(int rotation) {
319 try {
320 mVideoProviderBinder.setDeviceOrientation(rotation);
321 } catch (RemoteException e) {
322 }
323 }
324
325 public void setZoom(float value) {
326 try {
327 mVideoProviderBinder.setZoom(value);
328 } catch (RemoteException e) {
329 }
330 }
331
332 public void sendSessionModifyRequest(VideoProfile reqProfile) {
333 try {
334 mVideoProviderBinder.sendSessionModifyRequest(reqProfile);
335 } catch (RemoteException e) {
336 }
337 }
338
339 public void sendSessionModifyResponse(VideoProfile responseProfile) {
340 try {
341 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
342 } catch (RemoteException e) {
343 }
344 }
345
346 public void requestCameraCapabilities() {
347 try {
348 mVideoProviderBinder.requestCameraCapabilities();
349 } catch (RemoteException e) {
350 }
351 }
352
353 public void requestCallDataUsage() {
354 try {
355 mVideoProviderBinder.requestCallDataUsage();
356 } catch (RemoteException e) {
357 }
358 }
359
360 public void setPauseImage(String uri) {
361 try {
362 mVideoProviderBinder.setPauseImage(uri);
363 } catch (RemoteException e) {
364 }
365 }
366 }
367
Evan Charltonbf11f982014-07-20 22:06:28 -0700368 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700369 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700370 /**
371 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
372 * load factor before resizing, 1 means we only expect a single thread to
373 * access the map so make only a single shard
374 */
Andrew Lee100e2932014-09-08 15:34:24 -0700375 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
376 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700377 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
378 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
379 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700380
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700381 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700382 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700383 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700384 private boolean mConnected;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700385 private int mCallCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700386 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700387 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700388 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700389 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700390 private Uri mAddress;
391 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700392 private String mCallerDisplayName;
393 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700394 private RemoteConference mConference;
Santos Cordon52d8a152014-06-17 19:08:45 -0700395
396 /**
397 * @hide
398 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700399 RemoteConnection(
400 String id,
401 IConnectionService connectionService,
402 ConnectionRequest request) {
403 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700404 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700405 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700406 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700407 }
408
409 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700410 * @hide
411 */
412 RemoteConnection(String callId, IConnectionService connectionService,
413 ParcelableConnection connection) {
414 mConnectionId = callId;
415 mConnectionService = connectionService;
416 mConnected = true;
417 mState = connection.getState();
418 mDisconnectCause = connection.getDisconnectCause();
419 mRingbackRequested = connection.isRingbackRequested();
420 mCallCapabilities = connection.getCapabilities();
421 mVideoState = connection.getVideoState();
422 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
423 mIsVoipAudioMode = connection.getIsVoipAudioMode();
424 mStatusHints = connection.getStatusHints();
425 mAddress = connection.getHandle();
426 mAddressPresentation = connection.getHandlePresentation();
427 mCallerDisplayName = connection.getCallerDisplayName();
428 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
429 mConference = null;
430 }
431
432 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700433 * Create a RemoteConnection which is used for failed connections. Note that using it for any
434 * "real" purpose will almost certainly fail. Callers should note the failure and act
435 * accordingly (moving on to another RemoteConnection, for example)
436 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700437 * @param disconnectCause The reason for the failed connection.
438 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700439 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700440 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700441 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700442 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700443 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700444 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700445 }
446
Ihab Awad5d0410f2014-07-30 10:07:40 -0700447 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700448 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700449 *
Andrew Lee100e2932014-09-08 15:34:24 -0700450 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700451 */
Andrew Lee100e2932014-09-08 15:34:24 -0700452 public void registerCallback(Callback callback) {
453 mCallbacks.add(callback);
Santos Cordon52d8a152014-06-17 19:08:45 -0700454 }
455
Ihab Awad5d0410f2014-07-30 10:07:40 -0700456 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700457 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700458 *
Andrew Lee100e2932014-09-08 15:34:24 -0700459 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700460 */
Andrew Lee100e2932014-09-08 15:34:24 -0700461 public void unregisterCallback(Callback callback) {
462 if (callback != null) {
463 mCallbacks.remove(callback);
Jay Shrauner229e3822014-08-15 09:23:07 -0700464 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700465 }
466
Ihab Awad5d0410f2014-07-30 10:07:40 -0700467 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700468 * Obtains the state of this {@code RemoteConnection}.
469 *
470 * @return A state value, chosen from the {@code STATE_*} constants.
471 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700472 public int getState() {
473 return mState;
474 }
475
Ihab Awad5d0410f2014-07-30 10:07:40 -0700476 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700477 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5d0410f2014-07-30 10:07:40 -0700478 * disconnect cause expressed as a code chosen from among those declared in
479 * {@link DisconnectCause}.
480 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700481 public DisconnectCause getDisconnectCause() {
482 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700483 }
484
Ihab Awad5d0410f2014-07-30 10:07:40 -0700485 /**
486 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700487 * {@link PhoneCapabilities}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700488 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700489 public int getCallCapabilities() {
490 return mCallCapabilities;
491 }
492
Ihab Awad5d0410f2014-07-30 10:07:40 -0700493 /**
494 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
495 */
Andrew Lee100e2932014-09-08 15:34:24 -0700496 public boolean isVoipAudioMode() {
497 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700498 }
499
Ihab Awad5d0410f2014-07-30 10:07:40 -0700500 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700501 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5d0410f2014-07-30 10:07:40 -0700502 * or {@code null} if none have been set.
503 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700504 public StatusHints getStatusHints() {
505 return mStatusHints;
506 }
507
Ihab Awad5d0410f2014-07-30 10:07:40 -0700508 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700509 * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently
Ihab Awad5d0410f2014-07-30 10:07:40 -0700510 * connected.
511 */
Andrew Lee100e2932014-09-08 15:34:24 -0700512 public Uri getAddress() {
513 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700514 }
515
Ihab Awad5d0410f2014-07-30 10:07:40 -0700516 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700517 * @return The presentation requirements for the address. See {@link TelecomManager} for valid
Andrew Lee100e2932014-09-08 15:34:24 -0700518 * values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700519 */
Andrew Lee100e2932014-09-08 15:34:24 -0700520 public int getAddressPresentation() {
521 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700522 }
523
Ihab Awad5d0410f2014-07-30 10:07:40 -0700524 /**
525 * @return The display name for the caller.
526 */
Andrew Lee100e2932014-09-08 15:34:24 -0700527 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700528 return mCallerDisplayName;
529 }
530
Ihab Awad5d0410f2014-07-30 10:07:40 -0700531 /**
532 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700533 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700534 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700535 public int getCallerDisplayNamePresentation() {
536 return mCallerDisplayNamePresentation;
537 }
538
Ihab Awad5d0410f2014-07-30 10:07:40 -0700539 /**
540 * @return The video state of the {@code RemoteConnection}. See
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700541 * {@link VideoProfile.VideoState}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700542 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700543 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700544 public int getVideoState() {
545 return mVideoState;
546 }
547
Ihab Awad5d0410f2014-07-30 10:07:40 -0700548 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700549 * @return The video provider associated with this {@code RemoteConnection}.
550 * @hide
551 */
552 public final VideoProvider getVideoProvider() {
553 return mVideoProvider;
554 }
555
556 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700557 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
558 * ringback tone on its behalf.
559 */
Andrew Lee100e2932014-09-08 15:34:24 -0700560 public boolean isRingbackRequested() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700561 return false;
562 }
563
564 /**
565 * Instructs this {@code RemoteConnection} to abort.
566 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700567 public void abort() {
568 try {
569 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700570 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700571 }
572 } catch (RemoteException ignored) {
573 }
574 }
575
Ihab Awad5d0410f2014-07-30 10:07:40 -0700576 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700577 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700578 */
579 public void answer() {
580 try {
581 if (mConnected) {
582 mConnectionService.answer(mConnectionId);
583 }
584 } catch (RemoteException ignored) {
585 }
586 }
587
588 /**
589 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700590 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700591 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700592 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700593 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700594 try {
595 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700596 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700597 }
598 } catch (RemoteException ignored) {
599 }
600 }
601
Ihab Awad5d0410f2014-07-30 10:07:40 -0700602 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700603 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700604 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700605 public void reject() {
606 try {
607 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700608 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700609 }
610 } catch (RemoteException ignored) {
611 }
612 }
613
Ihab Awad5d0410f2014-07-30 10:07:40 -0700614 /**
615 * Instructs this {@code RemoteConnection} to go on hold.
616 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700617 public void hold() {
618 try {
619 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700620 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700621 }
622 } catch (RemoteException ignored) {
623 }
624 }
625
Ihab Awad5d0410f2014-07-30 10:07:40 -0700626 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700627 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700628 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700629 public void unhold() {
630 try {
631 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700632 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700633 }
634 } catch (RemoteException ignored) {
635 }
636 }
637
Ihab Awad5d0410f2014-07-30 10:07:40 -0700638 /**
639 * Instructs this {@code RemoteConnection} to disconnect.
640 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700641 public void disconnect() {
642 try {
643 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700644 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700645 }
646 } catch (RemoteException ignored) {
647 }
648 }
649
Ihab Awad5d0410f2014-07-30 10:07:40 -0700650 /**
651 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
652 * (DTMF) tone.
653 *
654 * Any other currently playing DTMF tone in the specified call is immediately stopped.
655 *
656 * @param digit A character representing the DTMF digit for which to play the tone. This
657 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
658 */
659 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700660 try {
661 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700662 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700663 }
664 } catch (RemoteException ignored) {
665 }
666 }
667
Ihab Awad5d0410f2014-07-30 10:07:40 -0700668 /**
669 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
670 * (DTMF) tone currently playing.
671 *
672 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
673 * currently playing, this method will do nothing.
674 */
675 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700676 try {
677 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700678 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700679 }
680 } catch (RemoteException ignored) {
681 }
682 }
683
Ihab Awad5d0410f2014-07-30 10:07:40 -0700684 /**
685 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
686 *
687 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700688 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700689 * These digits are immediately sent as DTMF tones to the recipient as soon as the
690 * connection is made.
691 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700692 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700693 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
694 * of time.
695 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700696 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Lee100e2932014-09-08 15:34:24 -0700697 * {@code RemoteConnection} will pause playing the tones and notify callbackss via
698 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700699 * should display to the user an indication of this state and an affordance to continue
700 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
701 * app should invoke the {@link #postDialContinue(boolean)} method.
702 *
703 * @param proceed Whether or not to continue with the post-dial sequence.
704 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700705 public void postDialContinue(boolean proceed) {
706 try {
707 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700708 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700709 }
710 } catch (RemoteException ignored) {
711 }
712 }
713
Ihab Awad5d0410f2014-07-30 10:07:40 -0700714 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700715 * Set the audio state of this {@code RemoteConnection}.
716 *
717 * @param state The audio state of this {@code RemoteConnection}.
718 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700719 public void setAudioState(AudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700720 try {
721 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700722 mConnectionService.onAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700723 }
724 } catch (RemoteException ignored) {
725 }
726 }
727
Santos Cordon52d8a152014-06-17 19:08:45 -0700728 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700729 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
730 * successfully asked to create a conference with.
731 *
732 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
733 * merged into a {@link RemoteConference}.
734 */
735 public List<RemoteConnection> getConferenceableConnections() {
736 return mUnmodifiableconferenceableConnections;
737 }
738
739 /**
740 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
741 * of, or {@code null} if there is no such {@code RemoteConference}.
742 *
743 * @return A {@code RemoteConference} or {@code null};
744 */
745 public RemoteConference getConference() {
746 return mConference;
747 }
748
749 /** {@hide} */
750 String getId() {
751 return mConnectionId;
752 }
753
754 /** {@hide} */
755 IConnectionService getConnectionService() {
756 return mConnectionService;
757 }
758
759 /**
Santos Cordon52d8a152014-06-17 19:08:45 -0700760 * @hide
761 */
762 void setState(int state) {
763 if (mState != state) {
764 mState = state;
Andrew Lee100e2932014-09-08 15:34:24 -0700765 for (Callback c: mCallbacks) {
766 c.onStateChanged(this, state);
Santos Cordon52d8a152014-06-17 19:08:45 -0700767 }
768 }
769 }
770
771 /**
772 * @hide
773 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700774 void setDisconnected(DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700775 if (mState != Connection.STATE_DISCONNECTED) {
776 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700777 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700778
Andrew Lee100e2932014-09-08 15:34:24 -0700779 for (Callback c : mCallbacks) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700780 c.onDisconnected(this, mDisconnectCause);
Santos Cordon52d8a152014-06-17 19:08:45 -0700781 }
782 }
783 }
784
785 /**
786 * @hide
787 */
Andrew Lee100e2932014-09-08 15:34:24 -0700788 void setRingbackRequested(boolean ringback) {
789 if (mRingbackRequested != ringback) {
790 mRingbackRequested = ringback;
791 for (Callback c : mCallbacks) {
792 c.onRingbackRequested(this, ringback);
Santos Cordon52d8a152014-06-17 19:08:45 -0700793 }
794 }
795 }
796
797 /**
798 * @hide
799 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700800 void setCallCapabilities(int callCapabilities) {
801 mCallCapabilities = callCapabilities;
Andrew Lee100e2932014-09-08 15:34:24 -0700802 for (Callback c : mCallbacks) {
803 c.onCallCapabilitiesChanged(this, callCapabilities);
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700804 }
805 }
806
807 /**
808 * @hide
809 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700810 void setDestroyed() {
Andrew Lee100e2932014-09-08 15:34:24 -0700811 if (!mCallbacks.isEmpty()) {
812 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700813 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700814 setDisconnected(
815 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -0700816 }
817
Andrew Lee100e2932014-09-08 15:34:24 -0700818 for (Callback c : mCallbacks) {
819 c.onDestroyed(this);
Santos Cordon52d8a152014-06-17 19:08:45 -0700820 }
Andrew Lee100e2932014-09-08 15:34:24 -0700821 mCallbacks.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -0700822
823 mConnected = false;
824 }
825 }
826
827 /**
828 * @hide
829 */
830 void setPostDialWait(String remainingDigits) {
Andrew Lee100e2932014-09-08 15:34:24 -0700831 for (Callback c : mCallbacks) {
832 c.onPostDialWait(this, remainingDigits);
Santos Cordon52d8a152014-06-17 19:08:45 -0700833 }
834 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700835
Tyler Gunnaa07df82014-07-17 07:50:22 -0700836 /**
837 * @hide
838 */
839 void setVideoState(int videoState) {
840 mVideoState = videoState;
Andrew Lee100e2932014-09-08 15:34:24 -0700841 for (Callback c : mCallbacks) {
842 c.onVideoStateChanged(this, videoState);
Tyler Gunnaa07df82014-07-17 07:50:22 -0700843 }
844 }
845
Ihab Awada64627c2014-08-20 09:36:40 -0700846 /**
847 * @hide
848 */
849 void setVideoProvider(VideoProvider videoProvider) {
850 mVideoProvider = videoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700851 for (Callback c : mCallbacks) {
852 c.onVideoProviderChanged(this, videoProvider);
Ihab Awada64627c2014-08-20 09:36:40 -0700853 }
854 }
855
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700856 /** @hide */
Andrew Lee100e2932014-09-08 15:34:24 -0700857 void setIsVoipAudioMode(boolean isVoip) {
858 mIsVoipAudioMode = isVoip;
859 for (Callback c : mCallbacks) {
860 c.onVoipAudioChanged(this, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700861 }
862 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700863
864 /** @hide */
865 void setStatusHints(StatusHints statusHints) {
866 mStatusHints = statusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700867 for (Callback c : mCallbacks) {
868 c.onStatusHintsChanged(this, statusHints);
Sailesh Nepal61203862014-07-11 14:50:13 -0700869 }
870 }
871
872 /** @hide */
Andrew Lee100e2932014-09-08 15:34:24 -0700873 void setAddress(Uri address, int presentation) {
874 mAddress = address;
875 mAddressPresentation = presentation;
876 for (Callback c : mCallbacks) {
877 c.onAddressChanged(this, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -0700878 }
879 }
880
881 /** @hide */
882 void setCallerDisplayName(String callerDisplayName, int presentation) {
883 mCallerDisplayName = callerDisplayName;
884 mCallerDisplayNamePresentation = presentation;
Andrew Lee100e2932014-09-08 15:34:24 -0700885 for (Callback c : mCallbacks) {
886 c.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700887 }
888 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -0700889
890 /** @hide */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700891 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
892 mConferenceableConnections.clear();
893 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee100e2932014-09-08 15:34:24 -0700894 for (Callback c : mCallbacks) {
895 c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700896 }
897 }
898
899 /** @hide */
900 void setConference(RemoteConference conference) {
901 if (mConference != conference) {
902 mConference = conference;
Andrew Lee100e2932014-09-08 15:34:24 -0700903 for (Callback c : mCallbacks) {
904 c.onConferenceChanged(this, conference);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700905 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700906 }
907 }
908
Evan Charltonbf11f982014-07-20 22:06:28 -0700909 /**
Ihab Awad6107bab2014-08-18 09:23:25 -0700910 * Create a RemoteConnection represents a failure, and which will be in
911 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
912 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -0700913 *
914 * @return a failed {@link RemoteConnection}
915 *
916 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700917 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700918 public static RemoteConnection failure(DisconnectCause disconnectCause) {
919 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -0700920 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700921}