blob: f9609590a697941bcea1f303d4d20f391f241add [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 Cordon6b7f9552015-05-27 17:21:45 -070023import android.annotation.Nullable;
Yorke Lee4af59352015-05-13 14:14:54 -070024import android.annotation.SystemApi;
Tyler Gunn295f5d72015-06-04 11:08:54 -070025import android.hardware.camera2.CameraManager;
Santos Cordon52d8a152014-06-17 19:08:45 -070026import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070027import android.os.Bundle;
Andrew Lee011728f2015-04-23 15:47:06 -070028import android.os.Handler;
Ihab Awada64627c2014-08-20 09:36:40 -070029import android.os.IBinder;
Santos Cordon52d8a152014-06-17 19:08:45 -070030import android.os.RemoteException;
Ihab Awada64627c2014-08-20 09:36:40 -070031import android.view.Surface;
Santos Cordon52d8a152014-06-17 19:08:45 -070032
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070033import java.util.ArrayList;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070034import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070035import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070036import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070037import java.util.concurrent.ConcurrentHashMap;
Santos Cordon52d8a152014-06-17 19:08:45 -070038
39/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070040 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
41 * running in a different process.
42 *
43 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
44 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070045 */
46public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070047
Santos Cordon895d4b82015-06-25 16:41:48 -070048 /**
49 * Callback base class for {@link RemoteConnection}.
50 */
Andrew Lee100e2932014-09-08 15:34:24 -070051 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070052 /**
53 * Invoked when the state of this {@code RemoteConnection} has changed. See
54 * {@link #getState()}.
55 *
56 * @param connection The {@code RemoteConnection} invoking this method.
57 * @param state The new state of the {@code RemoteConnection}.
58 */
Evan Charltonbf11f982014-07-20 22:06:28 -070059 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070060
61 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070062 * Invoked when this {@code RemoteConnection} is disconnected.
63 *
64 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070065 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
66 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070067 */
68 public void onDisconnected(
69 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070070 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070071
72 /**
73 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070074 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070075 *
76 * @param connection The {@code RemoteConnection} invoking this method.
77 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
78 */
Andrew Lee100e2932014-09-08 15:34:24 -070079 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070080
81 /**
82 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080083 * See {@link #getConnectionCapabilities()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070084 *
85 * @param connection The {@code RemoteConnection} invoking this method.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080086 * @param connectionCapabilities The new capabilities of the {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070087 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080088 public void onConnectionCapabilitiesChanged(
89 RemoteConnection connection,
90 int connectionCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070091
92 /**
93 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
94 * pause character. This causes the post-dial signals to stop pending user confirmation. An
95 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -070096 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -070097 *
98 * @param connection The {@code RemoteConnection} invoking this method.
99 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
100 */
101 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
102
103 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800104 * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
105 * a character.
106 *
107 * @param connection The {@code RemoteConnection} invoking this method.
108 * @param nextChar The character being processed.
109 */
110 public void onPostDialChar(RemoteConnection connection, char nextChar) {}
111
112 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700113 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -0700114 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700115 *
116 * @param connection The {@code RemoteConnection} invoking this method.
117 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
118 */
Andrew Lee100e2932014-09-08 15:34:24 -0700119 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700120
121 /**
122 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
123 * {@link #getStatusHints()} ()}.
124 *
125 * @param connection The {@code RemoteConnection} invoking this method.
126 * @param statusHints The new status hints of the {@code RemoteConnection}.
127 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700128 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700129
130 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700131 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
132 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700133 *
134 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700135 * @param address The new address of the {@code RemoteConnection}.
136 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700137 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700138 */
Andrew Lee100e2932014-09-08 15:34:24 -0700139 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700140
141 /**
142 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
143 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
144 *
145 * @param connection The {@code RemoteConnection} invoking this method.
146 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700147 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700148 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700149 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700150 public void onCallerDisplayNameChanged(
151 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700152
153 /**
154 * Indicates that the video state of this {@code RemoteConnection} has changed.
155 * See {@link #getVideoState()}.
156 *
157 * @param connection The {@code RemoteConnection} invoking this method.
158 * @param videoState The new video state of the {@code RemoteConnection}.
159 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700160 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700161
162 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700163 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
164 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
165 *
166 * @param connection The {@code RemoteConnection} invoking this method.
167 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700168 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700169
170 /**
171 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
172 * may be asked to create a conference has changed.
173 *
174 * @param connection The {@code RemoteConnection} invoking this method.
175 * @param conferenceableConnections The {@code RemoteConnection}s with which this
176 * {@code RemoteConnection} may be asked to create a conference.
177 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700178 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700179 RemoteConnection connection,
180 List<RemoteConnection> conferenceableConnections) {}
181
182 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700183 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
184 * has changed.
185 *
186 * @param connection The {@code RemoteConnection} invoking this method.
187 * @param videoProvider The new {@code VideoProvider} associated with this
188 * {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700189 */
190 public void onVideoProviderChanged(
191 RemoteConnection connection, VideoProvider videoProvider) {}
192
193 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700194 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
195 * of has changed.
196 *
197 * @param connection The {@code RemoteConnection} invoking this method.
198 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
199 * a part, which may be {@code null}.
200 */
201 public void onConferenceChanged(
202 RemoteConnection connection,
203 RemoteConference conference) {}
Santos Cordon6b7f9552015-05-27 17:21:45 -0700204
205 /**
Santos Cordon895d4b82015-06-25 16:41:48 -0700206 * Handles changes to the {@code RemoteConnection} extras.
Santos Cordon6b7f9552015-05-27 17:21:45 -0700207 *
208 * @param connection The {@code RemoteConnection} invoking this method.
209 * @param extras The extras containing other information associated with the connection.
210 */
211 public void onExtrasChanged(RemoteConnection connection, @Nullable Bundle extras) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700212 }
213
Tyler Gunn295f5d72015-06-04 11:08:54 -0700214 /**
215 * {@link RemoteConnection.VideoProvider} associated with a {@link RemoteConnection}. Used to
216 * receive video related events and control the video associated with a
217 * {@link RemoteConnection}.
218 *
219 * @see Connection.VideoProvider
220 */
Ihab Awada64627c2014-08-20 09:36:40 -0700221 public static class VideoProvider {
222
Tyler Gunn295f5d72015-06-04 11:08:54 -0700223 /**
224 * Callback class used by the {@link RemoteConnection.VideoProvider} to relay events from
225 * the {@link Connection.VideoProvider}.
226 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700227 public abstract static class Callback {
Tyler Gunn295f5d72015-06-04 11:08:54 -0700228 /**
229 * Reports a session modification request received from the
230 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
231 *
232 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
233 * @param videoProfile The requested video call profile.
234 * @see InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)
235 * @see Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)
236 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700237 public void onSessionModifyRequestReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700238 VideoProvider videoProvider,
239 VideoProfile videoProfile) {}
240
Tyler Gunn295f5d72015-06-04 11:08:54 -0700241 /**
242 * Reports a session modification response received from the
243 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
244 *
245 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
246 * @param status Status of the session modify request.
247 * @param requestedProfile The original request which was sent to the peer device.
248 * @param responseProfile The actual profile changes made by the peer device.
249 * @see InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
250 * VideoProfile, VideoProfile)
251 * @see Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile,
252 * VideoProfile)
253 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700254 public void onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700255 VideoProvider videoProvider,
256 int status,
257 VideoProfile requestedProfile,
258 VideoProfile responseProfile) {}
259
Tyler Gunn295f5d72015-06-04 11:08:54 -0700260 /**
261 * Reports a call session event received from the {@link Connection.VideoProvider}
262 * associated with a {@link RemoteConnection}.
263 *
264 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
265 * @param event The event.
266 * @see InCallService.VideoCall.Callback#onCallSessionEvent(int)
267 * @see Connection.VideoProvider#handleCallSessionEvent(int)
268 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700269 public void onCallSessionEvent(VideoProvider videoProvider, int event) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700270
Tyler Gunn295f5d72015-06-04 11:08:54 -0700271 /**
272 * Reports a change in the peer video dimensions received from the
273 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
274 *
275 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
276 * @param width The updated peer video width.
277 * @param height The updated peer video height.
278 * @see InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)
279 * @see Connection.VideoProvider#changePeerDimensions(int, int)
280 */
281 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width,
282 int height) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700283
Tyler Gunn295f5d72015-06-04 11:08:54 -0700284 /**
285 * Reports a change in the data usage (in bytes) received from the
286 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
287 *
288 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
289 * @param dataUsage The updated data usage (in bytes).
290 * @see InCallService.VideoCall.Callback#onCallDataUsageChanged(long)
291 * @see Connection.VideoProvider#setCallDataUsage(long)
292 */
Rekha Kumar07366812015-03-24 16:42:31 -0700293 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700294
Tyler Gunn295f5d72015-06-04 11:08:54 -0700295 /**
296 * Reports a change in the capabilities of the current camera, received from the
297 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
298 *
299 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
300 * @param cameraCapabilities The changed camera capabilities.
301 * @see InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
302 * VideoProfile.CameraCapabilities)
303 * @see Connection.VideoProvider#changeCameraCapabilities(
304 * VideoProfile.CameraCapabilities)
305 */
Ihab Awada64627c2014-08-20 09:36:40 -0700306 public void onCameraCapabilitiesChanged(
307 VideoProvider videoProvider,
Yorke Lee400470f2015-05-12 13:31:25 -0700308 VideoProfile.CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700309
Tyler Gunn295f5d72015-06-04 11:08:54 -0700310 /**
311 * Reports a change in the video quality received from the
312 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
313 *
314 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
315 * @param videoQuality The updated peer video quality.
316 * @see InCallService.VideoCall.Callback#onVideoQualityChanged(int)
317 * @see Connection.VideoProvider#changeVideoQuality(int)
318 */
Rekha Kumar07366812015-03-24 16:42:31 -0700319 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700320 }
321
322 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
323 @Override
324 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700325 for (Callback l : mCallbacks) {
326 l.onSessionModifyRequestReceived(VideoProvider.this, videoProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700327 }
328 }
329
330 @Override
331 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
332 VideoProfile responseProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700333 for (Callback l : mCallbacks) {
334 l.onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700335 VideoProvider.this,
336 status,
337 requestedProfile,
338 responseProfile);
339 }
340 }
341
342 @Override
343 public void handleCallSessionEvent(int event) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700344 for (Callback l : mCallbacks) {
345 l.onCallSessionEvent(VideoProvider.this, event);
Ihab Awada64627c2014-08-20 09:36:40 -0700346 }
347 }
348
349 @Override
350 public void changePeerDimensions(int width, int height) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700351 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700352 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
353 }
354 }
355
356 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700357 public void changeCallDataUsage(long dataUsage) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700358 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700359 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
360 }
361 }
362
363 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700364 public void changeCameraCapabilities(
365 VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700366 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700367 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
368 }
369 }
370
371 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700372 public void changeVideoQuality(int videoQuality) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700373 for (Callback l : mCallbacks) {
Rekha Kumar07366812015-03-24 16:42:31 -0700374 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
375 }
376 }
377
378 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700379 public IBinder asBinder() {
380 return null;
381 }
382 };
383
384 private final VideoCallbackServant mVideoCallbackServant =
385 new VideoCallbackServant(mVideoCallbackDelegate);
386
387 private final IVideoProvider mVideoProviderBinder;
388
389 /**
390 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
391 * load factor before resizing, 1 means we only expect a single thread to
392 * access the map so make only a single shard
393 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700394 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
395 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awada64627c2014-08-20 09:36:40 -0700396
Tyler Gunna2df9252015-05-29 10:05:46 -0700397 VideoProvider(IVideoProvider videoProviderBinder) {
Ihab Awada64627c2014-08-20 09:36:40 -0700398 mVideoProviderBinder = videoProviderBinder;
399 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700400 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700401 } catch (RemoteException e) {
402 }
403 }
404
Tyler Gunn295f5d72015-06-04 11:08:54 -0700405 /**
406 * Registers a callback to receive commands and state changes for video calls.
407 *
408 * @param l The video call callback.
409 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700410 public void registerCallback(Callback l) {
411 mCallbacks.add(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700412 }
413
Tyler Gunn295f5d72015-06-04 11:08:54 -0700414 /**
415 * Clears the video call callback set via {@link #registerCallback}.
416 *
417 * @param l The video call callback to clear.
418 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700419 public void unregisterCallback(Callback l) {
420 mCallbacks.remove(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700421 }
422
Tyler Gunn295f5d72015-06-04 11:08:54 -0700423 /**
424 * Sets the camera to be used for the outgoing video for the
425 * {@link RemoteConnection.VideoProvider}.
426 *
427 * @param cameraId The id of the camera (use ids as reported by
428 * {@link CameraManager#getCameraIdList()}).
429 * @see Connection.VideoProvider#onSetCamera(String)
430 */
Ihab Awada64627c2014-08-20 09:36:40 -0700431 public void setCamera(String cameraId) {
432 try {
433 mVideoProviderBinder.setCamera(cameraId);
434 } catch (RemoteException e) {
435 }
436 }
437
Tyler Gunn295f5d72015-06-04 11:08:54 -0700438 /**
439 * Sets the surface to be used for displaying a preview of what the user's camera is
440 * currently capturing for the {@link RemoteConnection.VideoProvider}.
441 *
442 * @param surface The {@link Surface}.
443 * @see Connection.VideoProvider#onSetPreviewSurface(Surface)
444 */
Ihab Awada64627c2014-08-20 09:36:40 -0700445 public void setPreviewSurface(Surface surface) {
446 try {
447 mVideoProviderBinder.setPreviewSurface(surface);
448 } catch (RemoteException e) {
449 }
450 }
451
Tyler Gunn295f5d72015-06-04 11:08:54 -0700452 /**
453 * Sets the surface to be used for displaying the video received from the remote device for
454 * the {@link RemoteConnection.VideoProvider}.
455 *
456 * @param surface The {@link Surface}.
457 * @see Connection.VideoProvider#onSetDisplaySurface(Surface)
458 */
Ihab Awada64627c2014-08-20 09:36:40 -0700459 public void setDisplaySurface(Surface surface) {
460 try {
461 mVideoProviderBinder.setDisplaySurface(surface);
462 } catch (RemoteException e) {
463 }
464 }
465
Tyler Gunn295f5d72015-06-04 11:08:54 -0700466 /**
467 * Sets the device orientation, in degrees, for the {@link RemoteConnection.VideoProvider}.
468 * Assumes that a standard portrait orientation of the device is 0 degrees.
469 *
470 * @param rotation The device orientation, in degrees.
471 * @see Connection.VideoProvider#onSetDeviceOrientation(int)
472 */
Ihab Awada64627c2014-08-20 09:36:40 -0700473 public void setDeviceOrientation(int rotation) {
474 try {
475 mVideoProviderBinder.setDeviceOrientation(rotation);
476 } catch (RemoteException e) {
477 }
478 }
479
Tyler Gunn295f5d72015-06-04 11:08:54 -0700480 /**
481 * Sets camera zoom ratio for the {@link RemoteConnection.VideoProvider}.
482 *
483 * @param value The camera zoom ratio.
484 * @see Connection.VideoProvider#onSetZoom(float)
485 */
Ihab Awada64627c2014-08-20 09:36:40 -0700486 public void setZoom(float value) {
487 try {
488 mVideoProviderBinder.setZoom(value);
489 } catch (RemoteException e) {
490 }
491 }
492
Tyler Gunn295f5d72015-06-04 11:08:54 -0700493 /**
494 * Issues a request to modify the properties of the current video session for the
495 * {@link RemoteConnection.VideoProvider}.
496 *
497 * @param fromProfile The video profile prior to the request.
498 * @param toProfile The video profile with the requested changes made.
499 * @see Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)
500 */
Tyler Gunn45382162015-05-06 08:52:27 -0700501 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700502 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700503 mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700504 } catch (RemoteException e) {
505 }
506 }
507
Tyler Gunn295f5d72015-06-04 11:08:54 -0700508 /**
509 * Provides a response to a request to change the current call video session
510 * properties for the {@link RemoteConnection.VideoProvider}.
511 *
512 * @param responseProfile The response call video properties.
513 * @see Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)
514 */
Ihab Awada64627c2014-08-20 09:36:40 -0700515 public void sendSessionModifyResponse(VideoProfile responseProfile) {
516 try {
517 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
518 } catch (RemoteException e) {
519 }
520 }
521
Tyler Gunn295f5d72015-06-04 11:08:54 -0700522 /**
523 * Issues a request to retrieve the capabilities of the current camera for the
524 * {@link RemoteConnection.VideoProvider}.
525 *
526 * @see Connection.VideoProvider#onRequestCameraCapabilities()
527 */
Ihab Awada64627c2014-08-20 09:36:40 -0700528 public void requestCameraCapabilities() {
529 try {
530 mVideoProviderBinder.requestCameraCapabilities();
531 } catch (RemoteException e) {
532 }
533 }
534
Tyler Gunn295f5d72015-06-04 11:08:54 -0700535 /**
536 * Issues a request to retrieve the data usage (in bytes) of the video portion of the
537 * {@link RemoteConnection} for the {@link RemoteConnection.VideoProvider}.
538 *
539 * @see Connection.VideoProvider#onRequestConnectionDataUsage()
540 */
Ihab Awada64627c2014-08-20 09:36:40 -0700541 public void requestCallDataUsage() {
542 try {
543 mVideoProviderBinder.requestCallDataUsage();
544 } catch (RemoteException e) {
545 }
546 }
547
Tyler Gunn295f5d72015-06-04 11:08:54 -0700548 /**
549 * Sets the {@link Uri} of an image to be displayed to the peer device when the video signal
550 * is paused, for the {@link RemoteConnection.VideoProvider}.
551 *
552 * @see Connection.VideoProvider#onSetPauseImage(Uri)
553 */
Yorke Lee32f24732015-05-12 16:18:03 -0700554 public void setPauseImage(Uri uri) {
Ihab Awada64627c2014-08-20 09:36:40 -0700555 try {
556 mVideoProviderBinder.setPauseImage(uri);
557 } catch (RemoteException e) {
558 }
559 }
560 }
561
Evan Charltonbf11f982014-07-20 22:06:28 -0700562 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700563 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700564 /**
565 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
566 * load factor before resizing, 1 means we only expect a single thread to
567 * access the map so make only a single shard
568 */
Andrew Lee011728f2015-04-23 15:47:06 -0700569 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
570 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700571 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
572 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
573 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700574
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700575 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700576 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700577 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700578 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800579 private int mConnectionCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700580 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700581 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700582 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700583 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700584 private Uri mAddress;
585 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700586 private String mCallerDisplayName;
587 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700588 private RemoteConference mConference;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700589 private Bundle mExtras;
Santos Cordon52d8a152014-06-17 19:08:45 -0700590
591 /**
592 * @hide
593 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700594 RemoteConnection(
595 String id,
596 IConnectionService connectionService,
597 ConnectionRequest request) {
598 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700599 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700600 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700601 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700602 }
603
604 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700605 * @hide
606 */
607 RemoteConnection(String callId, IConnectionService connectionService,
608 ParcelableConnection connection) {
609 mConnectionId = callId;
610 mConnectionService = connectionService;
611 mConnected = true;
612 mState = connection.getState();
613 mDisconnectCause = connection.getDisconnectCause();
614 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800615 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700616 mVideoState = connection.getVideoState();
617 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
618 mIsVoipAudioMode = connection.getIsVoipAudioMode();
619 mStatusHints = connection.getStatusHints();
620 mAddress = connection.getHandle();
621 mAddressPresentation = connection.getHandlePresentation();
622 mCallerDisplayName = connection.getCallerDisplayName();
623 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
624 mConference = null;
625 }
626
627 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700628 * Create a RemoteConnection which is used for failed connections. Note that using it for any
629 * "real" purpose will almost certainly fail. Callers should note the failure and act
630 * accordingly (moving on to another RemoteConnection, for example)
631 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700632 * @param disconnectCause The reason for the failed connection.
633 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700634 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700635 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700636 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700637 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700638 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700639 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700640 }
641
Ihab Awad5d0410f2014-07-30 10:07:40 -0700642 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700643 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700644 *
Andrew Lee100e2932014-09-08 15:34:24 -0700645 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700646 */
Andrew Lee100e2932014-09-08 15:34:24 -0700647 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700648 registerCallback(callback, new Handler());
649 }
650
651 /**
652 * Adds a callback to this {@code RemoteConnection}.
653 *
654 * @param callback A {@code Callback}.
655 * @param handler A {@code Handler} which command and status changes will be delivered to.
656 */
657 public void registerCallback(Callback callback, Handler handler) {
658 unregisterCallback(callback);
659 if (callback != null && handler != null) {
660 mCallbackRecords.add(new CallbackRecord(callback, handler));
661 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700662 }
663
Ihab Awad5d0410f2014-07-30 10:07:40 -0700664 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700665 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700666 *
Andrew Lee100e2932014-09-08 15:34:24 -0700667 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700668 */
Andrew Lee100e2932014-09-08 15:34:24 -0700669 public void unregisterCallback(Callback callback) {
670 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700671 for (CallbackRecord record : mCallbackRecords) {
672 if (record.getCallback() == callback) {
673 mCallbackRecords.remove(record);
674 break;
675 }
676 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700677 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700678 }
679
Ihab Awad5d0410f2014-07-30 10:07:40 -0700680 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700681 * Obtains the state of this {@code RemoteConnection}.
682 *
683 * @return A state value, chosen from the {@code STATE_*} constants.
684 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700685 public int getState() {
686 return mState;
687 }
688
Ihab Awad5d0410f2014-07-30 10:07:40 -0700689 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800690 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
691 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700692 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800693 * disconnect cause expressed as a code chosen from among those declared in
694 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700695 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700696 public DisconnectCause getDisconnectCause() {
697 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700698 }
699
Ihab Awad5d0410f2014-07-30 10:07:40 -0700700 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800701 * Obtains the capabilities of this {@code RemoteConnection}.
702 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700703 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800704 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700705 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800706 public int getConnectionCapabilities() {
707 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700708 }
709
Ihab Awad5d0410f2014-07-30 10:07:40 -0700710 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800711 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
712 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700713 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
714 */
Andrew Lee100e2932014-09-08 15:34:24 -0700715 public boolean isVoipAudioMode() {
716 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700717 }
718
Ihab Awad5d0410f2014-07-30 10:07:40 -0700719 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800720 * Obtains status hints pertaining to this {@code RemoteConnection}.
721 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700722 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800723 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700724 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700725 public StatusHints getStatusHints() {
726 return mStatusHints;
727 }
728
Ihab Awad5d0410f2014-07-30 10:07:40 -0700729 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800730 * Obtains the address of this {@code RemoteConnection}.
731 *
732 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
733 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700734 */
Andrew Lee100e2932014-09-08 15:34:24 -0700735 public Uri getAddress() {
736 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700737 }
738
Ihab Awad5d0410f2014-07-30 10:07:40 -0700739 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800740 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
741 *
742 * @return The presentation requirements for the address. See
743 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700744 */
Andrew Lee100e2932014-09-08 15:34:24 -0700745 public int getAddressPresentation() {
746 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700747 }
748
Ihab Awad5d0410f2014-07-30 10:07:40 -0700749 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800750 * Obtains the display name for this {@code RemoteConnection}'s caller.
751 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700752 * @return The display name for the caller.
753 */
Andrew Lee100e2932014-09-08 15:34:24 -0700754 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700755 return mCallerDisplayName;
756 }
757
Ihab Awad5d0410f2014-07-30 10:07:40 -0700758 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800759 * Obtains the presentation requirements for this {@code RemoteConnection}'s
760 * caller's display name.
761 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700762 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800763 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700764 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700765 public int getCallerDisplayNamePresentation() {
766 return mCallerDisplayNamePresentation;
767 }
768
Ihab Awad5d0410f2014-07-30 10:07:40 -0700769 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800770 * Obtains the video state of this {@code RemoteConnection}.
771 *
Tyler Gunn87b73f32015-06-03 10:09:59 -0700772 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700773 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700774 public int getVideoState() {
775 return mVideoState;
776 }
777
Ihab Awad5d0410f2014-07-30 10:07:40 -0700778 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700779 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700780 * @return The video provider associated with this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700781 */
782 public final VideoProvider getVideoProvider() {
783 return mVideoProvider;
784 }
785
786 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700787 * Obtain the extras associated with this {@code RemoteConnection}.
788 *
789 * @return The extras for this connection.
790 */
791 public final Bundle getExtras() {
792 return mExtras;
793 }
794
795 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800796 * Determines whether this {@code RemoteConnection} is requesting ringback.
797 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700798 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800799 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700800 */
Andrew Lee100e2932014-09-08 15:34:24 -0700801 public boolean isRingbackRequested() {
Santos Cordon15d63c72015-06-02 15:08:26 -0700802 return mRingbackRequested;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700803 }
804
805 /**
806 * Instructs this {@code RemoteConnection} to abort.
807 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700808 public void abort() {
809 try {
810 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700811 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700812 }
813 } catch (RemoteException ignored) {
814 }
815 }
816
Ihab Awad5d0410f2014-07-30 10:07:40 -0700817 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700818 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700819 */
820 public void answer() {
821 try {
822 if (mConnected) {
823 mConnectionService.answer(mConnectionId);
824 }
825 } catch (RemoteException ignored) {
826 }
827 }
828
829 /**
830 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700831 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700832 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700833 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700834 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700835 try {
836 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700837 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700838 }
839 } catch (RemoteException ignored) {
840 }
841 }
842
Ihab Awad5d0410f2014-07-30 10:07:40 -0700843 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700844 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700845 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700846 public void reject() {
847 try {
848 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700849 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700850 }
851 } catch (RemoteException ignored) {
852 }
853 }
854
Ihab Awad5d0410f2014-07-30 10:07:40 -0700855 /**
856 * Instructs this {@code RemoteConnection} to go on hold.
857 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700858 public void hold() {
859 try {
860 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700861 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700862 }
863 } catch (RemoteException ignored) {
864 }
865 }
866
Ihab Awad5d0410f2014-07-30 10:07:40 -0700867 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700868 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700869 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700870 public void unhold() {
871 try {
872 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700873 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700874 }
875 } catch (RemoteException ignored) {
876 }
877 }
878
Ihab Awad5d0410f2014-07-30 10:07:40 -0700879 /**
880 * Instructs this {@code RemoteConnection} to disconnect.
881 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700882 public void disconnect() {
883 try {
884 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700885 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700886 }
887 } catch (RemoteException ignored) {
888 }
889 }
890
Ihab Awad5d0410f2014-07-30 10:07:40 -0700891 /**
892 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
893 * (DTMF) tone.
894 *
895 * Any other currently playing DTMF tone in the specified call is immediately stopped.
896 *
897 * @param digit A character representing the DTMF digit for which to play the tone. This
898 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
899 */
900 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700901 try {
902 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700903 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700904 }
905 } catch (RemoteException ignored) {
906 }
907 }
908
Ihab Awad5d0410f2014-07-30 10:07:40 -0700909 /**
910 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
911 * (DTMF) tone currently playing.
912 *
913 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
914 * currently playing, this method will do nothing.
915 */
916 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700917 try {
918 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700919 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700920 }
921 } catch (RemoteException ignored) {
922 }
923 }
924
Ihab Awad5d0410f2014-07-30 10:07:40 -0700925 /**
926 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
927 *
928 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700929 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700930 * These digits are immediately sent as DTMF tones to the recipient as soon as the
931 * connection is made.
932 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700933 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700934 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
935 * of time.
936 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700937 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800938 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -0700939 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700940 * should display to the user an indication of this state and an affordance to continue
941 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
942 * app should invoke the {@link #postDialContinue(boolean)} method.
943 *
944 * @param proceed Whether or not to continue with the post-dial sequence.
945 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700946 public void postDialContinue(boolean proceed) {
947 try {
948 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700949 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700950 }
951 } catch (RemoteException ignored) {
952 }
953 }
954
Ihab Awad5d0410f2014-07-30 10:07:40 -0700955 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700956 * Set the audio state of this {@code RemoteConnection}.
957 *
958 * @param state The audio state of this {@code RemoteConnection}.
Yorke Lee4af59352015-05-13 14:14:54 -0700959 * @hide
960 * @deprecated Use {@link #setCallAudioState(CallAudioState) instead.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700961 */
Yorke Lee4af59352015-05-13 14:14:54 -0700962 @SystemApi
963 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700964 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -0700965 setCallAudioState(new CallAudioState(state));
966 }
967
968 /**
969 * Set the audio state of this {@code RemoteConnection}.
970 *
971 * @param state The audio state of this {@code RemoteConnection}.
972 */
973 public void setCallAudioState(CallAudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700974 try {
975 if (mConnected) {
Yorke Lee4af59352015-05-13 14:14:54 -0700976 mConnectionService.onCallAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700977 }
978 } catch (RemoteException ignored) {
979 }
980 }
981
Santos Cordon52d8a152014-06-17 19:08:45 -0700982 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700983 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
984 * successfully asked to create a conference with.
985 *
986 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
987 * merged into a {@link RemoteConference}.
988 */
989 public List<RemoteConnection> getConferenceableConnections() {
990 return mUnmodifiableconferenceableConnections;
991 }
992
993 /**
994 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
995 * of, or {@code null} if there is no such {@code RemoteConference}.
996 *
997 * @return A {@code RemoteConference} or {@code null};
998 */
999 public RemoteConference getConference() {
1000 return mConference;
1001 }
1002
1003 /** {@hide} */
1004 String getId() {
1005 return mConnectionId;
1006 }
1007
1008 /** {@hide} */
1009 IConnectionService getConnectionService() {
1010 return mConnectionService;
1011 }
1012
1013 /**
Santos Cordon52d8a152014-06-17 19:08:45 -07001014 * @hide
1015 */
Andrew Lee011728f2015-04-23 15:47:06 -07001016 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -07001017 if (mState != state) {
1018 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -07001019 for (CallbackRecord record: mCallbackRecords) {
1020 final RemoteConnection connection = this;
1021 final Callback callback = record.getCallback();
1022 record.getHandler().post(new Runnable() {
1023 @Override
1024 public void run() {
1025 callback.onStateChanged(connection, state);
1026 }
1027 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001028 }
1029 }
1030 }
1031
1032 /**
1033 * @hide
1034 */
Andrew Lee011728f2015-04-23 15:47:06 -07001035 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001036 if (mState != Connection.STATE_DISCONNECTED) {
1037 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001038 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -07001039
Andrew Lee011728f2015-04-23 15:47:06 -07001040 for (CallbackRecord record : mCallbackRecords) {
1041 final RemoteConnection connection = this;
1042 final Callback callback = record.getCallback();
1043 record.getHandler().post(new Runnable() {
1044 @Override
1045 public void run() {
1046 callback.onDisconnected(connection, disconnectCause);
1047 }
1048 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001049 }
1050 }
1051 }
1052
1053 /**
1054 * @hide
1055 */
Andrew Lee011728f2015-04-23 15:47:06 -07001056 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -07001057 if (mRingbackRequested != ringback) {
1058 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -07001059 for (CallbackRecord record : mCallbackRecords) {
1060 final RemoteConnection connection = this;
1061 final Callback callback = record.getCallback();
1062 record.getHandler().post(new Runnable() {
1063 @Override
1064 public void run() {
1065 callback.onRingbackRequested(connection, ringback);
1066 }
1067 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001068 }
1069 }
1070 }
1071
1072 /**
1073 * @hide
1074 */
Andrew Lee011728f2015-04-23 15:47:06 -07001075 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001076 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -07001077 for (CallbackRecord record : mCallbackRecords) {
1078 final RemoteConnection connection = this;
1079 final Callback callback = record.getCallback();
1080 record.getHandler().post(new Runnable() {
1081 @Override
1082 public void run() {
1083 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
1084 }
1085 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001086 }
1087 }
1088
1089 /**
1090 * @hide
1091 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001092 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -07001093 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -07001094 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001095 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001096 setDisconnected(
1097 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -07001098 }
1099
Andrew Lee011728f2015-04-23 15:47:06 -07001100 for (CallbackRecord record : mCallbackRecords) {
1101 final RemoteConnection connection = this;
1102 final Callback callback = record.getCallback();
1103 record.getHandler().post(new Runnable() {
1104 @Override
1105 public void run() {
1106 callback.onDestroyed(connection);
1107 }
1108 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001109 }
Andrew Lee011728f2015-04-23 15:47:06 -07001110 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -07001111
1112 mConnected = false;
1113 }
1114 }
1115
1116 /**
1117 * @hide
1118 */
Andrew Lee011728f2015-04-23 15:47:06 -07001119 void setPostDialWait(final String remainingDigits) {
1120 for (CallbackRecord record : mCallbackRecords) {
1121 final RemoteConnection connection = this;
1122 final Callback callback = record.getCallback();
1123 record.getHandler().post(new Runnable() {
1124 @Override
1125 public void run() {
1126 callback.onPostDialWait(connection, remainingDigits);
1127 }
1128 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001129 }
1130 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001131
Tyler Gunnaa07df82014-07-17 07:50:22 -07001132 /**
1133 * @hide
1134 */
Andrew Lee011728f2015-04-23 15:47:06 -07001135 void onPostDialChar(final char nextChar) {
1136 for (CallbackRecord record : mCallbackRecords) {
1137 final RemoteConnection connection = this;
1138 final Callback callback = record.getCallback();
1139 record.getHandler().post(new Runnable() {
1140 @Override
1141 public void run() {
Sailesh Nepal40451b32015-05-14 17:39:41 -07001142 callback.onPostDialChar(connection, nextChar);
Andrew Lee011728f2015-04-23 15:47:06 -07001143 }
1144 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001145 }
1146 }
1147
1148 /**
1149 * @hide
1150 */
Andrew Lee011728f2015-04-23 15:47:06 -07001151 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -07001152 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -07001153 for (CallbackRecord record : mCallbackRecords) {
1154 final RemoteConnection connection = this;
1155 final Callback callback = record.getCallback();
1156 record.getHandler().post(new Runnable() {
1157 @Override
1158 public void run() {
1159 callback.onVideoStateChanged(connection, videoState);
1160 }
1161 });
Tyler Gunnaa07df82014-07-17 07:50:22 -07001162 }
1163 }
1164
Ihab Awada64627c2014-08-20 09:36:40 -07001165 /**
1166 * @hide
1167 */
Andrew Lee011728f2015-04-23 15:47:06 -07001168 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -07001169 mVideoProvider = videoProvider;
Andrew Lee011728f2015-04-23 15:47:06 -07001170 for (CallbackRecord record : mCallbackRecords) {
1171 final RemoteConnection connection = this;
1172 final Callback callback = record.getCallback();
1173 record.getHandler().post(new Runnable() {
1174 @Override
1175 public void run() {
1176 callback.onVideoProviderChanged(connection, videoProvider);
1177 }
1178 });
Ihab Awada64627c2014-08-20 09:36:40 -07001179 }
1180 }
1181
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001182 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001183 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -07001184 mIsVoipAudioMode = isVoip;
Andrew Lee011728f2015-04-23 15:47:06 -07001185 for (CallbackRecord record : mCallbackRecords) {
1186 final RemoteConnection connection = this;
1187 final Callback callback = record.getCallback();
1188 record.getHandler().post(new Runnable() {
1189 @Override
1190 public void run() {
1191 callback.onVoipAudioChanged(connection, isVoip);
1192 }
1193 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001194 }
1195 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001196
1197 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001198 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001199 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001200 for (CallbackRecord record : mCallbackRecords) {
1201 final RemoteConnection connection = this;
1202 final Callback callback = record.getCallback();
1203 record.getHandler().post(new Runnable() {
1204 @Override
1205 public void run() {
1206 callback.onStatusHintsChanged(connection, statusHints);
1207 }
1208 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001209 }
1210 }
1211
1212 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001213 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001214 mAddress = address;
1215 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001216 for (CallbackRecord record : mCallbackRecords) {
1217 final RemoteConnection connection = this;
1218 final Callback callback = record.getCallback();
1219 record.getHandler().post(new Runnable() {
1220 @Override
1221 public void run() {
1222 callback.onAddressChanged(connection, address, presentation);
1223 }
1224 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001225 }
1226 }
1227
1228 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001229 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001230 mCallerDisplayName = callerDisplayName;
1231 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001232 for (CallbackRecord record : mCallbackRecords) {
1233 final RemoteConnection connection = this;
1234 final Callback callback = record.getCallback();
1235 record.getHandler().post(new Runnable() {
1236 @Override
1237 public void run() {
1238 callback.onCallerDisplayNameChanged(
1239 connection, callerDisplayName, presentation);
1240 }
1241 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001242 }
1243 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001244
1245 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001246 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001247 mConferenceableConnections.clear();
1248 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001249 for (CallbackRecord record : mCallbackRecords) {
1250 final RemoteConnection connection = this;
1251 final Callback callback = record.getCallback();
1252 record.getHandler().post(new Runnable() {
1253 @Override
1254 public void run() {
1255 callback.onConferenceableConnectionsChanged(
1256 connection, mUnmodifiableconferenceableConnections);
1257 }
1258 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001259 }
1260 }
1261
1262 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001263 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001264 if (mConference != conference) {
1265 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001266 for (CallbackRecord record : mCallbackRecords) {
1267 final RemoteConnection connection = this;
1268 final Callback callback = record.getCallback();
1269 record.getHandler().post(new Runnable() {
1270 @Override
1271 public void run() {
1272 callback.onConferenceChanged(connection, conference);
1273 }
1274 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001275 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001276 }
1277 }
1278
Santos Cordon6b7f9552015-05-27 17:21:45 -07001279 /** @hide */
1280 void setExtras(final Bundle extras) {
1281 mExtras = extras;
1282 for (CallbackRecord record : mCallbackRecords) {
1283 final RemoteConnection connection = this;
1284 final Callback callback = record.getCallback();
1285 record.getHandler().post(new Runnable() {
1286 @Override
1287 public void run() {
1288 callback.onExtrasChanged(connection, extras);
1289 }
1290 });
1291 }
1292 }
1293
Evan Charltonbf11f982014-07-20 22:06:28 -07001294 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001295 * Create a RemoteConnection represents a failure, and which will be in
1296 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1297 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001298 *
1299 * @return a failed {@link RemoteConnection}
1300 *
1301 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001302 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001303 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1304 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001305 }
Andrew Lee011728f2015-04-23 15:47:06 -07001306
1307 private static final class CallbackRecord extends Callback {
1308 private final Callback mCallback;
1309 private final Handler mHandler;
1310
1311 public CallbackRecord(Callback callback, Handler handler) {
1312 mCallback = callback;
1313 mHandler = handler;
1314 }
1315
1316 public Callback getCallback() {
1317 return mCallback;
1318 }
1319
1320 public Handler getHandler() {
1321 return mHandler;
1322 }
1323 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001324}