blob: 8b2b51e29c9138c67ab98f5d00e6a5f6eabd3d3c [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
Hall Liu49cabcc2021-01-15 11:41:48 -080019import android.Manifest;
Hall Liu57006aa2017-02-06 10:49:48 -080020import android.annotation.NonNull;
Santos Cordon6b7f9552015-05-27 17:21:45 -070021import android.annotation.Nullable;
Hall Liu49cabcc2021-01-15 11:41:48 -080022import android.annotation.RequiresPermission;
Yorke Lee4af59352015-05-13 14:14:54 -070023import android.annotation.SystemApi;
Tyler Gunn295f5d72015-06-04 11:08:54 -070024import android.hardware.camera2.CameraManager;
Santos Cordon52d8a152014-06-17 19:08:45 -070025import android.net.Uri;
Tyler Gunn14343ee2017-08-11 09:24:41 -070026import android.os.BadParcelableException;
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;
Tyler Gunnffbcd892020-05-04 15:01:59 -070031import android.telecom.Logging.Session;
Ihab Awada64627c2014-08-20 09:36:40 -070032import android.view.Surface;
Santos Cordon52d8a152014-06-17 19:08:45 -070033
Grace Jia9a09c672020-08-04 12:52:09 -070034import com.android.internal.telecom.IConnectionService;
35import com.android.internal.telecom.IVideoCallback;
36import com.android.internal.telecom.IVideoProvider;
37
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070038import java.util.ArrayList;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070039import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070040import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070041import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070042import java.util.concurrent.ConcurrentHashMap;
Santos Cordon52d8a152014-06-17 19:08:45 -070043
44/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070045 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
46 * running in a different process.
47 *
48 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
49 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070050 */
51public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070052
Santos Cordon895d4b82015-06-25 16:41:48 -070053 /**
54 * Callback base class for {@link RemoteConnection}.
55 */
Andrew Lee100e2932014-09-08 15:34:24 -070056 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070057 /**
58 * Invoked when the state of this {@code RemoteConnection} has changed. See
59 * {@link #getState()}.
60 *
61 * @param connection The {@code RemoteConnection} invoking this method.
62 * @param state The new state of the {@code RemoteConnection}.
63 */
Evan Charltonbf11f982014-07-20 22:06:28 -070064 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070065
66 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070067 * Invoked when this {@code RemoteConnection} is disconnected.
68 *
69 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070070 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
71 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070072 */
73 public void onDisconnected(
74 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070075 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070076
77 /**
78 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070079 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070080 *
81 * @param connection The {@code RemoteConnection} invoking this method.
82 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
83 */
Andrew Lee100e2932014-09-08 15:34:24 -070084 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070085
86 /**
87 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080088 * See {@link #getConnectionCapabilities()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070089 *
90 * @param connection The {@code RemoteConnection} invoking this method.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080091 * @param connectionCapabilities The new capabilities of the {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070092 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080093 public void onConnectionCapabilitiesChanged(
94 RemoteConnection connection,
95 int connectionCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070096
97 /**
Tyler Gunn720c6642016-03-22 09:02:47 -070098 * Indicates that the call properties of this {@code RemoteConnection} have changed.
99 * See {@link #getConnectionProperties()}.
100 *
101 * @param connection The {@code RemoteConnection} invoking this method.
102 * @param connectionProperties The new properties of the {@code RemoteConnection}.
103 */
104 public void onConnectionPropertiesChanged(
105 RemoteConnection connection,
106 int connectionProperties) {}
107
108 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700109 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
110 * pause character. This causes the post-dial signals to stop pending user confirmation. An
111 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700112 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700113 *
114 * @param connection The {@code RemoteConnection} invoking this method.
115 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
116 */
117 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
118
119 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800120 * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
121 * a character.
122 *
123 * @param connection The {@code RemoteConnection} invoking this method.
124 * @param nextChar The character being processed.
125 */
126 public void onPostDialChar(RemoteConnection connection, char nextChar) {}
127
128 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700129 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -0700130 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700131 *
132 * @param connection The {@code RemoteConnection} invoking this method.
133 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
134 */
Andrew Lee100e2932014-09-08 15:34:24 -0700135 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700136
137 /**
138 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
139 * {@link #getStatusHints()} ()}.
140 *
141 * @param connection The {@code RemoteConnection} invoking this method.
142 * @param statusHints The new status hints of the {@code RemoteConnection}.
143 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700144 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700145
146 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700147 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
148 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700149 *
150 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700151 * @param address The new address of the {@code RemoteConnection}.
152 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700153 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700154 */
Andrew Lee100e2932014-09-08 15:34:24 -0700155 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700156
157 /**
158 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
159 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
160 *
161 * @param connection The {@code RemoteConnection} invoking this method.
162 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700163 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700164 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700165 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700166 public void onCallerDisplayNameChanged(
167 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700168
169 /**
170 * Indicates that the video state of this {@code RemoteConnection} has changed.
171 * See {@link #getVideoState()}.
172 *
173 * @param connection The {@code RemoteConnection} invoking this method.
174 * @param videoState The new video state of the {@code RemoteConnection}.
175 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700176 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700177
178 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700179 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
180 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
181 *
182 * @param connection The {@code RemoteConnection} invoking this method.
183 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700184 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700185
186 /**
187 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
188 * may be asked to create a conference has changed.
189 *
190 * @param connection The {@code RemoteConnection} invoking this method.
191 * @param conferenceableConnections The {@code RemoteConnection}s with which this
192 * {@code RemoteConnection} may be asked to create a conference.
193 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700194 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700195 RemoteConnection connection,
196 List<RemoteConnection> conferenceableConnections) {}
197
198 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700199 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
200 * has changed.
201 *
202 * @param connection The {@code RemoteConnection} invoking this method.
203 * @param videoProvider The new {@code VideoProvider} associated with this
204 * {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700205 */
206 public void onVideoProviderChanged(
207 RemoteConnection connection, VideoProvider videoProvider) {}
208
209 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700210 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
211 * of has changed.
212 *
213 * @param connection The {@code RemoteConnection} invoking this method.
214 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
215 * a part, which may be {@code null}.
216 */
217 public void onConferenceChanged(
218 RemoteConnection connection,
219 RemoteConference conference) {}
Santos Cordon6b7f9552015-05-27 17:21:45 -0700220
221 /**
Santos Cordon895d4b82015-06-25 16:41:48 -0700222 * Handles changes to the {@code RemoteConnection} extras.
Santos Cordon6b7f9552015-05-27 17:21:45 -0700223 *
224 * @param connection The {@code RemoteConnection} invoking this method.
225 * @param extras The extras containing other information associated with the connection.
226 */
227 public void onExtrasChanged(RemoteConnection connection, @Nullable Bundle extras) {}
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800228
229 /**
230 * Handles a connection event propagated to this {@link RemoteConnection}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700231 * <p>
232 * Connection events originate from {@link Connection#sendConnectionEvent(String, Bundle)}.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800233 *
234 * @param connection The {@code RemoteConnection} invoking this method.
235 * @param event The connection event.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700236 * @param extras Extras associated with the event.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800237 */
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700238 public void onConnectionEvent(RemoteConnection connection, String event, Bundle extras) {}
Hall Liu57006aa2017-02-06 10:49:48 -0800239
240 /**
241 * Indicates that a RTT session was successfully established on this
242 * {@link RemoteConnection}. See {@link Connection#sendRttInitiationSuccess()}.
243 * @hide
244 * @param connection The {@code RemoteConnection} invoking this method.
245 */
246 public void onRttInitiationSuccess(RemoteConnection connection) {}
247
248 /**
249 * Indicates that a RTT session failed to be established on this
250 * {@link RemoteConnection}. See {@link Connection#sendRttInitiationFailure()}.
251 * @hide
252 * @param connection The {@code RemoteConnection} invoking this method.
253 * @param reason One of the reason codes defined in {@link Connection.RttModifyStatus},
254 * with the exception of
255 * {@link Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
256 */
257 public void onRttInitiationFailure(RemoteConnection connection, int reason) {}
258
259 /**
260 * Indicates that an established RTT session was terminated remotely on this
261 * {@link RemoteConnection}. See {@link Connection#sendRttSessionRemotelyTerminated()}
262 * @hide
263 * @param connection The {@code RemoteConnection} invoking this method.
264 */
265 public void onRttSessionRemotelyTerminated(RemoteConnection connection) {}
266
267 /**
268 * Indicates that the remote user on this {@link RemoteConnection} has requested an upgrade
269 * to an RTT session. See {@link Connection#sendRemoteRttRequest()}
270 * @hide
271 * @param connection The {@code RemoteConnection} invoking this method.
272 */
273 public void onRemoteRttRequest(RemoteConnection connection) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700274 }
275
Tyler Gunn295f5d72015-06-04 11:08:54 -0700276 /**
277 * {@link RemoteConnection.VideoProvider} associated with a {@link RemoteConnection}. Used to
278 * receive video related events and control the video associated with a
279 * {@link RemoteConnection}.
280 *
281 * @see Connection.VideoProvider
282 */
Ihab Awada64627c2014-08-20 09:36:40 -0700283 public static class VideoProvider {
284
Tyler Gunn295f5d72015-06-04 11:08:54 -0700285 /**
286 * Callback class used by the {@link RemoteConnection.VideoProvider} to relay events from
287 * the {@link Connection.VideoProvider}.
288 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700289 public abstract static class Callback {
Tyler Gunn295f5d72015-06-04 11:08:54 -0700290 /**
291 * Reports a session modification request received from the
292 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
293 *
294 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
295 * @param videoProfile The requested video call profile.
296 * @see InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)
297 * @see Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)
298 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700299 public void onSessionModifyRequestReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700300 VideoProvider videoProvider,
301 VideoProfile videoProfile) {}
302
Tyler Gunn295f5d72015-06-04 11:08:54 -0700303 /**
304 * Reports a session modification response received from the
305 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
306 *
307 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
308 * @param status Status of the session modify request.
309 * @param requestedProfile The original request which was sent to the peer device.
310 * @param responseProfile The actual profile changes made by the peer device.
311 * @see InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
312 * VideoProfile, VideoProfile)
313 * @see Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile,
314 * VideoProfile)
315 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700316 public void onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700317 VideoProvider videoProvider,
318 int status,
319 VideoProfile requestedProfile,
320 VideoProfile responseProfile) {}
321
Tyler Gunn295f5d72015-06-04 11:08:54 -0700322 /**
323 * Reports a call session event received from the {@link Connection.VideoProvider}
324 * associated with a {@link RemoteConnection}.
325 *
326 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
327 * @param event The event.
328 * @see InCallService.VideoCall.Callback#onCallSessionEvent(int)
329 * @see Connection.VideoProvider#handleCallSessionEvent(int)
330 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700331 public void onCallSessionEvent(VideoProvider videoProvider, int event) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700332
Tyler Gunn295f5d72015-06-04 11:08:54 -0700333 /**
334 * Reports a change in the peer video dimensions received from the
335 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
336 *
337 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
338 * @param width The updated peer video width.
339 * @param height The updated peer video height.
340 * @see InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)
341 * @see Connection.VideoProvider#changePeerDimensions(int, int)
342 */
343 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width,
344 int height) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700345
Tyler Gunn295f5d72015-06-04 11:08:54 -0700346 /**
347 * Reports a change in the data usage (in bytes) received from the
348 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
349 *
350 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
351 * @param dataUsage The updated data usage (in bytes).
352 * @see InCallService.VideoCall.Callback#onCallDataUsageChanged(long)
353 * @see Connection.VideoProvider#setCallDataUsage(long)
354 */
Rekha Kumar07366812015-03-24 16:42:31 -0700355 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700356
Tyler Gunn295f5d72015-06-04 11:08:54 -0700357 /**
358 * Reports a change in the capabilities of the current camera, received from the
359 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
360 *
361 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
362 * @param cameraCapabilities The changed camera capabilities.
363 * @see InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
364 * VideoProfile.CameraCapabilities)
365 * @see Connection.VideoProvider#changeCameraCapabilities(
366 * VideoProfile.CameraCapabilities)
367 */
Ihab Awada64627c2014-08-20 09:36:40 -0700368 public void onCameraCapabilitiesChanged(
369 VideoProvider videoProvider,
Yorke Lee400470f2015-05-12 13:31:25 -0700370 VideoProfile.CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700371
Tyler Gunn295f5d72015-06-04 11:08:54 -0700372 /**
373 * Reports a change in the video quality received from the
374 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
375 *
376 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
377 * @param videoQuality The updated peer video quality.
378 * @see InCallService.VideoCall.Callback#onVideoQualityChanged(int)
379 * @see Connection.VideoProvider#changeVideoQuality(int)
380 */
Rekha Kumar07366812015-03-24 16:42:31 -0700381 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700382 }
383
384 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
385 @Override
386 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700387 for (Callback l : mCallbacks) {
388 l.onSessionModifyRequestReceived(VideoProvider.this, videoProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700389 }
390 }
391
392 @Override
393 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
394 VideoProfile responseProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700395 for (Callback l : mCallbacks) {
396 l.onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700397 VideoProvider.this,
398 status,
399 requestedProfile,
400 responseProfile);
401 }
402 }
403
404 @Override
405 public void handleCallSessionEvent(int event) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700406 for (Callback l : mCallbacks) {
407 l.onCallSessionEvent(VideoProvider.this, event);
Ihab Awada64627c2014-08-20 09:36:40 -0700408 }
409 }
410
411 @Override
412 public void changePeerDimensions(int width, int height) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700413 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700414 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
415 }
416 }
417
418 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700419 public void changeCallDataUsage(long dataUsage) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700420 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700421 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
422 }
423 }
424
425 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700426 public void changeCameraCapabilities(
427 VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700428 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700429 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
430 }
431 }
432
433 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700434 public void changeVideoQuality(int videoQuality) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700435 for (Callback l : mCallbacks) {
Rekha Kumar07366812015-03-24 16:42:31 -0700436 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
437 }
438 }
439
440 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700441 public IBinder asBinder() {
442 return null;
443 }
444 };
445
446 private final VideoCallbackServant mVideoCallbackServant =
447 new VideoCallbackServant(mVideoCallbackDelegate);
448
449 private final IVideoProvider mVideoProviderBinder;
450
Tyler Gunnb88b3112016-11-09 10:19:23 -0800451 private final String mCallingPackage;
452
Tyler Gunn159f35c2017-03-02 09:28:37 -0800453 private final int mTargetSdkVersion;
454
Ihab Awada64627c2014-08-20 09:36:40 -0700455 /**
456 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
457 * load factor before resizing, 1 means we only expect a single thread to
458 * access the map so make only a single shard
459 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700460 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
461 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awada64627c2014-08-20 09:36:40 -0700462
Tyler Gunn159f35c2017-03-02 09:28:37 -0800463 VideoProvider(IVideoProvider videoProviderBinder, String callingPackage,
464 int targetSdkVersion) {
465
Ihab Awada64627c2014-08-20 09:36:40 -0700466 mVideoProviderBinder = videoProviderBinder;
Tyler Gunnb88b3112016-11-09 10:19:23 -0800467 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800468 mTargetSdkVersion = targetSdkVersion;
Ihab Awada64627c2014-08-20 09:36:40 -0700469 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700470 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700471 } catch (RemoteException e) {
472 }
473 }
474
Tyler Gunn295f5d72015-06-04 11:08:54 -0700475 /**
476 * Registers a callback to receive commands and state changes for video calls.
477 *
478 * @param l The video call callback.
479 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700480 public void registerCallback(Callback l) {
481 mCallbacks.add(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700482 }
483
Tyler Gunn295f5d72015-06-04 11:08:54 -0700484 /**
485 * Clears the video call callback set via {@link #registerCallback}.
486 *
487 * @param l The video call callback to clear.
488 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700489 public void unregisterCallback(Callback l) {
490 mCallbacks.remove(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700491 }
492
Tyler Gunn295f5d72015-06-04 11:08:54 -0700493 /**
494 * Sets the camera to be used for the outgoing video for the
495 * {@link RemoteConnection.VideoProvider}.
496 *
497 * @param cameraId The id of the camera (use ids as reported by
498 * {@link CameraManager#getCameraIdList()}).
499 * @see Connection.VideoProvider#onSetCamera(String)
500 */
Ihab Awada64627c2014-08-20 09:36:40 -0700501 public void setCamera(String cameraId) {
502 try {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800503 mVideoProviderBinder.setCamera(cameraId, mCallingPackage, mTargetSdkVersion);
Ihab Awada64627c2014-08-20 09:36:40 -0700504 } catch (RemoteException e) {
505 }
506 }
507
Tyler Gunn295f5d72015-06-04 11:08:54 -0700508 /**
509 * Sets the surface to be used for displaying a preview of what the user's camera is
510 * currently capturing for the {@link RemoteConnection.VideoProvider}.
511 *
512 * @param surface The {@link Surface}.
513 * @see Connection.VideoProvider#onSetPreviewSurface(Surface)
514 */
Ihab Awada64627c2014-08-20 09:36:40 -0700515 public void setPreviewSurface(Surface surface) {
516 try {
517 mVideoProviderBinder.setPreviewSurface(surface);
518 } catch (RemoteException e) {
519 }
520 }
521
Tyler Gunn295f5d72015-06-04 11:08:54 -0700522 /**
523 * Sets the surface to be used for displaying the video received from the remote device for
524 * the {@link RemoteConnection.VideoProvider}.
525 *
526 * @param surface The {@link Surface}.
527 * @see Connection.VideoProvider#onSetDisplaySurface(Surface)
528 */
Ihab Awada64627c2014-08-20 09:36:40 -0700529 public void setDisplaySurface(Surface surface) {
530 try {
531 mVideoProviderBinder.setDisplaySurface(surface);
532 } catch (RemoteException e) {
533 }
534 }
535
Tyler Gunn295f5d72015-06-04 11:08:54 -0700536 /**
537 * Sets the device orientation, in degrees, for the {@link RemoteConnection.VideoProvider}.
538 * Assumes that a standard portrait orientation of the device is 0 degrees.
539 *
540 * @param rotation The device orientation, in degrees.
541 * @see Connection.VideoProvider#onSetDeviceOrientation(int)
542 */
Ihab Awada64627c2014-08-20 09:36:40 -0700543 public void setDeviceOrientation(int rotation) {
544 try {
545 mVideoProviderBinder.setDeviceOrientation(rotation);
546 } catch (RemoteException e) {
547 }
548 }
549
Tyler Gunn295f5d72015-06-04 11:08:54 -0700550 /**
551 * Sets camera zoom ratio for the {@link RemoteConnection.VideoProvider}.
552 *
553 * @param value The camera zoom ratio.
554 * @see Connection.VideoProvider#onSetZoom(float)
555 */
Ihab Awada64627c2014-08-20 09:36:40 -0700556 public void setZoom(float value) {
557 try {
558 mVideoProviderBinder.setZoom(value);
559 } catch (RemoteException e) {
560 }
561 }
562
Tyler Gunn295f5d72015-06-04 11:08:54 -0700563 /**
564 * Issues a request to modify the properties of the current video session for the
565 * {@link RemoteConnection.VideoProvider}.
566 *
567 * @param fromProfile The video profile prior to the request.
568 * @param toProfile The video profile with the requested changes made.
569 * @see Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)
570 */
Tyler Gunn45382162015-05-06 08:52:27 -0700571 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700572 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700573 mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700574 } catch (RemoteException e) {
575 }
576 }
577
Tyler Gunn295f5d72015-06-04 11:08:54 -0700578 /**
579 * Provides a response to a request to change the current call video session
580 * properties for the {@link RemoteConnection.VideoProvider}.
581 *
582 * @param responseProfile The response call video properties.
583 * @see Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)
584 */
Ihab Awada64627c2014-08-20 09:36:40 -0700585 public void sendSessionModifyResponse(VideoProfile responseProfile) {
586 try {
587 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
588 } catch (RemoteException e) {
589 }
590 }
591
Tyler Gunn295f5d72015-06-04 11:08:54 -0700592 /**
593 * Issues a request to retrieve the capabilities of the current camera for the
594 * {@link RemoteConnection.VideoProvider}.
595 *
596 * @see Connection.VideoProvider#onRequestCameraCapabilities()
597 */
Ihab Awada64627c2014-08-20 09:36:40 -0700598 public void requestCameraCapabilities() {
599 try {
600 mVideoProviderBinder.requestCameraCapabilities();
601 } catch (RemoteException e) {
602 }
603 }
604
Tyler Gunn295f5d72015-06-04 11:08:54 -0700605 /**
606 * Issues a request to retrieve the data usage (in bytes) of the video portion of the
607 * {@link RemoteConnection} for the {@link RemoteConnection.VideoProvider}.
608 *
609 * @see Connection.VideoProvider#onRequestConnectionDataUsage()
610 */
Ihab Awada64627c2014-08-20 09:36:40 -0700611 public void requestCallDataUsage() {
612 try {
613 mVideoProviderBinder.requestCallDataUsage();
614 } catch (RemoteException e) {
615 }
616 }
617
Tyler Gunn295f5d72015-06-04 11:08:54 -0700618 /**
619 * Sets the {@link Uri} of an image to be displayed to the peer device when the video signal
620 * is paused, for the {@link RemoteConnection.VideoProvider}.
621 *
622 * @see Connection.VideoProvider#onSetPauseImage(Uri)
623 */
Yorke Lee32f24732015-05-12 16:18:03 -0700624 public void setPauseImage(Uri uri) {
Ihab Awada64627c2014-08-20 09:36:40 -0700625 try {
626 mVideoProviderBinder.setPauseImage(uri);
627 } catch (RemoteException e) {
628 }
629 }
630 }
631
Evan Charltonbf11f982014-07-20 22:06:28 -0700632 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700633 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700634 /**
635 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
636 * load factor before resizing, 1 means we only expect a single thread to
637 * access the map so make only a single shard
638 */
Andrew Lee011728f2015-04-23 15:47:06 -0700639 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
640 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700641 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
642 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
643 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700644
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700645 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700646 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700647 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700648 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800649 private int mConnectionCapabilities;
Tyler Gunn720c6642016-03-22 09:02:47 -0700650 private int mConnectionProperties;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700651 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700652 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700653 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700654 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700655 private Uri mAddress;
656 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700657 private String mCallerDisplayName;
658 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700659 private RemoteConference mConference;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700660 private Bundle mExtras;
Tyler Gunnffbcd892020-05-04 15:01:59 -0700661 private String mCallingPackageAbbreviation;
Santos Cordon52d8a152014-06-17 19:08:45 -0700662
663 /**
664 * @hide
665 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700666 RemoteConnection(
667 String id,
668 IConnectionService connectionService,
669 ConnectionRequest request) {
670 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700671 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700672 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700673 mState = Connection.STATE_INITIALIZING;
Tyler Gunnffbcd892020-05-04 15:01:59 -0700674 if (request != null && request.getExtras() != null
675 && request.getExtras().containsKey(
676 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700677 String callingPackage = request.getExtras().getString(
Tyler Gunnffbcd892020-05-04 15:01:59 -0700678 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME);
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700679 mCallingPackageAbbreviation = Log.getPackageAbbreviation(callingPackage);
Tyler Gunnffbcd892020-05-04 15:01:59 -0700680 }
Evan Charltonbf11f982014-07-20 22:06:28 -0700681 }
682
683 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700684 * @hide
685 */
686 RemoteConnection(String callId, IConnectionService connectionService,
Tyler Gunn159f35c2017-03-02 09:28:37 -0800687 ParcelableConnection connection, String callingPackage, int targetSdkVersion) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700688 mConnectionId = callId;
689 mConnectionService = connectionService;
690 mConnected = true;
691 mState = connection.getState();
692 mDisconnectCause = connection.getDisconnectCause();
693 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800694 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn720c6642016-03-22 09:02:47 -0700695 mConnectionProperties = connection.getConnectionProperties();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700696 mVideoState = connection.getVideoState();
Tyler Gunn9c2c5832016-09-16 15:08:50 -0700697 IVideoProvider videoProvider = connection.getVideoProvider();
698 if (videoProvider != null) {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800699 mVideoProvider = new RemoteConnection.VideoProvider(videoProvider, callingPackage,
700 targetSdkVersion);
Tyler Gunn9c2c5832016-09-16 15:08:50 -0700701 } else {
702 mVideoProvider = null;
703 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700704 mIsVoipAudioMode = connection.getIsVoipAudioMode();
705 mStatusHints = connection.getStatusHints();
706 mAddress = connection.getHandle();
707 mAddressPresentation = connection.getHandlePresentation();
708 mCallerDisplayName = connection.getCallerDisplayName();
709 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
710 mConference = null;
Tyler Gunn2282bb92016-10-17 15:48:19 -0700711 putExtras(connection.getExtras());
712
713 // Stash the original connection ID as it exists in the source ConnectionService.
714 // Telecom will use this to avoid adding duplicates later.
715 // See comments on Connection.EXTRA_ORIGINAL_CONNECTION_ID for more information.
716 Bundle newExtras = new Bundle();
717 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
718 putExtras(newExtras);
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700719 mCallingPackageAbbreviation = Log.getPackageAbbreviation(callingPackage);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700720 }
721
722 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700723 * Create a RemoteConnection which is used for failed connections. Note that using it for any
724 * "real" purpose will almost certainly fail. Callers should note the failure and act
725 * accordingly (moving on to another RemoteConnection, for example)
726 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700727 * @param disconnectCause The reason for the failed connection.
728 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700729 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700730 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700731 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700732 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700733 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700734 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700735 }
736
Ihab Awad5d0410f2014-07-30 10:07:40 -0700737 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700738 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700739 *
Andrew Lee100e2932014-09-08 15:34:24 -0700740 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700741 */
Andrew Lee100e2932014-09-08 15:34:24 -0700742 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700743 registerCallback(callback, new Handler());
744 }
745
746 /**
747 * Adds a callback to this {@code RemoteConnection}.
748 *
749 * @param callback A {@code Callback}.
750 * @param handler A {@code Handler} which command and status changes will be delivered to.
751 */
752 public void registerCallback(Callback callback, Handler handler) {
753 unregisterCallback(callback);
754 if (callback != null && handler != null) {
755 mCallbackRecords.add(new CallbackRecord(callback, handler));
756 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700757 }
758
Ihab Awad5d0410f2014-07-30 10:07:40 -0700759 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700760 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700761 *
Andrew Lee100e2932014-09-08 15:34:24 -0700762 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700763 */
Andrew Lee100e2932014-09-08 15:34:24 -0700764 public void unregisterCallback(Callback callback) {
765 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700766 for (CallbackRecord record : mCallbackRecords) {
767 if (record.getCallback() == callback) {
768 mCallbackRecords.remove(record);
769 break;
770 }
771 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700772 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700773 }
774
Ihab Awad5d0410f2014-07-30 10:07:40 -0700775 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700776 * Obtains the state of this {@code RemoteConnection}.
777 *
778 * @return A state value, chosen from the {@code STATE_*} constants.
779 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700780 public int getState() {
781 return mState;
782 }
783
Ihab Awad5d0410f2014-07-30 10:07:40 -0700784 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800785 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
786 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700787 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800788 * disconnect cause expressed as a code chosen from among those declared in
789 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700790 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700791 public DisconnectCause getDisconnectCause() {
792 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700793 }
794
Ihab Awad5d0410f2014-07-30 10:07:40 -0700795 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800796 * Obtains the capabilities of this {@code RemoteConnection}.
797 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700798 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800799 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700800 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800801 public int getConnectionCapabilities() {
802 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700803 }
804
Ihab Awad5d0410f2014-07-30 10:07:40 -0700805 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700806 * Obtains the properties of this {@code RemoteConnection}.
807 *
808 * @return A bitmask of the properties of the {@code RemoteConnection}, as defined in the
809 * {@code PROPERTY_*} constants in class {@link Connection}.
810 */
811 public int getConnectionProperties() {
812 return mConnectionProperties;
813 }
814
815 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800816 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
817 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700818 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
819 */
Andrew Lee100e2932014-09-08 15:34:24 -0700820 public boolean isVoipAudioMode() {
821 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700822 }
823
Ihab Awad5d0410f2014-07-30 10:07:40 -0700824 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800825 * Obtains status hints pertaining to this {@code RemoteConnection}.
826 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700827 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800828 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700829 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700830 public StatusHints getStatusHints() {
831 return mStatusHints;
832 }
833
Ihab Awad5d0410f2014-07-30 10:07:40 -0700834 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800835 * Obtains the address of this {@code RemoteConnection}.
836 *
837 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
838 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700839 */
Andrew Lee100e2932014-09-08 15:34:24 -0700840 public Uri getAddress() {
841 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700842 }
843
Ihab Awad5d0410f2014-07-30 10:07:40 -0700844 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800845 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
846 *
847 * @return The presentation requirements for the address. See
848 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700849 */
Andrew Lee100e2932014-09-08 15:34:24 -0700850 public int getAddressPresentation() {
851 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700852 }
853
Ihab Awad5d0410f2014-07-30 10:07:40 -0700854 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800855 * Obtains the display name for this {@code RemoteConnection}'s caller.
856 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700857 * @return The display name for the caller.
858 */
Andrew Lee100e2932014-09-08 15:34:24 -0700859 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700860 return mCallerDisplayName;
861 }
862
Ihab Awad5d0410f2014-07-30 10:07:40 -0700863 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800864 * Obtains the presentation requirements for this {@code RemoteConnection}'s
865 * caller's display name.
866 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700867 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800868 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700869 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700870 public int getCallerDisplayNamePresentation() {
871 return mCallerDisplayNamePresentation;
872 }
873
Ihab Awad5d0410f2014-07-30 10:07:40 -0700874 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800875 * Obtains the video state of this {@code RemoteConnection}.
876 *
Tyler Gunn87b73f32015-06-03 10:09:59 -0700877 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700878 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700879 public int getVideoState() {
880 return mVideoState;
881 }
882
Ihab Awad5d0410f2014-07-30 10:07:40 -0700883 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700884 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700885 * @return The video provider associated with this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700886 */
887 public final VideoProvider getVideoProvider() {
888 return mVideoProvider;
889 }
890
891 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700892 * Obtain the extras associated with this {@code RemoteConnection}.
893 *
894 * @return The extras for this connection.
895 */
896 public final Bundle getExtras() {
897 return mExtras;
898 }
899
900 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800901 * Determines whether this {@code RemoteConnection} is requesting ringback.
902 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700903 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800904 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700905 */
Andrew Lee100e2932014-09-08 15:34:24 -0700906 public boolean isRingbackRequested() {
Santos Cordon15d63c72015-06-02 15:08:26 -0700907 return mRingbackRequested;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700908 }
909
910 /**
911 * Instructs this {@code RemoteConnection} to abort.
912 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700913 public void abort() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700914 Log.startSession("RC.a", getActiveOwnerInfo());
Sailesh Nepal091768c2014-06-30 15:15:23 -0700915 try {
916 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700917 mConnectionService.abort(mConnectionId, Log.getExternalSession(
918 mCallingPackageAbbreviation));
Sailesh Nepal091768c2014-06-30 15:15:23 -0700919 }
920 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700921 } finally {
922 Log.endSession();
Sailesh Nepal091768c2014-06-30 15:15:23 -0700923 }
924 }
925
Ihab Awad5d0410f2014-07-30 10:07:40 -0700926 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700927 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700928 */
929 public void answer() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700930 Log.startSession("RC.an", getActiveOwnerInfo());
Tyler Gunnbe74de02014-08-29 14:51:48 -0700931 try {
932 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700933 mConnectionService.answer(mConnectionId, Log.getExternalSession(
934 mCallingPackageAbbreviation));
Tyler Gunnbe74de02014-08-29 14:51:48 -0700935 }
936 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700937 } finally {
938 Log.endSession();
Tyler Gunnbe74de02014-08-29 14:51:48 -0700939 }
940 }
941
942 /**
943 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700944 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700945 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700946 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700947 public void answer(int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700948 Log.startSession("RC.an2", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700949 try {
950 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700951 mConnectionService.answerVideo(mConnectionId, videoState,
952 Log.getExternalSession(mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -0700953 }
954 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700955 } finally {
956 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -0700957 }
958 }
959
Ihab Awad5d0410f2014-07-30 10:07:40 -0700960 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700961 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700962 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700963 public void reject() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700964 Log.startSession("RC.r", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700965 try {
966 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700967 mConnectionService.reject(mConnectionId, Log.getExternalSession(
968 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -0700969 }
970 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700971 } finally {
972 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -0700973 }
974 }
975
Ihab Awad5d0410f2014-07-30 10:07:40 -0700976 /**
977 * Instructs this {@code RemoteConnection} to go on hold.
978 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700979 public void hold() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700980 Log.startSession("RC.h", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700981 try {
982 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700983 mConnectionService.hold(mConnectionId, Log.getExternalSession(
984 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -0700985 }
986 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700987 } finally {
988 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -0700989 }
990 }
991
Ihab Awad5d0410f2014-07-30 10:07:40 -0700992 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700993 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700994 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700995 public void unhold() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700996 Log.startSession("RC.u", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700997 try {
998 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700999 mConnectionService.unhold(mConnectionId, Log.getExternalSession(
1000 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -07001001 }
1002 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001003 } finally {
1004 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001005 }
1006 }
1007
Ihab Awad5d0410f2014-07-30 10:07:40 -07001008 /**
1009 * Instructs this {@code RemoteConnection} to disconnect.
1010 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001011 public void disconnect() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001012 Log.startSession("RC.d", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001013 try {
1014 if (mConnected) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001015 mConnectionService.disconnect(mConnectionId, Log.getExternalSession(
1016 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -07001017 }
1018 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001019 } finally {
1020 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001021 }
1022 }
1023
Ihab Awad5d0410f2014-07-30 10:07:40 -07001024 /**
1025 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
1026 * (DTMF) tone.
1027 *
1028 * Any other currently playing DTMF tone in the specified call is immediately stopped.
1029 *
1030 * @param digit A character representing the DTMF digit for which to play the tone. This
1031 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
1032 */
1033 public void playDtmfTone(char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001034 Log.startSession("RC.pDT", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001035 try {
1036 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001037 mConnectionService.playDtmfTone(mConnectionId, digit, null /*Session.Info*/);
Santos Cordon52d8a152014-06-17 19:08:45 -07001038 }
1039 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001040 } finally {
1041 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001042 }
1043 }
1044
Ihab Awad5d0410f2014-07-30 10:07:40 -07001045 /**
1046 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
1047 * (DTMF) tone currently playing.
1048 *
1049 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
1050 * currently playing, this method will do nothing.
1051 */
1052 public void stopDtmfTone() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001053 Log.startSession("RC.sDT", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001054 try {
1055 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001056 mConnectionService.stopDtmfTone(mConnectionId, null /*Session.Info*/);
Santos Cordon52d8a152014-06-17 19:08:45 -07001057 }
1058 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001059 } finally {
1060 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001061 }
1062 }
1063
Ihab Awad5d0410f2014-07-30 10:07:40 -07001064 /**
1065 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
1066 *
1067 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001068 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -07001069 * These digits are immediately sent as DTMF tones to the recipient as soon as the
1070 * connection is made.
1071 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001072 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -07001073 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
1074 * of time.
1075 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001076 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001077 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -07001078 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -07001079 * should display to the user an indication of this state and an affordance to continue
1080 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
1081 * app should invoke the {@link #postDialContinue(boolean)} method.
1082 *
1083 * @param proceed Whether or not to continue with the post-dial sequence.
1084 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001085 public void postDialContinue(boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001086 Log.startSession("RC.pDC", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001087 try {
1088 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001089 mConnectionService.onPostDialContinue(mConnectionId, proceed,
1090 null /*Session.Info*/);
Santos Cordon52d8a152014-06-17 19:08:45 -07001091 }
1092 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001093 // bliss
1094 } finally {
1095 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001096 }
1097 }
1098
Ihab Awad5d0410f2014-07-30 10:07:40 -07001099 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001100 * Instructs this {@link RemoteConnection} to pull itself to the local device.
1101 * <p>
1102 * See {@link Call#pullExternalCall()} for more information.
1103 */
1104 public void pullExternalCall() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001105 Log.startSession("RC.pEC", getActiveOwnerInfo());
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001106 try {
1107 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001108 mConnectionService.pullExternalCall(mConnectionId, null /*Session.Info*/);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001109 }
1110 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001111 } finally {
1112 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001113 }
1114 }
1115
1116 /**
Grace Jia9a09c672020-08-04 12:52:09 -07001117 * Instructs this {@link RemoteConnection} to initiate a conference with a list of
1118 * participants.
1119 * <p>
1120 *
1121 * @param participants with which conference call will be formed.
1122 */
1123 public void addConferenceParticipants(@NonNull List<Uri> participants) {
1124 try {
1125 if (mConnected) {
1126 mConnectionService.addConferenceParticipants(mConnectionId, participants,
1127 null /*Session.Info*/);
1128 }
1129 } catch (RemoteException ignored) {
1130 }
1131 }
1132
1133 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -07001134 * Set the audio state of this {@code RemoteConnection}.
1135 *
1136 * @param state The audio state of this {@code RemoteConnection}.
Yorke Lee4af59352015-05-13 14:14:54 -07001137 * @hide
Tyler Gunn94ffde72017-11-17 08:36:41 -08001138 * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead.
Ihab Awad5d0410f2014-07-30 10:07:40 -07001139 */
Yorke Lee4af59352015-05-13 14:14:54 -07001140 @SystemApi
1141 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001142 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -07001143 setCallAudioState(new CallAudioState(state));
1144 }
1145
1146 /**
1147 * Set the audio state of this {@code RemoteConnection}.
1148 *
1149 * @param state The audio state of this {@code RemoteConnection}.
1150 */
1151 public void setCallAudioState(CallAudioState state) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001152 Log.startSession("RC.sCAS", getActiveOwnerInfo());
Sailesh Nepal091768c2014-06-30 15:15:23 -07001153 try {
1154 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001155 mConnectionService.onCallAudioStateChanged(mConnectionId, state,
1156 null /*Session.Info*/);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001157 }
1158 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001159 } finally {
1160 Log.endSession();
Sailesh Nepal091768c2014-06-30 15:15:23 -07001161 }
1162 }
1163
Santos Cordon52d8a152014-06-17 19:08:45 -07001164 /**
Hall Liu57006aa2017-02-06 10:49:48 -08001165 * Notifies this {@link RemoteConnection} that the user has requested an RTT session.
1166 * @param rttTextStream The object that should be used to send text to or receive text from
1167 * the in-call app.
1168 * @hide
1169 */
1170 public void startRtt(@NonNull Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001171 Log.startSession("RC.sR", getActiveOwnerInfo());
Hall Liu57006aa2017-02-06 10:49:48 -08001172 try {
1173 if (mConnected) {
1174 mConnectionService.startRtt(mConnectionId, rttTextStream.getFdFromInCall(),
1175 rttTextStream.getFdToInCall(), null /*Session.Info*/);
1176 }
1177 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001178 } finally {
1179 Log.endSession();
Hall Liu57006aa2017-02-06 10:49:48 -08001180 }
1181 }
1182
1183 /**
1184 * Notifies this {@link RemoteConnection} that it should terminate any existing RTT
1185 * session. No response to Telecom is needed for this method.
1186 * @hide
1187 */
1188 public void stopRtt() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001189 Log.startSession("RC.stR", getActiveOwnerInfo());
Hall Liu57006aa2017-02-06 10:49:48 -08001190 try {
1191 if (mConnected) {
1192 mConnectionService.stopRtt(mConnectionId, null /*Session.Info*/);
1193 }
1194 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001195 } finally {
1196 Log.endSession();
Hall Liu57006aa2017-02-06 10:49:48 -08001197 }
1198 }
1199
1200 /**
Hall Liu49cabcc2021-01-15 11:41:48 -08001201 * Notifies this {@link RemoteConnection} that call filtering has completed, as well as
1202 * the results of a contacts lookup for the remote party.
Hall Liu73903142021-02-18 18:41:41 -08001203 *
1204 * @param completionInfo Info provided by Telecom on the results of call filtering.
Hall Liu49cabcc2021-01-15 11:41:48 -08001205 * @hide
1206 */
1207 @SystemApi
1208 @RequiresPermission(Manifest.permission.READ_CONTACTS)
Hall Liu73903142021-02-18 18:41:41 -08001209 public void onCallFilteringCompleted(
1210 @NonNull Connection.CallFilteringCompletionInfo completionInfo) {
Hall Liu49cabcc2021-01-15 11:41:48 -08001211 Log.startSession("RC.oCFC", getActiveOwnerInfo());
1212 try {
1213 if (mConnected) {
Hall Liu73903142021-02-18 18:41:41 -08001214 mConnectionService.onCallFilteringCompleted(mConnectionId, completionInfo,
Hall Liu49cabcc2021-01-15 11:41:48 -08001215 null /*Session.Info*/);
1216 }
1217 } catch (RemoteException ignored) {
1218 } finally {
1219 Log.endSession();
1220 }
1221 }
1222
1223 /**
Hall Liu57006aa2017-02-06 10:49:48 -08001224 * Notifies this {@link RemoteConnection} of a response to a previous remotely-initiated RTT
1225 * upgrade request sent via {@link Connection#sendRemoteRttRequest}.
1226 * Acceptance of the request is indicated by the supplied {@link RttTextStream} being non-null,
1227 * and rejection is indicated by {@code rttTextStream} being {@code null}
1228 * @hide
1229 * @param rttTextStream The object that should be used to send text to or receive text from
1230 * the in-call app.
1231 */
1232 public void sendRttUpgradeResponse(@Nullable Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001233 Log.startSession("RC.sRUR", getActiveOwnerInfo());
Hall Liu57006aa2017-02-06 10:49:48 -08001234 try {
1235 if (mConnected) {
1236 if (rttTextStream == null) {
1237 mConnectionService.respondToRttUpgradeRequest(mConnectionId,
1238 null, null, null /*Session.Info*/);
1239 } else {
1240 mConnectionService.respondToRttUpgradeRequest(mConnectionId,
1241 rttTextStream.getFdFromInCall(), rttTextStream.getFdToInCall(),
1242 null /*Session.Info*/);
1243 }
1244 }
1245 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001246 } finally {
1247 Log.endSession();
Hall Liu57006aa2017-02-06 10:49:48 -08001248 }
1249 }
1250
1251 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -07001252 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
1253 * successfully asked to create a conference with.
1254 *
1255 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
1256 * merged into a {@link RemoteConference}.
1257 */
1258 public List<RemoteConnection> getConferenceableConnections() {
1259 return mUnmodifiableconferenceableConnections;
1260 }
1261
1262 /**
1263 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
1264 * of, or {@code null} if there is no such {@code RemoteConference}.
1265 *
1266 * @return A {@code RemoteConference} or {@code null};
1267 */
1268 public RemoteConference getConference() {
1269 return mConference;
1270 }
1271
Tyler Gunnffbcd892020-05-04 15:01:59 -07001272 /**
1273 * Get the owner info for the currently active session. We want to make sure that any owner
1274 * info from the original call into the connection manager gets retained so that the full
1275 * context of the calls can be traced down to Telephony.
1276 * Example: Telecom will provide owner info in it's external session info that indicates
1277 * 'cast' as the calling owner.
1278 * @return The active owner
1279 */
1280 private String getActiveOwnerInfo() {
1281 Session.Info info = Log.getExternalSession();
1282 if (info == null) {
1283 return null;
1284 }
1285 return info.ownerInfo;
1286 }
1287
Ihab Awadb8e85c72014-08-23 20:34:57 -07001288 /** {@hide} */
1289 String getId() {
1290 return mConnectionId;
1291 }
1292
1293 /** {@hide} */
1294 IConnectionService getConnectionService() {
1295 return mConnectionService;
1296 }
1297
1298 /**
Santos Cordon52d8a152014-06-17 19:08:45 -07001299 * @hide
1300 */
Andrew Lee011728f2015-04-23 15:47:06 -07001301 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -07001302 if (mState != state) {
1303 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -07001304 for (CallbackRecord record: mCallbackRecords) {
1305 final RemoteConnection connection = this;
1306 final Callback callback = record.getCallback();
1307 record.getHandler().post(new Runnable() {
1308 @Override
1309 public void run() {
1310 callback.onStateChanged(connection, state);
1311 }
1312 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001313 }
1314 }
1315 }
1316
1317 /**
1318 * @hide
1319 */
Andrew Lee011728f2015-04-23 15:47:06 -07001320 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001321 if (mState != Connection.STATE_DISCONNECTED) {
1322 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001323 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -07001324
Andrew Lee011728f2015-04-23 15:47:06 -07001325 for (CallbackRecord record : mCallbackRecords) {
1326 final RemoteConnection connection = this;
1327 final Callback callback = record.getCallback();
1328 record.getHandler().post(new Runnable() {
1329 @Override
1330 public void run() {
1331 callback.onDisconnected(connection, disconnectCause);
1332 }
1333 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001334 }
1335 }
1336 }
1337
1338 /**
1339 * @hide
1340 */
Andrew Lee011728f2015-04-23 15:47:06 -07001341 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -07001342 if (mRingbackRequested != ringback) {
1343 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -07001344 for (CallbackRecord record : mCallbackRecords) {
1345 final RemoteConnection connection = this;
1346 final Callback callback = record.getCallback();
1347 record.getHandler().post(new Runnable() {
1348 @Override
1349 public void run() {
1350 callback.onRingbackRequested(connection, ringback);
1351 }
1352 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001353 }
1354 }
1355 }
1356
1357 /**
1358 * @hide
1359 */
Andrew Lee011728f2015-04-23 15:47:06 -07001360 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001361 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -07001362 for (CallbackRecord record : mCallbackRecords) {
1363 final RemoteConnection connection = this;
1364 final Callback callback = record.getCallback();
1365 record.getHandler().post(new Runnable() {
1366 @Override
1367 public void run() {
1368 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
1369 }
1370 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001371 }
1372 }
1373
1374 /**
1375 * @hide
1376 */
Tyler Gunn720c6642016-03-22 09:02:47 -07001377 void setConnectionProperties(final int connectionProperties) {
1378 mConnectionProperties = connectionProperties;
1379 for (CallbackRecord record : mCallbackRecords) {
1380 final RemoteConnection connection = this;
1381 final Callback callback = record.getCallback();
1382 record.getHandler().post(new Runnable() {
1383 @Override
1384 public void run() {
1385 callback.onConnectionPropertiesChanged(connection, connectionProperties);
1386 }
1387 });
1388 }
1389 }
1390
1391 /**
1392 * @hide
1393 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001394 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -07001395 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -07001396 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001397 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001398 setDisconnected(
1399 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -07001400 }
1401
Andrew Lee011728f2015-04-23 15:47:06 -07001402 for (CallbackRecord record : mCallbackRecords) {
1403 final RemoteConnection connection = this;
1404 final Callback callback = record.getCallback();
1405 record.getHandler().post(new Runnable() {
1406 @Override
1407 public void run() {
1408 callback.onDestroyed(connection);
1409 }
1410 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001411 }
Andrew Lee011728f2015-04-23 15:47:06 -07001412 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -07001413
1414 mConnected = false;
1415 }
1416 }
1417
1418 /**
1419 * @hide
1420 */
Andrew Lee011728f2015-04-23 15:47:06 -07001421 void setPostDialWait(final String remainingDigits) {
1422 for (CallbackRecord record : mCallbackRecords) {
1423 final RemoteConnection connection = this;
1424 final Callback callback = record.getCallback();
1425 record.getHandler().post(new Runnable() {
1426 @Override
1427 public void run() {
1428 callback.onPostDialWait(connection, remainingDigits);
1429 }
1430 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001431 }
1432 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001433
Tyler Gunnaa07df82014-07-17 07:50:22 -07001434 /**
1435 * @hide
1436 */
Andrew Lee011728f2015-04-23 15:47:06 -07001437 void onPostDialChar(final char nextChar) {
1438 for (CallbackRecord record : mCallbackRecords) {
1439 final RemoteConnection connection = this;
1440 final Callback callback = record.getCallback();
1441 record.getHandler().post(new Runnable() {
1442 @Override
1443 public void run() {
Sailesh Nepal40451b32015-05-14 17:39:41 -07001444 callback.onPostDialChar(connection, nextChar);
Andrew Lee011728f2015-04-23 15:47:06 -07001445 }
1446 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001447 }
1448 }
1449
1450 /**
1451 * @hide
1452 */
Andrew Lee011728f2015-04-23 15:47:06 -07001453 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -07001454 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -07001455 for (CallbackRecord record : mCallbackRecords) {
1456 final RemoteConnection connection = this;
1457 final Callback callback = record.getCallback();
1458 record.getHandler().post(new Runnable() {
1459 @Override
1460 public void run() {
1461 callback.onVideoStateChanged(connection, videoState);
1462 }
1463 });
Tyler Gunnaa07df82014-07-17 07:50:22 -07001464 }
1465 }
1466
Ihab Awada64627c2014-08-20 09:36:40 -07001467 /**
1468 * @hide
1469 */
Andrew Lee011728f2015-04-23 15:47:06 -07001470 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -07001471 mVideoProvider = videoProvider;
Andrew Lee011728f2015-04-23 15:47:06 -07001472 for (CallbackRecord record : mCallbackRecords) {
1473 final RemoteConnection connection = this;
1474 final Callback callback = record.getCallback();
1475 record.getHandler().post(new Runnable() {
1476 @Override
1477 public void run() {
1478 callback.onVideoProviderChanged(connection, videoProvider);
1479 }
1480 });
Ihab Awada64627c2014-08-20 09:36:40 -07001481 }
1482 }
1483
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001484 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001485 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -07001486 mIsVoipAudioMode = isVoip;
Andrew Lee011728f2015-04-23 15:47:06 -07001487 for (CallbackRecord record : mCallbackRecords) {
1488 final RemoteConnection connection = this;
1489 final Callback callback = record.getCallback();
1490 record.getHandler().post(new Runnable() {
1491 @Override
1492 public void run() {
1493 callback.onVoipAudioChanged(connection, isVoip);
1494 }
1495 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001496 }
1497 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001498
1499 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001500 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001501 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001502 for (CallbackRecord record : mCallbackRecords) {
1503 final RemoteConnection connection = this;
1504 final Callback callback = record.getCallback();
1505 record.getHandler().post(new Runnable() {
1506 @Override
1507 public void run() {
1508 callback.onStatusHintsChanged(connection, statusHints);
1509 }
1510 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001511 }
1512 }
1513
1514 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001515 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001516 mAddress = address;
1517 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001518 for (CallbackRecord record : mCallbackRecords) {
1519 final RemoteConnection connection = this;
1520 final Callback callback = record.getCallback();
1521 record.getHandler().post(new Runnable() {
1522 @Override
1523 public void run() {
1524 callback.onAddressChanged(connection, address, presentation);
1525 }
1526 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001527 }
1528 }
1529
1530 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001531 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001532 mCallerDisplayName = callerDisplayName;
1533 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001534 for (CallbackRecord record : mCallbackRecords) {
1535 final RemoteConnection connection = this;
1536 final Callback callback = record.getCallback();
1537 record.getHandler().post(new Runnable() {
1538 @Override
1539 public void run() {
1540 callback.onCallerDisplayNameChanged(
1541 connection, callerDisplayName, presentation);
1542 }
1543 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001544 }
1545 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001546
1547 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001548 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001549 mConferenceableConnections.clear();
1550 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001551 for (CallbackRecord record : mCallbackRecords) {
1552 final RemoteConnection connection = this;
1553 final Callback callback = record.getCallback();
1554 record.getHandler().post(new Runnable() {
1555 @Override
1556 public void run() {
1557 callback.onConferenceableConnectionsChanged(
1558 connection, mUnmodifiableconferenceableConnections);
1559 }
1560 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001561 }
1562 }
1563
1564 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001565 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001566 if (mConference != conference) {
1567 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001568 for (CallbackRecord record : mCallbackRecords) {
1569 final RemoteConnection connection = this;
1570 final Callback callback = record.getCallback();
1571 record.getHandler().post(new Runnable() {
1572 @Override
1573 public void run() {
1574 callback.onConferenceChanged(connection, conference);
1575 }
1576 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001577 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001578 }
1579 }
1580
Santos Cordon6b7f9552015-05-27 17:21:45 -07001581 /** @hide */
Tyler Gunndee56a82016-03-23 16:06:34 -07001582 void putExtras(final Bundle extras) {
Tyler Gunn2282bb92016-10-17 15:48:19 -07001583 if (extras == null) {
1584 return;
1585 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001586 if (mExtras == null) {
1587 mExtras = new Bundle();
1588 }
Tyler Gunn14343ee2017-08-11 09:24:41 -07001589 try {
1590 mExtras.putAll(extras);
1591 } catch (BadParcelableException bpe) {
1592 Log.w(this, "putExtras: could not unmarshal extras; exception = " + bpe);
1593 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001594
1595 notifyExtrasChanged();
1596 }
1597
1598 /** @hide */
1599 void removeExtras(List<String> keys) {
1600 if (mExtras == null || keys == null || keys.isEmpty()) {
1601 return;
1602 }
1603 for (String key : keys) {
1604 mExtras.remove(key);
1605 }
1606
1607 notifyExtrasChanged();
1608 }
1609
1610 private void notifyExtrasChanged() {
Santos Cordon6b7f9552015-05-27 17:21:45 -07001611 for (CallbackRecord record : mCallbackRecords) {
1612 final RemoteConnection connection = this;
1613 final Callback callback = record.getCallback();
1614 record.getHandler().post(new Runnable() {
1615 @Override
1616 public void run() {
Tyler Gunndee56a82016-03-23 16:06:34 -07001617 callback.onExtrasChanged(connection, mExtras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001618 }
1619 });
1620 }
1621 }
1622
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001623 /** @hide */
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001624 void onConnectionEvent(final String event, final Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001625 for (CallbackRecord record : mCallbackRecords) {
1626 final RemoteConnection connection = this;
1627 final Callback callback = record.getCallback();
1628 record.getHandler().post(new Runnable() {
1629 @Override
1630 public void run() {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001631 callback.onConnectionEvent(connection, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001632 }
1633 });
1634 }
1635 }
1636
Hall Liu57006aa2017-02-06 10:49:48 -08001637 /** @hide */
1638 void onRttInitiationSuccess() {
1639 for (CallbackRecord record : mCallbackRecords) {
1640 final RemoteConnection connection = this;
1641 final Callback callback = record.getCallback();
1642 record.getHandler().post(
1643 () -> callback.onRttInitiationSuccess(connection));
1644 }
1645 }
1646
1647 /** @hide */
1648 void onRttInitiationFailure(int reason) {
1649 for (CallbackRecord record : mCallbackRecords) {
1650 final RemoteConnection connection = this;
1651 final Callback callback = record.getCallback();
1652 record.getHandler().post(
1653 () -> callback.onRttInitiationFailure(connection, reason));
1654 }
1655 }
1656
1657 /** @hide */
1658 void onRttSessionRemotelyTerminated() {
1659 for (CallbackRecord record : mCallbackRecords) {
1660 final RemoteConnection connection = this;
1661 final Callback callback = record.getCallback();
1662 record.getHandler().post(
1663 () -> callback.onRttSessionRemotelyTerminated(connection));
1664 }
1665 }
1666
1667 /** @hide */
1668 void onRemoteRttRequest() {
1669 for (CallbackRecord record : mCallbackRecords) {
1670 final RemoteConnection connection = this;
1671 final Callback callback = record.getCallback();
1672 record.getHandler().post(
1673 () -> callback.onRemoteRttRequest(connection));
1674 }
1675 }
1676
1677 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07001678 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001679 * Create a RemoteConnection represents a failure, and which will be in
1680 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1681 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001682 *
1683 * @return a failed {@link RemoteConnection}
1684 *
1685 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001686 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001687 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1688 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001689 }
Andrew Lee011728f2015-04-23 15:47:06 -07001690
1691 private static final class CallbackRecord extends Callback {
1692 private final Callback mCallback;
1693 private final Handler mHandler;
1694
1695 public CallbackRecord(Callback callback, Handler handler) {
1696 mCallback = callback;
1697 mHandler = handler;
1698 }
1699
1700 public Callback getCallback() {
1701 return mCallback;
1702 }
1703
1704 public Handler getHandler() {
1705 return mHandler;
1706 }
1707 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001708}