blob: 88be832fbeee1fdf4e541312706b2e84e35ab9ba [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
Andrew Lee100e2932014-09-08 15:34:24 -070048 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070049 /**
50 * Invoked when the state of this {@code RemoteConnection} has changed. See
51 * {@link #getState()}.
52 *
53 * @param connection The {@code RemoteConnection} invoking this method.
54 * @param state The new state of the {@code RemoteConnection}.
55 */
Evan Charltonbf11f982014-07-20 22:06:28 -070056 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070057
58 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070059 * Invoked when this {@code RemoteConnection} is disconnected.
60 *
61 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070062 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
63 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070064 */
65 public void onDisconnected(
66 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070067 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070068
69 /**
70 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070071 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070072 *
73 * @param connection The {@code RemoteConnection} invoking this method.
74 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
75 */
Andrew Lee100e2932014-09-08 15:34:24 -070076 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070077
78 /**
79 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080080 * See {@link #getConnectionCapabilities()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070081 *
82 * @param connection The {@code RemoteConnection} invoking this method.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080083 * @param connectionCapabilities The new capabilities of the {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070084 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080085 public void onConnectionCapabilitiesChanged(
86 RemoteConnection connection,
87 int connectionCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070088
89 /**
90 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
91 * pause character. This causes the post-dial signals to stop pending user confirmation. An
92 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -070093 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -070094 *
95 * @param connection The {@code RemoteConnection} invoking this method.
96 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
97 */
98 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
99
100 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800101 * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
102 * a character.
103 *
104 * @param connection The {@code RemoteConnection} invoking this method.
105 * @param nextChar The character being processed.
106 */
107 public void onPostDialChar(RemoteConnection connection, char nextChar) {}
108
109 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700110 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -0700111 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700112 *
113 * @param connection The {@code RemoteConnection} invoking this method.
114 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
115 */
Andrew Lee100e2932014-09-08 15:34:24 -0700116 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700117
118 /**
119 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
120 * {@link #getStatusHints()} ()}.
121 *
122 * @param connection The {@code RemoteConnection} invoking this method.
123 * @param statusHints The new status hints of the {@code RemoteConnection}.
124 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700125 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700126
127 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700128 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
129 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700130 *
131 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700132 * @param address The new address of the {@code RemoteConnection}.
133 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700134 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700135 */
Andrew Lee100e2932014-09-08 15:34:24 -0700136 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700137
138 /**
139 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
140 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
141 *
142 * @param connection The {@code RemoteConnection} invoking this method.
143 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700144 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700145 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700146 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700147 public void onCallerDisplayNameChanged(
148 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700149
150 /**
151 * Indicates that the video state of this {@code RemoteConnection} has changed.
152 * See {@link #getVideoState()}.
153 *
154 * @param connection The {@code RemoteConnection} invoking this method.
155 * @param videoState The new video state of the {@code RemoteConnection}.
156 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700157 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700158
159 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700160 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
161 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
162 *
163 * @param connection The {@code RemoteConnection} invoking this method.
164 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700165 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700166
167 /**
168 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
169 * may be asked to create a conference has changed.
170 *
171 * @param connection The {@code RemoteConnection} invoking this method.
172 * @param conferenceableConnections The {@code RemoteConnection}s with which this
173 * {@code RemoteConnection} may be asked to create a conference.
174 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700175 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700176 RemoteConnection connection,
177 List<RemoteConnection> conferenceableConnections) {}
178
179 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700180 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
181 * has changed.
182 *
183 * @param connection The {@code RemoteConnection} invoking this method.
184 * @param videoProvider The new {@code VideoProvider} associated with this
185 * {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700186 */
187 public void onVideoProviderChanged(
188 RemoteConnection connection, VideoProvider videoProvider) {}
189
190 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700191 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
192 * of has changed.
193 *
194 * @param connection The {@code RemoteConnection} invoking this method.
195 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
196 * a part, which may be {@code null}.
197 */
198 public void onConferenceChanged(
199 RemoteConnection connection,
200 RemoteConference conference) {}
Santos Cordon6b7f9552015-05-27 17:21:45 -0700201
202 /**
203 * Handles changes to the {@code RemoteConference} extras.
204 *
205 * @param connection The {@code RemoteConnection} invoking this method.
206 * @param extras The extras containing other information associated with the connection.
207 */
208 public void onExtrasChanged(RemoteConnection connection, @Nullable Bundle extras) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700209 }
210
Tyler Gunn295f5d72015-06-04 11:08:54 -0700211 /**
212 * {@link RemoteConnection.VideoProvider} associated with a {@link RemoteConnection}. Used to
213 * receive video related events and control the video associated with a
214 * {@link RemoteConnection}.
215 *
216 * @see Connection.VideoProvider
217 */
Ihab Awada64627c2014-08-20 09:36:40 -0700218 public static class VideoProvider {
219
Tyler Gunn295f5d72015-06-04 11:08:54 -0700220 /**
221 * Callback class used by the {@link RemoteConnection.VideoProvider} to relay events from
222 * the {@link Connection.VideoProvider}.
223 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700224 public abstract static class Callback {
Tyler Gunn295f5d72015-06-04 11:08:54 -0700225 /**
226 * Reports a session modification request received from the
227 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
228 *
229 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
230 * @param videoProfile The requested video call profile.
231 * @see InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)
232 * @see Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)
233 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700234 public void onSessionModifyRequestReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700235 VideoProvider videoProvider,
236 VideoProfile videoProfile) {}
237
Tyler Gunn295f5d72015-06-04 11:08:54 -0700238 /**
239 * Reports a session modification response received from the
240 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
241 *
242 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
243 * @param status Status of the session modify request.
244 * @param requestedProfile The original request which was sent to the peer device.
245 * @param responseProfile The actual profile changes made by the peer device.
246 * @see InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
247 * VideoProfile, VideoProfile)
248 * @see Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile,
249 * VideoProfile)
250 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700251 public void onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700252 VideoProvider videoProvider,
253 int status,
254 VideoProfile requestedProfile,
255 VideoProfile responseProfile) {}
256
Tyler Gunn295f5d72015-06-04 11:08:54 -0700257 /**
258 * Reports a call session event received from the {@link Connection.VideoProvider}
259 * associated with a {@link RemoteConnection}.
260 *
261 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
262 * @param event The event.
263 * @see InCallService.VideoCall.Callback#onCallSessionEvent(int)
264 * @see Connection.VideoProvider#handleCallSessionEvent(int)
265 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700266 public void onCallSessionEvent(VideoProvider videoProvider, int event) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700267
Tyler Gunn295f5d72015-06-04 11:08:54 -0700268 /**
269 * Reports a change in the peer video dimensions received from the
270 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
271 *
272 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
273 * @param width The updated peer video width.
274 * @param height The updated peer video height.
275 * @see InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)
276 * @see Connection.VideoProvider#changePeerDimensions(int, int)
277 */
278 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width,
279 int height) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700280
Tyler Gunn295f5d72015-06-04 11:08:54 -0700281 /**
282 * Reports a change in the data usage (in bytes) received from the
283 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
284 *
285 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
286 * @param dataUsage The updated data usage (in bytes).
287 * @see InCallService.VideoCall.Callback#onCallDataUsageChanged(long)
288 * @see Connection.VideoProvider#setCallDataUsage(long)
289 */
Rekha Kumar07366812015-03-24 16:42:31 -0700290 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700291
Tyler Gunn295f5d72015-06-04 11:08:54 -0700292 /**
293 * Reports a change in the capabilities of the current camera, received from the
294 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
295 *
296 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
297 * @param cameraCapabilities The changed camera capabilities.
298 * @see InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
299 * VideoProfile.CameraCapabilities)
300 * @see Connection.VideoProvider#changeCameraCapabilities(
301 * VideoProfile.CameraCapabilities)
302 */
Ihab Awada64627c2014-08-20 09:36:40 -0700303 public void onCameraCapabilitiesChanged(
304 VideoProvider videoProvider,
Yorke Lee400470f2015-05-12 13:31:25 -0700305 VideoProfile.CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700306
Tyler Gunn295f5d72015-06-04 11:08:54 -0700307 /**
308 * Reports a change in the video quality received from the
309 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
310 *
311 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
312 * @param videoQuality The updated peer video quality.
313 * @see InCallService.VideoCall.Callback#onVideoQualityChanged(int)
314 * @see Connection.VideoProvider#changeVideoQuality(int)
315 */
Rekha Kumar07366812015-03-24 16:42:31 -0700316 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700317 }
318
319 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
320 @Override
321 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700322 for (Callback l : mCallbacks) {
323 l.onSessionModifyRequestReceived(VideoProvider.this, videoProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700324 }
325 }
326
327 @Override
328 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
329 VideoProfile responseProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700330 for (Callback l : mCallbacks) {
331 l.onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700332 VideoProvider.this,
333 status,
334 requestedProfile,
335 responseProfile);
336 }
337 }
338
339 @Override
340 public void handleCallSessionEvent(int event) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700341 for (Callback l : mCallbacks) {
342 l.onCallSessionEvent(VideoProvider.this, event);
Ihab Awada64627c2014-08-20 09:36:40 -0700343 }
344 }
345
346 @Override
347 public void changePeerDimensions(int width, int height) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700348 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700349 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
350 }
351 }
352
353 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700354 public void changeCallDataUsage(long dataUsage) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700355 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700356 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
357 }
358 }
359
360 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700361 public void changeCameraCapabilities(
362 VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700363 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700364 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
365 }
366 }
367
368 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700369 public void changeVideoQuality(int videoQuality) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700370 for (Callback l : mCallbacks) {
Rekha Kumar07366812015-03-24 16:42:31 -0700371 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
372 }
373 }
374
375 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700376 public IBinder asBinder() {
377 return null;
378 }
379 };
380
381 private final VideoCallbackServant mVideoCallbackServant =
382 new VideoCallbackServant(mVideoCallbackDelegate);
383
384 private final IVideoProvider mVideoProviderBinder;
385
386 /**
387 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
388 * load factor before resizing, 1 means we only expect a single thread to
389 * access the map so make only a single shard
390 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700391 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
392 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awada64627c2014-08-20 09:36:40 -0700393
Tyler Gunna2df9252015-05-29 10:05:46 -0700394 VideoProvider(IVideoProvider videoProviderBinder) {
Ihab Awada64627c2014-08-20 09:36:40 -0700395 mVideoProviderBinder = videoProviderBinder;
396 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700397 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700398 } catch (RemoteException e) {
399 }
400 }
401
Tyler Gunn295f5d72015-06-04 11:08:54 -0700402 /**
403 * Registers a callback to receive commands and state changes for video calls.
404 *
405 * @param l The video call callback.
406 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700407 public void registerCallback(Callback l) {
408 mCallbacks.add(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700409 }
410
Tyler Gunn295f5d72015-06-04 11:08:54 -0700411 /**
412 * Clears the video call callback set via {@link #registerCallback}.
413 *
414 * @param l The video call callback to clear.
415 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700416 public void unregisterCallback(Callback l) {
417 mCallbacks.remove(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700418 }
419
Tyler Gunn295f5d72015-06-04 11:08:54 -0700420 /**
421 * Sets the camera to be used for the outgoing video for the
422 * {@link RemoteConnection.VideoProvider}.
423 *
424 * @param cameraId The id of the camera (use ids as reported by
425 * {@link CameraManager#getCameraIdList()}).
426 * @see Connection.VideoProvider#onSetCamera(String)
427 */
Ihab Awada64627c2014-08-20 09:36:40 -0700428 public void setCamera(String cameraId) {
429 try {
430 mVideoProviderBinder.setCamera(cameraId);
431 } catch (RemoteException e) {
432 }
433 }
434
Tyler Gunn295f5d72015-06-04 11:08:54 -0700435 /**
436 * Sets the surface to be used for displaying a preview of what the user's camera is
437 * currently capturing for the {@link RemoteConnection.VideoProvider}.
438 *
439 * @param surface The {@link Surface}.
440 * @see Connection.VideoProvider#onSetPreviewSurface(Surface)
441 */
Ihab Awada64627c2014-08-20 09:36:40 -0700442 public void setPreviewSurface(Surface surface) {
443 try {
444 mVideoProviderBinder.setPreviewSurface(surface);
445 } catch (RemoteException e) {
446 }
447 }
448
Tyler Gunn295f5d72015-06-04 11:08:54 -0700449 /**
450 * Sets the surface to be used for displaying the video received from the remote device for
451 * the {@link RemoteConnection.VideoProvider}.
452 *
453 * @param surface The {@link Surface}.
454 * @see Connection.VideoProvider#onSetDisplaySurface(Surface)
455 */
Ihab Awada64627c2014-08-20 09:36:40 -0700456 public void setDisplaySurface(Surface surface) {
457 try {
458 mVideoProviderBinder.setDisplaySurface(surface);
459 } catch (RemoteException e) {
460 }
461 }
462
Tyler Gunn295f5d72015-06-04 11:08:54 -0700463 /**
464 * Sets the device orientation, in degrees, for the {@link RemoteConnection.VideoProvider}.
465 * Assumes that a standard portrait orientation of the device is 0 degrees.
466 *
467 * @param rotation The device orientation, in degrees.
468 * @see Connection.VideoProvider#onSetDeviceOrientation(int)
469 */
Ihab Awada64627c2014-08-20 09:36:40 -0700470 public void setDeviceOrientation(int rotation) {
471 try {
472 mVideoProviderBinder.setDeviceOrientation(rotation);
473 } catch (RemoteException e) {
474 }
475 }
476
Tyler Gunn295f5d72015-06-04 11:08:54 -0700477 /**
478 * Sets camera zoom ratio for the {@link RemoteConnection.VideoProvider}.
479 *
480 * @param value The camera zoom ratio.
481 * @see Connection.VideoProvider#onSetZoom(float)
482 */
Ihab Awada64627c2014-08-20 09:36:40 -0700483 public void setZoom(float value) {
484 try {
485 mVideoProviderBinder.setZoom(value);
486 } catch (RemoteException e) {
487 }
488 }
489
Tyler Gunn295f5d72015-06-04 11:08:54 -0700490 /**
491 * Issues a request to modify the properties of the current video session for the
492 * {@link RemoteConnection.VideoProvider}.
493 *
494 * @param fromProfile The video profile prior to the request.
495 * @param toProfile The video profile with the requested changes made.
496 * @see Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)
497 */
Tyler Gunn45382162015-05-06 08:52:27 -0700498 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700499 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700500 mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700501 } catch (RemoteException e) {
502 }
503 }
504
Tyler Gunn295f5d72015-06-04 11:08:54 -0700505 /**
506 * Provides a response to a request to change the current call video session
507 * properties for the {@link RemoteConnection.VideoProvider}.
508 *
509 * @param responseProfile The response call video properties.
510 * @see Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)
511 */
Ihab Awada64627c2014-08-20 09:36:40 -0700512 public void sendSessionModifyResponse(VideoProfile responseProfile) {
513 try {
514 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
515 } catch (RemoteException e) {
516 }
517 }
518
Tyler Gunn295f5d72015-06-04 11:08:54 -0700519 /**
520 * Issues a request to retrieve the capabilities of the current camera for the
521 * {@link RemoteConnection.VideoProvider}.
522 *
523 * @see Connection.VideoProvider#onRequestCameraCapabilities()
524 */
Ihab Awada64627c2014-08-20 09:36:40 -0700525 public void requestCameraCapabilities() {
526 try {
527 mVideoProviderBinder.requestCameraCapabilities();
528 } catch (RemoteException e) {
529 }
530 }
531
Tyler Gunn295f5d72015-06-04 11:08:54 -0700532 /**
533 * Issues a request to retrieve the data usage (in bytes) of the video portion of the
534 * {@link RemoteConnection} for the {@link RemoteConnection.VideoProvider}.
535 *
536 * @see Connection.VideoProvider#onRequestConnectionDataUsage()
537 */
Ihab Awada64627c2014-08-20 09:36:40 -0700538 public void requestCallDataUsage() {
539 try {
540 mVideoProviderBinder.requestCallDataUsage();
541 } catch (RemoteException e) {
542 }
543 }
544
Tyler Gunn295f5d72015-06-04 11:08:54 -0700545 /**
546 * Sets the {@link Uri} of an image to be displayed to the peer device when the video signal
547 * is paused, for the {@link RemoteConnection.VideoProvider}.
548 *
549 * @see Connection.VideoProvider#onSetPauseImage(Uri)
550 */
Yorke Lee32f24732015-05-12 16:18:03 -0700551 public void setPauseImage(Uri uri) {
Ihab Awada64627c2014-08-20 09:36:40 -0700552 try {
553 mVideoProviderBinder.setPauseImage(uri);
554 } catch (RemoteException e) {
555 }
556 }
557 }
558
Evan Charltonbf11f982014-07-20 22:06:28 -0700559 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700560 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700561 /**
562 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
563 * load factor before resizing, 1 means we only expect a single thread to
564 * access the map so make only a single shard
565 */
Andrew Lee011728f2015-04-23 15:47:06 -0700566 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
567 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700568 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
569 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
570 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700571
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700572 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700573 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700574 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700575 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800576 private int mConnectionCapabilities;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700577 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700578 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700579 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700580 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700581 private Uri mAddress;
582 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700583 private String mCallerDisplayName;
584 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700585 private RemoteConference mConference;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700586 private Bundle mExtras;
Santos Cordon52d8a152014-06-17 19:08:45 -0700587
588 /**
589 * @hide
590 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700591 RemoteConnection(
592 String id,
593 IConnectionService connectionService,
594 ConnectionRequest request) {
595 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700596 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700597 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700598 mState = Connection.STATE_INITIALIZING;
Evan Charltonbf11f982014-07-20 22:06:28 -0700599 }
600
601 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700602 * @hide
603 */
604 RemoteConnection(String callId, IConnectionService connectionService,
605 ParcelableConnection connection) {
606 mConnectionId = callId;
607 mConnectionService = connectionService;
608 mConnected = true;
609 mState = connection.getState();
610 mDisconnectCause = connection.getDisconnectCause();
611 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800612 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700613 mVideoState = connection.getVideoState();
614 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
615 mIsVoipAudioMode = connection.getIsVoipAudioMode();
616 mStatusHints = connection.getStatusHints();
617 mAddress = connection.getHandle();
618 mAddressPresentation = connection.getHandlePresentation();
619 mCallerDisplayName = connection.getCallerDisplayName();
620 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
621 mConference = null;
622 }
623
624 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700625 * Create a RemoteConnection which is used for failed connections. Note that using it for any
626 * "real" purpose will almost certainly fail. Callers should note the failure and act
627 * accordingly (moving on to another RemoteConnection, for example)
628 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700629 * @param disconnectCause The reason for the failed connection.
630 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700631 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700632 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700633 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700634 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700635 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700636 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700637 }
638
Ihab Awad5d0410f2014-07-30 10:07:40 -0700639 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700640 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700641 *
Andrew Lee100e2932014-09-08 15:34:24 -0700642 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700643 */
Andrew Lee100e2932014-09-08 15:34:24 -0700644 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700645 registerCallback(callback, new Handler());
646 }
647
648 /**
649 * Adds a callback to this {@code RemoteConnection}.
650 *
651 * @param callback A {@code Callback}.
652 * @param handler A {@code Handler} which command and status changes will be delivered to.
653 */
654 public void registerCallback(Callback callback, Handler handler) {
655 unregisterCallback(callback);
656 if (callback != null && handler != null) {
657 mCallbackRecords.add(new CallbackRecord(callback, handler));
658 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700659 }
660
Ihab Awad5d0410f2014-07-30 10:07:40 -0700661 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700662 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700663 *
Andrew Lee100e2932014-09-08 15:34:24 -0700664 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700665 */
Andrew Lee100e2932014-09-08 15:34:24 -0700666 public void unregisterCallback(Callback callback) {
667 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700668 for (CallbackRecord record : mCallbackRecords) {
669 if (record.getCallback() == callback) {
670 mCallbackRecords.remove(record);
671 break;
672 }
673 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700674 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700675 }
676
Ihab Awad5d0410f2014-07-30 10:07:40 -0700677 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700678 * Obtains the state of this {@code RemoteConnection}.
679 *
680 * @return A state value, chosen from the {@code STATE_*} constants.
681 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700682 public int getState() {
683 return mState;
684 }
685
Ihab Awad5d0410f2014-07-30 10:07:40 -0700686 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800687 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
688 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700689 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800690 * disconnect cause expressed as a code chosen from among those declared in
691 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700692 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700693 public DisconnectCause getDisconnectCause() {
694 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700695 }
696
Ihab Awad5d0410f2014-07-30 10:07:40 -0700697 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800698 * Obtains the capabilities of this {@code RemoteConnection}.
699 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700700 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800701 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700702 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800703 public int getConnectionCapabilities() {
704 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700705 }
706
Ihab Awad5d0410f2014-07-30 10:07:40 -0700707 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800708 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
709 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700710 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
711 */
Andrew Lee100e2932014-09-08 15:34:24 -0700712 public boolean isVoipAudioMode() {
713 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700714 }
715
Ihab Awad5d0410f2014-07-30 10:07:40 -0700716 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800717 * Obtains status hints pertaining to this {@code RemoteConnection}.
718 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700719 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800720 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700721 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700722 public StatusHints getStatusHints() {
723 return mStatusHints;
724 }
725
Ihab Awad5d0410f2014-07-30 10:07:40 -0700726 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800727 * Obtains the address of this {@code RemoteConnection}.
728 *
729 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
730 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700731 */
Andrew Lee100e2932014-09-08 15:34:24 -0700732 public Uri getAddress() {
733 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700734 }
735
Ihab Awad5d0410f2014-07-30 10:07:40 -0700736 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800737 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
738 *
739 * @return The presentation requirements for the address. See
740 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700741 */
Andrew Lee100e2932014-09-08 15:34:24 -0700742 public int getAddressPresentation() {
743 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700744 }
745
Ihab Awad5d0410f2014-07-30 10:07:40 -0700746 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800747 * Obtains the display name for this {@code RemoteConnection}'s caller.
748 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700749 * @return The display name for the caller.
750 */
Andrew Lee100e2932014-09-08 15:34:24 -0700751 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700752 return mCallerDisplayName;
753 }
754
Ihab Awad5d0410f2014-07-30 10:07:40 -0700755 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800756 * Obtains the presentation requirements for this {@code RemoteConnection}'s
757 * caller's display name.
758 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700759 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800760 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700761 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700762 public int getCallerDisplayNamePresentation() {
763 return mCallerDisplayNamePresentation;
764 }
765
Ihab Awad5d0410f2014-07-30 10:07:40 -0700766 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800767 * Obtains the video state of this {@code RemoteConnection}.
768 *
769 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile.VideoState}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700770 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700771 public int getVideoState() {
772 return mVideoState;
773 }
774
Ihab Awad5d0410f2014-07-30 10:07:40 -0700775 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700776 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700777 * @return The video provider associated with this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700778 */
779 public final VideoProvider getVideoProvider() {
780 return mVideoProvider;
781 }
782
783 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700784 * Obtain the extras associated with this {@code RemoteConnection}.
785 *
786 * @return The extras for this connection.
787 */
788 public final Bundle getExtras() {
789 return mExtras;
790 }
791
792 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800793 * Determines whether this {@code RemoteConnection} is requesting ringback.
794 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700795 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800796 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700797 */
Andrew Lee100e2932014-09-08 15:34:24 -0700798 public boolean isRingbackRequested() {
Santos Cordon15d63c72015-06-02 15:08:26 -0700799 return mRingbackRequested;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700800 }
801
802 /**
803 * Instructs this {@code RemoteConnection} to abort.
804 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700805 public void abort() {
806 try {
807 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700808 mConnectionService.abort(mConnectionId);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700809 }
810 } catch (RemoteException ignored) {
811 }
812 }
813
Ihab Awad5d0410f2014-07-30 10:07:40 -0700814 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700815 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700816 */
817 public void answer() {
818 try {
819 if (mConnected) {
820 mConnectionService.answer(mConnectionId);
821 }
822 } catch (RemoteException ignored) {
823 }
824 }
825
826 /**
827 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700828 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700829 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700830 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700831 public void answer(int videoState) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700832 try {
833 if (mConnected) {
Tyler Gunnbe74de02014-08-29 14:51:48 -0700834 mConnectionService.answerVideo(mConnectionId, videoState);
Santos Cordon52d8a152014-06-17 19:08:45 -0700835 }
836 } catch (RemoteException ignored) {
837 }
838 }
839
Ihab Awad5d0410f2014-07-30 10:07:40 -0700840 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700841 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700842 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700843 public void reject() {
844 try {
845 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700846 mConnectionService.reject(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700847 }
848 } catch (RemoteException ignored) {
849 }
850 }
851
Ihab Awad5d0410f2014-07-30 10:07:40 -0700852 /**
853 * Instructs this {@code RemoteConnection} to go on hold.
854 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700855 public void hold() {
856 try {
857 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700858 mConnectionService.hold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700859 }
860 } catch (RemoteException ignored) {
861 }
862 }
863
Ihab Awad5d0410f2014-07-30 10:07:40 -0700864 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700865 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700866 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700867 public void unhold() {
868 try {
869 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700870 mConnectionService.unhold(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700871 }
872 } catch (RemoteException ignored) {
873 }
874 }
875
Ihab Awad5d0410f2014-07-30 10:07:40 -0700876 /**
877 * Instructs this {@code RemoteConnection} to disconnect.
878 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700879 public void disconnect() {
880 try {
881 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700882 mConnectionService.disconnect(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 play a dual-tone multi-frequency signaling
890 * (DTMF) tone.
891 *
892 * Any other currently playing DTMF tone in the specified call is immediately stopped.
893 *
894 * @param digit A character representing the DTMF digit for which to play the tone. This
895 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
896 */
897 public void playDtmfTone(char digit) {
Santos Cordon52d8a152014-06-17 19:08:45 -0700898 try {
899 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700900 mConnectionService.playDtmfTone(mConnectionId, digit);
Santos Cordon52d8a152014-06-17 19:08:45 -0700901 }
902 } catch (RemoteException ignored) {
903 }
904 }
905
Ihab Awad5d0410f2014-07-30 10:07:40 -0700906 /**
907 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
908 * (DTMF) tone currently playing.
909 *
910 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
911 * currently playing, this method will do nothing.
912 */
913 public void stopDtmfTone() {
Santos Cordon52d8a152014-06-17 19:08:45 -0700914 try {
915 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700916 mConnectionService.stopDtmfTone(mConnectionId);
Santos Cordon52d8a152014-06-17 19:08:45 -0700917 }
918 } catch (RemoteException ignored) {
919 }
920 }
921
Ihab Awad5d0410f2014-07-30 10:07:40 -0700922 /**
923 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
924 *
925 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700926 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700927 * These digits are immediately sent as DTMF tones to the recipient as soon as the
928 * connection is made.
929 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700930 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -0700931 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
932 * of time.
933 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700934 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800935 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -0700936 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -0700937 * should display to the user an indication of this state and an affordance to continue
938 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
939 * app should invoke the {@link #postDialContinue(boolean)} method.
940 *
941 * @param proceed Whether or not to continue with the post-dial sequence.
942 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700943 public void postDialContinue(boolean proceed) {
944 try {
945 if (mConnected) {
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700946 mConnectionService.onPostDialContinue(mConnectionId, proceed);
Santos Cordon52d8a152014-06-17 19:08:45 -0700947 }
948 } catch (RemoteException ignored) {
949 }
950 }
951
Ihab Awad5d0410f2014-07-30 10:07:40 -0700952 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700953 * Set the audio state of this {@code RemoteConnection}.
954 *
955 * @param state The audio state of this {@code RemoteConnection}.
Yorke Lee4af59352015-05-13 14:14:54 -0700956 * @hide
957 * @deprecated Use {@link #setCallAudioState(CallAudioState) instead.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700958 */
Yorke Lee4af59352015-05-13 14:14:54 -0700959 @SystemApi
960 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700961 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -0700962 setCallAudioState(new CallAudioState(state));
963 }
964
965 /**
966 * Set the audio state of this {@code RemoteConnection}.
967 *
968 * @param state The audio state of this {@code RemoteConnection}.
969 */
970 public void setCallAudioState(CallAudioState state) {
Sailesh Nepal091768c2014-06-30 15:15:23 -0700971 try {
972 if (mConnected) {
Yorke Lee4af59352015-05-13 14:14:54 -0700973 mConnectionService.onCallAudioStateChanged(mConnectionId, state);
Sailesh Nepal091768c2014-06-30 15:15:23 -0700974 }
975 } catch (RemoteException ignored) {
976 }
977 }
978
Santos Cordon52d8a152014-06-17 19:08:45 -0700979 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700980 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
981 * successfully asked to create a conference with.
982 *
983 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
984 * merged into a {@link RemoteConference}.
985 */
986 public List<RemoteConnection> getConferenceableConnections() {
987 return mUnmodifiableconferenceableConnections;
988 }
989
990 /**
991 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
992 * of, or {@code null} if there is no such {@code RemoteConference}.
993 *
994 * @return A {@code RemoteConference} or {@code null};
995 */
996 public RemoteConference getConference() {
997 return mConference;
998 }
999
1000 /** {@hide} */
1001 String getId() {
1002 return mConnectionId;
1003 }
1004
1005 /** {@hide} */
1006 IConnectionService getConnectionService() {
1007 return mConnectionService;
1008 }
1009
1010 /**
Santos Cordon52d8a152014-06-17 19:08:45 -07001011 * @hide
1012 */
Andrew Lee011728f2015-04-23 15:47:06 -07001013 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -07001014 if (mState != state) {
1015 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -07001016 for (CallbackRecord record: mCallbackRecords) {
1017 final RemoteConnection connection = this;
1018 final Callback callback = record.getCallback();
1019 record.getHandler().post(new Runnable() {
1020 @Override
1021 public void run() {
1022 callback.onStateChanged(connection, state);
1023 }
1024 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001025 }
1026 }
1027 }
1028
1029 /**
1030 * @hide
1031 */
Andrew Lee011728f2015-04-23 15:47:06 -07001032 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001033 if (mState != Connection.STATE_DISCONNECTED) {
1034 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001035 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -07001036
Andrew Lee011728f2015-04-23 15:47:06 -07001037 for (CallbackRecord record : mCallbackRecords) {
1038 final RemoteConnection connection = this;
1039 final Callback callback = record.getCallback();
1040 record.getHandler().post(new Runnable() {
1041 @Override
1042 public void run() {
1043 callback.onDisconnected(connection, disconnectCause);
1044 }
1045 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001046 }
1047 }
1048 }
1049
1050 /**
1051 * @hide
1052 */
Andrew Lee011728f2015-04-23 15:47:06 -07001053 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -07001054 if (mRingbackRequested != ringback) {
1055 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -07001056 for (CallbackRecord record : mCallbackRecords) {
1057 final RemoteConnection connection = this;
1058 final Callback callback = record.getCallback();
1059 record.getHandler().post(new Runnable() {
1060 @Override
1061 public void run() {
1062 callback.onRingbackRequested(connection, ringback);
1063 }
1064 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001065 }
1066 }
1067 }
1068
1069 /**
1070 * @hide
1071 */
Andrew Lee011728f2015-04-23 15:47:06 -07001072 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001073 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -07001074 for (CallbackRecord record : mCallbackRecords) {
1075 final RemoteConnection connection = this;
1076 final Callback callback = record.getCallback();
1077 record.getHandler().post(new Runnable() {
1078 @Override
1079 public void run() {
1080 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
1081 }
1082 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001083 }
1084 }
1085
1086 /**
1087 * @hide
1088 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001089 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -07001090 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -07001091 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001092 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001093 setDisconnected(
1094 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -07001095 }
1096
Andrew Lee011728f2015-04-23 15:47:06 -07001097 for (CallbackRecord record : mCallbackRecords) {
1098 final RemoteConnection connection = this;
1099 final Callback callback = record.getCallback();
1100 record.getHandler().post(new Runnable() {
1101 @Override
1102 public void run() {
1103 callback.onDestroyed(connection);
1104 }
1105 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001106 }
Andrew Lee011728f2015-04-23 15:47:06 -07001107 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -07001108
1109 mConnected = false;
1110 }
1111 }
1112
1113 /**
1114 * @hide
1115 */
Andrew Lee011728f2015-04-23 15:47:06 -07001116 void setPostDialWait(final String remainingDigits) {
1117 for (CallbackRecord record : mCallbackRecords) {
1118 final RemoteConnection connection = this;
1119 final Callback callback = record.getCallback();
1120 record.getHandler().post(new Runnable() {
1121 @Override
1122 public void run() {
1123 callback.onPostDialWait(connection, remainingDigits);
1124 }
1125 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001126 }
1127 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001128
Tyler Gunnaa07df82014-07-17 07:50:22 -07001129 /**
1130 * @hide
1131 */
Andrew Lee011728f2015-04-23 15:47:06 -07001132 void onPostDialChar(final char nextChar) {
1133 for (CallbackRecord record : mCallbackRecords) {
1134 final RemoteConnection connection = this;
1135 final Callback callback = record.getCallback();
1136 record.getHandler().post(new Runnable() {
1137 @Override
1138 public void run() {
Sailesh Nepal40451b32015-05-14 17:39:41 -07001139 callback.onPostDialChar(connection, nextChar);
Andrew Lee011728f2015-04-23 15:47:06 -07001140 }
1141 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001142 }
1143 }
1144
1145 /**
1146 * @hide
1147 */
Andrew Lee011728f2015-04-23 15:47:06 -07001148 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -07001149 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -07001150 for (CallbackRecord record : mCallbackRecords) {
1151 final RemoteConnection connection = this;
1152 final Callback callback = record.getCallback();
1153 record.getHandler().post(new Runnable() {
1154 @Override
1155 public void run() {
1156 callback.onVideoStateChanged(connection, videoState);
1157 }
1158 });
Tyler Gunnaa07df82014-07-17 07:50:22 -07001159 }
1160 }
1161
Ihab Awada64627c2014-08-20 09:36:40 -07001162 /**
1163 * @hide
1164 */
Andrew Lee011728f2015-04-23 15:47:06 -07001165 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -07001166 mVideoProvider = videoProvider;
Andrew Lee011728f2015-04-23 15:47:06 -07001167 for (CallbackRecord record : mCallbackRecords) {
1168 final RemoteConnection connection = this;
1169 final Callback callback = record.getCallback();
1170 record.getHandler().post(new Runnable() {
1171 @Override
1172 public void run() {
1173 callback.onVideoProviderChanged(connection, videoProvider);
1174 }
1175 });
Ihab Awada64627c2014-08-20 09:36:40 -07001176 }
1177 }
1178
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001179 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001180 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -07001181 mIsVoipAudioMode = isVoip;
Andrew Lee011728f2015-04-23 15:47:06 -07001182 for (CallbackRecord record : mCallbackRecords) {
1183 final RemoteConnection connection = this;
1184 final Callback callback = record.getCallback();
1185 record.getHandler().post(new Runnable() {
1186 @Override
1187 public void run() {
1188 callback.onVoipAudioChanged(connection, isVoip);
1189 }
1190 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001191 }
1192 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001193
1194 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001195 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001196 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001197 for (CallbackRecord record : mCallbackRecords) {
1198 final RemoteConnection connection = this;
1199 final Callback callback = record.getCallback();
1200 record.getHandler().post(new Runnable() {
1201 @Override
1202 public void run() {
1203 callback.onStatusHintsChanged(connection, statusHints);
1204 }
1205 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001206 }
1207 }
1208
1209 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001210 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001211 mAddress = address;
1212 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001213 for (CallbackRecord record : mCallbackRecords) {
1214 final RemoteConnection connection = this;
1215 final Callback callback = record.getCallback();
1216 record.getHandler().post(new Runnable() {
1217 @Override
1218 public void run() {
1219 callback.onAddressChanged(connection, address, presentation);
1220 }
1221 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001222 }
1223 }
1224
1225 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001226 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001227 mCallerDisplayName = callerDisplayName;
1228 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001229 for (CallbackRecord record : mCallbackRecords) {
1230 final RemoteConnection connection = this;
1231 final Callback callback = record.getCallback();
1232 record.getHandler().post(new Runnable() {
1233 @Override
1234 public void run() {
1235 callback.onCallerDisplayNameChanged(
1236 connection, callerDisplayName, presentation);
1237 }
1238 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001239 }
1240 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001241
1242 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001243 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001244 mConferenceableConnections.clear();
1245 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001246 for (CallbackRecord record : mCallbackRecords) {
1247 final RemoteConnection connection = this;
1248 final Callback callback = record.getCallback();
1249 record.getHandler().post(new Runnable() {
1250 @Override
1251 public void run() {
1252 callback.onConferenceableConnectionsChanged(
1253 connection, mUnmodifiableconferenceableConnections);
1254 }
1255 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001256 }
1257 }
1258
1259 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001260 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001261 if (mConference != conference) {
1262 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001263 for (CallbackRecord record : mCallbackRecords) {
1264 final RemoteConnection connection = this;
1265 final Callback callback = record.getCallback();
1266 record.getHandler().post(new Runnable() {
1267 @Override
1268 public void run() {
1269 callback.onConferenceChanged(connection, conference);
1270 }
1271 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001272 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001273 }
1274 }
1275
Santos Cordon6b7f9552015-05-27 17:21:45 -07001276 /** @hide */
1277 void setExtras(final Bundle extras) {
1278 mExtras = extras;
1279 for (CallbackRecord record : mCallbackRecords) {
1280 final RemoteConnection connection = this;
1281 final Callback callback = record.getCallback();
1282 record.getHandler().post(new Runnable() {
1283 @Override
1284 public void run() {
1285 callback.onExtrasChanged(connection, extras);
1286 }
1287 });
1288 }
1289 }
1290
Evan Charltonbf11f982014-07-20 22:06:28 -07001291 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001292 * Create a RemoteConnection represents a failure, and which will be in
1293 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1294 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001295 *
1296 * @return a failed {@link RemoteConnection}
1297 *
1298 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001299 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001300 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1301 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001302 }
Andrew Lee011728f2015-04-23 15:47:06 -07001303
1304 private static final class CallbackRecord extends Callback {
1305 private final Callback mCallback;
1306 private final Handler mHandler;
1307
1308 public CallbackRecord(Callback callback, Handler handler) {
1309 mCallback = callback;
1310 mHandler = handler;
1311 }
1312
1313 public Callback getCallback() {
1314 return mCallback;
1315 }
1316
1317 public Handler getHandler() {
1318 return mHandler;
1319 }
1320 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001321}