blob: d70ddf66437d5714da68e7cecc14d190e9794672 [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
Evan Charlton0e094d92014-11-08 15:49:16 -080023import android.annotation.SystemApi;
Santos Cordon52d8a152014-06-17 19:08:45 -070024import android.net.Uri;
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)
Evan Charlton0e094d92014-11-08 15:49:16 -080041 * @hide
Santos Cordon52d8a152014-06-17 19:08:45 -070042 */
Evan Charlton0e094d92014-11-08 15:49:16 -080043@SystemApi
Santos Cordon52d8a152014-06-17 19:08:45 -070044public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070045
Andrew Lee100e2932014-09-08 15:34:24 -070046 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070047 /**
48 * Invoked when the state of this {@code RemoteConnection} has changed. See
49 * {@link #getState()}.
50 *
51 * @param connection The {@code RemoteConnection} invoking this method.
52 * @param state The new state of the {@code RemoteConnection}.
53 */
Evan Charltonbf11f982014-07-20 22:06:28 -070054 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070055
56 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070057 * Invoked when this {@code RemoteConnection} is disconnected.
58 *
59 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070060 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
61 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070062 */
63 public void onDisconnected(
64 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070065 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070066
67 /**
68 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070069 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070070 *
71 * @param connection The {@code RemoteConnection} invoking this method.
72 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
73 */
Andrew Lee100e2932014-09-08 15:34:24 -070074 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070075
76 /**
77 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
78 * See {@link #getCallCapabilities()}.
79 *
80 * @param connection The {@code RemoteConnection} invoking this method.
81 * @param callCapabilities The new call capabilities of the {@code RemoteConnection}.
82 */
Evan Charltonbf11f982014-07-20 22:06:28 -070083 public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {}
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 /**
97 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -070098 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070099 *
100 * @param connection The {@code RemoteConnection} invoking this method.
101 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
102 */
Andrew Lee100e2932014-09-08 15:34:24 -0700103 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700104
105 /**
106 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
107 * {@link #getStatusHints()} ()}.
108 *
109 * @param connection The {@code RemoteConnection} invoking this method.
110 * @param statusHints The new status hints of the {@code RemoteConnection}.
111 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700112 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700113
114 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700115 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
116 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700117 *
118 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700119 * @param address The new address of the {@code RemoteConnection}.
120 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700121 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700122 */
Andrew Lee100e2932014-09-08 15:34:24 -0700123 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700124
125 /**
126 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
127 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
128 *
129 * @param connection The {@code RemoteConnection} invoking this method.
130 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700131 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700132 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700133 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700134 public void onCallerDisplayNameChanged(
135 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700136
137 /**
138 * Indicates that the video state of this {@code RemoteConnection} has changed.
139 * See {@link #getVideoState()}.
140 *
141 * @param connection The {@code RemoteConnection} invoking this method.
142 * @param videoState The new video state of the {@code RemoteConnection}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700143 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700144 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700145 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700146
147 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700148 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
149 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
150 *
151 * @param connection The {@code RemoteConnection} invoking this method.
152 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700153 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700154
155 /**
156 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
157 * may be asked to create a conference has changed.
158 *
159 * @param connection The {@code RemoteConnection} invoking this method.
160 * @param conferenceableConnections The {@code RemoteConnection}s with which this
161 * {@code RemoteConnection} may be asked to create a conference.
162 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700163 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700164 RemoteConnection connection,
165 List<RemoteConnection> conferenceableConnections) {}
166
167 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700168 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
169 * has changed.
170 *
171 * @param connection The {@code RemoteConnection} invoking this method.
172 * @param videoProvider The new {@code VideoProvider} associated with this
173 * {@code RemoteConnection}.
174 * @hide
175 */
176 public void onVideoProviderChanged(
177 RemoteConnection connection, VideoProvider videoProvider) {}
178
179 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700180 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
181 * of has changed.
182 *
183 * @param connection The {@code RemoteConnection} invoking this method.
184 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
185 * a part, which may be {@code null}.
186 */
187 public void onConferenceChanged(
188 RemoteConnection connection,
189 RemoteConference conference) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700190 }
191
Ihab Awada64627c2014-08-20 09:36:40 -0700192 /** {@hide} */
193 public static class VideoProvider {
194
195 public abstract static class Listener {
196 public void onReceiveSessionModifyRequest(
197 VideoProvider videoProvider,
198 VideoProfile videoProfile) {}
199
200 public void onReceiveSessionModifyResponse(
201 VideoProvider videoProvider,
202 int status,
203 VideoProfile requestedProfile,
204 VideoProfile responseProfile) {}
205
206 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {}
207
208 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {}
209
210 public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {}
211
212 public void onCameraCapabilitiesChanged(
213 VideoProvider videoProvider,
214 CameraCapabilities cameraCapabilities) {}
215 }
216
217 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
218 @Override
219 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
220 for (Listener l : mListeners) {
221 l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile);
222 }
223 }
224
225 @Override
226 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
227 VideoProfile responseProfile) {
228 for (Listener l : mListeners) {
229 l.onReceiveSessionModifyResponse(
230 VideoProvider.this,
231 status,
232 requestedProfile,
233 responseProfile);
234 }
235 }
236
237 @Override
238 public void handleCallSessionEvent(int event) {
239 for (Listener l : mListeners) {
240 l.onHandleCallSessionEvent(VideoProvider.this, event);
241 }
242 }
243
244 @Override
245 public void changePeerDimensions(int width, int height) {
246 for (Listener l : mListeners) {
247 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
248 }
249 }
250
251 @Override
252 public void changeCallDataUsage(int dataUsage) {
253 for (Listener l : mListeners) {
254 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
255 }
256 }
257
258 @Override
259 public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
260 for (Listener l : mListeners) {
261 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
262 }
263 }
264
265 @Override
266 public IBinder asBinder() {
267 return null;
268 }
269 };
270
271 private final VideoCallbackServant mVideoCallbackServant =
272 new VideoCallbackServant(mVideoCallbackDelegate);
273
274 private final IVideoProvider mVideoProviderBinder;
275
276 /**
277 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
278 * load factor before resizing, 1 means we only expect a single thread to
279 * access the map so make only a single shard
280 */
281 private final Set<Listener> mListeners = Collections.newSetFromMap(
282 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
283
284 public VideoProvider(IVideoProvider videoProviderBinder) {
285 mVideoProviderBinder = videoProviderBinder;
286 try {
287 mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder());
288 } catch (RemoteException e) {
289 }
290 }
291
292 public void addListener(Listener l) {
293 mListeners.add(l);
294 }
295
296 public void removeListener(Listener l) {
297 mListeners.remove(l);
298 }
299
300 public void setCamera(String cameraId) {
301 try {
302 mVideoProviderBinder.setCamera(cameraId);
303 } catch (RemoteException e) {
304 }
305 }
306
307 public void setPreviewSurface(Surface surface) {
308 try {
309 mVideoProviderBinder.setPreviewSurface(surface);
310 } catch (RemoteException e) {
311 }
312 }
313
314 public void setDisplaySurface(Surface surface) {
315 try {
316 mVideoProviderBinder.setDisplaySurface(surface);
317 } catch (RemoteException e) {
318 }
319 }
320
321 public void setDeviceOrientation(int rotation) {
322 try {
323 mVideoProviderBinder.setDeviceOrientation(rotation);
324 } catch (RemoteException e) {
325 }
326 }
327
328 public void setZoom(float value) {
329 try {
330 mVideoProviderBinder.setZoom(value);
331 } catch (RemoteException e) {
332 }
333 }
334
335 public void sendSessionModifyRequest(VideoProfile reqProfile) {
336 try {
337 mVideoProviderBinder.sendSessionModifyRequest(reqProfile);
338 } catch (RemoteException e) {
339 }
340 }
341
342 public void sendSessionModifyResponse(VideoProfile responseProfile) {
343 try {
344 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
345 } catch (RemoteException e) {
346 }
347 }
348
349 public void requestCameraCapabilities() {
350 try {
351 mVideoProviderBinder.requestCameraCapabilities();
352 } catch (RemoteException e) {
353 }
354 }
355
356 public void requestCallDataUsage() {
357 try {
358 mVideoProviderBinder.requestCallDataUsage();
359 } catch (RemoteException e) {
360 }
361 }
362
363 public void setPauseImage(String uri) {
364 try {
365 mVideoProviderBinder.setPauseImage(uri);
366 } catch (RemoteException e) {
367 }
368 }
369 }
370
Evan Charltonbf11f982014-07-20 22:06:28 -0700371 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700372 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700373 /**
374 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
375 * load factor before resizing, 1 means we only expect a single thread to
376 * access the map so make only a single shard
377 */
Andrew Lee100e2932014-09-08 15:34:24 -0700378 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
379 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700380 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
381 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
382 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700383
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700384 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700385 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700386 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700387 private boolean mConnected;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700388 private int mCallCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700389 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700390 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700391 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700392 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700393 private Uri mAddress;
394 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700395 private String mCallerDisplayName;
396 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700397 private RemoteConference mConference;
Santos Cordon52d8a152014-06-17 19:08:45 -0700398
399 /**
400 * @hide
401 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700402 RemoteConnection(
403 String id,
404 IConnectionService connectionService,
405 ConnectionRequest request) {
406 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700407 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700408 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700409 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700410 }
411
412 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700413 * @hide
414 */
415 RemoteConnection(String callId, IConnectionService connectionService,
416 ParcelableConnection connection) {
417 mConnectionId = callId;
418 mConnectionService = connectionService;
419 mConnected = true;
420 mState = connection.getState();
421 mDisconnectCause = connection.getDisconnectCause();
422 mRingbackRequested = connection.isRingbackRequested();
423 mCallCapabilities = connection.getCapabilities();
424 mVideoState = connection.getVideoState();
425 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
426 mIsVoipAudioMode = connection.getIsVoipAudioMode();
427 mStatusHints = connection.getStatusHints();
428 mAddress = connection.getHandle();
429 mAddressPresentation = connection.getHandlePresentation();
430 mCallerDisplayName = connection.getCallerDisplayName();
431 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
432 mConference = null;
433 }
434
435 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700436 * Create a RemoteConnection which is used for failed connections. Note that using it for any
437 * "real" purpose will almost certainly fail. Callers should note the failure and act
438 * accordingly (moving on to another RemoteConnection, for example)
439 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700440 * @param disconnectCause The reason for the failed connection.
441 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700442 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700443 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700444 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700445 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700446 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700447 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700448 }
449
Ihab Awad5d0410f2014-07-30 10:07:40 -0700450 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700451 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700452 *
Andrew Lee100e2932014-09-08 15:34:24 -0700453 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700454 */
Andrew Lee100e2932014-09-08 15:34:24 -0700455 public void registerCallback(Callback callback) {
456 mCallbacks.add(callback);
Santos Cordon52d8a152014-06-17 19:08:45 -0700457 }
458
Ihab Awad5d0410f2014-07-30 10:07:40 -0700459 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700460 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700461 *
Andrew Lee100e2932014-09-08 15:34:24 -0700462 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700463 */
Andrew Lee100e2932014-09-08 15:34:24 -0700464 public void unregisterCallback(Callback callback) {
465 if (callback != null) {
466 mCallbacks.remove(callback);
Jay Shrauner229e3822014-08-15 09:23:07 -0700467 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700468 }
469
Ihab Awad5d0410f2014-07-30 10:07:40 -0700470 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700471 * Obtains the state of this {@code RemoteConnection}.
472 *
473 * @return A state value, chosen from the {@code STATE_*} constants.
474 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700475 public int getState() {
476 return mState;
477 }
478
Ihab Awad5d0410f2014-07-30 10:07:40 -0700479 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700480 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5d0410f2014-07-30 10:07:40 -0700481 * disconnect cause expressed as a code chosen from among those declared in
482 * {@link DisconnectCause}.
483 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700484 public DisconnectCause getDisconnectCause() {
485 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700486 }
487
Ihab Awad5d0410f2014-07-30 10:07:40 -0700488 /**
489 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700490 * {@link PhoneCapabilities}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700491 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700492 public int getCallCapabilities() {
493 return mCallCapabilities;
494 }
495
Ihab Awad5d0410f2014-07-30 10:07:40 -0700496 /**
497 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
498 */
Andrew Lee100e2932014-09-08 15:34:24 -0700499 public boolean isVoipAudioMode() {
500 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700501 }
502
Ihab Awad5d0410f2014-07-30 10:07:40 -0700503 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700504 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5d0410f2014-07-30 10:07:40 -0700505 * or {@code null} if none have been set.
506 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700507 public StatusHints getStatusHints() {
508 return mStatusHints;
509 }
510
Ihab Awad5d0410f2014-07-30 10:07:40 -0700511 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700512 * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently
Ihab Awad5d0410f2014-07-30 10:07:40 -0700513 * connected.
514 */
Andrew Lee100e2932014-09-08 15:34:24 -0700515 public Uri getAddress() {
516 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700517 }
518
Ihab Awad5d0410f2014-07-30 10:07:40 -0700519 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700520 * @return The presentation requirements for the address. See {@link TelecomManager} for valid
Andrew Lee100e2932014-09-08 15:34:24 -0700521 * values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700522 */
Andrew Lee100e2932014-09-08 15:34:24 -0700523 public int getAddressPresentation() {
524 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700525 }
526
Ihab Awad5d0410f2014-07-30 10:07:40 -0700527 /**
528 * @return The display name for the caller.
529 */
Andrew Lee100e2932014-09-08 15:34:24 -0700530 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700531 return mCallerDisplayName;
532 }
533
Ihab Awad5d0410f2014-07-30 10:07:40 -0700534 /**
535 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700536 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700537 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700538 public int getCallerDisplayNamePresentation() {
539 return mCallerDisplayNamePresentation;
540 }
541
Ihab Awad5d0410f2014-07-30 10:07:40 -0700542 /**
543 * @return The video state of the {@code RemoteConnection}. See
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700544 * {@link VideoProfile.VideoState}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700545 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700546 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700547 public int getVideoState() {
548 return mVideoState;
549 }
550
Ihab Awad5d0410f2014-07-30 10:07:40 -0700551 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700552 * @return The video provider associated with this {@code RemoteConnection}.
553 * @hide
554 */
555 public final VideoProvider getVideoProvider() {
556 return mVideoProvider;
557 }
558
559 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700560 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
561 * ringback tone on its behalf.
562 */
Andrew Lee100e2932014-09-08 15:34:24 -0700563 public boolean isRingbackRequested() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700564 return false;
565 }
566
567 /**
568 * Instructs this {@code RemoteConnection} to abort.
569 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700570 public void abort() {
571 try {
572 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700573 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700574 }
575 } catch (RemoteException ignored) {
576 }
577 }
578
Ihab Awad5d0410f2014-07-30 10:07:40 -0700579 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700580 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700581 */
582 public void answer() {
583 try {
584 if (mConnected) {
585 mConnectionService.answer(mConnectionId);
586 }
587 } catch (RemoteException ignored) {
588 }
589 }
590
591 /**
592 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700593 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700594 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700595 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700596 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700597 try {
598 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700599 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700600 }
601 } catch (RemoteException ignored) {
602 }
603 }
604
Ihab Awad5d0410f2014-07-30 10:07:40 -0700605 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700606 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700607 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700608 public void reject() {
609 try {
610 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700611 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700612 }
613 } catch (RemoteException ignored) {
614 }
615 }
616
Ihab Awad5d0410f2014-07-30 10:07:40 -0700617 /**
618 * Instructs this {@code RemoteConnection} to go on hold.
619 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700620 public void hold() {
621 try {
622 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700623 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700624 }
625 } catch (RemoteException ignored) {
626 }
627 }
628
Ihab Awad5d0410f2014-07-30 10:07:40 -0700629 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700630 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700631 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700632 public void unhold() {
633 try {
634 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700635 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700636 }
637 } catch (RemoteException ignored) {
638 }
639 }
640
Ihab Awad5d0410f2014-07-30 10:07:40 -0700641 /**
642 * Instructs this {@code RemoteConnection} to disconnect.
643 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700644 public void disconnect() {
645 try {
646 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700647 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700648 }
649 } catch (RemoteException ignored) {
650 }
651 }
652
Ihab Awad5d0410f2014-07-30 10:07:40 -0700653 /**
654 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
655 * (DTMF) tone.
656 *
657 * Any other currently playing DTMF tone in the specified call is immediately stopped.
658 *
659 * @param digit A character representing the DTMF digit for which to play the tone. This
660 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
661 */
662 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700663 try {
664 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700665 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700666 }
667 } catch (RemoteException ignored) {
668 }
669 }
670
Ihab Awad5d0410f2014-07-30 10:07:40 -0700671 /**
672 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
673 * (DTMF) tone currently playing.
674 *
675 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
676 * currently playing, this method will do nothing.
677 */
678 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700679 try {
680 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700681 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700682 }
683 } catch (RemoteException ignored) {
684 }
685 }
686
Ihab Awad5d0410f2014-07-30 10:07:40 -0700687 /**
688 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
689 *
690 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700691 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700692 * These digits are immediately sent as DTMF tones to the recipient as soon as the
693 * connection is made.
694 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700695 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700696 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
697 * of time.
698 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700699 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Lee100e2932014-09-08 15:34:24 -0700700 * {@code RemoteConnection} will pause playing the tones and notify callbackss via
701 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700702 * should display to the user an indication of this state and an affordance to continue
703 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
704 * app should invoke the {@link #postDialContinue(boolean)} method.
705 *
706 * @param proceed Whether or not to continue with the post-dial sequence.
707 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700708 public void postDialContinue(boolean proceed) {
709 try {
710 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700711 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700712 }
713 } catch (RemoteException ignored) {
714 }
715 }
716
Ihab Awad5d0410f2014-07-30 10:07:40 -0700717 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700718 * Set the audio state of this {@code RemoteConnection}.
719 *
720 * @param state The audio state of this {@code RemoteConnection}.
721 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700722 public void setAudioState(AudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700723 try {
724 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700725 mConnectionService.onAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700726 }
727 } catch (RemoteException ignored) {
728 }
729 }
730
Santos Cordon52d8a152014-06-17 19:08:45 -0700731 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700732 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
733 * successfully asked to create a conference with.
734 *
735 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
736 * merged into a {@link RemoteConference}.
737 */
738 public List<RemoteConnection> getConferenceableConnections() {
739 return mUnmodifiableconferenceableConnections;
740 }
741
742 /**
743 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
744 * of, or {@code null} if there is no such {@code RemoteConference}.
745 *
746 * @return A {@code RemoteConference} or {@code null};
747 */
748 public RemoteConference getConference() {
749 return mConference;
750 }
751
752 /** {@hide} */
753 String getId() {
754 return mConnectionId;
755 }
756
757 /** {@hide} */
758 IConnectionService getConnectionService() {
759 return mConnectionService;
760 }
761
762 /**
Santos Cordon52d8a152014-06-17 19:08:45 -0700763 * @hide
764 */
765 void setState(int state) {
766 if (mState != state) {
767 mState = state;
Andrew Lee100e2932014-09-08 15:34:24 -0700768 for (Callback c: mCallbacks) {
769 c.onStateChanged(this, state);
Santos Cordon52d8a152014-06-17 19:08:45 -0700770 }
771 }
772 }
773
774 /**
775 * @hide
776 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700777 void setDisconnected(DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700778 if (mState != Connection.STATE_DISCONNECTED) {
779 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700780 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700781
Andrew Lee100e2932014-09-08 15:34:24 -0700782 for (Callback c : mCallbacks) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700783 c.onDisconnected(this, mDisconnectCause);
Santos Cordon52d8a152014-06-17 19:08:45 -0700784 }
785 }
786 }
787
788 /**
789 * @hide
790 */
Andrew Lee100e2932014-09-08 15:34:24 -0700791 void setRingbackRequested(boolean ringback) {
792 if (mRingbackRequested != ringback) {
793 mRingbackRequested = ringback;
794 for (Callback c : mCallbacks) {
795 c.onRingbackRequested(this, ringback);
Santos Cordon52d8a152014-06-17 19:08:45 -0700796 }
797 }
798 }
799
800 /**
801 * @hide
802 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700803 void setCallCapabilities(int callCapabilities) {
804 mCallCapabilities = callCapabilities;
Andrew Lee100e2932014-09-08 15:34:24 -0700805 for (Callback c : mCallbacks) {
806 c.onCallCapabilitiesChanged(this, callCapabilities);
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700807 }
808 }
809
810 /**
811 * @hide
812 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700813 void setDestroyed() {
Andrew Lee100e2932014-09-08 15:34:24 -0700814 if (!mCallbacks.isEmpty()) {
815 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700816 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700817 setDisconnected(
818 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -0700819 }
820
Andrew Lee100e2932014-09-08 15:34:24 -0700821 for (Callback c : mCallbacks) {
822 c.onDestroyed(this);
Santos Cordon52d8a152014-06-17 19:08:45 -0700823 }
Andrew Lee100e2932014-09-08 15:34:24 -0700824 mCallbacks.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -0700825
826 mConnected = false;
827 }
828 }
829
830 /**
831 * @hide
832 */
833 void setPostDialWait(String remainingDigits) {
Andrew Lee100e2932014-09-08 15:34:24 -0700834 for (Callback c : mCallbacks) {
835 c.onPostDialWait(this, remainingDigits);
Santos Cordon52d8a152014-06-17 19:08:45 -0700836 }
837 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700838
Tyler Gunnaa07df82014-07-17 07:50:22 -0700839 /**
840 * @hide
841 */
842 void setVideoState(int videoState) {
843 mVideoState = videoState;
Andrew Lee100e2932014-09-08 15:34:24 -0700844 for (Callback c : mCallbacks) {
845 c.onVideoStateChanged(this, videoState);
Tyler Gunnaa07df82014-07-17 07:50:22 -0700846 }
847 }
848
Ihab Awada64627c2014-08-20 09:36:40 -0700849 /**
850 * @hide
851 */
852 void setVideoProvider(VideoProvider videoProvider) {
853 mVideoProvider = videoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700854 for (Callback c : mCallbacks) {
855 c.onVideoProviderChanged(this, videoProvider);
Ihab Awada64627c2014-08-20 09:36:40 -0700856 }
857 }
858
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700859 /** @hide */
Andrew Lee100e2932014-09-08 15:34:24 -0700860 void setIsVoipAudioMode(boolean isVoip) {
861 mIsVoipAudioMode = isVoip;
862 for (Callback c : mCallbacks) {
863 c.onVoipAudioChanged(this, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700864 }
865 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700866
867 /** @hide */
868 void setStatusHints(StatusHints statusHints) {
869 mStatusHints = statusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700870 for (Callback c : mCallbacks) {
871 c.onStatusHintsChanged(this, statusHints);
Sailesh Nepal61203862014-07-11 14:50:13 -0700872 }
873 }
874
875 /** @hide */
Andrew Lee100e2932014-09-08 15:34:24 -0700876 void setAddress(Uri address, int presentation) {
877 mAddress = address;
878 mAddressPresentation = presentation;
879 for (Callback c : mCallbacks) {
880 c.onAddressChanged(this, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -0700881 }
882 }
883
884 /** @hide */
885 void setCallerDisplayName(String callerDisplayName, int presentation) {
886 mCallerDisplayName = callerDisplayName;
887 mCallerDisplayNamePresentation = presentation;
Andrew Lee100e2932014-09-08 15:34:24 -0700888 for (Callback c : mCallbacks) {
889 c.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700890 }
891 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -0700892
893 /** @hide */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700894 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
895 mConferenceableConnections.clear();
896 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee100e2932014-09-08 15:34:24 -0700897 for (Callback c : mCallbacks) {
898 c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700899 }
900 }
901
902 /** @hide */
903 void setConference(RemoteConference conference) {
904 if (mConference != conference) {
905 mConference = conference;
Andrew Lee100e2932014-09-08 15:34:24 -0700906 for (Callback c : mCallbacks) {
907 c.onConferenceChanged(this, conference);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700908 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700909 }
910 }
911
Evan Charltonbf11f982014-07-20 22:06:28 -0700912 /**
Ihab Awad6107bab2014-08-18 09:23:25 -0700913 * Create a RemoteConnection represents a failure, and which will be in
914 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
915 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -0700916 *
917 * @return a failed {@link RemoteConnection}
918 *
919 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700920 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700921 public static RemoteConnection failure(DisconnectCause disconnectCause) {
922 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -0700923 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700924}