blob: 01858080d7d7dd33cce0ef7dd399537827ec9fd7 [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) {}
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800212
213 /**
214 * Handles a connection event propagated to this {@link RemoteConnection}.
215 *
216 * @param connection The {@code RemoteConnection} invoking this method.
217 * @param event The connection event.
218 * @hide
219 */
220 public void onConnectionEvent(RemoteConnection connection, String event) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700221 }
222
Tyler Gunn295f5d72015-06-04 11:08:54 -0700223 /**
224 * {@link RemoteConnection.VideoProvider} associated with a {@link RemoteConnection}. Used to
225 * receive video related events and control the video associated with a
226 * {@link RemoteConnection}.
227 *
228 * @see Connection.VideoProvider
229 */
Ihab Awada64627c2014-08-20 09:36:40 -0700230 public static class VideoProvider {
231
Tyler Gunn295f5d72015-06-04 11:08:54 -0700232 /**
233 * Callback class used by the {@link RemoteConnection.VideoProvider} to relay events from
234 * the {@link Connection.VideoProvider}.
235 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700236 public abstract static class Callback {
Tyler Gunn295f5d72015-06-04 11:08:54 -0700237 /**
238 * Reports a session modification request received from the
239 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
240 *
241 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
242 * @param videoProfile The requested video call profile.
243 * @see InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)
244 * @see Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)
245 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700246 public void onSessionModifyRequestReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700247 VideoProvider videoProvider,
248 VideoProfile videoProfile) {}
249
Tyler Gunn295f5d72015-06-04 11:08:54 -0700250 /**
251 * Reports a session modification response received from the
252 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
253 *
254 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
255 * @param status Status of the session modify request.
256 * @param requestedProfile The original request which was sent to the peer device.
257 * @param responseProfile The actual profile changes made by the peer device.
258 * @see InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
259 * VideoProfile, VideoProfile)
260 * @see Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile,
261 * VideoProfile)
262 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700263 public void onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700264 VideoProvider videoProvider,
265 int status,
266 VideoProfile requestedProfile,
267 VideoProfile responseProfile) {}
268
Tyler Gunn295f5d72015-06-04 11:08:54 -0700269 /**
270 * Reports a call session event received from the {@link Connection.VideoProvider}
271 * associated with a {@link RemoteConnection}.
272 *
273 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
274 * @param event The event.
275 * @see InCallService.VideoCall.Callback#onCallSessionEvent(int)
276 * @see Connection.VideoProvider#handleCallSessionEvent(int)
277 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700278 public void onCallSessionEvent(VideoProvider videoProvider, int event) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700279
Tyler Gunn295f5d72015-06-04 11:08:54 -0700280 /**
281 * Reports a change in the peer video dimensions received from the
282 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
283 *
284 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
285 * @param width The updated peer video width.
286 * @param height The updated peer video height.
287 * @see InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)
288 * @see Connection.VideoProvider#changePeerDimensions(int, int)
289 */
290 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width,
291 int height) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700292
Tyler Gunn295f5d72015-06-04 11:08:54 -0700293 /**
294 * Reports a change in the data usage (in bytes) received from the
295 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
296 *
297 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
298 * @param dataUsage The updated data usage (in bytes).
299 * @see InCallService.VideoCall.Callback#onCallDataUsageChanged(long)
300 * @see Connection.VideoProvider#setCallDataUsage(long)
301 */
Rekha Kumar07366812015-03-24 16:42:31 -0700302 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700303
Tyler Gunn295f5d72015-06-04 11:08:54 -0700304 /**
305 * Reports a change in the capabilities of the current camera, received from the
306 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
307 *
308 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
309 * @param cameraCapabilities The changed camera capabilities.
310 * @see InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
311 * VideoProfile.CameraCapabilities)
312 * @see Connection.VideoProvider#changeCameraCapabilities(
313 * VideoProfile.CameraCapabilities)
314 */
Ihab Awada64627c2014-08-20 09:36:40 -0700315 public void onCameraCapabilitiesChanged(
316 VideoProvider videoProvider,
Yorke Lee400470f2015-05-12 13:31:25 -0700317 VideoProfile.CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700318
Tyler Gunn295f5d72015-06-04 11:08:54 -0700319 /**
320 * Reports a change in the video quality received from the
321 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
322 *
323 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
324 * @param videoQuality The updated peer video quality.
325 * @see InCallService.VideoCall.Callback#onVideoQualityChanged(int)
326 * @see Connection.VideoProvider#changeVideoQuality(int)
327 */
Rekha Kumar07366812015-03-24 16:42:31 -0700328 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700329 }
330
331 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
332 @Override
333 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700334 for (Callback l : mCallbacks) {
335 l.onSessionModifyRequestReceived(VideoProvider.this, videoProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700336 }
337 }
338
339 @Override
340 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
341 VideoProfile responseProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700342 for (Callback l : mCallbacks) {
343 l.onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700344 VideoProvider.this,
345 status,
346 requestedProfile,
347 responseProfile);
348 }
349 }
350
351 @Override
352 public void handleCallSessionEvent(int event) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700353 for (Callback l : mCallbacks) {
354 l.onCallSessionEvent(VideoProvider.this, event);
Ihab Awada64627c2014-08-20 09:36:40 -0700355 }
356 }
357
358 @Override
359 public void changePeerDimensions(int width, int height) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700360 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700361 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
362 }
363 }
364
365 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700366 public void changeCallDataUsage(long dataUsage) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700367 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700368 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
369 }
370 }
371
372 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700373 public void changeCameraCapabilities(
374 VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700375 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700376 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
377 }
378 }
379
380 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700381 public void changeVideoQuality(int videoQuality) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700382 for (Callback l : mCallbacks) {
Rekha Kumar07366812015-03-24 16:42:31 -0700383 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
384 }
385 }
386
387 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700388 public IBinder asBinder() {
389 return null;
390 }
391 };
392
393 private final VideoCallbackServant mVideoCallbackServant =
394 new VideoCallbackServant(mVideoCallbackDelegate);
395
396 private final IVideoProvider mVideoProviderBinder;
397
398 /**
399 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
400 * load factor before resizing, 1 means we only expect a single thread to
401 * access the map so make only a single shard
402 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700403 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
404 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awada64627c2014-08-20 09:36:40 -0700405
Tyler Gunna2df9252015-05-29 10:05:46 -0700406 VideoProvider(IVideoProvider videoProviderBinder) {
Ihab Awada64627c2014-08-20 09:36:40 -0700407 mVideoProviderBinder = videoProviderBinder;
408 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700409 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700410 } catch (RemoteException e) {
411 }
412 }
413
Tyler Gunn295f5d72015-06-04 11:08:54 -0700414 /**
415 * Registers a callback to receive commands and state changes for video calls.
416 *
417 * @param l The video call callback.
418 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700419 public void registerCallback(Callback l) {
420 mCallbacks.add(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700421 }
422
Tyler Gunn295f5d72015-06-04 11:08:54 -0700423 /**
424 * Clears the video call callback set via {@link #registerCallback}.
425 *
426 * @param l The video call callback to clear.
427 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700428 public void unregisterCallback(Callback l) {
429 mCallbacks.remove(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700430 }
431
Tyler Gunn295f5d72015-06-04 11:08:54 -0700432 /**
433 * Sets the camera to be used for the outgoing video for the
434 * {@link RemoteConnection.VideoProvider}.
435 *
436 * @param cameraId The id of the camera (use ids as reported by
437 * {@link CameraManager#getCameraIdList()}).
438 * @see Connection.VideoProvider#onSetCamera(String)
439 */
Ihab Awada64627c2014-08-20 09:36:40 -0700440 public void setCamera(String cameraId) {
441 try {
442 mVideoProviderBinder.setCamera(cameraId);
443 } catch (RemoteException e) {
444 }
445 }
446
Tyler Gunn295f5d72015-06-04 11:08:54 -0700447 /**
448 * Sets the surface to be used for displaying a preview of what the user's camera is
449 * currently capturing for the {@link RemoteConnection.VideoProvider}.
450 *
451 * @param surface The {@link Surface}.
452 * @see Connection.VideoProvider#onSetPreviewSurface(Surface)
453 */
Ihab Awada64627c2014-08-20 09:36:40 -0700454 public void setPreviewSurface(Surface surface) {
455 try {
456 mVideoProviderBinder.setPreviewSurface(surface);
457 } catch (RemoteException e) {
458 }
459 }
460
Tyler Gunn295f5d72015-06-04 11:08:54 -0700461 /**
462 * Sets the surface to be used for displaying the video received from the remote device for
463 * the {@link RemoteConnection.VideoProvider}.
464 *
465 * @param surface The {@link Surface}.
466 * @see Connection.VideoProvider#onSetDisplaySurface(Surface)
467 */
Ihab Awada64627c2014-08-20 09:36:40 -0700468 public void setDisplaySurface(Surface surface) {
469 try {
470 mVideoProviderBinder.setDisplaySurface(surface);
471 } catch (RemoteException e) {
472 }
473 }
474
Tyler Gunn295f5d72015-06-04 11:08:54 -0700475 /**
476 * Sets the device orientation, in degrees, for the {@link RemoteConnection.VideoProvider}.
477 * Assumes that a standard portrait orientation of the device is 0 degrees.
478 *
479 * @param rotation The device orientation, in degrees.
480 * @see Connection.VideoProvider#onSetDeviceOrientation(int)
481 */
Ihab Awada64627c2014-08-20 09:36:40 -0700482 public void setDeviceOrientation(int rotation) {
483 try {
484 mVideoProviderBinder.setDeviceOrientation(rotation);
485 } catch (RemoteException e) {
486 }
487 }
488
Tyler Gunn295f5d72015-06-04 11:08:54 -0700489 /**
490 * Sets camera zoom ratio for the {@link RemoteConnection.VideoProvider}.
491 *
492 * @param value The camera zoom ratio.
493 * @see Connection.VideoProvider#onSetZoom(float)
494 */
Ihab Awada64627c2014-08-20 09:36:40 -0700495 public void setZoom(float value) {
496 try {
497 mVideoProviderBinder.setZoom(value);
498 } catch (RemoteException e) {
499 }
500 }
501
Tyler Gunn295f5d72015-06-04 11:08:54 -0700502 /**
503 * Issues a request to modify the properties of the current video session for the
504 * {@link RemoteConnection.VideoProvider}.
505 *
506 * @param fromProfile The video profile prior to the request.
507 * @param toProfile The video profile with the requested changes made.
508 * @see Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)
509 */
Tyler Gunn45382162015-05-06 08:52:27 -0700510 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700511 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700512 mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700513 } catch (RemoteException e) {
514 }
515 }
516
Tyler Gunn295f5d72015-06-04 11:08:54 -0700517 /**
518 * Provides a response to a request to change the current call video session
519 * properties for the {@link RemoteConnection.VideoProvider}.
520 *
521 * @param responseProfile The response call video properties.
522 * @see Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)
523 */
Ihab Awada64627c2014-08-20 09:36:40 -0700524 public void sendSessionModifyResponse(VideoProfile responseProfile) {
525 try {
526 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
527 } catch (RemoteException e) {
528 }
529 }
530
Tyler Gunn295f5d72015-06-04 11:08:54 -0700531 /**
532 * Issues a request to retrieve the capabilities of the current camera for the
533 * {@link RemoteConnection.VideoProvider}.
534 *
535 * @see Connection.VideoProvider#onRequestCameraCapabilities()
536 */
Ihab Awada64627c2014-08-20 09:36:40 -0700537 public void requestCameraCapabilities() {
538 try {
539 mVideoProviderBinder.requestCameraCapabilities();
540 } catch (RemoteException e) {
541 }
542 }
543
Tyler Gunn295f5d72015-06-04 11:08:54 -0700544 /**
545 * Issues a request to retrieve the data usage (in bytes) of the video portion of the
546 * {@link RemoteConnection} for the {@link RemoteConnection.VideoProvider}.
547 *
548 * @see Connection.VideoProvider#onRequestConnectionDataUsage()
549 */
Ihab Awada64627c2014-08-20 09:36:40 -0700550 public void requestCallDataUsage() {
551 try {
552 mVideoProviderBinder.requestCallDataUsage();
553 } catch (RemoteException e) {
554 }
555 }
556
Tyler Gunn295f5d72015-06-04 11:08:54 -0700557 /**
558 * Sets the {@link Uri} of an image to be displayed to the peer device when the video signal
559 * is paused, for the {@link RemoteConnection.VideoProvider}.
560 *
561 * @see Connection.VideoProvider#onSetPauseImage(Uri)
562 */
Yorke Lee32f24732015-05-12 16:18:03 -0700563 public void setPauseImage(Uri uri) {
Ihab Awada64627c2014-08-20 09:36:40 -0700564 try {
565 mVideoProviderBinder.setPauseImage(uri);
566 } catch (RemoteException e) {
567 }
568 }
569 }
570
Evan Charltonbf11f982014-07-20 22:06:28 -0700571 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700572 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700573 /**
574 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
575 * load factor before resizing, 1 means we only expect a single thread to
576 * access the map so make only a single shard
577 */
Andrew Lee011728f2015-04-23 15:47:06 -0700578 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
579 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700580 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
581 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
582 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700583
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700584 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700585 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700586 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700587 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800588 private int mConnectionCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700589 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700590 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700591 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700592 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700593 private Uri mAddress;
594 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700595 private String mCallerDisplayName;
596 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700597 private RemoteConference mConference;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700598 private Bundle mExtras;
Santos Cordon52d8a152014-06-17 19:08:45 -0700599
600 /**
601 * @hide
602 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700603 RemoteConnection(
604 String id,
605 IConnectionService connectionService,
606 ConnectionRequest request) {
607 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700608 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700609 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700610 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700611 }
612
613 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700614 * @hide
615 */
616 RemoteConnection(String callId, IConnectionService connectionService,
617 ParcelableConnection connection) {
618 mConnectionId = callId;
619 mConnectionService = connectionService;
620 mConnected = true;
621 mState = connection.getState();
622 mDisconnectCause = connection.getDisconnectCause();
623 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800624 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700625 mVideoState = connection.getVideoState();
626 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
627 mIsVoipAudioMode = connection.getIsVoipAudioMode();
628 mStatusHints = connection.getStatusHints();
629 mAddress = connection.getHandle();
630 mAddressPresentation = connection.getHandlePresentation();
631 mCallerDisplayName = connection.getCallerDisplayName();
632 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
633 mConference = null;
634 }
635
636 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700637 * Create a RemoteConnection which is used for failed connections. Note that using it for any
638 * "real" purpose will almost certainly fail. Callers should note the failure and act
639 * accordingly (moving on to another RemoteConnection, for example)
640 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700641 * @param disconnectCause The reason for the failed connection.
642 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700643 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700644 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700645 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700646 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700647 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700648 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700649 }
650
Ihab Awad5d0410f2014-07-30 10:07:40 -0700651 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700652 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700653 *
Andrew Lee100e2932014-09-08 15:34:24 -0700654 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700655 */
Andrew Lee100e2932014-09-08 15:34:24 -0700656 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700657 registerCallback(callback, new Handler());
658 }
659
660 /**
661 * Adds a callback to this {@code RemoteConnection}.
662 *
663 * @param callback A {@code Callback}.
664 * @param handler A {@code Handler} which command and status changes will be delivered to.
665 */
666 public void registerCallback(Callback callback, Handler handler) {
667 unregisterCallback(callback);
668 if (callback != null && handler != null) {
669 mCallbackRecords.add(new CallbackRecord(callback, handler));
670 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700671 }
672
Ihab Awad5d0410f2014-07-30 10:07:40 -0700673 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700674 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700675 *
Andrew Lee100e2932014-09-08 15:34:24 -0700676 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700677 */
Andrew Lee100e2932014-09-08 15:34:24 -0700678 public void unregisterCallback(Callback callback) {
679 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700680 for (CallbackRecord record : mCallbackRecords) {
681 if (record.getCallback() == callback) {
682 mCallbackRecords.remove(record);
683 break;
684 }
685 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700686 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700687 }
688
Ihab Awad5d0410f2014-07-30 10:07:40 -0700689 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700690 * Obtains the state of this {@code RemoteConnection}.
691 *
692 * @return A state value, chosen from the {@code STATE_*} constants.
693 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700694 public int getState() {
695 return mState;
696 }
697
Ihab Awad5d0410f2014-07-30 10:07:40 -0700698 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800699 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
700 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700701 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800702 * disconnect cause expressed as a code chosen from among those declared in
703 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700704 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700705 public DisconnectCause getDisconnectCause() {
706 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700707 }
708
Ihab Awad5d0410f2014-07-30 10:07:40 -0700709 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800710 * Obtains the capabilities of this {@code RemoteConnection}.
711 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700712 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800713 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700714 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800715 public int getConnectionCapabilities() {
716 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700717 }
718
Ihab Awad5d0410f2014-07-30 10:07:40 -0700719 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800720 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
721 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700722 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
723 */
Andrew Lee100e2932014-09-08 15:34:24 -0700724 public boolean isVoipAudioMode() {
725 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700726 }
727
Ihab Awad5d0410f2014-07-30 10:07:40 -0700728 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800729 * Obtains status hints pertaining to this {@code RemoteConnection}.
730 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700731 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800732 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700733 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700734 public StatusHints getStatusHints() {
735 return mStatusHints;
736 }
737
Ihab Awad5d0410f2014-07-30 10:07:40 -0700738 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800739 * Obtains the address of this {@code RemoteConnection}.
740 *
741 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
742 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700743 */
Andrew Lee100e2932014-09-08 15:34:24 -0700744 public Uri getAddress() {
745 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700746 }
747
Ihab Awad5d0410f2014-07-30 10:07:40 -0700748 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800749 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
750 *
751 * @return The presentation requirements for the address. See
752 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700753 */
Andrew Lee100e2932014-09-08 15:34:24 -0700754 public int getAddressPresentation() {
755 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700756 }
757
Ihab Awad5d0410f2014-07-30 10:07:40 -0700758 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800759 * Obtains the display name for this {@code RemoteConnection}'s caller.
760 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700761 * @return The display name for the caller.
762 */
Andrew Lee100e2932014-09-08 15:34:24 -0700763 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700764 return mCallerDisplayName;
765 }
766
Ihab Awad5d0410f2014-07-30 10:07:40 -0700767 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800768 * Obtains the presentation requirements for this {@code RemoteConnection}'s
769 * caller's display name.
770 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700771 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800772 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700773 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700774 public int getCallerDisplayNamePresentation() {
775 return mCallerDisplayNamePresentation;
776 }
777
Ihab Awad5d0410f2014-07-30 10:07:40 -0700778 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800779 * Obtains the video state of this {@code RemoteConnection}.
780 *
Tyler Gunn87b73f32015-06-03 10:09:59 -0700781 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700782 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700783 public int getVideoState() {
784 return mVideoState;
785 }
786
Ihab Awad5d0410f2014-07-30 10:07:40 -0700787 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700788 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700789 * @return The video provider associated with this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700790 */
791 public final VideoProvider getVideoProvider() {
792 return mVideoProvider;
793 }
794
795 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700796 * Obtain the extras associated with this {@code RemoteConnection}.
797 *
798 * @return The extras for this connection.
799 */
800 public final Bundle getExtras() {
801 return mExtras;
802 }
803
804 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800805 * Determines whether this {@code RemoteConnection} is requesting ringback.
806 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700807 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800808 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700809 */
Andrew Lee100e2932014-09-08 15:34:24 -0700810 public boolean isRingbackRequested() {
Santos Cordon15d63c72015-06-02 15:08:26 -0700811 return mRingbackRequested;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700812 }
813
814 /**
815 * Instructs this {@code RemoteConnection} to abort.
816 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700817 public void abort() {
818 try {
819 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700820 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700821 }
822 } catch (RemoteException ignored) {
823 }
824 }
825
Ihab Awad5d0410f2014-07-30 10:07:40 -0700826 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700827 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700828 */
829 public void answer() {
830 try {
831 if (mConnected) {
832 mConnectionService.answer(mConnectionId);
833 }
834 } catch (RemoteException ignored) {
835 }
836 }
837
838 /**
839 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700840 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700841 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700842 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700843 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700844 try {
845 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700846 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700847 }
848 } catch (RemoteException ignored) {
849 }
850 }
851
Ihab Awad5d0410f2014-07-30 10:07:40 -0700852 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700853 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700854 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700855 public void reject() {
856 try {
857 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700858 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700859 }
860 } catch (RemoteException ignored) {
861 }
862 }
863
Ihab Awad5d0410f2014-07-30 10:07:40 -0700864 /**
865 * Instructs this {@code RemoteConnection} to go on hold.
866 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700867 public void hold() {
868 try {
869 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700870 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700871 }
872 } catch (RemoteException ignored) {
873 }
874 }
875
Ihab Awad5d0410f2014-07-30 10:07:40 -0700876 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700877 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700878 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700879 public void unhold() {
880 try {
881 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700882 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700883 }
884 } catch (RemoteException ignored) {
885 }
886 }
887
Ihab Awad5d0410f2014-07-30 10:07:40 -0700888 /**
889 * Instructs this {@code RemoteConnection} to disconnect.
890 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700891 public void disconnect() {
892 try {
893 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700894 mConnectionService.disconnect(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700895 }
896 } catch (RemoteException ignored) {
897 }
898 }
899
Ihab Awad5d0410f2014-07-30 10:07:40 -0700900 /**
901 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
902 * (DTMF) tone.
903 *
904 * Any other currently playing DTMF tone in the specified call is immediately stopped.
905 *
906 * @param digit A character representing the DTMF digit for which to play the tone. This
907 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
908 */
909 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700910 try {
911 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700912 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700913 }
914 } catch (RemoteException ignored) {
915 }
916 }
917
Ihab Awad5d0410f2014-07-30 10:07:40 -0700918 /**
919 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
920 * (DTMF) tone currently playing.
921 *
922 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
923 * currently playing, this method will do nothing.
924 */
925 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700926 try {
927 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700928 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700929 }
930 } catch (RemoteException ignored) {
931 }
932 }
933
Ihab Awad5d0410f2014-07-30 10:07:40 -0700934 /**
935 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
936 *
937 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700938 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700939 * These digits are immediately sent as DTMF tones to the recipient as soon as the
940 * connection is made.
941 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700942 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700943 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
944 * of time.
945 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700946 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800947 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -0700948 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700949 * should display to the user an indication of this state and an affordance to continue
950 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
951 * app should invoke the {@link #postDialContinue(boolean)} method.
952 *
953 * @param proceed Whether or not to continue with the post-dial sequence.
954 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700955 public void postDialContinue(boolean proceed) {
956 try {
957 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700958 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700959 }
960 } catch (RemoteException ignored) {
961 }
962 }
963
Ihab Awad5d0410f2014-07-30 10:07:40 -0700964 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700965 * Set the audio state of this {@code RemoteConnection}.
966 *
967 * @param state The audio state of this {@code RemoteConnection}.
Yorke Lee4af59352015-05-13 14:14:54 -0700968 * @hide
969 * @deprecated Use {@link #setCallAudioState(CallAudioState) instead.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700970 */
Yorke Lee4af59352015-05-13 14:14:54 -0700971 @SystemApi
972 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700973 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -0700974 setCallAudioState(new CallAudioState(state));
975 }
976
977 /**
978 * Set the audio state of this {@code RemoteConnection}.
979 *
980 * @param state The audio state of this {@code RemoteConnection}.
981 */
982 public void setCallAudioState(CallAudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700983 try {
984 if (mConnected) {
Yorke Lee4af59352015-05-13 14:14:54 -0700985 mConnectionService.onCallAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700986 }
987 } catch (RemoteException ignored) {
988 }
989 }
990
Santos Cordon52d8a152014-06-17 19:08:45 -0700991 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700992 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
993 * successfully asked to create a conference with.
994 *
995 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
996 * merged into a {@link RemoteConference}.
997 */
998 public List<RemoteConnection> getConferenceableConnections() {
999 return mUnmodifiableconferenceableConnections;
1000 }
1001
1002 /**
1003 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
1004 * of, or {@code null} if there is no such {@code RemoteConference}.
1005 *
1006 * @return A {@code RemoteConference} or {@code null};
1007 */
1008 public RemoteConference getConference() {
1009 return mConference;
1010 }
1011
1012 /** {@hide} */
1013 String getId() {
1014 return mConnectionId;
1015 }
1016
1017 /** {@hide} */
1018 IConnectionService getConnectionService() {
1019 return mConnectionService;
1020 }
1021
1022 /**
Santos Cordon52d8a152014-06-17 19:08:45 -07001023 * @hide
1024 */
Andrew Lee011728f2015-04-23 15:47:06 -07001025 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -07001026 if (mState != state) {
1027 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -07001028 for (CallbackRecord record: mCallbackRecords) {
1029 final RemoteConnection connection = this;
1030 final Callback callback = record.getCallback();
1031 record.getHandler().post(new Runnable() {
1032 @Override
1033 public void run() {
1034 callback.onStateChanged(connection, state);
1035 }
1036 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001037 }
1038 }
1039 }
1040
1041 /**
1042 * @hide
1043 */
Andrew Lee011728f2015-04-23 15:47:06 -07001044 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001045 if (mState != Connection.STATE_DISCONNECTED) {
1046 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001047 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -07001048
Andrew Lee011728f2015-04-23 15:47:06 -07001049 for (CallbackRecord record : mCallbackRecords) {
1050 final RemoteConnection connection = this;
1051 final Callback callback = record.getCallback();
1052 record.getHandler().post(new Runnable() {
1053 @Override
1054 public void run() {
1055 callback.onDisconnected(connection, disconnectCause);
1056 }
1057 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001058 }
1059 }
1060 }
1061
1062 /**
1063 * @hide
1064 */
Andrew Lee011728f2015-04-23 15:47:06 -07001065 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -07001066 if (mRingbackRequested != ringback) {
1067 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -07001068 for (CallbackRecord record : mCallbackRecords) {
1069 final RemoteConnection connection = this;
1070 final Callback callback = record.getCallback();
1071 record.getHandler().post(new Runnable() {
1072 @Override
1073 public void run() {
1074 callback.onRingbackRequested(connection, ringback);
1075 }
1076 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001077 }
1078 }
1079 }
1080
1081 /**
1082 * @hide
1083 */
Andrew Lee011728f2015-04-23 15:47:06 -07001084 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001085 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -07001086 for (CallbackRecord record : mCallbackRecords) {
1087 final RemoteConnection connection = this;
1088 final Callback callback = record.getCallback();
1089 record.getHandler().post(new Runnable() {
1090 @Override
1091 public void run() {
1092 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
1093 }
1094 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001095 }
1096 }
1097
1098 /**
1099 * @hide
1100 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001101 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -07001102 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -07001103 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001104 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001105 setDisconnected(
1106 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -07001107 }
1108
Andrew Lee011728f2015-04-23 15:47:06 -07001109 for (CallbackRecord record : mCallbackRecords) {
1110 final RemoteConnection connection = this;
1111 final Callback callback = record.getCallback();
1112 record.getHandler().post(new Runnable() {
1113 @Override
1114 public void run() {
1115 callback.onDestroyed(connection);
1116 }
1117 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001118 }
Andrew Lee011728f2015-04-23 15:47:06 -07001119 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -07001120
1121 mConnected = false;
1122 }
1123 }
1124
1125 /**
1126 * @hide
1127 */
Andrew Lee011728f2015-04-23 15:47:06 -07001128 void setPostDialWait(final String remainingDigits) {
1129 for (CallbackRecord record : mCallbackRecords) {
1130 final RemoteConnection connection = this;
1131 final Callback callback = record.getCallback();
1132 record.getHandler().post(new Runnable() {
1133 @Override
1134 public void run() {
1135 callback.onPostDialWait(connection, remainingDigits);
1136 }
1137 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001138 }
1139 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001140
Tyler Gunnaa07df82014-07-17 07:50:22 -07001141 /**
1142 * @hide
1143 */
Andrew Lee011728f2015-04-23 15:47:06 -07001144 void onPostDialChar(final char nextChar) {
1145 for (CallbackRecord record : mCallbackRecords) {
1146 final RemoteConnection connection = this;
1147 final Callback callback = record.getCallback();
1148 record.getHandler().post(new Runnable() {
1149 @Override
1150 public void run() {
Sailesh Nepal40451b32015-05-14 17:39:41 -07001151 callback.onPostDialChar(connection, nextChar);
Andrew Lee011728f2015-04-23 15:47:06 -07001152 }
1153 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001154 }
1155 }
1156
1157 /**
1158 * @hide
1159 */
Andrew Lee011728f2015-04-23 15:47:06 -07001160 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -07001161 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -07001162 for (CallbackRecord record : mCallbackRecords) {
1163 final RemoteConnection connection = this;
1164 final Callback callback = record.getCallback();
1165 record.getHandler().post(new Runnable() {
1166 @Override
1167 public void run() {
1168 callback.onVideoStateChanged(connection, videoState);
1169 }
1170 });
Tyler Gunnaa07df82014-07-17 07:50:22 -07001171 }
1172 }
1173
Ihab Awada64627c2014-08-20 09:36:40 -07001174 /**
1175 * @hide
1176 */
Andrew Lee011728f2015-04-23 15:47:06 -07001177 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -07001178 mVideoProvider = videoProvider;
Andrew Lee011728f2015-04-23 15:47:06 -07001179 for (CallbackRecord record : mCallbackRecords) {
1180 final RemoteConnection connection = this;
1181 final Callback callback = record.getCallback();
1182 record.getHandler().post(new Runnable() {
1183 @Override
1184 public void run() {
1185 callback.onVideoProviderChanged(connection, videoProvider);
1186 }
1187 });
Ihab Awada64627c2014-08-20 09:36:40 -07001188 }
1189 }
1190
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001191 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001192 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -07001193 mIsVoipAudioMode = isVoip;
Andrew Lee011728f2015-04-23 15:47:06 -07001194 for (CallbackRecord record : mCallbackRecords) {
1195 final RemoteConnection connection = this;
1196 final Callback callback = record.getCallback();
1197 record.getHandler().post(new Runnable() {
1198 @Override
1199 public void run() {
1200 callback.onVoipAudioChanged(connection, isVoip);
1201 }
1202 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001203 }
1204 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001205
1206 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001207 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001208 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001209 for (CallbackRecord record : mCallbackRecords) {
1210 final RemoteConnection connection = this;
1211 final Callback callback = record.getCallback();
1212 record.getHandler().post(new Runnable() {
1213 @Override
1214 public void run() {
1215 callback.onStatusHintsChanged(connection, statusHints);
1216 }
1217 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001218 }
1219 }
1220
1221 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001222 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001223 mAddress = address;
1224 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001225 for (CallbackRecord record : mCallbackRecords) {
1226 final RemoteConnection connection = this;
1227 final Callback callback = record.getCallback();
1228 record.getHandler().post(new Runnable() {
1229 @Override
1230 public void run() {
1231 callback.onAddressChanged(connection, address, presentation);
1232 }
1233 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001234 }
1235 }
1236
1237 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001238 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001239 mCallerDisplayName = callerDisplayName;
1240 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001241 for (CallbackRecord record : mCallbackRecords) {
1242 final RemoteConnection connection = this;
1243 final Callback callback = record.getCallback();
1244 record.getHandler().post(new Runnable() {
1245 @Override
1246 public void run() {
1247 callback.onCallerDisplayNameChanged(
1248 connection, callerDisplayName, presentation);
1249 }
1250 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001251 }
1252 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001253
1254 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001255 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001256 mConferenceableConnections.clear();
1257 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001258 for (CallbackRecord record : mCallbackRecords) {
1259 final RemoteConnection connection = this;
1260 final Callback callback = record.getCallback();
1261 record.getHandler().post(new Runnable() {
1262 @Override
1263 public void run() {
1264 callback.onConferenceableConnectionsChanged(
1265 connection, mUnmodifiableconferenceableConnections);
1266 }
1267 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001268 }
1269 }
1270
1271 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001272 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001273 if (mConference != conference) {
1274 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001275 for (CallbackRecord record : mCallbackRecords) {
1276 final RemoteConnection connection = this;
1277 final Callback callback = record.getCallback();
1278 record.getHandler().post(new Runnable() {
1279 @Override
1280 public void run() {
1281 callback.onConferenceChanged(connection, conference);
1282 }
1283 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001284 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001285 }
1286 }
1287
Santos Cordon6b7f9552015-05-27 17:21:45 -07001288 /** @hide */
1289 void setExtras(final Bundle extras) {
1290 mExtras = extras;
1291 for (CallbackRecord record : mCallbackRecords) {
1292 final RemoteConnection connection = this;
1293 final Callback callback = record.getCallback();
1294 record.getHandler().post(new Runnable() {
1295 @Override
1296 public void run() {
1297 callback.onExtrasChanged(connection, extras);
1298 }
1299 });
1300 }
1301 }
1302
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001303 /** @hide */
1304 void onConnectionEvent(final String event) {
1305 for (CallbackRecord record : mCallbackRecords) {
1306 final RemoteConnection connection = this;
1307 final Callback callback = record.getCallback();
1308 record.getHandler().post(new Runnable() {
1309 @Override
1310 public void run() {
1311 callback.onConnectionEvent(connection, event);
1312 }
1313 });
1314 }
1315 }
1316
Evan Charltonbf11f982014-07-20 22:06:28 -07001317 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001318 * Create a RemoteConnection represents a failure, and which will be in
1319 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1320 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001321 *
1322 * @return a failed {@link RemoteConnection}
1323 *
1324 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001325 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001326 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1327 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001328 }
Andrew Lee011728f2015-04-23 15:47:06 -07001329
1330 private static final class CallbackRecord extends Callback {
1331 private final Callback mCallback;
1332 private final Handler mHandler;
1333
1334 public CallbackRecord(Callback callback, Handler handler) {
1335 mCallback = callback;
1336 mHandler = handler;
1337 }
1338
1339 public Callback getCallback() {
1340 return mCallback;
1341 }
1342
1343 public Handler getHandler() {
1344 return mHandler;
1345 }
1346 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001347}