blob: bf699b39777d8950dcf80c2585e2db985d974d10 [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;
26import android.telephony.DisconnectCause;
Ihab Awada64627c2014-08-20 09:36:40 -070027import android.view.Surface;
Santos Cordon52d8a152014-06-17 19:08:45 -070028
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070029import java.util.ArrayList;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070030import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070031import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070032import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070033import java.util.concurrent.ConcurrentHashMap;
Santos Cordon52d8a152014-06-17 19:08:45 -070034
35/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070036 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
37 * running in a different process.
38 *
39 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
40 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070041 */
42public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070043
Andrew Lee100e2932014-09-08 15:34:24 -070044 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070045 /**
46 * Invoked when the state of this {@code RemoteConnection} has changed. See
47 * {@link #getState()}.
48 *
49 * @param connection The {@code RemoteConnection} invoking this method.
50 * @param state The new state of the {@code RemoteConnection}.
51 */
Evan Charltonbf11f982014-07-20 22:06:28 -070052 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070053
54 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070055 * Invoked when this {@code RemoteConnection} is disconnected.
56 *
57 * @param connection The {@code RemoteConnection} invoking this method.
58 * @param disconnectCauseCode The failure code ({@see DisconnectCause}) associated with this
59 * failed connection.
60 * @param disconnectCauseMessage The reason for the connection failure. This will not be
61 * displayed to the user.
62 */
63 public void onDisconnected(
64 RemoteConnection connection,
65 int disconnectCauseCode,
66 String disconnectCauseMessage) {}
67
68 /**
69 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070070 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070071 *
72 * @param connection The {@code RemoteConnection} invoking this method.
73 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
74 */
Andrew Lee100e2932014-09-08 15:34:24 -070075 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070076
77 /**
78 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
79 * See {@link #getCallCapabilities()}.
80 *
81 * @param connection The {@code RemoteConnection} invoking this method.
82 * @param callCapabilities The new call capabilities of the {@code RemoteConnection}.
83 */
Evan Charltonbf11f982014-07-20 22:06:28 -070084 public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {}
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 /**
98 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -070099 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700100 *
101 * @param connection The {@code RemoteConnection} invoking this method.
102 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
103 */
Andrew Lee100e2932014-09-08 15:34:24 -0700104 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700105
106 /**
107 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
108 * {@link #getStatusHints()} ()}.
109 *
110 * @param connection The {@code RemoteConnection} invoking this method.
111 * @param statusHints The new status hints of the {@code RemoteConnection}.
112 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700113 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700114
115 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700116 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
117 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700118 *
119 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700120 * @param address The new address of the {@code RemoteConnection}.
121 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700122 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700123 */
Andrew Lee100e2932014-09-08 15:34:24 -0700124 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700125
126 /**
127 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
128 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
129 *
130 * @param connection The {@code RemoteConnection} invoking this method.
131 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700132 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700133 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700134 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700135 public void onCallerDisplayNameChanged(
136 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700137
138 /**
139 * Indicates that the video state of this {@code RemoteConnection} has changed.
140 * See {@link #getVideoState()}.
141 *
142 * @param connection The {@code RemoteConnection} invoking this method.
143 * @param videoState The new video state of the {@code RemoteConnection}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700144 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700145 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700146 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700147
148 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700149 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
150 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
151 *
152 * @param connection The {@code RemoteConnection} invoking this method.
153 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700154 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700155
156 /**
157 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
158 * may be asked to create a conference has changed.
159 *
160 * @param connection The {@code RemoteConnection} invoking this method.
161 * @param conferenceableConnections The {@code RemoteConnection}s with which this
162 * {@code RemoteConnection} may be asked to create a conference.
163 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700164 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700165 RemoteConnection connection,
166 List<RemoteConnection> conferenceableConnections) {}
167
168 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700169 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
170 * has changed.
171 *
172 * @param connection The {@code RemoteConnection} invoking this method.
173 * @param videoProvider The new {@code VideoProvider} associated with this
174 * {@code RemoteConnection}.
175 * @hide
176 */
177 public void onVideoProviderChanged(
178 RemoteConnection connection, VideoProvider videoProvider) {}
179
180 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700181 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
182 * of has changed.
183 *
184 * @param connection The {@code RemoteConnection} invoking this method.
185 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
186 * a part, which may be {@code null}.
187 */
188 public void onConferenceChanged(
189 RemoteConnection connection,
190 RemoteConference conference) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700191 }
192
Ihab Awada64627c2014-08-20 09:36:40 -0700193 /** {@hide} */
194 public static class VideoProvider {
195
196 public abstract static class Listener {
197 public void onReceiveSessionModifyRequest(
198 VideoProvider videoProvider,
199 VideoProfile videoProfile) {}
200
201 public void onReceiveSessionModifyResponse(
202 VideoProvider videoProvider,
203 int status,
204 VideoProfile requestedProfile,
205 VideoProfile responseProfile) {}
206
207 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {}
208
209 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {}
210
211 public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {}
212
213 public void onCameraCapabilitiesChanged(
214 VideoProvider videoProvider,
215 CameraCapabilities cameraCapabilities) {}
216 }
217
218 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
219 @Override
220 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
221 for (Listener l : mListeners) {
222 l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile);
223 }
224 }
225
226 @Override
227 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
228 VideoProfile responseProfile) {
229 for (Listener l : mListeners) {
230 l.onReceiveSessionModifyResponse(
231 VideoProvider.this,
232 status,
233 requestedProfile,
234 responseProfile);
235 }
236 }
237
238 @Override
239 public void handleCallSessionEvent(int event) {
240 for (Listener l : mListeners) {
241 l.onHandleCallSessionEvent(VideoProvider.this, event);
242 }
243 }
244
245 @Override
246 public void changePeerDimensions(int width, int height) {
247 for (Listener l : mListeners) {
248 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
249 }
250 }
251
252 @Override
253 public void changeCallDataUsage(int dataUsage) {
254 for (Listener l : mListeners) {
255 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
256 }
257 }
258
259 @Override
260 public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
261 for (Listener l : mListeners) {
262 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
263 }
264 }
265
266 @Override
267 public IBinder asBinder() {
268 return null;
269 }
270 };
271
272 private final VideoCallbackServant mVideoCallbackServant =
273 new VideoCallbackServant(mVideoCallbackDelegate);
274
275 private final IVideoProvider mVideoProviderBinder;
276
277 /**
278 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
279 * load factor before resizing, 1 means we only expect a single thread to
280 * access the map so make only a single shard
281 */
282 private final Set<Listener> mListeners = Collections.newSetFromMap(
283 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
284
285 public VideoProvider(IVideoProvider videoProviderBinder) {
286 mVideoProviderBinder = videoProviderBinder;
287 try {
288 mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder());
289 } catch (RemoteException e) {
290 }
291 }
292
293 public void addListener(Listener l) {
294 mListeners.add(l);
295 }
296
297 public void removeListener(Listener l) {
298 mListeners.remove(l);
299 }
300
301 public void setCamera(String cameraId) {
302 try {
303 mVideoProviderBinder.setCamera(cameraId);
304 } catch (RemoteException e) {
305 }
306 }
307
308 public void setPreviewSurface(Surface surface) {
309 try {
310 mVideoProviderBinder.setPreviewSurface(surface);
311 } catch (RemoteException e) {
312 }
313 }
314
315 public void setDisplaySurface(Surface surface) {
316 try {
317 mVideoProviderBinder.setDisplaySurface(surface);
318 } catch (RemoteException e) {
319 }
320 }
321
322 public void setDeviceOrientation(int rotation) {
323 try {
324 mVideoProviderBinder.setDeviceOrientation(rotation);
325 } catch (RemoteException e) {
326 }
327 }
328
329 public void setZoom(float value) {
330 try {
331 mVideoProviderBinder.setZoom(value);
332 } catch (RemoteException e) {
333 }
334 }
335
336 public void sendSessionModifyRequest(VideoProfile reqProfile) {
337 try {
338 mVideoProviderBinder.sendSessionModifyRequest(reqProfile);
339 } catch (RemoteException e) {
340 }
341 }
342
343 public void sendSessionModifyResponse(VideoProfile responseProfile) {
344 try {
345 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
346 } catch (RemoteException e) {
347 }
348 }
349
350 public void requestCameraCapabilities() {
351 try {
352 mVideoProviderBinder.requestCameraCapabilities();
353 } catch (RemoteException e) {
354 }
355 }
356
357 public void requestCallDataUsage() {
358 try {
359 mVideoProviderBinder.requestCallDataUsage();
360 } catch (RemoteException e) {
361 }
362 }
363
364 public void setPauseImage(String uri) {
365 try {
366 mVideoProviderBinder.setPauseImage(uri);
367 } catch (RemoteException e) {
368 }
369 }
370 }
371
Evan Charltonbf11f982014-07-20 22:06:28 -0700372 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700373 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700374 /**
375 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
376 * load factor before resizing, 1 means we only expect a single thread to
377 * access the map so make only a single shard
378 */
Andrew Lee100e2932014-09-08 15:34:24 -0700379 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
380 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700381 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
382 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
383 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700384
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700385 private int mState = Connection.STATE_NEW;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700386 private int mDisconnectCauseCode = DisconnectCause.NOT_VALID;
387 private String mDisconnectCauseMessage;
Andrew Lee100e2932014-09-08 15:34:24 -0700388 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700389 private boolean mConnected;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700390 private int mCallCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700391 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700392 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700393 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700394 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700395 private Uri mAddress;
396 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700397 private String mCallerDisplayName;
398 private int mCallerDisplayNamePresentation;
Evan Charltonbf11f982014-07-20 22:06:28 -0700399 private int mFailureCode;
400 private String mFailureMessage;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700401 private RemoteConference mConference;
Santos Cordon52d8a152014-06-17 19:08:45 -0700402
403 /**
404 * @hide
405 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700406 RemoteConnection(
407 String id,
408 IConnectionService connectionService,
409 ConnectionRequest request) {
410 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700411 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700412 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700413 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700414 }
415
416 /**
417 * Create a RemoteConnection which is used for failed connections. Note that using it for any
418 * "real" purpose will almost certainly fail. Callers should note the failure and act
419 * accordingly (moving on to another RemoteConnection, for example)
420 *
421 * @param failureCode
422 * @param failureMessage
423 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700424 RemoteConnection(int failureCode, String failureMessage) {
425 this("NULL", null, null);
Evan Charltonbf11f982014-07-20 22:06:28 -0700426 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700427 mState = Connection.STATE_DISCONNECTED;
428 mFailureCode = DisconnectCause.OUTGOING_FAILURE;
429 mFailureMessage = failureMessage + " original code = " + failureCode;
Santos Cordon52d8a152014-06-17 19:08:45 -0700430 }
431
Ihab Awad5d0410f2014-07-30 10:07:40 -0700432 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700433 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700434 *
Andrew Lee100e2932014-09-08 15:34:24 -0700435 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700436 */
Andrew Lee100e2932014-09-08 15:34:24 -0700437 public void registerCallback(Callback callback) {
438 mCallbacks.add(callback);
Santos Cordon52d8a152014-06-17 19:08:45 -0700439 }
440
Ihab Awad5d0410f2014-07-30 10:07:40 -0700441 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700442 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700443 *
Andrew Lee100e2932014-09-08 15:34:24 -0700444 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700445 */
Andrew Lee100e2932014-09-08 15:34:24 -0700446 public void unregisterCallback(Callback callback) {
447 if (callback != null) {
448 mCallbacks.remove(callback);
Jay Shrauner229e3822014-08-15 09:23:07 -0700449 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700450 }
451
Ihab Awad5d0410f2014-07-30 10:07:40 -0700452 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700453 * Obtains the state of this {@code RemoteConnection}.
454 *
455 * @return A state value, chosen from the {@code STATE_*} constants.
456 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700457 public int getState() {
458 return mState;
459 }
460
Ihab Awad5d0410f2014-07-30 10:07:40 -0700461 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700462 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5d0410f2014-07-30 10:07:40 -0700463 * disconnect cause expressed as a code chosen from among those declared in
464 * {@link DisconnectCause}.
465 */
466 public int getDisconnectCauseCode() {
467 return mDisconnectCauseCode;
Santos Cordon52d8a152014-06-17 19:08:45 -0700468 }
469
Ihab Awad5d0410f2014-07-30 10:07:40 -0700470 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700471 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, an optional
Ihab Awad5d0410f2014-07-30 10:07:40 -0700472 * reason for disconnection expressed as a free text message.
473 */
474 public String getDisconnectCauseMessage() {
475 return mDisconnectCauseMessage;
Santos Cordon52d8a152014-06-17 19:08:45 -0700476 }
477
Ihab Awad5d0410f2014-07-30 10:07:40 -0700478 /**
479 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700480 * {@link PhoneCapabilities}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700481 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700482 public int getCallCapabilities() {
483 return mCallCapabilities;
484 }
485
Ihab Awad5d0410f2014-07-30 10:07:40 -0700486 /**
487 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
488 */
Andrew Lee100e2932014-09-08 15:34:24 -0700489 public boolean isVoipAudioMode() {
490 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700491 }
492
Ihab Awad5d0410f2014-07-30 10:07:40 -0700493 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700494 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5d0410f2014-07-30 10:07:40 -0700495 * or {@code null} if none have been set.
496 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700497 public StatusHints getStatusHints() {
498 return mStatusHints;
499 }
500
Ihab Awad5d0410f2014-07-30 10:07:40 -0700501 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700502 * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently
Ihab Awad5d0410f2014-07-30 10:07:40 -0700503 * connected.
504 */
Andrew Lee100e2932014-09-08 15:34:24 -0700505 public Uri getAddress() {
506 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700507 }
508
Ihab Awad5d0410f2014-07-30 10:07:40 -0700509 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700510 * @return The presentation requirements for the address. See {@link TelecomManager} for valid
Andrew Lee100e2932014-09-08 15:34:24 -0700511 * values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700512 */
Andrew Lee100e2932014-09-08 15:34:24 -0700513 public int getAddressPresentation() {
514 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700515 }
516
Ihab Awad5d0410f2014-07-30 10:07:40 -0700517 /**
518 * @return The display name for the caller.
519 */
Andrew Lee100e2932014-09-08 15:34:24 -0700520 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700521 return mCallerDisplayName;
522 }
523
Ihab Awad5d0410f2014-07-30 10:07:40 -0700524 /**
525 * @return The presentation requirements for the caller display name. See
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700526 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700527 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700528 public int getCallerDisplayNamePresentation() {
529 return mCallerDisplayNamePresentation;
530 }
531
Ihab Awad5d0410f2014-07-30 10:07:40 -0700532 /**
533 * @return The video state of the {@code RemoteConnection}. See
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700534 * {@link VideoProfile.VideoState}.
Tyler Gunn27d1e252014-08-21 16:38:40 -0700535 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700536 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700537 public int getVideoState() {
538 return mVideoState;
539 }
540
Ihab Awad5d0410f2014-07-30 10:07:40 -0700541 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700542 * @return The video provider associated with this {@code RemoteConnection}.
543 * @hide
544 */
545 public final VideoProvider getVideoProvider() {
546 return mVideoProvider;
547 }
548
549 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700550 * @return The failure code ({@see DisconnectCause}) associated with this failed
551 * {@code RemoteConnection}.
552 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700553 public int getFailureCode() {
554 return mFailureCode;
555 }
556
Ihab Awad5d0410f2014-07-30 10:07:40 -0700557 /**
558 * @return The reason for the connection failure. This will not be displayed to the user.
559 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700560 public String getFailureMessage() {
561 return mFailureMessage;
562 }
563
Ihab Awad5d0410f2014-07-30 10:07:40 -0700564 /**
565 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
566 * ringback tone on its behalf.
567 */
Andrew Lee100e2932014-09-08 15:34:24 -0700568 public boolean isRingbackRequested() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700569 return false;
570 }
571
572 /**
573 * Instructs this {@code RemoteConnection} to abort.
574 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700575 public void abort() {
576 try {
577 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700578 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700579 }
580 } catch (RemoteException ignored) {
581 }
582 }
583
Ihab Awad5d0410f2014-07-30 10:07:40 -0700584 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700585 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700586 */
587 public void answer() {
588 try {
589 if (mConnected) {
590 mConnectionService.answer(mConnectionId);
591 }
592 } catch (RemoteException ignored) {
593 }
594 }
595
596 /**
597 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700598 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700599 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700600 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700601 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700602 try {
603 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700604 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700605 }
606 } catch (RemoteException ignored) {
607 }
608 }
609
Ihab Awad5d0410f2014-07-30 10:07:40 -0700610 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700611 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700612 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700613 public void reject() {
614 try {
615 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700616 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700617 }
618 } catch (RemoteException ignored) {
619 }
620 }
621
Ihab Awad5d0410f2014-07-30 10:07:40 -0700622 /**
623 * Instructs this {@code RemoteConnection} to go on hold.
624 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700625 public void hold() {
626 try {
627 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700628 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700629 }
630 } catch (RemoteException ignored) {
631 }
632 }
633
Ihab Awad5d0410f2014-07-30 10:07:40 -0700634 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700635 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700636 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700637 public void unhold() {
638 try {
639 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700640 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700641 }
642 } catch (RemoteException ignored) {
643 }
644 }
645
Ihab Awad5d0410f2014-07-30 10:07:40 -0700646 /**
647 * Instructs this {@code RemoteConnection} to disconnect.
648 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700649 public void disconnect() {
650 try {
651 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700652 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700653 }
654 } catch (RemoteException ignored) {
655 }
656 }
657
Ihab Awad5d0410f2014-07-30 10:07:40 -0700658 /**
659 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
660 * (DTMF) tone.
661 *
662 * Any other currently playing DTMF tone in the specified call is immediately stopped.
663 *
664 * @param digit A character representing the DTMF digit for which to play the tone. This
665 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
666 */
667 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700668 try {
669 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700670 mConnectionService.playDtmfTone(mConnectionId, digit);
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 stop any dual-tone multi-frequency signaling
678 * (DTMF) tone currently playing.
679 *
680 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
681 * currently playing, this method will do nothing.
682 */
683 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700684 try {
685 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700686 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700687 }
688 } catch (RemoteException ignored) {
689 }
690 }
691
Ihab Awad5d0410f2014-07-30 10:07:40 -0700692 /**
693 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
694 *
695 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700696 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700697 * These digits are immediately sent as DTMF tones to the recipient as soon as the
698 * connection is made.
699 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700700 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700701 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
702 * of time.
703 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700704 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Andrew Lee100e2932014-09-08 15:34:24 -0700705 * {@code RemoteConnection} will pause playing the tones and notify callbackss via
706 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700707 * should display to the user an indication of this state and an affordance to continue
708 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
709 * app should invoke the {@link #postDialContinue(boolean)} method.
710 *
711 * @param proceed Whether or not to continue with the post-dial sequence.
712 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700713 public void postDialContinue(boolean proceed) {
714 try {
715 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700716 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700717 }
718 } catch (RemoteException ignored) {
719 }
720 }
721
Ihab Awad5d0410f2014-07-30 10:07:40 -0700722 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700723 * Set the audio state of this {@code RemoteConnection}.
724 *
725 * @param state The audio state of this {@code RemoteConnection}.
726 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700727 public void setAudioState(AudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700728 try {
729 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700730 mConnectionService.onAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700731 }
732 } catch (RemoteException ignored) {
733 }
734 }
735
Santos Cordon52d8a152014-06-17 19:08:45 -0700736 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700737 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
738 * successfully asked to create a conference with.
739 *
740 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
741 * merged into a {@link RemoteConference}.
742 */
743 public List<RemoteConnection> getConferenceableConnections() {
744 return mUnmodifiableconferenceableConnections;
745 }
746
747 /**
748 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
749 * of, or {@code null} if there is no such {@code RemoteConference}.
750 *
751 * @return A {@code RemoteConference} or {@code null};
752 */
753 public RemoteConference getConference() {
754 return mConference;
755 }
756
757 /** {@hide} */
758 String getId() {
759 return mConnectionId;
760 }
761
762 /** {@hide} */
763 IConnectionService getConnectionService() {
764 return mConnectionService;
765 }
766
767 /**
Santos Cordon52d8a152014-06-17 19:08:45 -0700768 * @hide
769 */
770 void setState(int state) {
771 if (mState != state) {
772 mState = state;
Andrew Lee100e2932014-09-08 15:34:24 -0700773 for (Callback c: mCallbacks) {
774 c.onStateChanged(this, state);
Santos Cordon52d8a152014-06-17 19:08:45 -0700775 }
776 }
777 }
778
779 /**
780 * @hide
781 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700782 void setDisconnected(int cause, String message) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700783 if (mState != Connection.STATE_DISCONNECTED) {
784 mState = Connection.STATE_DISCONNECTED;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700785 mDisconnectCauseCode = cause;
786 mDisconnectCauseMessage = message;
Santos Cordon52d8a152014-06-17 19:08:45 -0700787
Andrew Lee100e2932014-09-08 15:34:24 -0700788 for (Callback c : mCallbacks) {
789 c.onDisconnected(this, cause, message);
Santos Cordon52d8a152014-06-17 19:08:45 -0700790 }
791 }
792 }
793
794 /**
795 * @hide
796 */
Andrew Lee100e2932014-09-08 15:34:24 -0700797 void setRingbackRequested(boolean ringback) {
798 if (mRingbackRequested != ringback) {
799 mRingbackRequested = ringback;
800 for (Callback c : mCallbacks) {
801 c.onRingbackRequested(this, ringback);
Santos Cordon52d8a152014-06-17 19:08:45 -0700802 }
803 }
804 }
805
806 /**
807 * @hide
808 */
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700809 void setCallCapabilities(int callCapabilities) {
810 mCallCapabilities = callCapabilities;
Andrew Lee100e2932014-09-08 15:34:24 -0700811 for (Callback c : mCallbacks) {
812 c.onCallCapabilitiesChanged(this, callCapabilities);
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700813 }
814 }
815
816 /**
817 * @hide
818 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700819 void setDestroyed() {
Andrew Lee100e2932014-09-08 15:34:24 -0700820 if (!mCallbacks.isEmpty()) {
821 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700822 if (mState != Connection.STATE_DISCONNECTED) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700823 setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed.");
824 }
825
Andrew Lee100e2932014-09-08 15:34:24 -0700826 for (Callback c : mCallbacks) {
827 c.onDestroyed(this);
Santos Cordon52d8a152014-06-17 19:08:45 -0700828 }
Andrew Lee100e2932014-09-08 15:34:24 -0700829 mCallbacks.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -0700830
831 mConnected = false;
832 }
833 }
834
835 /**
836 * @hide
837 */
838 void setPostDialWait(String remainingDigits) {
Andrew Lee100e2932014-09-08 15:34:24 -0700839 for (Callback c : mCallbacks) {
840 c.onPostDialWait(this, remainingDigits);
Santos Cordon52d8a152014-06-17 19:08:45 -0700841 }
842 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700843
Tyler Gunnaa07df82014-07-17 07:50:22 -0700844 /**
845 * @hide
846 */
847 void setVideoState(int videoState) {
848 mVideoState = videoState;
Andrew Lee100e2932014-09-08 15:34:24 -0700849 for (Callback c : mCallbacks) {
850 c.onVideoStateChanged(this, videoState);
Tyler Gunnaa07df82014-07-17 07:50:22 -0700851 }
852 }
853
Ihab Awada64627c2014-08-20 09:36:40 -0700854 /**
855 * @hide
856 */
857 void setVideoProvider(VideoProvider videoProvider) {
858 mVideoProvider = videoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700859 for (Callback c : mCallbacks) {
860 c.onVideoProviderChanged(this, videoProvider);
Ihab Awada64627c2014-08-20 09:36:40 -0700861 }
862 }
863
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700864 /** @hide */
Andrew Lee100e2932014-09-08 15:34:24 -0700865 void setIsVoipAudioMode(boolean isVoip) {
866 mIsVoipAudioMode = isVoip;
867 for (Callback c : mCallbacks) {
868 c.onVoipAudioChanged(this, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700869 }
870 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700871
872 /** @hide */
873 void setStatusHints(StatusHints statusHints) {
874 mStatusHints = statusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700875 for (Callback c : mCallbacks) {
876 c.onStatusHintsChanged(this, statusHints);
Sailesh Nepal61203862014-07-11 14:50:13 -0700877 }
878 }
879
880 /** @hide */
Andrew Lee100e2932014-09-08 15:34:24 -0700881 void setAddress(Uri address, int presentation) {
882 mAddress = address;
883 mAddressPresentation = presentation;
884 for (Callback c : mCallbacks) {
885 c.onAddressChanged(this, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -0700886 }
887 }
888
889 /** @hide */
890 void setCallerDisplayName(String callerDisplayName, int presentation) {
891 mCallerDisplayName = callerDisplayName;
892 mCallerDisplayNamePresentation = presentation;
Andrew Lee100e2932014-09-08 15:34:24 -0700893 for (Callback c : mCallbacks) {
894 c.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700895 }
896 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -0700897
898 /** @hide */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700899 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
900 mConferenceableConnections.clear();
901 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee100e2932014-09-08 15:34:24 -0700902 for (Callback c : mCallbacks) {
903 c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700904 }
905 }
906
907 /** @hide */
908 void setConference(RemoteConference conference) {
909 if (mConference != conference) {
910 mConference = conference;
Andrew Lee100e2932014-09-08 15:34:24 -0700911 for (Callback c : mCallbacks) {
912 c.onConferenceChanged(this, conference);
Ihab Awadb8e85c72014-08-23 20:34:57 -0700913 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700914 }
915 }
916
Evan Charltonbf11f982014-07-20 22:06:28 -0700917 /**
Ihab Awad6107bab2014-08-18 09:23:25 -0700918 * Create a RemoteConnection represents a failure, and which will be in
919 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
920 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -0700921 *
922 * @return a failed {@link RemoteConnection}
923 *
924 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700925 */
926 public static RemoteConnection failure(int failureCode, String failureMessage) {
927 return new RemoteConnection(failureCode, failureMessage);
928 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700929}