blob: 7a6fddb6f0291b0ecb021d7db4079f3976132227 [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;
Tyler Gunnffbcd892020-05-04 15:01:59 -070039import java.util.Arrays;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070040import java.util.Collections;
Ihab Awad5d0410f2014-07-30 10:07:40 -070041import java.util.List;
Santos Cordon52d8a152014-06-17 19:08:45 -070042import java.util.Set;
Sailesh Nepalf4669df2014-08-14 17:43:13 -070043import java.util.concurrent.ConcurrentHashMap;
Tyler Gunnffbcd892020-05-04 15:01:59 -070044import java.util.stream.Collectors;
Santos Cordon52d8a152014-06-17 19:08:45 -070045
46/**
Ihab Awadb19a0bc2014-08-07 19:46:01 -070047 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
48 * running in a different process.
49 *
50 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
51 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Santos Cordon52d8a152014-06-17 19:08:45 -070052 */
53public final class RemoteConnection {
Ihab Awad5d0410f2014-07-30 10:07:40 -070054
Santos Cordon895d4b82015-06-25 16:41:48 -070055 /**
56 * Callback base class for {@link RemoteConnection}.
57 */
Andrew Lee100e2932014-09-08 15:34:24 -070058 public static abstract class Callback {
Ihab Awad5d0410f2014-07-30 10:07:40 -070059 /**
60 * Invoked when the state of this {@code RemoteConnection} has changed. See
61 * {@link #getState()}.
62 *
63 * @param connection The {@code RemoteConnection} invoking this method.
64 * @param state The new state of the {@code RemoteConnection}.
65 */
Evan Charltonbf11f982014-07-20 22:06:28 -070066 public void onStateChanged(RemoteConnection connection, int state) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070067
68 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -070069 * Invoked when this {@code RemoteConnection} is disconnected.
70 *
71 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070072 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
73 * connection.
Ihab Awad5d0410f2014-07-30 10:07:40 -070074 */
75 public void onDisconnected(
76 RemoteConnection connection,
Andrew Lee7f3d41f2014-09-11 17:33:16 -070077 DisconnectCause disconnectCause) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070078
79 /**
80 * Invoked when this {@code RemoteConnection} is requesting ringback. See
Andrew Lee100e2932014-09-08 15:34:24 -070081 * {@link #isRingbackRequested()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070082 *
83 * @param connection The {@code RemoteConnection} invoking this method.
84 * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
85 */
Andrew Lee100e2932014-09-08 15:34:24 -070086 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070087
88 /**
89 * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080090 * See {@link #getConnectionCapabilities()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070091 *
92 * @param connection The {@code RemoteConnection} invoking this method.
Ihab Awad5c9c86e2014-11-12 13:41:16 -080093 * @param connectionCapabilities The new capabilities of the {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -070094 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -080095 public void onConnectionCapabilitiesChanged(
96 RemoteConnection connection,
97 int connectionCapabilities) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -070098
99 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700100 * Indicates that the call properties of this {@code RemoteConnection} have changed.
101 * See {@link #getConnectionProperties()}.
102 *
103 * @param connection The {@code RemoteConnection} invoking this method.
104 * @param connectionProperties The new properties of the {@code RemoteConnection}.
105 */
106 public void onConnectionPropertiesChanged(
107 RemoteConnection connection,
108 int connectionProperties) {}
109
110 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700111 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
112 * pause character. This causes the post-dial signals to stop pending user confirmation. An
113 * implementation should present this choice to the user and invoke
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700114 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700115 *
116 * @param connection The {@code RemoteConnection} invoking this method.
117 * @param remainingPostDialSequence The post-dial characters that remain to be sent.
118 */
119 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
120
121 /**
Nancy Chen27d1c2d2014-12-15 16:12:50 -0800122 * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
123 * a character.
124 *
125 * @param connection The {@code RemoteConnection} invoking this method.
126 * @param nextChar The character being processed.
127 */
128 public void onPostDialChar(RemoteConnection connection, char nextChar) {}
129
130 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700131 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
Andrew Lee100e2932014-09-08 15:34:24 -0700132 * See {@link #isVoipAudioMode()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700133 *
134 * @param connection The {@code RemoteConnection} invoking this method.
135 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
136 */
Andrew Lee100e2932014-09-08 15:34:24 -0700137 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700138
139 /**
140 * Indicates that the status hints of this {@code RemoteConnection} have changed. See
141 * {@link #getStatusHints()} ()}.
142 *
143 * @param connection The {@code RemoteConnection} invoking this method.
144 * @param statusHints The new status hints of the {@code RemoteConnection}.
145 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700146 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700147
148 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700149 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
150 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700151 *
152 * @param connection The {@code RemoteConnection} invoking this method.
Andrew Lee100e2932014-09-08 15:34:24 -0700153 * @param address The new address of the {@code RemoteConnection}.
154 * @param presentation The presentation requirements for the address.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700155 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700156 */
Andrew Lee100e2932014-09-08 15:34:24 -0700157 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700158
159 /**
160 * Indicates that the caller display name of this {@code RemoteConnection} has changed.
161 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}.
162 *
163 * @param connection The {@code RemoteConnection} invoking this method.
164 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
Nancy Chen9d568c02014-09-08 14:17:59 -0700165 * @param presentation The presentation requirements for the handle.
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700166 * See {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700167 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700168 public void onCallerDisplayNameChanged(
169 RemoteConnection connection, String callerDisplayName, int presentation) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700170
171 /**
172 * Indicates that the video state of this {@code RemoteConnection} has changed.
173 * See {@link #getVideoState()}.
174 *
175 * @param connection The {@code RemoteConnection} invoking this method.
176 * @param videoState The new video state of the {@code RemoteConnection}.
177 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700178 public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
Ihab Awad5d0410f2014-07-30 10:07:40 -0700179
180 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700181 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
182 * should be made to the {@code RemoteConnection}, and references to it should be cleared.
183 *
184 * @param connection The {@code RemoteConnection} invoking this method.
185 */
Evan Charltonbf11f982014-07-20 22:06:28 -0700186 public void onDestroyed(RemoteConnection connection) {}
Ihab Awadb8e85c72014-08-23 20:34:57 -0700187
188 /**
189 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection}
190 * may be asked to create a conference has changed.
191 *
192 * @param connection The {@code RemoteConnection} invoking this method.
193 * @param conferenceableConnections The {@code RemoteConnection}s with which this
194 * {@code RemoteConnection} may be asked to create a conference.
195 */
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700196 public void onConferenceableConnectionsChanged(
Ihab Awadb8e85c72014-08-23 20:34:57 -0700197 RemoteConnection connection,
198 List<RemoteConnection> conferenceableConnections) {}
199
200 /**
Ihab Awada64627c2014-08-20 09:36:40 -0700201 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection}
202 * has changed.
203 *
204 * @param connection The {@code RemoteConnection} invoking this method.
205 * @param videoProvider The new {@code VideoProvider} associated with this
206 * {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700207 */
208 public void onVideoProviderChanged(
209 RemoteConnection connection, VideoProvider videoProvider) {}
210
211 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -0700212 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part
213 * of has changed.
214 *
215 * @param connection The {@code RemoteConnection} invoking this method.
216 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is
217 * a part, which may be {@code null}.
218 */
219 public void onConferenceChanged(
220 RemoteConnection connection,
221 RemoteConference conference) {}
Santos Cordon6b7f9552015-05-27 17:21:45 -0700222
223 /**
Santos Cordon895d4b82015-06-25 16:41:48 -0700224 * Handles changes to the {@code RemoteConnection} extras.
Santos Cordon6b7f9552015-05-27 17:21:45 -0700225 *
226 * @param connection The {@code RemoteConnection} invoking this method.
227 * @param extras The extras containing other information associated with the connection.
228 */
229 public void onExtrasChanged(RemoteConnection connection, @Nullable Bundle extras) {}
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800230
231 /**
232 * Handles a connection event propagated to this {@link RemoteConnection}.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700233 * <p>
234 * Connection events originate from {@link Connection#sendConnectionEvent(String, Bundle)}.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800235 *
236 * @param connection The {@code RemoteConnection} invoking this method.
237 * @param event The connection event.
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700238 * @param extras Extras associated with the event.
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -0800239 */
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700240 public void onConnectionEvent(RemoteConnection connection, String event, Bundle extras) {}
Hall Liu57006aa2017-02-06 10:49:48 -0800241
242 /**
243 * Indicates that a RTT session was successfully established on this
244 * {@link RemoteConnection}. See {@link Connection#sendRttInitiationSuccess()}.
245 * @hide
246 * @param connection The {@code RemoteConnection} invoking this method.
247 */
248 public void onRttInitiationSuccess(RemoteConnection connection) {}
249
250 /**
251 * Indicates that a RTT session failed to be established on this
252 * {@link RemoteConnection}. See {@link Connection#sendRttInitiationFailure()}.
253 * @hide
254 * @param connection The {@code RemoteConnection} invoking this method.
255 * @param reason One of the reason codes defined in {@link Connection.RttModifyStatus},
256 * with the exception of
257 * {@link Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
258 */
259 public void onRttInitiationFailure(RemoteConnection connection, int reason) {}
260
261 /**
262 * Indicates that an established RTT session was terminated remotely on this
263 * {@link RemoteConnection}. See {@link Connection#sendRttSessionRemotelyTerminated()}
264 * @hide
265 * @param connection The {@code RemoteConnection} invoking this method.
266 */
267 public void onRttSessionRemotelyTerminated(RemoteConnection connection) {}
268
269 /**
270 * Indicates that the remote user on this {@link RemoteConnection} has requested an upgrade
271 * to an RTT session. See {@link Connection#sendRemoteRttRequest()}
272 * @hide
273 * @param connection The {@code RemoteConnection} invoking this method.
274 */
275 public void onRemoteRttRequest(RemoteConnection connection) {}
Santos Cordon52d8a152014-06-17 19:08:45 -0700276 }
277
Tyler Gunn295f5d72015-06-04 11:08:54 -0700278 /**
279 * {@link RemoteConnection.VideoProvider} associated with a {@link RemoteConnection}. Used to
280 * receive video related events and control the video associated with a
281 * {@link RemoteConnection}.
282 *
283 * @see Connection.VideoProvider
284 */
Ihab Awada64627c2014-08-20 09:36:40 -0700285 public static class VideoProvider {
286
Tyler Gunn295f5d72015-06-04 11:08:54 -0700287 /**
288 * Callback class used by the {@link RemoteConnection.VideoProvider} to relay events from
289 * the {@link Connection.VideoProvider}.
290 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700291 public abstract static class Callback {
Tyler Gunn295f5d72015-06-04 11:08:54 -0700292 /**
293 * Reports a session modification request 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 videoProfile The requested video call profile.
298 * @see InCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)
299 * @see Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)
300 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700301 public void onSessionModifyRequestReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700302 VideoProvider videoProvider,
303 VideoProfile videoProfile) {}
304
Tyler Gunn295f5d72015-06-04 11:08:54 -0700305 /**
306 * Reports a session modification response received from the
307 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
308 *
309 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
310 * @param status Status of the session modify request.
311 * @param requestedProfile The original request which was sent to the peer device.
312 * @param responseProfile The actual profile changes made by the peer device.
313 * @see InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
314 * VideoProfile, VideoProfile)
315 * @see Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile,
316 * VideoProfile)
317 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700318 public void onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700319 VideoProvider videoProvider,
320 int status,
321 VideoProfile requestedProfile,
322 VideoProfile responseProfile) {}
323
Tyler Gunn295f5d72015-06-04 11:08:54 -0700324 /**
325 * Reports a call session event received from the {@link Connection.VideoProvider}
326 * associated with a {@link RemoteConnection}.
327 *
328 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
329 * @param event The event.
330 * @see InCallService.VideoCall.Callback#onCallSessionEvent(int)
331 * @see Connection.VideoProvider#handleCallSessionEvent(int)
332 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700333 public void onCallSessionEvent(VideoProvider videoProvider, int event) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700334
Tyler Gunn295f5d72015-06-04 11:08:54 -0700335 /**
336 * Reports a change in the peer video dimensions received from the
337 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
338 *
339 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
340 * @param width The updated peer video width.
341 * @param height The updated peer video height.
342 * @see InCallService.VideoCall.Callback#onPeerDimensionsChanged(int, int)
343 * @see Connection.VideoProvider#changePeerDimensions(int, int)
344 */
345 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width,
346 int height) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700347
Tyler Gunn295f5d72015-06-04 11:08:54 -0700348 /**
349 * Reports a change in the data usage (in bytes) received from the
350 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
351 *
352 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
353 * @param dataUsage The updated data usage (in bytes).
354 * @see InCallService.VideoCall.Callback#onCallDataUsageChanged(long)
355 * @see Connection.VideoProvider#setCallDataUsage(long)
356 */
Rekha Kumar07366812015-03-24 16:42:31 -0700357 public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700358
Tyler Gunn295f5d72015-06-04 11:08:54 -0700359 /**
360 * Reports a change in the capabilities of the current camera, received from the
361 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
362 *
363 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
364 * @param cameraCapabilities The changed camera capabilities.
365 * @see InCallService.VideoCall.Callback#onCameraCapabilitiesChanged(
366 * VideoProfile.CameraCapabilities)
367 * @see Connection.VideoProvider#changeCameraCapabilities(
368 * VideoProfile.CameraCapabilities)
369 */
Ihab Awada64627c2014-08-20 09:36:40 -0700370 public void onCameraCapabilitiesChanged(
371 VideoProvider videoProvider,
Yorke Lee400470f2015-05-12 13:31:25 -0700372 VideoProfile.CameraCapabilities cameraCapabilities) {}
Rekha Kumar07366812015-03-24 16:42:31 -0700373
Tyler Gunn295f5d72015-06-04 11:08:54 -0700374 /**
375 * Reports a change in the video quality received from the
376 * {@link Connection.VideoProvider} associated with a {@link RemoteConnection}.
377 *
378 * @param videoProvider The {@link RemoteConnection.VideoProvider} invoking this method.
379 * @param videoQuality The updated peer video quality.
380 * @see InCallService.VideoCall.Callback#onVideoQualityChanged(int)
381 * @see Connection.VideoProvider#changeVideoQuality(int)
382 */
Rekha Kumar07366812015-03-24 16:42:31 -0700383 public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
Ihab Awada64627c2014-08-20 09:36:40 -0700384 }
385
386 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() {
387 @Override
388 public void receiveSessionModifyRequest(VideoProfile videoProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700389 for (Callback l : mCallbacks) {
390 l.onSessionModifyRequestReceived(VideoProvider.this, videoProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700391 }
392 }
393
394 @Override
395 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile,
396 VideoProfile responseProfile) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700397 for (Callback l : mCallbacks) {
398 l.onSessionModifyResponseReceived(
Ihab Awada64627c2014-08-20 09:36:40 -0700399 VideoProvider.this,
400 status,
401 requestedProfile,
402 responseProfile);
403 }
404 }
405
406 @Override
407 public void handleCallSessionEvent(int event) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700408 for (Callback l : mCallbacks) {
409 l.onCallSessionEvent(VideoProvider.this, event);
Ihab Awada64627c2014-08-20 09:36:40 -0700410 }
411 }
412
413 @Override
414 public void changePeerDimensions(int width, int height) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700415 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700416 l.onPeerDimensionsChanged(VideoProvider.this, width, height);
417 }
418 }
419
420 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700421 public void changeCallDataUsage(long dataUsage) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700422 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700423 l.onCallDataUsageChanged(VideoProvider.this, dataUsage);
424 }
425 }
426
427 @Override
Yorke Lee400470f2015-05-12 13:31:25 -0700428 public void changeCameraCapabilities(
429 VideoProfile.CameraCapabilities cameraCapabilities) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700430 for (Callback l : mCallbacks) {
Ihab Awada64627c2014-08-20 09:36:40 -0700431 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
432 }
433 }
434
435 @Override
Rekha Kumar07366812015-03-24 16:42:31 -0700436 public void changeVideoQuality(int videoQuality) {
Tyler Gunna2df9252015-05-29 10:05:46 -0700437 for (Callback l : mCallbacks) {
Rekha Kumar07366812015-03-24 16:42:31 -0700438 l.onVideoQualityChanged(VideoProvider.this, videoQuality);
439 }
440 }
441
442 @Override
Ihab Awada64627c2014-08-20 09:36:40 -0700443 public IBinder asBinder() {
444 return null;
445 }
446 };
447
448 private final VideoCallbackServant mVideoCallbackServant =
449 new VideoCallbackServant(mVideoCallbackDelegate);
450
451 private final IVideoProvider mVideoProviderBinder;
452
Tyler Gunnb88b3112016-11-09 10:19:23 -0800453 private final String mCallingPackage;
454
Tyler Gunn159f35c2017-03-02 09:28:37 -0800455 private final int mTargetSdkVersion;
456
Ihab Awada64627c2014-08-20 09:36:40 -0700457 /**
458 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
459 * load factor before resizing, 1 means we only expect a single thread to
460 * access the map so make only a single shard
461 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700462 private final Set<Callback> mCallbacks = Collections.newSetFromMap(
463 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
Ihab Awada64627c2014-08-20 09:36:40 -0700464
Tyler Gunn159f35c2017-03-02 09:28:37 -0800465 VideoProvider(IVideoProvider videoProviderBinder, String callingPackage,
466 int targetSdkVersion) {
467
Ihab Awada64627c2014-08-20 09:36:40 -0700468 mVideoProviderBinder = videoProviderBinder;
Tyler Gunnb88b3112016-11-09 10:19:23 -0800469 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800470 mTargetSdkVersion = targetSdkVersion;
Ihab Awada64627c2014-08-20 09:36:40 -0700471 try {
Tyler Gunn75958422015-04-15 14:23:42 -0700472 mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
Ihab Awada64627c2014-08-20 09:36:40 -0700473 } catch (RemoteException e) {
474 }
475 }
476
Tyler Gunn295f5d72015-06-04 11:08:54 -0700477 /**
478 * Registers a callback to receive commands and state changes for video calls.
479 *
480 * @param l The video call callback.
481 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700482 public void registerCallback(Callback l) {
483 mCallbacks.add(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700484 }
485
Tyler Gunn295f5d72015-06-04 11:08:54 -0700486 /**
487 * Clears the video call callback set via {@link #registerCallback}.
488 *
489 * @param l The video call callback to clear.
490 */
Tyler Gunna2df9252015-05-29 10:05:46 -0700491 public void unregisterCallback(Callback l) {
492 mCallbacks.remove(l);
Ihab Awada64627c2014-08-20 09:36:40 -0700493 }
494
Tyler Gunn295f5d72015-06-04 11:08:54 -0700495 /**
496 * Sets the camera to be used for the outgoing video for the
497 * {@link RemoteConnection.VideoProvider}.
498 *
499 * @param cameraId The id of the camera (use ids as reported by
500 * {@link CameraManager#getCameraIdList()}).
501 * @see Connection.VideoProvider#onSetCamera(String)
502 */
Ihab Awada64627c2014-08-20 09:36:40 -0700503 public void setCamera(String cameraId) {
504 try {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800505 mVideoProviderBinder.setCamera(cameraId, mCallingPackage, mTargetSdkVersion);
Ihab Awada64627c2014-08-20 09:36:40 -0700506 } catch (RemoteException e) {
507 }
508 }
509
Tyler Gunn295f5d72015-06-04 11:08:54 -0700510 /**
511 * Sets the surface to be used for displaying a preview of what the user's camera is
512 * currently capturing for the {@link RemoteConnection.VideoProvider}.
513 *
514 * @param surface The {@link Surface}.
515 * @see Connection.VideoProvider#onSetPreviewSurface(Surface)
516 */
Ihab Awada64627c2014-08-20 09:36:40 -0700517 public void setPreviewSurface(Surface surface) {
518 try {
519 mVideoProviderBinder.setPreviewSurface(surface);
520 } catch (RemoteException e) {
521 }
522 }
523
Tyler Gunn295f5d72015-06-04 11:08:54 -0700524 /**
525 * Sets the surface to be used for displaying the video received from the remote device for
526 * the {@link RemoteConnection.VideoProvider}.
527 *
528 * @param surface The {@link Surface}.
529 * @see Connection.VideoProvider#onSetDisplaySurface(Surface)
530 */
Ihab Awada64627c2014-08-20 09:36:40 -0700531 public void setDisplaySurface(Surface surface) {
532 try {
533 mVideoProviderBinder.setDisplaySurface(surface);
534 } catch (RemoteException e) {
535 }
536 }
537
Tyler Gunn295f5d72015-06-04 11:08:54 -0700538 /**
539 * Sets the device orientation, in degrees, for the {@link RemoteConnection.VideoProvider}.
540 * Assumes that a standard portrait orientation of the device is 0 degrees.
541 *
542 * @param rotation The device orientation, in degrees.
543 * @see Connection.VideoProvider#onSetDeviceOrientation(int)
544 */
Ihab Awada64627c2014-08-20 09:36:40 -0700545 public void setDeviceOrientation(int rotation) {
546 try {
547 mVideoProviderBinder.setDeviceOrientation(rotation);
548 } catch (RemoteException e) {
549 }
550 }
551
Tyler Gunn295f5d72015-06-04 11:08:54 -0700552 /**
553 * Sets camera zoom ratio for the {@link RemoteConnection.VideoProvider}.
554 *
555 * @param value The camera zoom ratio.
556 * @see Connection.VideoProvider#onSetZoom(float)
557 */
Ihab Awada64627c2014-08-20 09:36:40 -0700558 public void setZoom(float value) {
559 try {
560 mVideoProviderBinder.setZoom(value);
561 } catch (RemoteException e) {
562 }
563 }
564
Tyler Gunn295f5d72015-06-04 11:08:54 -0700565 /**
566 * Issues a request to modify the properties of the current video session for the
567 * {@link RemoteConnection.VideoProvider}.
568 *
569 * @param fromProfile The video profile prior to the request.
570 * @param toProfile The video profile with the requested changes made.
571 * @see Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)
572 */
Tyler Gunn45382162015-05-06 08:52:27 -0700573 public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
Ihab Awada64627c2014-08-20 09:36:40 -0700574 try {
Tyler Gunn45382162015-05-06 08:52:27 -0700575 mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile);
Ihab Awada64627c2014-08-20 09:36:40 -0700576 } catch (RemoteException e) {
577 }
578 }
579
Tyler Gunn295f5d72015-06-04 11:08:54 -0700580 /**
581 * Provides a response to a request to change the current call video session
582 * properties for the {@link RemoteConnection.VideoProvider}.
583 *
584 * @param responseProfile The response call video properties.
585 * @see Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)
586 */
Ihab Awada64627c2014-08-20 09:36:40 -0700587 public void sendSessionModifyResponse(VideoProfile responseProfile) {
588 try {
589 mVideoProviderBinder.sendSessionModifyResponse(responseProfile);
590 } catch (RemoteException e) {
591 }
592 }
593
Tyler Gunn295f5d72015-06-04 11:08:54 -0700594 /**
595 * Issues a request to retrieve the capabilities of the current camera for the
596 * {@link RemoteConnection.VideoProvider}.
597 *
598 * @see Connection.VideoProvider#onRequestCameraCapabilities()
599 */
Ihab Awada64627c2014-08-20 09:36:40 -0700600 public void requestCameraCapabilities() {
601 try {
602 mVideoProviderBinder.requestCameraCapabilities();
603 } catch (RemoteException e) {
604 }
605 }
606
Tyler Gunn295f5d72015-06-04 11:08:54 -0700607 /**
608 * Issues a request to retrieve the data usage (in bytes) of the video portion of the
609 * {@link RemoteConnection} for the {@link RemoteConnection.VideoProvider}.
610 *
611 * @see Connection.VideoProvider#onRequestConnectionDataUsage()
612 */
Ihab Awada64627c2014-08-20 09:36:40 -0700613 public void requestCallDataUsage() {
614 try {
615 mVideoProviderBinder.requestCallDataUsage();
616 } catch (RemoteException e) {
617 }
618 }
619
Tyler Gunn295f5d72015-06-04 11:08:54 -0700620 /**
621 * Sets the {@link Uri} of an image to be displayed to the peer device when the video signal
622 * is paused, for the {@link RemoteConnection.VideoProvider}.
623 *
624 * @see Connection.VideoProvider#onSetPauseImage(Uri)
625 */
Yorke Lee32f24732015-05-12 16:18:03 -0700626 public void setPauseImage(Uri uri) {
Ihab Awada64627c2014-08-20 09:36:40 -0700627 try {
628 mVideoProviderBinder.setPauseImage(uri);
629 } catch (RemoteException e) {
630 }
631 }
632 }
633
Evan Charltonbf11f982014-07-20 22:06:28 -0700634 private IConnectionService mConnectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700635 private final String mConnectionId;
Jay Shrauner229e3822014-08-15 09:23:07 -0700636 /**
637 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
638 * load factor before resizing, 1 means we only expect a single thread to
639 * access the map so make only a single shard
640 */
Andrew Lee011728f2015-04-23 15:47:06 -0700641 private final Set<CallbackRecord> mCallbackRecords = Collections.newSetFromMap(
642 new ConcurrentHashMap<CallbackRecord, Boolean>(8, 0.9f, 1));
Ihab Awadb8e85c72014-08-23 20:34:57 -0700643 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
644 private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
645 Collections.unmodifiableList(mConferenceableConnections);
Santos Cordon52d8a152014-06-17 19:08:45 -0700646
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700647 private int mState = Connection.STATE_NEW;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700648 private DisconnectCause mDisconnectCause;
Andrew Lee100e2932014-09-08 15:34:24 -0700649 private boolean mRingbackRequested;
Santos Cordon52d8a152014-06-17 19:08:45 -0700650 private boolean mConnected;
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800651 private int mConnectionCapabilities;
Tyler Gunn720c6642016-03-22 09:02:47 -0700652 private int mConnectionProperties;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700653 private int mVideoState;
Ihab Awada64627c2014-08-20 09:36:40 -0700654 private VideoProvider mVideoProvider;
Andrew Lee100e2932014-09-08 15:34:24 -0700655 private boolean mIsVoipAudioMode;
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700656 private StatusHints mStatusHints;
Andrew Lee100e2932014-09-08 15:34:24 -0700657 private Uri mAddress;
658 private int mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700659 private String mCallerDisplayName;
660 private int mCallerDisplayNamePresentation;
Ihab Awadb8e85c72014-08-23 20:34:57 -0700661 private RemoteConference mConference;
Santos Cordon6b7f9552015-05-27 17:21:45 -0700662 private Bundle mExtras;
Tyler Gunnffbcd892020-05-04 15:01:59 -0700663 private String mCallingPackageAbbreviation;
Santos Cordon52d8a152014-06-17 19:08:45 -0700664
665 /**
666 * @hide
667 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700668 RemoteConnection(
669 String id,
670 IConnectionService connectionService,
671 ConnectionRequest request) {
672 mConnectionId = id;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700673 mConnectionService = connectionService;
Santos Cordon52d8a152014-06-17 19:08:45 -0700674 mConnected = true;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700675 mState = Connection.STATE_INITIALIZING;
Tyler Gunnffbcd892020-05-04 15:01:59 -0700676 if (request != null && request.getExtras() != null
677 && request.getExtras().containsKey(
678 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700679 String callingPackage = request.getExtras().getString(
Tyler Gunnffbcd892020-05-04 15:01:59 -0700680 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME);
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700681 mCallingPackageAbbreviation = Log.getPackageAbbreviation(callingPackage);
Tyler Gunnffbcd892020-05-04 15:01:59 -0700682 }
Evan Charltonbf11f982014-07-20 22:06:28 -0700683 }
684
685 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700686 * @hide
687 */
688 RemoteConnection(String callId, IConnectionService connectionService,
Tyler Gunn159f35c2017-03-02 09:28:37 -0800689 ParcelableConnection connection, String callingPackage, int targetSdkVersion) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700690 mConnectionId = callId;
691 mConnectionService = connectionService;
692 mConnected = true;
693 mState = connection.getState();
694 mDisconnectCause = connection.getDisconnectCause();
695 mRingbackRequested = connection.isRingbackRequested();
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800696 mConnectionCapabilities = connection.getConnectionCapabilities();
Tyler Gunn720c6642016-03-22 09:02:47 -0700697 mConnectionProperties = connection.getConnectionProperties();
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700698 mVideoState = connection.getVideoState();
Tyler Gunn9c2c5832016-09-16 15:08:50 -0700699 IVideoProvider videoProvider = connection.getVideoProvider();
700 if (videoProvider != null) {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800701 mVideoProvider = new RemoteConnection.VideoProvider(videoProvider, callingPackage,
702 targetSdkVersion);
Tyler Gunn9c2c5832016-09-16 15:08:50 -0700703 } else {
704 mVideoProvider = null;
705 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700706 mIsVoipAudioMode = connection.getIsVoipAudioMode();
707 mStatusHints = connection.getStatusHints();
708 mAddress = connection.getHandle();
709 mAddressPresentation = connection.getHandlePresentation();
710 mCallerDisplayName = connection.getCallerDisplayName();
711 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
712 mConference = null;
Tyler Gunn2282bb92016-10-17 15:48:19 -0700713 putExtras(connection.getExtras());
714
715 // Stash the original connection ID as it exists in the source ConnectionService.
716 // Telecom will use this to avoid adding duplicates later.
717 // See comments on Connection.EXTRA_ORIGINAL_CONNECTION_ID for more information.
718 Bundle newExtras = new Bundle();
719 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
720 putExtras(newExtras);
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700721 mCallingPackageAbbreviation = Log.getPackageAbbreviation(callingPackage);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700722 }
723
724 /**
Evan Charltonbf11f982014-07-20 22:06:28 -0700725 * Create a RemoteConnection which is used for failed connections. Note that using it for any
726 * "real" purpose will almost certainly fail. Callers should note the failure and act
727 * accordingly (moving on to another RemoteConnection, for example)
728 *
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700729 * @param disconnectCause The reason for the failed connection.
730 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -0700731 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700732 RemoteConnection(DisconnectCause disconnectCause) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -0700733 mConnectionId = "NULL";
Evan Charltonbf11f982014-07-20 22:06:28 -0700734 mConnected = false;
Ihab Awad6107bab2014-08-18 09:23:25 -0700735 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700736 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700737 }
738
Ihab Awad5d0410f2014-07-30 10:07:40 -0700739 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700740 * Adds a callback to this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700741 *
Andrew Lee100e2932014-09-08 15:34:24 -0700742 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700743 */
Andrew Lee100e2932014-09-08 15:34:24 -0700744 public void registerCallback(Callback callback) {
Andrew Lee011728f2015-04-23 15:47:06 -0700745 registerCallback(callback, new Handler());
746 }
747
748 /**
749 * Adds a callback to this {@code RemoteConnection}.
750 *
751 * @param callback A {@code Callback}.
752 * @param handler A {@code Handler} which command and status changes will be delivered to.
753 */
754 public void registerCallback(Callback callback, Handler handler) {
755 unregisterCallback(callback);
756 if (callback != null && handler != null) {
757 mCallbackRecords.add(new CallbackRecord(callback, handler));
758 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700759 }
760
Ihab Awad5d0410f2014-07-30 10:07:40 -0700761 /**
Andrew Lee100e2932014-09-08 15:34:24 -0700762 * Removes a callback from this {@code RemoteConnection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700763 *
Andrew Lee100e2932014-09-08 15:34:24 -0700764 * @param callback A {@code Callback}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700765 */
Andrew Lee100e2932014-09-08 15:34:24 -0700766 public void unregisterCallback(Callback callback) {
767 if (callback != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700768 for (CallbackRecord record : mCallbackRecords) {
769 if (record.getCallback() == callback) {
770 mCallbackRecords.remove(record);
771 break;
772 }
773 }
Jay Shrauner229e3822014-08-15 09:23:07 -0700774 }
Santos Cordon52d8a152014-06-17 19:08:45 -0700775 }
776
Ihab Awad5d0410f2014-07-30 10:07:40 -0700777 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -0700778 * Obtains the state of this {@code RemoteConnection}.
779 *
780 * @return A state value, chosen from the {@code STATE_*} constants.
781 */
Sailesh Nepalade3f252014-07-01 17:25:37 -0700782 public int getState() {
783 return mState;
784 }
785
Ihab Awad5d0410f2014-07-30 10:07:40 -0700786 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800787 * Obtains the reason why this {@code RemoteConnection} may have been disconnected.
788 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700789 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800790 * disconnect cause expressed as a code chosen from among those declared in
791 * {@link DisconnectCause}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700792 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700793 public DisconnectCause getDisconnectCause() {
794 return mDisconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -0700795 }
796
Ihab Awad5d0410f2014-07-30 10:07:40 -0700797 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800798 * Obtains the capabilities of this {@code RemoteConnection}.
799 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700800 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800801 * the {@code CAPABILITY_*} constants in class {@link Connection}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700802 */
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800803 public int getConnectionCapabilities() {
804 return mConnectionCapabilities;
Sailesh Nepal1a7061b2014-07-09 21:03:20 -0700805 }
806
Ihab Awad5d0410f2014-07-30 10:07:40 -0700807 /**
Tyler Gunn720c6642016-03-22 09:02:47 -0700808 * Obtains the properties of this {@code RemoteConnection}.
809 *
810 * @return A bitmask of the properties of the {@code RemoteConnection}, as defined in the
811 * {@code PROPERTY_*} constants in class {@link Connection}.
812 */
813 public int getConnectionProperties() {
814 return mConnectionProperties;
815 }
816
817 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800818 * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
819 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700820 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
821 */
Andrew Lee100e2932014-09-08 15:34:24 -0700822 public boolean isVoipAudioMode() {
823 return mIsVoipAudioMode;
Sailesh Nepal33aaae42014-07-07 22:49:44 -0700824 }
825
Ihab Awad5d0410f2014-07-30 10:07:40 -0700826 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800827 * Obtains status hints pertaining to this {@code RemoteConnection}.
828 *
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700829 * @return The current {@link StatusHints} of this {@code RemoteConnection},
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800830 * or {@code null} if none have been set.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700831 */
Sailesh Nepale7ef59a2014-07-08 21:48:22 -0700832 public StatusHints getStatusHints() {
833 return mStatusHints;
834 }
835
Ihab Awad5d0410f2014-07-30 10:07:40 -0700836 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800837 * Obtains the address of this {@code RemoteConnection}.
838 *
839 * @return The address (e.g., phone number) to which the {@code RemoteConnection}
840 * is currently connected.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700841 */
Andrew Lee100e2932014-09-08 15:34:24 -0700842 public Uri getAddress() {
843 return mAddress;
Sailesh Nepal61203862014-07-11 14:50:13 -0700844 }
845
Ihab Awad5d0410f2014-07-30 10:07:40 -0700846 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800847 * Obtains the presentation requirements for the address of this {@code RemoteConnection}.
848 *
849 * @return The presentation requirements for the address. See
850 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700851 */
Andrew Lee100e2932014-09-08 15:34:24 -0700852 public int getAddressPresentation() {
853 return mAddressPresentation;
Sailesh Nepal61203862014-07-11 14:50:13 -0700854 }
855
Ihab Awad5d0410f2014-07-30 10:07:40 -0700856 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800857 * Obtains the display name for this {@code RemoteConnection}'s caller.
858 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700859 * @return The display name for the caller.
860 */
Andrew Lee100e2932014-09-08 15:34:24 -0700861 public CharSequence getCallerDisplayName() {
Sailesh Nepal61203862014-07-11 14:50:13 -0700862 return mCallerDisplayName;
863 }
864
Ihab Awad5d0410f2014-07-30 10:07:40 -0700865 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800866 * Obtains the presentation requirements for this {@code RemoteConnection}'s
867 * caller's display name.
868 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700869 * @return The presentation requirements for the caller display name. See
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800870 * {@link TelecomManager} for valid values.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700871 */
Sailesh Nepal61203862014-07-11 14:50:13 -0700872 public int getCallerDisplayNamePresentation() {
873 return mCallerDisplayNamePresentation;
874 }
875
Ihab Awad5d0410f2014-07-30 10:07:40 -0700876 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800877 * Obtains the video state of this {@code RemoteConnection}.
878 *
Tyler Gunn87b73f32015-06-03 10:09:59 -0700879 * @return The video state of the {@code RemoteConnection}. See {@link VideoProfile}.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700880 */
Tyler Gunnaa07df82014-07-17 07:50:22 -0700881 public int getVideoState() {
882 return mVideoState;
883 }
884
Ihab Awad5d0410f2014-07-30 10:07:40 -0700885 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700886 * Obtains the video provider of this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700887 * @return The video provider associated with this {@code RemoteConnection}.
Ihab Awada64627c2014-08-20 09:36:40 -0700888 */
889 public final VideoProvider getVideoProvider() {
890 return mVideoProvider;
891 }
892
893 /**
Santos Cordon6b7f9552015-05-27 17:21:45 -0700894 * Obtain the extras associated with this {@code RemoteConnection}.
895 *
896 * @return The extras for this connection.
897 */
898 public final Bundle getExtras() {
899 return mExtras;
900 }
901
902 /**
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800903 * Determines whether this {@code RemoteConnection} is requesting ringback.
904 *
Ihab Awad5d0410f2014-07-30 10:07:40 -0700905 * @return Whether the {@code RemoteConnection} is requesting that the framework play a
Ihab Awad5c9c86e2014-11-12 13:41:16 -0800906 * ringback tone on its behalf.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700907 */
Andrew Lee100e2932014-09-08 15:34:24 -0700908 public boolean isRingbackRequested() {
Santos Cordon15d63c72015-06-02 15:08:26 -0700909 return mRingbackRequested;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700910 }
911
912 /**
913 * Instructs this {@code RemoteConnection} to abort.
914 */
Sailesh Nepal091768c2014-06-30 15:15:23 -0700915 public void abort() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700916 Log.startSession("RC.a", getActiveOwnerInfo());
Sailesh Nepal091768c2014-06-30 15:15:23 -0700917 try {
918 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700919 mConnectionService.abort(mConnectionId, Log.getExternalSession(
920 mCallingPackageAbbreviation));
Sailesh Nepal091768c2014-06-30 15:15:23 -0700921 }
922 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700923 } finally {
924 Log.endSession();
Sailesh Nepal091768c2014-06-30 15:15:23 -0700925 }
926 }
927
Ihab Awad5d0410f2014-07-30 10:07:40 -0700928 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700929 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700930 */
931 public void answer() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700932 Log.startSession("RC.an", getActiveOwnerInfo());
Tyler Gunnbe74de02014-08-29 14:51:48 -0700933 try {
934 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700935 mConnectionService.answer(mConnectionId, Log.getExternalSession(
936 mCallingPackageAbbreviation));
Tyler Gunnbe74de02014-08-29 14:51:48 -0700937 }
938 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700939 } finally {
940 Log.endSession();
Tyler Gunnbe74de02014-08-29 14:51:48 -0700941 }
942 }
943
944 /**
945 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700946 * @param videoState The video state in which to answer the call.
Tyler Gunnbe74de02014-08-29 14:51:48 -0700947 * @hide
Ihab Awad5d0410f2014-07-30 10:07:40 -0700948 */
Andrew Lee8da4c3c2014-07-16 10:11:42 -0700949 public void answer(int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700950 Log.startSession("RC.an2", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700951 try {
952 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700953 mConnectionService.answerVideo(mConnectionId, videoState,
954 Log.getExternalSession(mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -0700955 }
956 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700957 } finally {
958 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -0700959 }
960 }
961
Ihab Awad5d0410f2014-07-30 10:07:40 -0700962 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700963 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700964 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700965 public void reject() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700966 Log.startSession("RC.r", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700967 try {
968 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700969 mConnectionService.reject(mConnectionId, Log.getExternalSession(
970 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -0700971 }
972 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700973 } finally {
974 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -0700975 }
976 }
977
Ihab Awad5d0410f2014-07-30 10:07:40 -0700978 /**
979 * Instructs this {@code RemoteConnection} to go on hold.
980 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700981 public void hold() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700982 Log.startSession("RC.h", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700983 try {
984 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -0700985 mConnectionService.hold(mConnectionId, Log.getExternalSession(
986 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -0700987 }
988 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700989 } finally {
990 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -0700991 }
992 }
993
Ihab Awad5d0410f2014-07-30 10:07:40 -0700994 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700995 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold.
Ihab Awad5d0410f2014-07-30 10:07:40 -0700996 */
Santos Cordon52d8a152014-06-17 19:08:45 -0700997 public void unhold() {
Tyler Gunnffbcd892020-05-04 15:01:59 -0700998 Log.startSession("RC.u", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -0700999 try {
1000 if (mConnected) {
Tyler Gunn6b0cfc32020-05-06 11:33:26 -07001001 mConnectionService.unhold(mConnectionId, Log.getExternalSession(
1002 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -07001003 }
1004 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001005 } finally {
1006 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001007 }
1008 }
1009
Ihab Awad5d0410f2014-07-30 10:07:40 -07001010 /**
1011 * Instructs this {@code RemoteConnection} to disconnect.
1012 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001013 public void disconnect() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001014 Log.startSession("RC.d", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001015 try {
1016 if (mConnected) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001017 mConnectionService.disconnect(mConnectionId, Log.getExternalSession(
1018 mCallingPackageAbbreviation));
Santos Cordon52d8a152014-06-17 19:08:45 -07001019 }
1020 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001021 } finally {
1022 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001023 }
1024 }
1025
Ihab Awad5d0410f2014-07-30 10:07:40 -07001026 /**
1027 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling
1028 * (DTMF) tone.
1029 *
1030 * Any other currently playing DTMF tone in the specified call is immediately stopped.
1031 *
1032 * @param digit A character representing the DTMF digit for which to play the tone. This
1033 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
1034 */
1035 public void playDtmfTone(char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001036 Log.startSession("RC.pDT", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001037 try {
1038 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001039 mConnectionService.playDtmfTone(mConnectionId, digit, null /*Session.Info*/);
Santos Cordon52d8a152014-06-17 19:08:45 -07001040 }
1041 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001042 } finally {
1043 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001044 }
1045 }
1046
Ihab Awad5d0410f2014-07-30 10:07:40 -07001047 /**
1048 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling
1049 * (DTMF) tone currently playing.
1050 *
1051 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is
1052 * currently playing, this method will do nothing.
1053 */
1054 public void stopDtmfTone() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001055 Log.startSession("RC.sDT", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001056 try {
1057 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001058 mConnectionService.stopDtmfTone(mConnectionId, null /*Session.Info*/);
Santos Cordon52d8a152014-06-17 19:08:45 -07001059 }
1060 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001061 } finally {
1062 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001063 }
1064 }
1065
Ihab Awad5d0410f2014-07-30 10:07:40 -07001066 /**
1067 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string.
1068 *
1069 * A post-dial DTMF string is a string of digits following the first instance of either
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001070 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}.
Ihab Awad5d0410f2014-07-30 10:07:40 -07001071 * These digits are immediately sent as DTMF tones to the recipient as soon as the
1072 * connection is made.
1073 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001074 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this
Ihab Awad5d0410f2014-07-30 10:07:40 -07001075 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period
1076 * of time.
1077 *
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001078 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001079 * {@code RemoteConnection} will pause playing the tones and notify callbacks via
Andrew Lee100e2932014-09-08 15:34:24 -07001080 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
Ihab Awad5d0410f2014-07-30 10:07:40 -07001081 * should display to the user an indication of this state and an affordance to continue
1082 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
1083 * app should invoke the {@link #postDialContinue(boolean)} method.
1084 *
1085 * @param proceed Whether or not to continue with the post-dial sequence.
1086 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001087 public void postDialContinue(boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001088 Log.startSession("RC.pDC", getActiveOwnerInfo());
Santos Cordon52d8a152014-06-17 19:08:45 -07001089 try {
1090 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001091 mConnectionService.onPostDialContinue(mConnectionId, proceed,
1092 null /*Session.Info*/);
Santos Cordon52d8a152014-06-17 19:08:45 -07001093 }
1094 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001095 // bliss
1096 } finally {
1097 Log.endSession();
Santos Cordon52d8a152014-06-17 19:08:45 -07001098 }
1099 }
1100
Ihab Awad5d0410f2014-07-30 10:07:40 -07001101 /**
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001102 * Instructs this {@link RemoteConnection} to pull itself to the local device.
1103 * <p>
1104 * See {@link Call#pullExternalCall()} for more information.
1105 */
1106 public void pullExternalCall() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001107 Log.startSession("RC.pEC", getActiveOwnerInfo());
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001108 try {
1109 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001110 mConnectionService.pullExternalCall(mConnectionId, null /*Session.Info*/);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001111 }
1112 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001113 } finally {
1114 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001115 }
1116 }
1117
1118 /**
Grace Jia9a09c672020-08-04 12:52:09 -07001119 * Instructs this {@link RemoteConnection} to initiate a conference with a list of
1120 * participants.
1121 * <p>
1122 *
1123 * @param participants with which conference call will be formed.
1124 */
1125 public void addConferenceParticipants(@NonNull List<Uri> participants) {
1126 try {
1127 if (mConnected) {
1128 mConnectionService.addConferenceParticipants(mConnectionId, participants,
1129 null /*Session.Info*/);
1130 }
1131 } catch (RemoteException ignored) {
1132 }
1133 }
1134
1135 /**
Ihab Awad5d0410f2014-07-30 10:07:40 -07001136 * Set the audio state of this {@code RemoteConnection}.
1137 *
1138 * @param state The audio state of this {@code RemoteConnection}.
Yorke Lee4af59352015-05-13 14:14:54 -07001139 * @hide
Tyler Gunn94ffde72017-11-17 08:36:41 -08001140 * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead.
Ihab Awad5d0410f2014-07-30 10:07:40 -07001141 */
Yorke Lee4af59352015-05-13 14:14:54 -07001142 @SystemApi
1143 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001144 public void setAudioState(AudioState state) {
Yorke Lee4af59352015-05-13 14:14:54 -07001145 setCallAudioState(new CallAudioState(state));
1146 }
1147
1148 /**
1149 * Set the audio state of this {@code RemoteConnection}.
1150 *
1151 * @param state The audio state of this {@code RemoteConnection}.
1152 */
1153 public void setCallAudioState(CallAudioState state) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001154 Log.startSession("RC.sCAS", getActiveOwnerInfo());
Sailesh Nepal091768c2014-06-30 15:15:23 -07001155 try {
1156 if (mConnected) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001157 mConnectionService.onCallAudioStateChanged(mConnectionId, state,
1158 null /*Session.Info*/);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001159 }
1160 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001161 } finally {
1162 Log.endSession();
Sailesh Nepal091768c2014-06-30 15:15:23 -07001163 }
1164 }
1165
Santos Cordon52d8a152014-06-17 19:08:45 -07001166 /**
Hall Liu57006aa2017-02-06 10:49:48 -08001167 * Notifies this {@link RemoteConnection} that the user has requested an RTT session.
1168 * @param rttTextStream The object that should be used to send text to or receive text from
1169 * the in-call app.
1170 * @hide
1171 */
1172 public void startRtt(@NonNull Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001173 Log.startSession("RC.sR", getActiveOwnerInfo());
Hall Liu57006aa2017-02-06 10:49:48 -08001174 try {
1175 if (mConnected) {
1176 mConnectionService.startRtt(mConnectionId, rttTextStream.getFdFromInCall(),
1177 rttTextStream.getFdToInCall(), null /*Session.Info*/);
1178 }
1179 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001180 } finally {
1181 Log.endSession();
Hall Liu57006aa2017-02-06 10:49:48 -08001182 }
1183 }
1184
1185 /**
1186 * Notifies this {@link RemoteConnection} that it should terminate any existing RTT
1187 * session. No response to Telecom is needed for this method.
1188 * @hide
1189 */
1190 public void stopRtt() {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001191 Log.startSession("RC.stR", getActiveOwnerInfo());
Hall Liu57006aa2017-02-06 10:49:48 -08001192 try {
1193 if (mConnected) {
1194 mConnectionService.stopRtt(mConnectionId, null /*Session.Info*/);
1195 }
1196 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001197 } finally {
1198 Log.endSession();
Hall Liu57006aa2017-02-06 10:49:48 -08001199 }
1200 }
1201
1202 /**
Hall Liu49cabcc2021-01-15 11:41:48 -08001203 * Notifies this {@link RemoteConnection} that call filtering has completed, as well as
1204 * the results of a contacts lookup for the remote party.
Hall Liu73903142021-02-18 18:41:41 -08001205 *
1206 * @param completionInfo Info provided by Telecom on the results of call filtering.
Hall Liu49cabcc2021-01-15 11:41:48 -08001207 * @hide
1208 */
1209 @SystemApi
1210 @RequiresPermission(Manifest.permission.READ_CONTACTS)
Hall Liu73903142021-02-18 18:41:41 -08001211 public void onCallFilteringCompleted(
1212 @NonNull Connection.CallFilteringCompletionInfo completionInfo) {
Hall Liu49cabcc2021-01-15 11:41:48 -08001213 Log.startSession("RC.oCFC", getActiveOwnerInfo());
1214 try {
1215 if (mConnected) {
Hall Liu73903142021-02-18 18:41:41 -08001216 mConnectionService.onCallFilteringCompleted(mConnectionId, completionInfo,
Hall Liu49cabcc2021-01-15 11:41:48 -08001217 null /*Session.Info*/);
1218 }
1219 } catch (RemoteException ignored) {
1220 } finally {
1221 Log.endSession();
1222 }
1223 }
1224
1225 /**
Hall Liu57006aa2017-02-06 10:49:48 -08001226 * Notifies this {@link RemoteConnection} of a response to a previous remotely-initiated RTT
1227 * upgrade request sent via {@link Connection#sendRemoteRttRequest}.
1228 * Acceptance of the request is indicated by the supplied {@link RttTextStream} being non-null,
1229 * and rejection is indicated by {@code rttTextStream} being {@code null}
1230 * @hide
1231 * @param rttTextStream The object that should be used to send text to or receive text from
1232 * the in-call app.
1233 */
1234 public void sendRttUpgradeResponse(@Nullable Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001235 Log.startSession("RC.sRUR", getActiveOwnerInfo());
Hall Liu57006aa2017-02-06 10:49:48 -08001236 try {
1237 if (mConnected) {
1238 if (rttTextStream == null) {
1239 mConnectionService.respondToRttUpgradeRequest(mConnectionId,
1240 null, null, null /*Session.Info*/);
1241 } else {
1242 mConnectionService.respondToRttUpgradeRequest(mConnectionId,
1243 rttTextStream.getFdFromInCall(), rttTextStream.getFdToInCall(),
1244 null /*Session.Info*/);
1245 }
1246 }
1247 } catch (RemoteException ignored) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07001248 } finally {
1249 Log.endSession();
Hall Liu57006aa2017-02-06 10:49:48 -08001250 }
1251 }
1252
1253 /**
Ihab Awadb8e85c72014-08-23 20:34:57 -07001254 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
1255 * successfully asked to create a conference with.
1256 *
1257 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be
1258 * merged into a {@link RemoteConference}.
1259 */
1260 public List<RemoteConnection> getConferenceableConnections() {
1261 return mUnmodifiableconferenceableConnections;
1262 }
1263
1264 /**
1265 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part
1266 * of, or {@code null} if there is no such {@code RemoteConference}.
1267 *
1268 * @return A {@code RemoteConference} or {@code null};
1269 */
1270 public RemoteConference getConference() {
1271 return mConference;
1272 }
1273
Tyler Gunnffbcd892020-05-04 15:01:59 -07001274 /**
1275 * Get the owner info for the currently active session. We want to make sure that any owner
1276 * info from the original call into the connection manager gets retained so that the full
1277 * context of the calls can be traced down to Telephony.
1278 * Example: Telecom will provide owner info in it's external session info that indicates
1279 * 'cast' as the calling owner.
1280 * @return The active owner
1281 */
1282 private String getActiveOwnerInfo() {
1283 Session.Info info = Log.getExternalSession();
1284 if (info == null) {
1285 return null;
1286 }
1287 return info.ownerInfo;
1288 }
1289
Ihab Awadb8e85c72014-08-23 20:34:57 -07001290 /** {@hide} */
1291 String getId() {
1292 return mConnectionId;
1293 }
1294
1295 /** {@hide} */
1296 IConnectionService getConnectionService() {
1297 return mConnectionService;
1298 }
1299
1300 /**
Santos Cordon52d8a152014-06-17 19:08:45 -07001301 * @hide
1302 */
Andrew Lee011728f2015-04-23 15:47:06 -07001303 void setState(final int state) {
Santos Cordon52d8a152014-06-17 19:08:45 -07001304 if (mState != state) {
1305 mState = state;
Andrew Lee011728f2015-04-23 15:47:06 -07001306 for (CallbackRecord record: mCallbackRecords) {
1307 final RemoteConnection connection = this;
1308 final Callback callback = record.getCallback();
1309 record.getHandler().post(new Runnable() {
1310 @Override
1311 public void run() {
1312 callback.onStateChanged(connection, state);
1313 }
1314 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001315 }
1316 }
1317 }
1318
1319 /**
1320 * @hide
1321 */
Andrew Lee011728f2015-04-23 15:47:06 -07001322 void setDisconnected(final DisconnectCause disconnectCause) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001323 if (mState != Connection.STATE_DISCONNECTED) {
1324 mState = Connection.STATE_DISCONNECTED;
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001325 mDisconnectCause = disconnectCause;
Santos Cordon52d8a152014-06-17 19:08:45 -07001326
Andrew Lee011728f2015-04-23 15:47:06 -07001327 for (CallbackRecord record : mCallbackRecords) {
1328 final RemoteConnection connection = this;
1329 final Callback callback = record.getCallback();
1330 record.getHandler().post(new Runnable() {
1331 @Override
1332 public void run() {
1333 callback.onDisconnected(connection, disconnectCause);
1334 }
1335 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001336 }
1337 }
1338 }
1339
1340 /**
1341 * @hide
1342 */
Andrew Lee011728f2015-04-23 15:47:06 -07001343 void setRingbackRequested(final boolean ringback) {
Andrew Lee100e2932014-09-08 15:34:24 -07001344 if (mRingbackRequested != ringback) {
1345 mRingbackRequested = ringback;
Andrew Lee011728f2015-04-23 15:47:06 -07001346 for (CallbackRecord record : mCallbackRecords) {
1347 final RemoteConnection connection = this;
1348 final Callback callback = record.getCallback();
1349 record.getHandler().post(new Runnable() {
1350 @Override
1351 public void run() {
1352 callback.onRingbackRequested(connection, ringback);
1353 }
1354 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001355 }
1356 }
1357 }
1358
1359 /**
1360 * @hide
1361 */
Andrew Lee011728f2015-04-23 15:47:06 -07001362 void setConnectionCapabilities(final int connectionCapabilities) {
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001363 mConnectionCapabilities = connectionCapabilities;
Andrew Lee011728f2015-04-23 15:47:06 -07001364 for (CallbackRecord record : mCallbackRecords) {
1365 final RemoteConnection connection = this;
1366 final Callback callback = record.getCallback();
1367 record.getHandler().post(new Runnable() {
1368 @Override
1369 public void run() {
1370 callback.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
1371 }
1372 });
Sailesh Nepal1a7061b2014-07-09 21:03:20 -07001373 }
1374 }
1375
1376 /**
1377 * @hide
1378 */
Tyler Gunn720c6642016-03-22 09:02:47 -07001379 void setConnectionProperties(final int connectionProperties) {
1380 mConnectionProperties = connectionProperties;
1381 for (CallbackRecord record : mCallbackRecords) {
1382 final RemoteConnection connection = this;
1383 final Callback callback = record.getCallback();
1384 record.getHandler().post(new Runnable() {
1385 @Override
1386 public void run() {
1387 callback.onConnectionPropertiesChanged(connection, connectionProperties);
1388 }
1389 });
1390 }
1391 }
1392
1393 /**
1394 * @hide
1395 */
Santos Cordon52d8a152014-06-17 19:08:45 -07001396 void setDestroyed() {
Andrew Lee011728f2015-04-23 15:47:06 -07001397 if (!mCallbackRecords.isEmpty()) {
Andrew Lee100e2932014-09-08 15:34:24 -07001398 // Make sure that the callbacks are notified that the call is destroyed first.
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001399 if (mState != Connection.STATE_DISCONNECTED) {
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001400 setDisconnected(
1401 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
Santos Cordon52d8a152014-06-17 19:08:45 -07001402 }
1403
Andrew Lee011728f2015-04-23 15:47:06 -07001404 for (CallbackRecord record : mCallbackRecords) {
1405 final RemoteConnection connection = this;
1406 final Callback callback = record.getCallback();
1407 record.getHandler().post(new Runnable() {
1408 @Override
1409 public void run() {
1410 callback.onDestroyed(connection);
1411 }
1412 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001413 }
Andrew Lee011728f2015-04-23 15:47:06 -07001414 mCallbackRecords.clear();
Santos Cordon52d8a152014-06-17 19:08:45 -07001415
1416 mConnected = false;
1417 }
1418 }
1419
1420 /**
1421 * @hide
1422 */
Andrew Lee011728f2015-04-23 15:47:06 -07001423 void setPostDialWait(final String remainingDigits) {
1424 for (CallbackRecord record : mCallbackRecords) {
1425 final RemoteConnection connection = this;
1426 final Callback callback = record.getCallback();
1427 record.getHandler().post(new Runnable() {
1428 @Override
1429 public void run() {
1430 callback.onPostDialWait(connection, remainingDigits);
1431 }
1432 });
Santos Cordon52d8a152014-06-17 19:08:45 -07001433 }
1434 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001435
Tyler Gunnaa07df82014-07-17 07:50:22 -07001436 /**
1437 * @hide
1438 */
Andrew Lee011728f2015-04-23 15:47:06 -07001439 void onPostDialChar(final char nextChar) {
1440 for (CallbackRecord record : mCallbackRecords) {
1441 final RemoteConnection connection = this;
1442 final Callback callback = record.getCallback();
1443 record.getHandler().post(new Runnable() {
1444 @Override
1445 public void run() {
Sailesh Nepal40451b32015-05-14 17:39:41 -07001446 callback.onPostDialChar(connection, nextChar);
Andrew Lee011728f2015-04-23 15:47:06 -07001447 }
1448 });
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001449 }
1450 }
1451
1452 /**
1453 * @hide
1454 */
Andrew Lee011728f2015-04-23 15:47:06 -07001455 void setVideoState(final int videoState) {
Tyler Gunnaa07df82014-07-17 07:50:22 -07001456 mVideoState = videoState;
Andrew Lee011728f2015-04-23 15:47:06 -07001457 for (CallbackRecord record : mCallbackRecords) {
1458 final RemoteConnection connection = this;
1459 final Callback callback = record.getCallback();
1460 record.getHandler().post(new Runnable() {
1461 @Override
1462 public void run() {
1463 callback.onVideoStateChanged(connection, videoState);
1464 }
1465 });
Tyler Gunnaa07df82014-07-17 07:50:22 -07001466 }
1467 }
1468
Ihab Awada64627c2014-08-20 09:36:40 -07001469 /**
1470 * @hide
1471 */
Andrew Lee011728f2015-04-23 15:47:06 -07001472 void setVideoProvider(final VideoProvider videoProvider) {
Ihab Awada64627c2014-08-20 09:36:40 -07001473 mVideoProvider = videoProvider;
Andrew Lee011728f2015-04-23 15:47:06 -07001474 for (CallbackRecord record : mCallbackRecords) {
1475 final RemoteConnection connection = this;
1476 final Callback callback = record.getCallback();
1477 record.getHandler().post(new Runnable() {
1478 @Override
1479 public void run() {
1480 callback.onVideoProviderChanged(connection, videoProvider);
1481 }
1482 });
Ihab Awada64627c2014-08-20 09:36:40 -07001483 }
1484 }
1485
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001486 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001487 void setIsVoipAudioMode(final boolean isVoip) {
Andrew Lee100e2932014-09-08 15:34:24 -07001488 mIsVoipAudioMode = isVoip;
Andrew Lee011728f2015-04-23 15:47:06 -07001489 for (CallbackRecord record : mCallbackRecords) {
1490 final RemoteConnection connection = this;
1491 final Callback callback = record.getCallback();
1492 record.getHandler().post(new Runnable() {
1493 @Override
1494 public void run() {
1495 callback.onVoipAudioChanged(connection, isVoip);
1496 }
1497 });
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001498 }
1499 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001500
1501 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001502 void setStatusHints(final StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001503 mStatusHints = statusHints;
Andrew Lee011728f2015-04-23 15:47:06 -07001504 for (CallbackRecord record : mCallbackRecords) {
1505 final RemoteConnection connection = this;
1506 final Callback callback = record.getCallback();
1507 record.getHandler().post(new Runnable() {
1508 @Override
1509 public void run() {
1510 callback.onStatusHintsChanged(connection, statusHints);
1511 }
1512 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001513 }
1514 }
1515
1516 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001517 void setAddress(final Uri address, final int presentation) {
Andrew Lee100e2932014-09-08 15:34:24 -07001518 mAddress = address;
1519 mAddressPresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001520 for (CallbackRecord record : mCallbackRecords) {
1521 final RemoteConnection connection = this;
1522 final Callback callback = record.getCallback();
1523 record.getHandler().post(new Runnable() {
1524 @Override
1525 public void run() {
1526 callback.onAddressChanged(connection, address, presentation);
1527 }
1528 });
Sailesh Nepal61203862014-07-11 14:50:13 -07001529 }
1530 }
1531
1532 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001533 void setCallerDisplayName(final String callerDisplayName, final int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001534 mCallerDisplayName = callerDisplayName;
1535 mCallerDisplayNamePresentation = presentation;
Andrew Lee011728f2015-04-23 15:47:06 -07001536 for (CallbackRecord record : mCallbackRecords) {
1537 final RemoteConnection connection = this;
1538 final Callback callback = record.getCallback();
1539 record.getHandler().post(new Runnable() {
1540 @Override
1541 public void run() {
1542 callback.onCallerDisplayNameChanged(
1543 connection, callerDisplayName, presentation);
1544 }
1545 });
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001546 }
1547 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001548
1549 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001550 void setConferenceableConnections(final List<RemoteConnection> conferenceableConnections) {
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001551 mConferenceableConnections.clear();
1552 mConferenceableConnections.addAll(conferenceableConnections);
Andrew Lee011728f2015-04-23 15:47:06 -07001553 for (CallbackRecord record : mCallbackRecords) {
1554 final RemoteConnection connection = this;
1555 final Callback callback = record.getCallback();
1556 record.getHandler().post(new Runnable() {
1557 @Override
1558 public void run() {
1559 callback.onConferenceableConnectionsChanged(
1560 connection, mUnmodifiableconferenceableConnections);
1561 }
1562 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001563 }
1564 }
1565
1566 /** @hide */
Andrew Lee011728f2015-04-23 15:47:06 -07001567 void setConference(final RemoteConference conference) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001568 if (mConference != conference) {
1569 mConference = conference;
Andrew Lee011728f2015-04-23 15:47:06 -07001570 for (CallbackRecord record : mCallbackRecords) {
1571 final RemoteConnection connection = this;
1572 final Callback callback = record.getCallback();
1573 record.getHandler().post(new Runnable() {
1574 @Override
1575 public void run() {
1576 callback.onConferenceChanged(connection, conference);
1577 }
1578 });
Ihab Awadb8e85c72014-08-23 20:34:57 -07001579 }
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001580 }
1581 }
1582
Santos Cordon6b7f9552015-05-27 17:21:45 -07001583 /** @hide */
Tyler Gunndee56a82016-03-23 16:06:34 -07001584 void putExtras(final Bundle extras) {
Tyler Gunn2282bb92016-10-17 15:48:19 -07001585 if (extras == null) {
1586 return;
1587 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001588 if (mExtras == null) {
1589 mExtras = new Bundle();
1590 }
Tyler Gunn14343ee2017-08-11 09:24:41 -07001591 try {
1592 mExtras.putAll(extras);
1593 } catch (BadParcelableException bpe) {
1594 Log.w(this, "putExtras: could not unmarshal extras; exception = " + bpe);
1595 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001596
1597 notifyExtrasChanged();
1598 }
1599
1600 /** @hide */
1601 void removeExtras(List<String> keys) {
1602 if (mExtras == null || keys == null || keys.isEmpty()) {
1603 return;
1604 }
1605 for (String key : keys) {
1606 mExtras.remove(key);
1607 }
1608
1609 notifyExtrasChanged();
1610 }
1611
1612 private void notifyExtrasChanged() {
Santos Cordon6b7f9552015-05-27 17:21:45 -07001613 for (CallbackRecord record : mCallbackRecords) {
1614 final RemoteConnection connection = this;
1615 final Callback callback = record.getCallback();
1616 record.getHandler().post(new Runnable() {
1617 @Override
1618 public void run() {
Tyler Gunndee56a82016-03-23 16:06:34 -07001619 callback.onExtrasChanged(connection, mExtras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001620 }
1621 });
1622 }
1623 }
1624
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001625 /** @hide */
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001626 void onConnectionEvent(final String event, final Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001627 for (CallbackRecord record : mCallbackRecords) {
1628 final RemoteConnection connection = this;
1629 final Callback callback = record.getCallback();
1630 record.getHandler().post(new Runnable() {
1631 @Override
1632 public void run() {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001633 callback.onConnectionEvent(connection, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001634 }
1635 });
1636 }
1637 }
1638
Hall Liu57006aa2017-02-06 10:49:48 -08001639 /** @hide */
1640 void onRttInitiationSuccess() {
1641 for (CallbackRecord record : mCallbackRecords) {
1642 final RemoteConnection connection = this;
1643 final Callback callback = record.getCallback();
1644 record.getHandler().post(
1645 () -> callback.onRttInitiationSuccess(connection));
1646 }
1647 }
1648
1649 /** @hide */
1650 void onRttInitiationFailure(int reason) {
1651 for (CallbackRecord record : mCallbackRecords) {
1652 final RemoteConnection connection = this;
1653 final Callback callback = record.getCallback();
1654 record.getHandler().post(
1655 () -> callback.onRttInitiationFailure(connection, reason));
1656 }
1657 }
1658
1659 /** @hide */
1660 void onRttSessionRemotelyTerminated() {
1661 for (CallbackRecord record : mCallbackRecords) {
1662 final RemoteConnection connection = this;
1663 final Callback callback = record.getCallback();
1664 record.getHandler().post(
1665 () -> callback.onRttSessionRemotelyTerminated(connection));
1666 }
1667 }
1668
1669 /** @hide */
1670 void onRemoteRttRequest() {
1671 for (CallbackRecord record : mCallbackRecords) {
1672 final RemoteConnection connection = this;
1673 final Callback callback = record.getCallback();
1674 record.getHandler().post(
1675 () -> callback.onRemoteRttRequest(connection));
1676 }
1677 }
1678
1679 /**
Evan Charltonbf11f982014-07-20 22:06:28 -07001680 /**
Ihab Awad6107bab2014-08-18 09:23:25 -07001681 * Create a RemoteConnection represents a failure, and which will be in
1682 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
1683 * certainly result in bad things happening. Do not do this.
Evan Charltonbf11f982014-07-20 22:06:28 -07001684 *
1685 * @return a failed {@link RemoteConnection}
1686 *
1687 * @hide
Evan Charltonbf11f982014-07-20 22:06:28 -07001688 */
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001689 public static RemoteConnection failure(DisconnectCause disconnectCause) {
1690 return new RemoteConnection(disconnectCause);
Evan Charltonbf11f982014-07-20 22:06:28 -07001691 }
Andrew Lee011728f2015-04-23 15:47:06 -07001692
1693 private static final class CallbackRecord extends Callback {
1694 private final Callback mCallback;
1695 private final Handler mHandler;
1696
1697 public CallbackRecord(Callback callback, Handler handler) {
1698 mCallback = callback;
1699 mHandler = handler;
1700 }
1701
1702 public Callback getCallback() {
1703 return mCallback;
1704 }
1705
1706 public Handler getHandler() {
1707 return mHandler;
1708 }
1709 }
Santos Cordon52d8a152014-06-17 19:08:45 -07001710}