blob: 01448c3bcd9e1fe9c73ed796e29dd5569480fd9f [file] [log] [blame]
Ihab Awad542e0ea2014-05-16 10:22:16 -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;
Ihab Awad542e0ea2014-05-16 10:22:16 -070018
yongnamcha8ec56242022-11-28 06:23:02 +000019import android.annotation.CallbackExecutor;
Tyler Gunnda266f22023-12-21 21:23:31 +000020import android.annotation.FlaggedApi;
Tyler Gunn5567d742019-10-31 13:04:37 -070021import android.annotation.NonNull;
22import android.annotation.Nullable;
Roopa Sattiraju45de470c2022-01-27 21:31:35 -080023import android.annotation.RequiresPermission;
Santos Cordon5c6fa952014-07-20 17:47:12 -070024import android.annotation.SdkConstant;
Tyler Gunn5567d742019-10-31 13:04:37 -070025import android.annotation.SystemApi;
Hall Liueb7c9ea2021-03-09 20:24:50 -080026import android.annotation.TestApi;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070027import android.app.Service;
Santos Cordon52d8a152014-06-17 19:08:45 -070028import android.content.ComponentName;
Santos Cordon5c6fa952014-07-20 17:47:12 -070029import android.content.Intent;
yongnamcha8ec56242022-11-28 06:23:02 +000030import android.location.Location;
Ihab Awad542e0ea2014-05-16 10:22:16 -070031import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070032import android.os.Bundle;
Santos Cordon52d8a152014-06-17 19:08:45 -070033import android.os.Handler;
34import android.os.IBinder;
35import android.os.Looper;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070036import android.os.Message;
Junhoedf3d822022-11-24 09:26:37 +000037import android.os.OutcomeReceiver;
Hall Liub64ac4c2017-02-06 10:49:48 -080038import android.os.ParcelFileDescriptor;
39import android.os.RemoteException;
Brad Ebingerb32d4f82016-10-24 16:40:49 -070040import android.telecom.Logging.Session;
Andrew Lee14185762014-07-25 09:41:56 -070041
Brad Ebinger99f17ce2019-09-11 18:06:51 -070042import com.android.internal.annotations.VisibleForTesting;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070043import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070044import com.android.internal.telecom.IConnectionService;
45import com.android.internal.telecom.IConnectionServiceAdapter;
46import com.android.internal.telecom.RemoteServiceCallback;
Tyler Gunnda266f22023-12-21 21:23:31 +000047import com.android.server.telecom.flags.Flags;
Santos Cordon52d8a152014-06-17 19:08:45 -070048
Ihab Awad5d0410f2014-07-30 10:07:40 -070049import java.util.ArrayList;
Santos Cordonb6939982014-06-04 20:20:58 -070050import java.util.Collection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070051import java.util.Collections;
Santos Cordon52d8a152014-06-17 19:08:45 -070052import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070053import java.util.Map;
Santos Cordon823fd3c2014-08-07 18:35:18 -070054import java.util.UUID;
mike dooley95e80702014-09-18 14:07:52 -070055import java.util.concurrent.ConcurrentHashMap;
Junhoedf3d822022-11-24 09:26:37 +000056import java.util.concurrent.Executor;
Ihab Awad542e0ea2014-05-16 10:22:16 -070057
58/**
Tyler Gunnf5035432017-01-09 09:43:12 -080059 * An abstract service that should be implemented by any apps which either:
60 * <ol>
61 * <li>Can make phone calls (VoIP or otherwise) and want those calls to be integrated into the
62 * built-in phone app. Referred to as a <b>system managed</b> {@link ConnectionService}.</li>
63 * <li>Are a standalone calling app and don't want their calls to be integrated into the
64 * built-in phone app. Referred to as a <b>self managed</b> {@link ConnectionService}.</li>
65 * </ol>
66 * Once implemented, the {@link ConnectionService} needs to take the following steps so that Telecom
67 * will bind to it:
Santos Cordona663f862014-10-29 13:49:58 -070068 * <p>
69 * 1. <i>Registration in AndroidManifest.xml</i>
70 * <br/>
71 * <pre>
72 * &lt;service android:name="com.example.package.MyConnectionService"
73 * android:label="@string/some_label_for_my_connection_service"
Yorke Lee249c12e2015-05-13 15:59:29 -070074 * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"&gt;
Santos Cordona663f862014-10-29 13:49:58 -070075 * &lt;intent-filter&gt;
76 * &lt;action android:name="android.telecom.ConnectionService" /&gt;
77 * &lt;/intent-filter&gt;
78 * &lt;/service&gt;
79 * </pre>
80 * <p>
81 * 2. <i> Registration of {@link PhoneAccount} with {@link TelecomManager}.</i>
82 * <br/>
83 * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
84 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080085 * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
Tyler Gunn8eeb94f2023-01-20 22:46:19 +000086 * before Telecom will bind to them. Self-managed {@link ConnectionService}s must declare the
87 * {@link android.Manifest.permission#MANAGE_OWN_CALLS} permission in their manifest before Telecom
88 * will bind to them.
Tyler Gunnf5035432017-01-09 09:43:12 -080089 * <p>
90 * Once registered and enabled by the user in the phone app settings or granted permission, telecom
91 * will bind to a {@link ConnectionService} implementation when it wants that
92 * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
Tyler Gunn8eeb94f2023-01-20 22:46:19 +000093 * call through {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}. The
94 * {@link ConnectionService} can then expect a call to
95 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)} or
96 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
Tyler Gunnf5035432017-01-09 09:43:12 -080097 * wherein it should provide a new instance of a {@link Connection} object. It is through this
98 * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
Santos Cordona663f862014-10-29 13:49:58 -070099 * receives call-commands such as answer, reject, hold and disconnect.
100 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -0800101 * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
Tyler Gunn8eeb94f2023-01-20 22:46:19 +0000102 * <p>
103 * <h1>Self-Managed Connection Services</h1>
104 * A VoIP app can implement a {@link ConnectionService} to ensure that its calls are integrated
105 * into the Android platform. There are numerous benefits to using the Telecom APIs for a VoIP app:
106 * <ul>
107 * <li>Call concurrency is handled - the user is able to swap between calls in different
108 * apps and on the mobile network.</li>
109 * <li>Simplified audio routing - the platform provides your app with a unified list of the
110 * audio routes which are available
111 * (e.g. {@link android.telecom.Connection#onAvailableCallEndpointsChanged(List)}) and a
112 * standardized way to switch audio routes
113 * (e.g. {@link android.telecom.Connection#requestCallEndpointChange(CallEndpoint, Executor,
114 * OutcomeReceiver)} ).</li>
115 * <li>Bluetooth integration - your calls will be visible on and controllable via
116 * bluetooth devices (e.g. car head units and headsets).</li>
117 * <li>Companion device integration - wearable devices such as watches which implement an
118 * {@link InCallService} can optionally subscribe to see self-managed calls. Similar to a
119 * bluetooth headunit, wearables will typically render your call using a generic call UX and
120 * provide the user with basic call controls such as hangup, answer, reject.</li>
121 * <li>Automotive calling experiences - Android supports automotive optimized experiences which
122 * provides a means for calls to be controlled and viewed in an automobile; these experiences
123 * are capable of leveraging call metadata provided by your app.</li>
124 * </ul>
125 * <h2>Registering a Phone Account</h2>
126 * Before your app can handle incoming or outgoing calls through Telecom it needs to register a
127 * {@link PhoneAccount} with Telecom indicating to the platform that your app is capable of calling.
128 * <p>
129 * Your app should create a new instance of {@link PhoneAccount} which meets the following
130 * requirements:
131 * <ul>
132 * <li>Has {@link PhoneAccount#CAPABILITY_SELF_MANAGED} (set using
133 * {@link PhoneAccount.Builder#setCapabilities(int)}). This indicates to Telecom that your
134 * app will report calls but that it provides a primary UI for the calls by itself.</li>
135 * <li>Provide a unique identifier for the {@link PhoneAccount} via the
136 * {@link PhoneAccountHandle#getId()} attribute. As per the {@link PhoneAccountHandle}
137 * documentation, you should NOT use an identifier which contains PII or other sensitive
138 * information. A typical choice is a UUID.</li>
139 * </ul>
140 * Your app should register the new {@link PhoneAccount} with Telecom using
141 * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}. {@link PhoneAccount}s persist across
142 * reboot. You can use {@link TelecomManager#getOwnSelfManagedPhoneAccounts()} to confirm the
143 * {@link PhoneAccount} you registered. Your app should generally only register a single
144 * {@link PhoneAccount}.
145 *
146 * <h2>Implementing ConnectionService</h2>
147 * Your app uses {@link TelecomManager#placeCall(Uri, Bundle)} to start new outgoing calls and
148 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)} to report new incoming
149 * calls. Calling these APIs causes the Telecom stack to bind to your app's
150 * {@link ConnectionService} implementation. Telecom will either inform your app that it cannot
151 * handle a call request at the current time (i.e. there could be an ongoing emergency call, which
152 * means your app is not allowed to handle calls at the current time), or it will ask your app to
153 * create a new instance of {@link Connection} to represent a call in your app.
154 *
155 * Your app should implement the following {@link ConnectionService} methods:
156 * <ul>
157 * <li>{@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
158 * ConnectionRequest)} - called by Telecom to ask your app to make a new {@link Connection}
159 * to represent an outgoing call your app requested via
160 * {@link TelecomManager#placeCall(Uri, Bundle)}.</li>
161 * <li><{@link ConnectionService#onCreateOutgoingConnectionFailed(PhoneAccountHandle,
162 * ConnectionRequest)} - called by Telecom to inform your app that a call it reported via
163 * {@link TelecomManager#placeCall(Uri, Bundle)} cannot be handled at this time. Your app
164 * should NOT place a call at the current time.</li>
165 * <li>{@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle,
166 * ConnectionRequest)} - called by Telecom to ask your app to make a new {@link Connection}
167 * to represent an incoming call your app reported via
168 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}.</li>
169 * <li>{@link ConnectionService#onCreateIncomingConnectionFailed(PhoneAccountHandle,
170 * ConnectionRequest)} - called by Telecom to inform your app that an incoming call it reported
171 * via {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)} cannot be handled
172 * at this time. Your app should NOT post a new incoming call notification and should silently
173 * reject the call.</li>
174 * </ul>
175 *
176 * <h2>Implementing a Connection</h2>
177 * Your app should extend the {@link Connection} class to represent calls in your app. When you
178 * create new instances of your {@link Connection}, you should ensure the following properties are
179 * set on the new {@link Connection} instance returned by your {@link ConnectionService}:
180 * <ul>
181 * <li>{@link Connection#setAddress(Uri, int)} - the identifier for the other party. For
182 * apps that user phone numbers the {@link Uri} can be a {@link PhoneAccount#SCHEME_TEL} URI
183 * representing the phone number.</li>
184 * <li>{@link Connection#setCallerDisplayName(String, int)} - the display name of the other
185 * party. This is what will be shown on Bluetooth devices and other calling surfaces such
186 * as wearable devices. This is particularly important for calls that do not use a phone
187 * number to identify the caller or called party.</li>
188 * <li>{@link Connection#setConnectionProperties(int)} - ensure you set
189 * {@link Connection#PROPERTY_SELF_MANAGED} to identify to the platform that the call is
190 * handled by your app.</li>
191 * <li>{@link Connection#setConnectionCapabilities(int)} - if your app supports making calls
192 * inactive (i.e. holding calls) you should get {@link Connection#CAPABILITY_SUPPORT_HOLD} and
193 * {@link Connection#CAPABILITY_HOLD} to indicate to the platform that you calls can potentially
194 * be held for concurrent calling scenarios.</li>
195 * <li>{@link Connection#setAudioModeIsVoip(boolean)} - set to {@code true} to ensure that the
196 * platform knows your call is a VoIP call.</li>
197 * <li>For newly created {@link Connection} instances, do NOT change the state of your call
198 * using {@link Connection#setActive()}, {@link Connection#setOnHold()} until the call is added
199 * to Telecom (ie you have returned it via
200 * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
201 * or
202 * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}).
203 * </li>
204 * </ul>
205 *
206 * <h2>How to Place Outgoing Calls</h2>
207 * When your app wants to place an outgoing call it calls
208 * {@link TelecomManager#placeCall(Uri, Bundle)}. You should specify a {@link Uri} to identify
209 * who the call is being placed to, and specify the {@link PhoneAccountHandle} associated with the
210 * {@link PhoneAccount} you registered for your app using
211 * {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} in the {@link Bundle} parameter.
212 * <p>
213 * Telecom will bind to your app's {@link ConnectionService} implementation and call either:
214 * <ul>
215 * <li>{@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
216 * ConnectionRequest)} - the {@link ConnectionRequest#getAddress()} will match the address
217 * you specified when placing the call. You should return a new instance of your app's
218 * {@link Connection} class to represent the outgoing call.</li>
219 * <li>{@link ConnectionService#onCreateOutgoingConnectionFailed(PhoneAccountHandle,
220 * ConnectionRequest)} - your app should not place the call at this time; the call should be
221 * cancelled and the user informed that the call cannot be placed.</li>
222 * </ul>
223 * <p>
224 * New outgoing calls will start in a {@link Connection#STATE_DIALING} state. This state indicates
225 * that your app is in the process of connecting the call to the other party.
226 * <p>
227 * Once the other party answers the call (or it is set up successfully), your app should call
228 * {@link Connection#setActive()} to inform Telecom that the call is now active.
229 *
230 * <h2>How to Add Incoming Calls</h2>
231 * When your app receives an incoming call, it should call
232 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}. Set the
233 * {@link PhoneAccountHandle} parameter to the {@link PhoneAccountHandle} associated with your
234 * app's {@link PhoneAccount}.
235 * <p>
236 * Telecom will bind to your app's {@link ConnectionService} implementation and call either:
237 * <ul>
238 * <li>{@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle,
239 * ConnectionRequest)} - You should return a new instance of your app's
240 * {@link Connection} class to represent the incoming call.</li>
241 * <li>{@link ConnectionService#onCreateIncomingConnectionFailed(PhoneAccountHandle,
242 * ConnectionRequest)} - your app should not receive the call at this time; the call should be
243 * rejected silently; the user may be informed of a missed call.</li>
244 * </ul>
245 * <p>
246 * New incoming calls will start with a {@link Connection#STATE_RINGING} state. This state
247 * indicates that your app has a new incoming call pending. Telecom will NOT play a ringtone or
248 * post a notification for your app. It is up to your app to post an incoming call notification
249 * with an associated ringtone. Telecom will call {@link Connection#onShowIncomingCallUi()} on the
250 * {@link Connection} when your app can post its incoming call notification. See
251 * {@link Connection#onShowIncomingCallUi() the docs} for more information on how to post the
252 * notification.
253 * <p>
254 * Your incoming call notification (or full screen UI) will typically have an "answer" and "decline"
255 * action which the user chooses. When your app receives the "answer" or "decline"
256 * {@link android.app.PendingIntent}, you should must call either {@link Connection#setActive()} to
257 * inform Telecom that the call was answered, or
258 * {@link Connection#setDisconnected(DisconnectCause)} to inform Telecom that the call was rejected.
259 * If the call was rejected, supply an instance of {@link DisconnectCause} with
260 * {@link DisconnectCause#REJECTED}, and then call {@link Connection#destroy()}.
261 * <p>
262 * In addition to handling requests to answer or decline the call via notification actions, your
263 * app should also be implement the {@link Connection#onAnswer(int)} and
264 * {@link Connection#onAnswer()} methods on the {@link Connection}. These will be raised if the
265 * user answers your call via a Bluetooth device or another device like a wearable or automotive
266 * calling UX. In response, your app should call {@link Connection#setActive()} to inform Telecom
267 * that the call was answered.
268 * <p>
269 * Additionally, your app should implement {@link Connection#onReject()} to handle requests to
270 * reject the call which are raised via Bluetooth or other calling surfaces. Your app should call
271 * {@link Connection#setDisconnected(DisconnectCause)} and supply an instance of
272 * {@link DisconnectCause} with {@link DisconnectCause#REJECTED} in this case.
273 *
274 * <h2>Ending Calls</h2>
275 * When an ongoing active call (incoming or outgoing) has ended, your app is responsible for
276 * informing Telecom that the call ended.
277 * <p>
278 * Your app calls:
279 * <ul>
280 * <li>{@link Connection#setDisconnected(DisconnectCause)} - this informs Telecom that the
281 * call has terminated. You should provide a new instance of {@link DisconnectCause} with
282 * either {@link DisconnectCause#LOCAL} or {@link DisconnectCause#REMOTE} to indicate where the
283 * call disconnection took place. {@link DisconnectCause#LOCAL} indicates that the call
284 * terminated in your app on the current device (i.e. via user action), where
285 * {@link DisconnectCause#REMOTE} indicates that the call terminates on the remote device.</li>
286 * <li>{@link Connection#destroy()} - this informs Telecom that your call instance can be
287 * cleaned up. You should always call this when you are finished with a call.</li>
288 * </ul>
289 * <p>
290 * Similar to answering incoming calls, requests to disconnect your call may originate from outside
291 * your app. You can handle these by implementing {@link Connection#onDisconnect()}. Your app
292 * should call {@link Connection#setDisconnected(DisconnectCause)} with an instance of
293 * {@link DisconnectCause} and reason {@link DisconnectCause#LOCAL} to indicate to Telecom that your
294 * app has disconnected the call as requested based on the user's request.
295 *
296 * <h2>Holding and Unholding Calls</h2>
297 * When your app specifies {@link Connection#CAPABILITY_SUPPORT_HOLD} and
298 * {@link Connection#CAPABILITY_HOLD} on your {@link Connection} instance, it is telling Telecom
299 * that your calls can be placed into a suspended, or "held" state if required. If your app
300 * supports holding its calls, it will be possible for the user to switch between calls in your app
301 * and holdable calls in another app or on the mobile network. If your app does not support
302 * holding its calls, you may receive a request to disconnect the call from Telecom if the user
303 * opts to answer an incoming call in another app or on the mobile network; this ensures that the
304 * user can only be in one call at a time.
305 * <p>
306 * Your app is free to change a call between the held and active state using
307 * {@link Connection#setOnHold()} and {@link Connection#setActive()}.
308 * <p>
309 * Your app may receive a request from Telecom to hold or unhold a call via
310 * {@link Connection#onHold()} and {@link Connection#onUnhold()}. Telecom can ask your app to
311 * hold or unhold its {@link Connection} either if the user requests this action through another
312 * calling surface such as Bluetooth, or if the user answers or switches to a call in a different
313 * app or on the mobile network.
314 * <p>
315 * When your app receives an {@link Connection#onHold()} it must call {@link Connection#setOnHold()}
316 * to inform Telecom that the call has been held successfully.
317 * <p>
318 * When your app receives an {@link Connection#onUnhold()} it must call
319 * {@link Connection#setActive()} to inform Telecom that the call has been resumed successfully.
Ihab Awad542e0ea2014-05-16 10:22:16 -0700320 */
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700321public abstract class ConnectionService extends Service {
Santos Cordon5c6fa952014-07-20 17:47:12 -0700322 /**
323 * The {@link Intent} that must be declared as handled by the service.
324 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700325 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700326 public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
Santos Cordon5c6fa952014-07-20 17:47:12 -0700327
Tyler Gunn8bf76572017-04-06 15:30:08 -0700328 /**
329 * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
330 * being asked to create a new outgoing {@link Connection} is to perform a handover of an
331 * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}. Will
332 * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
333 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
334 * <p>
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700335 * When your {@link ConnectionService} receives this extra, it should communicate the fact that
336 * this is a handover to the other device's matching {@link ConnectionService}. That
Tyler Gunn8bf76572017-04-06 15:30:08 -0700337 * {@link ConnectionService} will continue the handover using
338 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700339 * {@link TelecomManager#EXTRA_IS_HANDOVER}. Telecom will match the phone numbers of the
340 * handover call on the other device with ongoing calls for {@link ConnectionService}s which
341 * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700342 * @hide
343 */
344 public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
345
Ihab Awad542e0ea2014-05-16 10:22:16 -0700346 // Flag controlling whether PII is emitted into the logs
Ihab Awad60ac30b2014-05-20 22:32:12 -0700347 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700348
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700349 // Session Definitions
350 private static final String SESSION_HANDLER = "H.";
351 private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
352 private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
353 private static final String SESSION_CREATE_CONN = "CS.crCo";
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700354 private static final String SESSION_CREATE_CONN_COMPLETE = "CS.crCoC";
Tyler Gunn44e01912017-01-31 10:49:05 -0800355 private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700356 private static final String SESSION_ABORT = "CS.ab";
357 private static final String SESSION_ANSWER = "CS.an";
358 private static final String SESSION_ANSWER_VIDEO = "CS.anV";
Pooja Jaind34698d2017-12-28 14:15:31 +0530359 private static final String SESSION_DEFLECT = "CS.def";
Ravi Palurif4b38e72020-02-05 12:35:41 +0530360 private static final String SESSION_TRANSFER = "CS.trans";
361 private static final String SESSION_CONSULTATIVE_TRANSFER = "CS.cTrans";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700362 private static final String SESSION_REJECT = "CS.r";
363 private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
364 private static final String SESSION_SILENCE = "CS.s";
365 private static final String SESSION_DISCONNECT = "CS.d";
366 private static final String SESSION_HOLD = "CS.h";
367 private static final String SESSION_UNHOLD = "CS.u";
368 private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
Grace Jiae99fde92021-01-19 14:58:01 -0800369 private static final String SESSION_USING_ALTERNATIVE_UI = "CS.uAU";
370 private static final String SESSION_TRACKED_BY_NON_UI_SERVICE = "CS.tBNUS";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700371 private static final String SESSION_PLAY_DTMF = "CS.pDT";
372 private static final String SESSION_STOP_DTMF = "CS.sDT";
373 private static final String SESSION_CONFERENCE = "CS.c";
374 private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
375 private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
376 private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
Ravi Paluri404babb2020-01-23 19:02:44 +0530377 private static final String SESSION_ADD_PARTICIPANT = "CS.aP";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700378 private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
379 private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
380 private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
Hall Liu49cabcc2021-01-15 11:41:48 -0800381 private static final String SESSION_CALL_FILTERING_COMPLETED = "CS.oCFC";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800382 private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700383 private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
Hall Liub64ac4c2017-02-06 10:49:48 -0800384 private static final String SESSION_START_RTT = "CS.+RTT";
Hall Liua549fed2018-02-09 16:40:03 -0800385 private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
Hall Liub64ac4c2017-02-06 10:49:48 -0800386 private static final String SESSION_STOP_RTT = "CS.-RTT";
387 private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
Pengquan Meng731c1a32017-11-21 18:01:13 -0800388 private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
389 private static final String SESSION_CONNECTION_SERVICE_FOCUS_GAINED = "CS.cSFG";
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800390 private static final String SESSION_HANDOVER_FAILED = "CS.haF";
Ravi Paluri80aa2142019-12-02 11:57:37 +0530391 private static final String SESSION_CREATE_CONF = "CS.crConf";
392 private static final String SESSION_CREATE_CONF_COMPLETE = "CS.crConfC";
393 private static final String SESSION_CREATE_CONF_FAILED = "CS.crConfF";
Junhoedf3d822022-11-24 09:26:37 +0000394 private static final String SESSION_CALL_ENDPOINT_CHANGED = "CS.oCEC";
395 private static final String SESSION_AVAILABLE_CALL_ENDPOINTS_CHANGED = "CS.oACEC";
396 private static final String SESSION_MUTE_STATE_CHANGED = "CS.oMSC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700397
Ihab Awad8aecfed2014-08-08 17:06:11 -0700398 private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700399 private static final int MSG_CREATE_CONNECTION = 2;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700400 private static final int MSG_ABORT = 3;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700401 private static final int MSG_ANSWER = 4;
402 private static final int MSG_REJECT = 5;
403 private static final int MSG_DISCONNECT = 6;
404 private static final int MSG_HOLD = 7;
405 private static final int MSG_UNHOLD = 8;
Yorke Lee4af59352015-05-13 14:14:54 -0700406 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700407 private static final int MSG_PLAY_DTMF_TONE = 10;
408 private static final int MSG_STOP_DTMF_TONE = 11;
409 private static final int MSG_CONFERENCE = 12;
410 private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700411 private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700412 private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
Tyler Gunnbe74de02014-08-29 14:51:48 -0700413 private static final int MSG_ANSWER_VIDEO = 17;
Santos Cordona4868042014-09-04 17:39:22 -0700414 private static final int MSG_MERGE_CONFERENCE = 18;
415 private static final int MSG_SWAP_CONFERENCE = 19;
Bryce Lee81901682015-08-28 16:38:02 -0700416 private static final int MSG_REJECT_WITH_MESSAGE = 20;
Bryce Leecac50772015-11-17 15:13:29 -0800417 private static final int MSG_SILENCE = 21;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700418 private static final int MSG_PULL_EXTERNAL_CALL = 22;
419 private static final int MSG_SEND_CALL_EVENT = 23;
Tyler Gunndee56a82016-03-23 16:06:34 -0700420 private static final int MSG_ON_EXTRAS_CHANGED = 24;
Tyler Gunn44e01912017-01-31 10:49:05 -0800421 private static final int MSG_CREATE_CONNECTION_FAILED = 25;
Hall Liub64ac4c2017-02-06 10:49:48 -0800422 private static final int MSG_ON_START_RTT = 26;
423 private static final int MSG_ON_STOP_RTT = 27;
424 private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700425 private static final int MSG_CREATE_CONNECTION_COMPLETE = 29;
Pengquan Meng731c1a32017-11-21 18:01:13 -0800426 private static final int MSG_CONNECTION_SERVICE_FOCUS_LOST = 30;
427 private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800428 private static final int MSG_HANDOVER_FAILED = 32;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800429 private static final int MSG_HANDOVER_COMPLETE = 33;
Pooja Jaind34698d2017-12-28 14:15:31 +0530430 private static final int MSG_DEFLECT = 34;
Ravi Paluri80aa2142019-12-02 11:57:37 +0530431 private static final int MSG_CREATE_CONFERENCE = 35;
432 private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
433 private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800434 private static final int MSG_REJECT_WITH_REASON = 38;
Ravi Paluri404babb2020-01-23 19:02:44 +0530435 private static final int MSG_ADD_PARTICIPANT = 39;
Ravi Palurif4b38e72020-02-05 12:35:41 +0530436 private static final int MSG_EXPLICIT_CALL_TRANSFER = 40;
437 private static final int MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE = 41;
Hall Liu49cabcc2021-01-15 11:41:48 -0800438 private static final int MSG_ON_CALL_FILTERING_COMPLETED = 42;
Grace Jiae99fde92021-01-19 14:58:01 -0800439 private static final int MSG_ON_USING_ALTERNATIVE_UI = 43;
440 private static final int MSG_ON_TRACKED_BY_NON_UI_SERVICE = 44;
Junhoedf3d822022-11-24 09:26:37 +0000441 private static final int MSG_ON_CALL_ENDPOINT_CHANGED = 45;
442 private static final int MSG_ON_AVAILABLE_CALL_ENDPOINTS_CHANGED = 46;
443 private static final int MSG_ON_MUTE_STATE_CHANGED = 47;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700444
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700445 private static Connection sNullConnection;
446
mike dooley95e80702014-09-18 14:07:52 -0700447 private final Map<String, Connection> mConnectionById = new ConcurrentHashMap<>();
448 private final Map<Connection, String> mIdByConnection = new ConcurrentHashMap<>();
449 private final Map<String, Conference> mConferenceById = new ConcurrentHashMap<>();
450 private final Map<Conference, String> mIdByConference = new ConcurrentHashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700451 private final RemoteConnectionManager mRemoteConnectionManager =
452 new RemoteConnectionManager(this);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700453 private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700454 private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
Ihab Awad542e0ea2014-05-16 10:22:16 -0700455
Santos Cordon823fd3c2014-08-07 18:35:18 -0700456 private boolean mAreAccountsInitialized = false;
Santos Cordon0159ac02014-08-21 14:28:11 -0700457 private Conference sNullConference;
Tyler Gunnf0500bd2015-09-01 10:59:48 -0700458 private Object mIdSyncRoot = new Object();
459 private int mId = 0;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700460
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700461 private final IBinder mBinder = new IConnectionService.Stub() {
462 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700463 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
464 Session.Info sessionInfo) {
465 Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
466 try {
467 SomeArgs args = SomeArgs.obtain();
468 args.arg1 = adapter;
469 args.arg2 = Log.createSubsession();
470 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
471 } finally {
472 Log.endSession();
473 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700474 }
475
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700476 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
477 Session.Info sessionInfo) {
478 Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
479 try {
480 SomeArgs args = SomeArgs.obtain();
481 args.arg1 = adapter;
482 args.arg2 = Log.createSubsession();
483 mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
484 } finally {
485 Log.endSession();
486 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700487 }
488
489 @Override
Ihab Awadf8b69882014-07-25 15:14:01 -0700490 public void createConnection(
491 PhoneAccountHandle connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700492 String id,
Ihab Awadf8b69882014-07-25 15:14:01 -0700493 ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700494 boolean isIncoming,
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700495 boolean isUnknown,
496 Session.Info sessionInfo) {
497 Log.startSession(sessionInfo, SESSION_CREATE_CONN);
498 try {
499 SomeArgs args = SomeArgs.obtain();
500 args.arg1 = connectionManagerPhoneAccount;
501 args.arg2 = id;
502 args.arg3 = request;
503 args.arg4 = Log.createSubsession();
504 args.argi1 = isIncoming ? 1 : 0;
505 args.argi2 = isUnknown ? 1 : 0;
506 mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
507 } finally {
508 Log.endSession();
509 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700510 }
511
512 @Override
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700513 public void createConnectionComplete(String id, Session.Info sessionInfo) {
514 Log.startSession(sessionInfo, SESSION_CREATE_CONN_COMPLETE);
515 try {
516 SomeArgs args = SomeArgs.obtain();
517 args.arg1 = id;
518 args.arg2 = Log.createSubsession();
519 mHandler.obtainMessage(MSG_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
520 } finally {
521 Log.endSession();
522 }
523 }
524
525 @Override
Tyler Gunn44e01912017-01-31 10:49:05 -0800526 public void createConnectionFailed(
Tyler Gunn159f35c2017-03-02 09:28:37 -0800527 PhoneAccountHandle connectionManagerPhoneAccount,
Tyler Gunn44e01912017-01-31 10:49:05 -0800528 String callId,
529 ConnectionRequest request,
530 boolean isIncoming,
531 Session.Info sessionInfo) {
532 Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
533 try {
534 SomeArgs args = SomeArgs.obtain();
535 args.arg1 = callId;
536 args.arg2 = request;
537 args.arg3 = Log.createSubsession();
Tyler Gunn159f35c2017-03-02 09:28:37 -0800538 args.arg4 = connectionManagerPhoneAccount;
Tyler Gunn44e01912017-01-31 10:49:05 -0800539 args.argi1 = isIncoming ? 1 : 0;
540 mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
541 } finally {
542 Log.endSession();
543 }
544 }
545
546 @Override
Ravi Paluri80aa2142019-12-02 11:57:37 +0530547 public void createConference(
548 PhoneAccountHandle connectionManagerPhoneAccount,
549 String id,
550 ConnectionRequest request,
551 boolean isIncoming,
552 boolean isUnknown,
553 Session.Info sessionInfo) {
554 Log.startSession(sessionInfo, SESSION_CREATE_CONF);
555 try {
556 SomeArgs args = SomeArgs.obtain();
557 args.arg1 = connectionManagerPhoneAccount;
558 args.arg2 = id;
559 args.arg3 = request;
560 args.arg4 = Log.createSubsession();
561 args.argi1 = isIncoming ? 1 : 0;
562 args.argi2 = isUnknown ? 1 : 0;
563 mHandler.obtainMessage(MSG_CREATE_CONFERENCE, args).sendToTarget();
564 } finally {
565 Log.endSession();
566 }
567 }
568
569 @Override
570 public void createConferenceComplete(String id, Session.Info sessionInfo) {
571 Log.startSession(sessionInfo, SESSION_CREATE_CONF_COMPLETE);
572 try {
573 SomeArgs args = SomeArgs.obtain();
574 args.arg1 = id;
575 args.arg2 = Log.createSubsession();
576 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_COMPLETE, args).sendToTarget();
577 } finally {
578 Log.endSession();
579 }
580 }
581
582 @Override
583 public void createConferenceFailed(
584 PhoneAccountHandle connectionManagerPhoneAccount,
585 String callId,
586 ConnectionRequest request,
587 boolean isIncoming,
588 Session.Info sessionInfo) {
589 Log.startSession(sessionInfo, SESSION_CREATE_CONF_FAILED);
590 try {
591 SomeArgs args = SomeArgs.obtain();
592 args.arg1 = callId;
593 args.arg2 = request;
594 args.arg3 = Log.createSubsession();
595 args.arg4 = connectionManagerPhoneAccount;
596 args.argi1 = isIncoming ? 1 : 0;
597 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_FAILED, args).sendToTarget();
598 } finally {
599 Log.endSession();
600 }
601 }
602
603 @Override
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800604 public void handoverFailed(String callId, ConnectionRequest request, int reason,
605 Session.Info sessionInfo) {
606 Log.startSession(sessionInfo, SESSION_HANDOVER_FAILED);
607 try {
608 SomeArgs args = SomeArgs.obtain();
609 args.arg1 = callId;
610 args.arg2 = request;
611 args.arg3 = Log.createSubsession();
612 args.arg4 = reason;
613 mHandler.obtainMessage(MSG_HANDOVER_FAILED, args).sendToTarget();
614 } finally {
615 Log.endSession();
616 }
617 }
618
619 @Override
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800620 public void handoverComplete(String callId, Session.Info sessionInfo) {
621 Log.startSession(sessionInfo, SESSION_HANDOVER_COMPLETE);
622 try {
623 SomeArgs args = SomeArgs.obtain();
624 args.arg1 = callId;
625 args.arg2 = Log.createSubsession();
626 mHandler.obtainMessage(MSG_HANDOVER_COMPLETE, args).sendToTarget();
627 } finally {
628 Log.endSession();
629 }
630 }
631
632 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700633 public void abort(String callId, Session.Info sessionInfo) {
634 Log.startSession(sessionInfo, SESSION_ABORT);
635 try {
636 SomeArgs args = SomeArgs.obtain();
637 args.arg1 = callId;
638 args.arg2 = Log.createSubsession();
639 mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
640 } finally {
641 Log.endSession();
642 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700643 }
644
645 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700646 public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
647 Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
648 try {
649 SomeArgs args = SomeArgs.obtain();
650 args.arg1 = callId;
651 args.arg2 = Log.createSubsession();
652 args.argi1 = videoState;
653 mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
654 } finally {
655 Log.endSession();
656 }
Tyler Gunnbe74de02014-08-29 14:51:48 -0700657 }
658
659 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700660 public void answer(String callId, Session.Info sessionInfo) {
661 Log.startSession(sessionInfo, SESSION_ANSWER);
662 try {
663 SomeArgs args = SomeArgs.obtain();
664 args.arg1 = callId;
665 args.arg2 = Log.createSubsession();
666 mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
667 } finally {
668 Log.endSession();
669 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700670 }
671
672 @Override
Pooja Jaind34698d2017-12-28 14:15:31 +0530673 public void deflect(String callId, Uri address, Session.Info sessionInfo) {
674 Log.startSession(sessionInfo, SESSION_DEFLECT);
675 try {
676 SomeArgs args = SomeArgs.obtain();
677 args.arg1 = callId;
678 args.arg2 = address;
679 args.arg3 = Log.createSubsession();
680 mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
681 } finally {
682 Log.endSession();
683 }
684 }
685
686 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700687 public void reject(String callId, Session.Info sessionInfo) {
688 Log.startSession(sessionInfo, SESSION_REJECT);
689 try {
690 SomeArgs args = SomeArgs.obtain();
691 args.arg1 = callId;
692 args.arg2 = Log.createSubsession();
693 mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
694 } finally {
695 Log.endSession();
696 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700697 }
698
699 @Override
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800700 public void rejectWithReason(String callId,
701 @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
702 Log.startSession(sessionInfo, SESSION_REJECT);
703 try {
704 SomeArgs args = SomeArgs.obtain();
705 args.arg1 = callId;
706 args.argi1 = rejectReason;
707 args.arg2 = Log.createSubsession();
708 mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
709 } finally {
710 Log.endSession();
711 }
712 }
713
714 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700715 public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
716 Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
717 try {
718 SomeArgs args = SomeArgs.obtain();
719 args.arg1 = callId;
720 args.arg2 = message;
721 args.arg3 = Log.createSubsession();
722 mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
723 } finally {
724 Log.endSession();
725 }
Bryce Lee81901682015-08-28 16:38:02 -0700726 }
727
728 @Override
Ravi Palurif4b38e72020-02-05 12:35:41 +0530729 public void transfer(@NonNull String callId, @NonNull Uri number,
730 boolean isConfirmationRequired, Session.Info sessionInfo) {
731 Log.startSession(sessionInfo, SESSION_TRANSFER);
732 try {
733 SomeArgs args = SomeArgs.obtain();
734 args.arg1 = callId;
735 args.arg2 = number;
736 args.argi1 = isConfirmationRequired ? 1 : 0;
737 args.arg3 = Log.createSubsession();
738 mHandler.obtainMessage(MSG_EXPLICIT_CALL_TRANSFER, args).sendToTarget();
739 } finally {
740 Log.endSession();
741 }
742 }
743
744 @Override
745 public void consultativeTransfer(@NonNull String callId, @NonNull String otherCallId,
746 Session.Info sessionInfo) {
747 Log.startSession(sessionInfo, SESSION_CONSULTATIVE_TRANSFER);
748 try {
749 SomeArgs args = SomeArgs.obtain();
750 args.arg1 = callId;
751 args.arg2 = otherCallId;
752 args.arg3 = Log.createSubsession();
753 mHandler.obtainMessage(
754 MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE, args).sendToTarget();
755 } finally {
756 Log.endSession();
757 }
758 }
759
760 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700761 public void silence(String callId, Session.Info sessionInfo) {
762 Log.startSession(sessionInfo, SESSION_SILENCE);
763 try {
764 SomeArgs args = SomeArgs.obtain();
765 args.arg1 = callId;
766 args.arg2 = Log.createSubsession();
767 mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
768 } finally {
769 Log.endSession();
770 }
Bryce Leecac50772015-11-17 15:13:29 -0800771 }
772
773 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700774 public void disconnect(String callId, Session.Info sessionInfo) {
775 Log.startSession(sessionInfo, SESSION_DISCONNECT);
776 try {
777 SomeArgs args = SomeArgs.obtain();
778 args.arg1 = callId;
779 args.arg2 = Log.createSubsession();
780 mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
781 } finally {
782 Log.endSession();
783 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700784 }
785
786 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700787 public void hold(String callId, Session.Info sessionInfo) {
788 Log.startSession(sessionInfo, SESSION_HOLD);
789 try {
790 SomeArgs args = SomeArgs.obtain();
791 args.arg1 = callId;
792 args.arg2 = Log.createSubsession();
793 mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
794 } finally {
795 Log.endSession();
796 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700797 }
798
799 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700800 public void unhold(String callId, Session.Info sessionInfo) {
801 Log.startSession(sessionInfo, SESSION_UNHOLD);
802 try {
803 SomeArgs args = SomeArgs.obtain();
804 args.arg1 = callId;
805 args.arg2 = Log.createSubsession();
806 mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
807 } finally {
808 Log.endSession();
809 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700810 }
811
812 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700813 public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
814 Session.Info sessionInfo) {
815 Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
816 try {
817 SomeArgs args = SomeArgs.obtain();
818 args.arg1 = callId;
819 args.arg2 = callAudioState;
820 args.arg3 = Log.createSubsession();
821 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
822 } finally {
823 Log.endSession();
824 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700825 }
826
827 @Override
Junhoedf3d822022-11-24 09:26:37 +0000828 public void onCallEndpointChanged(String callId, CallEndpoint callEndpoint,
829 Session.Info sessionInfo) {
830 Log.startSession(sessionInfo, SESSION_CALL_ENDPOINT_CHANGED);
831 try {
832 SomeArgs args = SomeArgs.obtain();
833 args.arg1 = callId;
834 args.arg2 = callEndpoint;
835 args.arg3 = Log.createSubsession();
836 mHandler.obtainMessage(MSG_ON_CALL_ENDPOINT_CHANGED, args).sendToTarget();
837 } finally {
838 Log.endSession();
839 }
840 }
841
842 @Override
843 public void onAvailableCallEndpointsChanged(String callId,
844 List<CallEndpoint> availableCallEndpoints, Session.Info sessionInfo) {
845 Log.startSession(sessionInfo, SESSION_AVAILABLE_CALL_ENDPOINTS_CHANGED);
846 try {
847 SomeArgs args = SomeArgs.obtain();
848 args.arg1 = callId;
849 args.arg2 = availableCallEndpoints;
850 args.arg3 = Log.createSubsession();
851 mHandler.obtainMessage(MSG_ON_AVAILABLE_CALL_ENDPOINTS_CHANGED, args)
852 .sendToTarget();
853 } finally {
854 Log.endSession();
855 }
856 }
857
858 @Override
859 public void onMuteStateChanged(String callId, boolean isMuted, Session.Info sessionInfo) {
860 Log.startSession(sessionInfo, SESSION_MUTE_STATE_CHANGED);
861 try {
862 SomeArgs args = SomeArgs.obtain();
863 args.arg1 = callId;
864 args.arg2 = isMuted;
865 args.arg3 = Log.createSubsession();
866 mHandler.obtainMessage(MSG_ON_MUTE_STATE_CHANGED, args).sendToTarget();
867 } finally {
868 Log.endSession();
869 }
870 }
871
872 @Override
Grace Jiae99fde92021-01-19 14:58:01 -0800873 public void onUsingAlternativeUi(String callId, boolean usingAlternativeUiShowing,
874 Session.Info sessionInfo) {
875 Log.startSession(sessionInfo, SESSION_USING_ALTERNATIVE_UI);
876 try {
877 SomeArgs args = SomeArgs.obtain();
878 args.arg1 = callId;
879 args.arg2 = usingAlternativeUiShowing;
880 args.arg3 = Log.createSubsession();
881 mHandler.obtainMessage(MSG_ON_USING_ALTERNATIVE_UI, args).sendToTarget();
882 } finally {
883 Log.endSession();
884 }
885 }
886
887 @Override
888 public void onTrackedByNonUiService(String callId, boolean isTracked,
889 Session.Info sessionInfo) {
890 Log.startSession(sessionInfo, SESSION_TRACKED_BY_NON_UI_SERVICE);
891 try {
892 SomeArgs args = SomeArgs.obtain();
893 args.arg1 = callId;
894 args.arg2 = isTracked;
895 args.arg3 = Log.createSubsession();
896 mHandler.obtainMessage(MSG_ON_TRACKED_BY_NON_UI_SERVICE, args).sendToTarget();
897 } finally {
898 Log.endSession();
899 }
900 }
901
902 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700903 public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
904 Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
905 try {
906 SomeArgs args = SomeArgs.obtain();
907 args.arg1 = digit;
908 args.arg2 = callId;
909 args.arg3 = Log.createSubsession();
910 mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, args).sendToTarget();
911 } finally {
912 Log.endSession();
913 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700914 }
915
916 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700917 public void stopDtmfTone(String callId, Session.Info sessionInfo) {
918 Log.startSession(sessionInfo, SESSION_STOP_DTMF);
919 try {
920 SomeArgs args = SomeArgs.obtain();
921 args.arg1 = callId;
922 args.arg2 = Log.createSubsession();
923 mHandler.obtainMessage(MSG_STOP_DTMF_TONE, args).sendToTarget();
924 } finally {
925 Log.endSession();
926 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700927 }
928
929 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700930 public void conference(String callId1, String callId2, Session.Info sessionInfo) {
931 Log.startSession(sessionInfo, SESSION_CONFERENCE);
932 try {
933 SomeArgs args = SomeArgs.obtain();
934 args.arg1 = callId1;
935 args.arg2 = callId2;
936 args.arg3 = Log.createSubsession();
937 mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
938 } finally {
939 Log.endSession();
940 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700941 }
942
943 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700944 public void splitFromConference(String callId, Session.Info sessionInfo) {
945 Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
946 try {
947 SomeArgs args = SomeArgs.obtain();
948 args.arg1 = callId;
949 args.arg2 = Log.createSubsession();
950 mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
951 } finally {
952 Log.endSession();
953 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700954 }
955
956 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700957 public void mergeConference(String callId, Session.Info sessionInfo) {
958 Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
959 try {
960 SomeArgs args = SomeArgs.obtain();
961 args.arg1 = callId;
962 args.arg2 = Log.createSubsession();
963 mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
964 } finally {
965 Log.endSession();
966 }
Santos Cordona4868042014-09-04 17:39:22 -0700967 }
968
969 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700970 public void swapConference(String callId, Session.Info sessionInfo) {
971 Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
972 try {
973 SomeArgs args = SomeArgs.obtain();
974 args.arg1 = callId;
975 args.arg2 = Log.createSubsession();
976 mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
977 } finally {
978 Log.endSession();
979 }
Santos Cordona4868042014-09-04 17:39:22 -0700980 }
981
982 @Override
Ravi Paluri404babb2020-01-23 19:02:44 +0530983 public void addConferenceParticipants(String callId, List<Uri> participants,
984 Session.Info sessionInfo) {
985 Log.startSession(sessionInfo, SESSION_ADD_PARTICIPANT);
986 try {
987 SomeArgs args = SomeArgs.obtain();
988 args.arg1 = callId;
989 args.arg2 = participants;
990 args.arg3 = Log.createSubsession();
991 mHandler.obtainMessage(MSG_ADD_PARTICIPANT, args).sendToTarget();
992 } finally {
993 Log.endSession();
994 }
995 }
996
997 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700998 public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
999 Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
1000 try {
1001 SomeArgs args = SomeArgs.obtain();
1002 args.arg1 = callId;
1003 args.arg2 = Log.createSubsession();
1004 args.argi1 = proceed ? 1 : 0;
1005 mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
1006 } finally {
1007 Log.endSession();
1008 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001009 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001010
1011 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001012 public void pullExternalCall(String callId, Session.Info sessionInfo) {
1013 Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
1014 try {
1015 SomeArgs args = SomeArgs.obtain();
1016 args.arg1 = callId;
1017 args.arg2 = Log.createSubsession();
1018 mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
1019 } finally {
1020 Log.endSession();
1021 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001022 }
1023
1024 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001025 public void sendCallEvent(String callId, String event, Bundle extras,
1026 Session.Info sessionInfo) {
1027 Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
1028 try {
1029 SomeArgs args = SomeArgs.obtain();
1030 args.arg1 = callId;
1031 args.arg2 = event;
1032 args.arg3 = extras;
1033 args.arg4 = Log.createSubsession();
1034 mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
1035 } finally {
1036 Log.endSession();
1037 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001038 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001039
1040 @Override
Hall Liu73903142021-02-18 18:41:41 -08001041 public void onCallFilteringCompleted(String callId,
1042 Connection.CallFilteringCompletionInfo completionInfo,
Hall Liu49cabcc2021-01-15 11:41:48 -08001043 Session.Info sessionInfo) {
1044 Log.startSession(sessionInfo, SESSION_CALL_FILTERING_COMPLETED);
1045 try {
1046 SomeArgs args = SomeArgs.obtain();
1047 args.arg1 = callId;
Hall Liu73903142021-02-18 18:41:41 -08001048 args.arg2 = completionInfo;
1049 args.arg3 = Log.createSubsession();
Hall Liu49cabcc2021-01-15 11:41:48 -08001050 mHandler.obtainMessage(MSG_ON_CALL_FILTERING_COMPLETED, args).sendToTarget();
1051 } finally {
1052 Log.endSession();
1053 }
1054 }
1055
1056 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001057 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
1058 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
1059 try {
1060 SomeArgs args = SomeArgs.obtain();
1061 args.arg1 = callId;
1062 args.arg2 = extras;
1063 args.arg3 = Log.createSubsession();
1064 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
1065 } finally {
1066 Log.endSession();
1067 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001068 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001069
1070 @Override
1071 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
1072 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
1073 Log.startSession(sessionInfo, SESSION_START_RTT);
1074 try {
1075 SomeArgs args = SomeArgs.obtain();
1076 args.arg1 = callId;
1077 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
1078 args.arg3 = Log.createSubsession();
1079 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
1080 } finally {
1081 Log.endSession();
1082 }
1083 }
1084
1085 @Override
1086 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
1087 Log.startSession(sessionInfo, SESSION_STOP_RTT);
1088 try {
1089 SomeArgs args = SomeArgs.obtain();
1090 args.arg1 = callId;
1091 args.arg2 = Log.createSubsession();
1092 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
1093 } finally {
1094 Log.endSession();
1095 }
1096 }
1097
1098 @Override
1099 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
1100 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
1101 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
1102 try {
1103 SomeArgs args = SomeArgs.obtain();
1104 args.arg1 = callId;
1105 if (toInCall == null || fromInCall == null) {
1106 args.arg2 = null;
1107 } else {
1108 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
1109 }
1110 args.arg3 = Log.createSubsession();
1111 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
1112 } finally {
1113 Log.endSession();
1114 }
1115 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001116
1117 @Override
1118 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
1119 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
1120 try {
1121 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
1122 } finally {
1123 Log.endSession();
1124 }
1125 }
1126
1127 @Override
1128 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
1129 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
1130 try {
1131 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
1132 } finally {
1133 Log.endSession();
1134 }
1135 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001136 };
1137
1138 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
1139 @Override
1140 public void handleMessage(Message msg) {
1141 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001142 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
1143 SomeArgs args = (SomeArgs) msg.obj;
1144 try {
1145 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
1146 Log.continueSession((Session) args.arg2,
1147 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
1148 mAdapter.addAdapter(adapter);
1149 onAdapterAttached();
1150 } finally {
1151 args.recycle();
1152 Log.endSession();
1153 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001154 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001155 }
1156 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
1157 SomeArgs args = (SomeArgs) msg.obj;
1158 try {
1159 Log.continueSession((Session) args.arg2,
1160 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
1161 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
1162 } finally {
1163 args.recycle();
1164 Log.endSession();
1165 }
Ihab Awad8aecfed2014-08-08 17:06:11 -07001166 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001167 }
Ihab Awadf8b69882014-07-25 15:14:01 -07001168 case MSG_CREATE_CONNECTION: {
1169 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001170 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -07001171 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -07001172 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -07001173 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001174 final String id = (String) args.arg2;
1175 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -07001176 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -07001177 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -07001178 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001179 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -07001180 mPreInitializationConnectionRequests.add(
1181 new android.telecom.Logging.Runnable(
1182 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
1183 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -07001184 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07001185 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -07001186 createConnection(
1187 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001188 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -07001189 request,
Yorke Leec3cf9822014-10-02 09:38:39 -07001190 isIncoming,
1191 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -07001192 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07001193 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -07001194 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001195 createConnection(
1196 connectionManagerPhoneAccount,
1197 id,
1198 request,
Yorke Leec3cf9822014-10-02 09:38:39 -07001199 isIncoming,
1200 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -07001201 }
Ihab Awadf8b69882014-07-25 15:14:01 -07001202 } finally {
1203 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001204 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -07001205 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001206 break;
Ihab Awadf8b69882014-07-25 15:14:01 -07001207 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07001208 case MSG_CREATE_CONNECTION_COMPLETE: {
1209 SomeArgs args = (SomeArgs) msg.obj;
1210 Log.continueSession((Session) args.arg2,
1211 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1212 try {
1213 final String id = (String) args.arg1;
1214 if (!mAreAccountsInitialized) {
1215 Log.d(this, "Enqueueing pre-init request %s", id);
1216 mPreInitializationConnectionRequests.add(
1217 new android.telecom.Logging.Runnable(
1218 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
1219 + ".pICR",
1220 null /*lock*/) {
1221 @Override
1222 public void loggedRun() {
1223 notifyCreateConnectionComplete(id);
1224 }
1225 }.prepare());
1226 } else {
1227 notifyCreateConnectionComplete(id);
1228 }
1229 } finally {
1230 args.recycle();
1231 Log.endSession();
1232 }
1233 break;
1234 }
Tyler Gunn44e01912017-01-31 10:49:05 -08001235 case MSG_CREATE_CONNECTION_FAILED: {
1236 SomeArgs args = (SomeArgs) msg.obj;
1237 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1238 SESSION_CREATE_CONN_FAILED);
1239 try {
1240 final String id = (String) args.arg1;
1241 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1242 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -08001243 final PhoneAccountHandle connectionMgrPhoneAccount =
1244 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -08001245 if (!mAreAccountsInitialized) {
1246 Log.d(this, "Enqueueing pre-init request %s", id);
1247 mPreInitializationConnectionRequests.add(
1248 new android.telecom.Logging.Runnable(
1249 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
1250 null /*lock*/) {
1251 @Override
1252 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -08001253 createConnectionFailed(connectionMgrPhoneAccount, id,
1254 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -08001255 }
1256 }.prepare());
1257 } else {
1258 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -08001259 createConnectionFailed(connectionMgrPhoneAccount, id, request,
1260 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -08001261 }
1262 } finally {
1263 args.recycle();
1264 Log.endSession();
1265 }
1266 break;
1267 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301268 case MSG_CREATE_CONFERENCE: {
1269 SomeArgs args = (SomeArgs) msg.obj;
1270 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
1271 try {
1272 final PhoneAccountHandle connectionManagerPhoneAccount =
1273 (PhoneAccountHandle) args.arg1;
1274 final String id = (String) args.arg2;
1275 final ConnectionRequest request = (ConnectionRequest) args.arg3;
1276 final boolean isIncoming = args.argi1 == 1;
1277 final boolean isUnknown = args.argi2 == 1;
1278 if (!mAreAccountsInitialized) {
1279 Log.d(this, "Enqueueing pre-initconference request %s", id);
1280 mPreInitializationConnectionRequests.add(
1281 new android.telecom.Logging.Runnable(
1282 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
1283 null /*lock*/) {
1284 @Override
1285 public void loggedRun() {
1286 createConference(connectionManagerPhoneAccount,
1287 id,
1288 request,
1289 isIncoming,
1290 isUnknown);
1291 }
1292 }.prepare());
1293 } else {
1294 createConference(connectionManagerPhoneAccount,
1295 id,
1296 request,
1297 isIncoming,
1298 isUnknown);
1299 }
1300 } finally {
1301 args.recycle();
1302 Log.endSession();
1303 }
1304 break;
1305 }
1306 case MSG_CREATE_CONFERENCE_COMPLETE: {
1307 SomeArgs args = (SomeArgs) msg.obj;
1308 Log.continueSession((Session) args.arg2,
1309 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1310 try {
1311 final String id = (String) args.arg1;
1312 if (!mAreAccountsInitialized) {
1313 Log.d(this, "Enqueueing pre-init conference request %s", id);
1314 mPreInitializationConnectionRequests.add(
1315 new android.telecom.Logging.Runnable(
1316 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
1317 + ".pIConfR",
1318 null /*lock*/) {
1319 @Override
1320 public void loggedRun() {
1321 notifyCreateConferenceComplete(id);
1322 }
1323 }.prepare());
1324 } else {
1325 notifyCreateConferenceComplete(id);
1326 }
1327 } finally {
1328 args.recycle();
1329 Log.endSession();
1330 }
1331 break;
1332 }
1333 case MSG_CREATE_CONFERENCE_FAILED: {
1334 SomeArgs args = (SomeArgs) msg.obj;
1335 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1336 SESSION_CREATE_CONN_FAILED);
1337 try {
1338 final String id = (String) args.arg1;
1339 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1340 final boolean isIncoming = args.argi1 == 1;
1341 final PhoneAccountHandle connectionMgrPhoneAccount =
1342 (PhoneAccountHandle) args.arg4;
1343 if (!mAreAccountsInitialized) {
1344 Log.d(this, "Enqueueing pre-init conference request %s", id);
1345 mPreInitializationConnectionRequests.add(
1346 new android.telecom.Logging.Runnable(
1347 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
1348 + ".pIConfR",
1349 null /*lock*/) {
1350 @Override
1351 public void loggedRun() {
1352 createConferenceFailed(connectionMgrPhoneAccount, id,
1353 request, isIncoming);
1354 }
1355 }.prepare());
1356 } else {
1357 Log.i(this, "createConferenceFailed %s", id);
1358 createConferenceFailed(connectionMgrPhoneAccount, id, request,
1359 isIncoming);
1360 }
1361 } finally {
1362 args.recycle();
1363 Log.endSession();
1364 }
1365 break;
1366 }
1367
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001368 case MSG_HANDOVER_FAILED: {
1369 SomeArgs args = (SomeArgs) msg.obj;
1370 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1371 SESSION_HANDOVER_FAILED);
1372 try {
1373 final String id = (String) args.arg1;
1374 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1375 final int reason = (int) args.arg4;
1376 if (!mAreAccountsInitialized) {
1377 Log.d(this, "Enqueueing pre-init request %s", id);
1378 mPreInitializationConnectionRequests.add(
1379 new android.telecom.Logging.Runnable(
1380 SESSION_HANDLER
1381 + SESSION_HANDOVER_FAILED + ".pICR",
1382 null /*lock*/) {
1383 @Override
1384 public void loggedRun() {
1385 handoverFailed(id, request, reason);
1386 }
1387 }.prepare());
1388 } else {
1389 Log.i(this, "createConnectionFailed %s", id);
1390 handoverFailed(id, request, reason);
1391 }
1392 } finally {
1393 args.recycle();
1394 Log.endSession();
1395 }
1396 break;
1397 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001398 case MSG_ABORT: {
1399 SomeArgs args = (SomeArgs) msg.obj;
1400 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1401 try {
1402 abort((String) args.arg1);
1403 } finally {
1404 args.recycle();
1405 Log.endSession();
1406 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001407 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001408 }
1409 case MSG_ANSWER: {
1410 SomeArgs args = (SomeArgs) msg.obj;
1411 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1412 try {
1413 answer((String) args.arg1);
1414 } finally {
1415 args.recycle();
1416 Log.endSession();
1417 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001418 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001419 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001420 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001421 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001422 Log.continueSession((Session) args.arg2,
1423 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001424 try {
1425 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001426 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001427 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001428 } finally {
1429 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001430 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001431 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001432 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001433 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301434 case MSG_DEFLECT: {
1435 SomeArgs args = (SomeArgs) msg.obj;
1436 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1437 try {
1438 deflect((String) args.arg1, (Uri) args.arg2);
1439 } finally {
1440 args.recycle();
1441 Log.endSession();
1442 }
1443 break;
1444 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001445 case MSG_REJECT: {
1446 SomeArgs args = (SomeArgs) msg.obj;
1447 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1448 try {
1449 reject((String) args.arg1);
1450 } finally {
1451 args.recycle();
1452 Log.endSession();
1453 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001454 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001455 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001456 case MSG_REJECT_WITH_REASON: {
1457 SomeArgs args = (SomeArgs) msg.obj;
1458 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1459 try {
1460 reject((String) args.arg1, args.argi1);
1461 } finally {
1462 args.recycle();
1463 Log.endSession();
1464 }
1465 break;
1466 }
Bryce Lee81901682015-08-28 16:38:02 -07001467 case MSG_REJECT_WITH_MESSAGE: {
1468 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001469 Log.continueSession((Session) args.arg3,
1470 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001471 try {
1472 reject((String) args.arg1, (String) args.arg2);
1473 } finally {
1474 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001475 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001476 }
1477 break;
1478 }
Ravi Palurif4b38e72020-02-05 12:35:41 +05301479 case MSG_EXPLICIT_CALL_TRANSFER: {
1480 SomeArgs args = (SomeArgs) msg.obj;
1481 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_TRANSFER);
1482 try {
1483 final boolean isConfirmationRequired = args.argi1 == 1;
1484 transfer((String) args.arg1, (Uri) args.arg2, isConfirmationRequired);
1485 } finally {
1486 args.recycle();
1487 Log.endSession();
1488 }
1489 break;
1490 }
1491 case MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE: {
1492 SomeArgs args = (SomeArgs) msg.obj;
1493 Log.continueSession(
1494 (Session) args.arg3, SESSION_HANDLER + SESSION_CONSULTATIVE_TRANSFER);
1495 try {
1496 consultativeTransfer((String) args.arg1, (String) args.arg2);
1497 } finally {
1498 args.recycle();
1499 Log.endSession();
1500 }
1501 break;
1502 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001503 case MSG_DISCONNECT: {
1504 SomeArgs args = (SomeArgs) msg.obj;
1505 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1506 try {
1507 disconnect((String) args.arg1);
1508 } finally {
1509 args.recycle();
1510 Log.endSession();
1511 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001512 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001513 }
1514 case MSG_SILENCE: {
1515 SomeArgs args = (SomeArgs) msg.obj;
1516 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1517 try {
1518 silence((String) args.arg1);
1519 } finally {
1520 args.recycle();
1521 Log.endSession();
1522 }
Bryce Leecac50772015-11-17 15:13:29 -08001523 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001524 }
1525 case MSG_HOLD: {
1526 SomeArgs args = (SomeArgs) msg.obj;
1527 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1528 try {
1529 hold((String) args.arg1);
1530 } finally {
1531 args.recycle();
1532 Log.endSession();
1533 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001534 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001535 }
1536 case MSG_UNHOLD: {
1537 SomeArgs args = (SomeArgs) msg.obj;
1538 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1539 try {
1540 unhold((String) args.arg1);
1541 } finally {
1542 args.recycle();
1543 Log.endSession();
1544 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001545 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001546 }
Yorke Lee4af59352015-05-13 14:14:54 -07001547 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001548 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001549 Log.continueSession((Session) args.arg3,
1550 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001551 try {
1552 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001553 CallAudioState audioState = (CallAudioState) args.arg2;
1554 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001555 } finally {
1556 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001557 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001558 }
1559 break;
1560 }
Grace Jiae99fde92021-01-19 14:58:01 -08001561 case MSG_ON_USING_ALTERNATIVE_UI: {
1562 SomeArgs args = (SomeArgs) msg.obj;
1563 Log.continueSession((Session) args.arg3,
1564 SESSION_HANDLER + SESSION_USING_ALTERNATIVE_UI);
1565 try {
1566 String callId = (String) args.arg1;
1567 boolean isUsingAlternativeUi = (boolean) args.arg2;
1568 onUsingAlternativeUi(callId, isUsingAlternativeUi);
1569 } finally {
1570 args.recycle();
1571 Log.endSession();
1572 }
1573 break;
1574 }
1575 case MSG_ON_TRACKED_BY_NON_UI_SERVICE: {
1576 SomeArgs args = (SomeArgs) msg.obj;
1577 Log.continueSession((Session) args.arg3,
1578 SESSION_HANDLER + SESSION_TRACKED_BY_NON_UI_SERVICE);
1579 try {
1580 String callId = (String) args.arg1;
1581 boolean isTracked = (boolean) args.arg2;
1582 onTrackedByNonUiService(callId, isTracked);
1583 } finally {
1584 args.recycle();
1585 Log.endSession();
1586 }
1587 break;
1588 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001589 case MSG_PLAY_DTMF_TONE: {
1590 SomeArgs args = (SomeArgs) msg.obj;
1591 try {
1592 Log.continueSession((Session) args.arg3,
1593 SESSION_HANDLER + SESSION_PLAY_DTMF);
1594 playDtmfTone((String) args.arg2, (char) args.arg1);
1595 } finally {
1596 args.recycle();
1597 Log.endSession();
1598 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001599 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001600 }
1601 case MSG_STOP_DTMF_TONE: {
1602 SomeArgs args = (SomeArgs) msg.obj;
1603 try {
1604 Log.continueSession((Session) args.arg2,
1605 SESSION_HANDLER + SESSION_STOP_DTMF);
1606 stopDtmfTone((String) args.arg1);
1607 } finally {
1608 args.recycle();
1609 Log.endSession();
1610 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001611 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001612 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001613 case MSG_CONFERENCE: {
1614 SomeArgs args = (SomeArgs) msg.obj;
1615 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001616 Log.continueSession((Session) args.arg3,
1617 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001618 String callId1 = (String) args.arg1;
1619 String callId2 = (String) args.arg2;
1620 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001621 } finally {
1622 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001623 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001624 }
1625 break;
1626 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001627 case MSG_SPLIT_FROM_CONFERENCE: {
1628 SomeArgs args = (SomeArgs) msg.obj;
1629 try {
1630 Log.continueSession((Session) args.arg2,
1631 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1632 splitFromConference((String) args.arg1);
1633 } finally {
1634 args.recycle();
1635 Log.endSession();
1636 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001637 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001638 }
1639 case MSG_MERGE_CONFERENCE: {
1640 SomeArgs args = (SomeArgs) msg.obj;
1641 try {
1642 Log.continueSession((Session) args.arg2,
1643 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1644 mergeConference((String) args.arg1);
1645 } finally {
1646 args.recycle();
1647 Log.endSession();
1648 }
Santos Cordona4868042014-09-04 17:39:22 -07001649 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001650 }
1651 case MSG_SWAP_CONFERENCE: {
1652 SomeArgs args = (SomeArgs) msg.obj;
1653 try {
1654 Log.continueSession((Session) args.arg2,
1655 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1656 swapConference((String) args.arg1);
1657 } finally {
1658 args.recycle();
1659 Log.endSession();
1660 }
Santos Cordona4868042014-09-04 17:39:22 -07001661 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001662 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301663 case MSG_ADD_PARTICIPANT: {
1664 SomeArgs args = (SomeArgs) msg.obj;
1665 try {
1666 Log.continueSession((Session) args.arg3,
1667 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1668 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1669 } finally {
1670 args.recycle();
1671 Log.endSession();
1672 }
1673 break;
1674 }
1675
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001676 case MSG_ON_POST_DIAL_CONTINUE: {
1677 SomeArgs args = (SomeArgs) msg.obj;
1678 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001679 Log.continueSession((Session) args.arg2,
1680 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001681 String callId = (String) args.arg1;
1682 boolean proceed = (args.argi1 == 1);
1683 onPostDialContinue(callId, proceed);
1684 } finally {
1685 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001686 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001687 }
1688 break;
1689 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001690 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001691 SomeArgs args = (SomeArgs) msg.obj;
1692 try {
1693 Log.continueSession((Session) args.arg2,
1694 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1695 pullExternalCall((String) args.arg1);
1696 } finally {
1697 args.recycle();
1698 Log.endSession();
1699 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001700 break;
1701 }
1702 case MSG_SEND_CALL_EVENT: {
1703 SomeArgs args = (SomeArgs) msg.obj;
1704 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001705 Log.continueSession((Session) args.arg4,
1706 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001707 String callId = (String) args.arg1;
1708 String event = (String) args.arg2;
1709 Bundle extras = (Bundle) args.arg3;
1710 sendCallEvent(callId, event, extras);
1711 } finally {
1712 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001713 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001714 }
1715 break;
1716 }
Hall Liu49cabcc2021-01-15 11:41:48 -08001717 case MSG_ON_CALL_FILTERING_COMPLETED: {
1718 SomeArgs args = (SomeArgs) msg.obj;
1719 try {
Hall Liu73903142021-02-18 18:41:41 -08001720 Log.continueSession((Session) args.arg3,
Hall Liu49cabcc2021-01-15 11:41:48 -08001721 SESSION_HANDLER + SESSION_CALL_FILTERING_COMPLETED);
1722 String callId = (String) args.arg1;
Hall Liu73903142021-02-18 18:41:41 -08001723 Connection.CallFilteringCompletionInfo completionInfo =
1724 (Connection.CallFilteringCompletionInfo) args.arg2;
1725 onCallFilteringCompleted(callId, completionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08001726 } finally {
1727 args.recycle();
1728 Log.endSession();
1729 }
1730 break;
1731 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001732 case MSG_HANDOVER_COMPLETE: {
1733 SomeArgs args = (SomeArgs) msg.obj;
1734 try {
1735 Log.continueSession((Session) args.arg2,
1736 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1737 String callId = (String) args.arg1;
1738 notifyHandoverComplete(callId);
1739 } finally {
1740 args.recycle();
1741 Log.endSession();
1742 }
1743 break;
1744 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001745 case MSG_ON_EXTRAS_CHANGED: {
1746 SomeArgs args = (SomeArgs) msg.obj;
1747 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001748 Log.continueSession((Session) args.arg3,
1749 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001750 String callId = (String) args.arg1;
1751 Bundle extras = (Bundle) args.arg2;
1752 handleExtrasChanged(callId, extras);
1753 } finally {
1754 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001755 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001756 }
1757 break;
1758 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001759 case MSG_ON_START_RTT: {
1760 SomeArgs args = (SomeArgs) msg.obj;
1761 try {
1762 Log.continueSession((Session) args.arg3,
1763 SESSION_HANDLER + SESSION_START_RTT);
1764 String callId = (String) args.arg1;
1765 Connection.RttTextStream rttTextStream =
1766 (Connection.RttTextStream) args.arg2;
1767 startRtt(callId, rttTextStream);
1768 } finally {
1769 args.recycle();
1770 Log.endSession();
1771 }
1772 break;
1773 }
1774 case MSG_ON_STOP_RTT: {
1775 SomeArgs args = (SomeArgs) msg.obj;
1776 try {
1777 Log.continueSession((Session) args.arg2,
1778 SESSION_HANDLER + SESSION_STOP_RTT);
1779 String callId = (String) args.arg1;
1780 stopRtt(callId);
1781 } finally {
1782 args.recycle();
1783 Log.endSession();
1784 }
1785 break;
1786 }
1787 case MSG_RTT_UPGRADE_RESPONSE: {
1788 SomeArgs args = (SomeArgs) msg.obj;
1789 try {
1790 Log.continueSession((Session) args.arg3,
1791 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1792 String callId = (String) args.arg1;
1793 Connection.RttTextStream rttTextStream =
1794 (Connection.RttTextStream) args.arg2;
1795 handleRttUpgradeResponse(callId, rttTextStream);
1796 } finally {
1797 args.recycle();
1798 Log.endSession();
1799 }
1800 break;
1801 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001802 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1803 onConnectionServiceFocusGained();
1804 break;
1805 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1806 onConnectionServiceFocusLost();
1807 break;
Junhoedf3d822022-11-24 09:26:37 +00001808 case MSG_ON_CALL_ENDPOINT_CHANGED: {
1809 SomeArgs args = (SomeArgs) msg.obj;
1810 Log.continueSession((Session) args.arg3,
1811 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
1812 try {
1813 String callId = (String) args.arg1;
1814 CallEndpoint callEndpoint = (CallEndpoint) args.arg2;
1815 onCallEndpointChanged(callId, callEndpoint);
1816 } finally {
1817 args.recycle();
1818 Log.endSession();
1819 }
1820 break;
1821 }
1822 case MSG_ON_AVAILABLE_CALL_ENDPOINTS_CHANGED: {
1823 SomeArgs args = (SomeArgs) msg.obj;
1824 Log.continueSession((Session) args.arg3,
1825 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
1826 try {
1827 String callId = (String) args.arg1;
1828 List<CallEndpoint> availableCallEndpoints = (List<CallEndpoint>) args.arg2;
1829 onAvailableCallEndpointsChanged(callId, availableCallEndpoints);
1830 } finally {
1831 args.recycle();
1832 Log.endSession();
1833 }
1834 break;
1835 }
1836 case MSG_ON_MUTE_STATE_CHANGED: {
1837 SomeArgs args = (SomeArgs) msg.obj;
1838 Log.continueSession((Session) args.arg3,
1839 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
1840 try {
1841 String callId = (String) args.arg1;
1842 boolean isMuted = (boolean) args.arg2;
1843 onMuteStateChanged(callId, isMuted);
1844 } finally {
1845 args.recycle();
1846 Log.endSession();
1847 }
1848 break;
1849 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001850 default:
1851 break;
1852 }
1853 }
1854 };
1855
Santos Cordon823fd3c2014-08-07 18:35:18 -07001856 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1857 @Override
1858 public void onStateChanged(Conference conference, int oldState, int newState) {
1859 String id = mIdByConference.get(conference);
1860 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301861 case Connection.STATE_RINGING:
1862 mAdapter.setRinging(id);
1863 break;
1864 case Connection.STATE_DIALING:
1865 mAdapter.setDialing(id);
1866 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001867 case Connection.STATE_ACTIVE:
1868 mAdapter.setActive(id);
1869 break;
1870 case Connection.STATE_HOLDING:
1871 mAdapter.setOnHold(id);
1872 break;
1873 case Connection.STATE_DISCONNECTED:
1874 // handled by onDisconnected
1875 break;
1876 }
1877 }
1878
1879 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001880 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001881 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001882 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001883 }
1884
1885 @Override
1886 public void onConnectionAdded(Conference conference, Connection connection) {
1887 }
1888
1889 @Override
1890 public void onConnectionRemoved(Conference conference, Connection connection) {
1891 }
1892
1893 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001894 public void onConferenceableConnectionsChanged(
1895 Conference conference, List<Connection> conferenceableConnections) {
1896 mAdapter.setConferenceableConnections(
1897 mIdByConference.get(conference),
1898 createConnectionIdList(conferenceableConnections));
1899 }
1900
1901 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001902 public void onDestroyed(Conference conference) {
1903 removeConference(conference);
1904 }
1905
1906 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001907 public void onConnectionCapabilitiesChanged(
1908 Conference conference,
1909 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001910 String id = mIdByConference.get(conference);
1911 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001912 Connection.capabilitiesToString(connectionCapabilities));
1913 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001914 }
Rekha Kumar07366812015-03-24 16:42:31 -07001915
1916 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001917 public void onConnectionPropertiesChanged(
1918 Conference conference,
1919 int connectionProperties) {
1920 String id = mIdByConference.get(conference);
1921 Log.d(this, "call capabilities: conference: %s",
1922 Connection.propertiesToString(connectionProperties));
1923 mAdapter.setConnectionProperties(id, connectionProperties);
1924 }
1925
1926 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001927 public void onVideoStateChanged(Conference c, int videoState) {
1928 String id = mIdByConference.get(c);
1929 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1930 mAdapter.setVideoState(id, videoState);
1931 }
1932
1933 @Override
1934 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1935 String id = mIdByConference.get(c);
1936 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1937 videoProvider);
1938 mAdapter.setVideoProvider(id, videoProvider);
1939 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001940
1941 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001942 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1943 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001944 if (id != null) {
1945 mAdapter.setStatusHints(id, statusHints);
1946 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001947 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001948
1949 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001950 public void onExtrasChanged(Conference c, Bundle extras) {
1951 String id = mIdByConference.get(c);
1952 if (id != null) {
1953 mAdapter.putExtras(id, extras);
1954 }
1955 }
1956
1957 @Override
1958 public void onExtrasRemoved(Conference c, List<String> keys) {
1959 String id = mIdByConference.get(c);
1960 if (id != null) {
1961 mAdapter.removeExtras(id, keys);
1962 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001963 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001964
1965 @Override
1966 public void onConferenceStateChanged(Conference c, boolean isConference) {
1967 String id = mIdByConference.get(c);
1968 if (id != null) {
1969 mAdapter.setConferenceState(id, isConference);
1970 }
1971 }
1972
1973 @Override
Brad Ebingere0c12f42020-04-08 16:25:12 -07001974 public void onCallDirectionChanged(Conference c, int direction) {
1975 String id = mIdByConference.get(c);
1976 if (id != null) {
1977 mAdapter.setCallDirection(id, direction);
1978 }
1979 }
1980
1981 @Override
Tyler Gunn68a73a42018-10-03 15:38:57 -07001982 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1983 String id = mIdByConference.get(c);
1984 if (id != null) {
1985 mAdapter.setAddress(id, newAddress, presentation);
1986 }
1987 }
1988
1989 @Override
1990 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1991 int presentation) {
1992 String id = mIdByConference.get(c);
1993 if (id != null) {
1994 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1995 }
1996 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001997
1998 @Override
1999 public void onConnectionEvent(Conference c, String event, Bundle extras) {
2000 String id = mIdByConference.get(c);
2001 if (id != null) {
2002 mAdapter.onConnectionEvent(id, event, extras);
2003 }
2004 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302005
2006 @Override
2007 public void onRingbackRequested(Conference c, boolean ringback) {
2008 String id = mIdByConference.get(c);
2009 Log.d(this, "Adapter conference onRingback %b", ringback);
2010 mAdapter.setRingbackRequested(id, ringback);
2011 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002012 };
2013
Ihab Awad542e0ea2014-05-16 10:22:16 -07002014 private final Connection.Listener mConnectionListener = new Connection.Listener() {
2015 @Override
2016 public void onStateChanged(Connection c, int state) {
2017 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07002018 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07002019 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002020 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002021 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002022 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002023 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002024 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002025 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07002026 case Connection.STATE_PULLING_CALL:
2027 mAdapter.setPulling(id);
2028 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002029 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07002030 // Handled in onDisconnected()
2031 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002032 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002033 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002034 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002035 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002036 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07002037 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002038 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002039 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002040 break;
2041 }
2042 }
2043
2044 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002045 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07002046 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07002047 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002048 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002049 }
2050
2051 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07002052 public void onVideoStateChanged(Connection c, int videoState) {
2053 String id = mIdByConnection.get(c);
2054 Log.d(this, "Adapter set video state %d", videoState);
2055 mAdapter.setVideoState(id, videoState);
2056 }
2057
2058 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07002059 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07002060 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07002061 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07002062 }
2063
2064 @Override
2065 public void onCallerDisplayNameChanged(
2066 Connection c, String callerDisplayName, int presentation) {
2067 String id = mIdByConnection.get(c);
2068 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002069 }
2070
2071 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07002072 public void onDestroyed(Connection c) {
2073 removeConnection(c);
2074 }
Ihab Awadf8358972014-05-28 16:46:42 -07002075
2076 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002077 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07002078 String id = mIdByConnection.get(c);
2079 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002080 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07002081 }
2082
2083 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08002084 public void onPostDialChar(Connection c, char nextChar) {
2085 String id = mIdByConnection.get(c);
2086 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
2087 mAdapter.onPostDialChar(id, nextChar);
2088 }
2089
2090 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07002091 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07002092 String id = mIdByConnection.get(c);
2093 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07002094 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07002095 }
Santos Cordonb6939982014-06-04 20:20:58 -07002096
2097 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002098 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07002099 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002100 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002101 Connection.capabilitiesToString(capabilities));
2102 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07002103 }
2104
Santos Cordonb6939982014-06-04 20:20:58 -07002105 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07002106 public void onConnectionPropertiesChanged(Connection c, int properties) {
2107 String id = mIdByConnection.get(c);
2108 Log.d(this, "properties: parcelableconnection: %s",
2109 Connection.propertiesToString(properties));
2110 mAdapter.setConnectionProperties(id, properties);
2111 }
2112
2113 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002114 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07002115 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07002116 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
2117 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002118 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07002119 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07002120
2121 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07002122 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07002123 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07002124 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07002125 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07002126
2127 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07002128 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07002129 String id = mIdByConnection.get(c);
2130 mAdapter.setStatusHints(id, statusHints);
2131 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07002132
2133 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002134 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07002135 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07002136 mAdapter.setConferenceableConnections(
2137 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002138 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002139 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002140
2141 @Override
2142 public void onConferenceChanged(Connection connection, Conference conference) {
2143 String id = mIdByConnection.get(connection);
2144 if (id != null) {
2145 String conferenceId = null;
2146 if (conference != null) {
2147 conferenceId = mIdByConference.get(conference);
2148 }
2149 mAdapter.setIsConferenced(id, conferenceId);
2150 }
2151 }
Anthony Lee17455a32015-04-24 15:25:29 -07002152
2153 @Override
2154 public void onConferenceMergeFailed(Connection connection) {
2155 String id = mIdByConnection.get(connection);
2156 if (id != null) {
2157 mAdapter.onConferenceMergeFailed(id);
2158 }
2159 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07002160
2161 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07002162 public void onExtrasChanged(Connection c, Bundle extras) {
2163 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07002164 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07002165 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07002166 }
2167 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07002168
Tyler Gunnf5035432017-01-09 09:43:12 -08002169 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07002170 public void onExtrasRemoved(Connection c, List<String> keys) {
2171 String id = mIdByConnection.get(c);
2172 if (id != null) {
2173 mAdapter.removeExtras(id, keys);
2174 }
2175 }
2176
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002177 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002178 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002179 String id = mIdByConnection.get(connection);
2180 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002181 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08002182 }
2183 }
Tyler Gunnf5035432017-01-09 09:43:12 -08002184
2185 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08002186 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002187 String id = mIdByConnection.get(c);
2188 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08002189 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08002190 }
2191 }
Hall Liub64ac4c2017-02-06 10:49:48 -08002192
2193 @Override
2194 public void onRttInitiationSuccess(Connection c) {
2195 String id = mIdByConnection.get(c);
2196 if (id != null) {
2197 mAdapter.onRttInitiationSuccess(id);
2198 }
2199 }
2200
2201 @Override
2202 public void onRttInitiationFailure(Connection c, int reason) {
2203 String id = mIdByConnection.get(c);
2204 if (id != null) {
2205 mAdapter.onRttInitiationFailure(id, reason);
2206 }
2207 }
2208
2209 @Override
2210 public void onRttSessionRemotelyTerminated(Connection c) {
2211 String id = mIdByConnection.get(c);
2212 if (id != null) {
2213 mAdapter.onRttSessionRemotelyTerminated(id);
2214 }
2215 }
2216
2217 @Override
2218 public void onRemoteRttRequest(Connection c) {
2219 String id = mIdByConnection.get(c);
2220 if (id != null) {
2221 mAdapter.onRemoteRttRequest(id);
2222 }
2223 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05302224
2225 @Override
2226 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
2227 String id = mIdByConnection.get(c);
2228 if (id != null) {
2229 mAdapter.onPhoneAccountChanged(id, pHandle);
2230 }
2231 }
Mengjun Leng25707742017-07-04 11:10:37 +08002232
2233 public void onConnectionTimeReset(Connection c) {
2234 String id = mIdByConnection.get(c);
2235 if (id != null) {
2236 mAdapter.resetConnectionTime(id);
2237 }
2238 }
Junhoedf3d822022-11-24 09:26:37 +00002239
2240 @Override
2241 public void onEndpointChanged(Connection c, CallEndpoint endpoint, Executor executor,
2242 OutcomeReceiver<Void, CallEndpointException> callback) {
2243 String id = mIdByConnection.get(c);
2244 if (id != null) {
2245 mAdapter.requestCallEndpointChange(id, endpoint, executor, callback);
2246 }
2247 }
yongnamcha8ec56242022-11-28 06:23:02 +00002248
2249 @Override
2250 public void onQueryLocation(Connection c, long timeoutMillis, @NonNull String provider,
2251 @NonNull @CallbackExecutor Executor executor,
2252 @NonNull OutcomeReceiver<Location, QueryLocationException> callback) {
2253 String id = mIdByConnection.get(c);
2254 if (id != null) {
2255 mAdapter.queryLocation(id, timeoutMillis, provider, executor, callback);
2256 }
2257 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002258 };
2259
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002260 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07002261 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002262 public final IBinder onBind(Intent intent) {
Hall Liueb7c9ea2021-03-09 20:24:50 -08002263 onBindClient(intent);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002264 return mBinder;
2265 }
2266
Santos Cordon29f2f2e2014-09-11 19:50:24 -07002267 /** {@inheritDoc} */
2268 @Override
2269 public boolean onUnbind(Intent intent) {
2270 endAllConnections();
2271 return super.onUnbind(intent);
2272 }
2273
Hall Liueb7c9ea2021-03-09 20:24:50 -08002274 /**
2275 * Used for testing to let the test suite know when the connection service has been bound.
2276 * @hide
2277 */
2278 @TestApi
2279 public void onBindClient(@Nullable Intent intent) {
2280 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302281
2282 /**
2283 * This can be used by telecom to either create a new outgoing conference call or attach
2284 * to an existing incoming conference call. In either case, telecom will cycle through a
2285 * set of services and call createConference until a connection service cancels the process
2286 * or completes it successfully.
2287 */
2288 private void createConference(
2289 final PhoneAccountHandle callManagerAccount,
2290 final String callId,
2291 final ConnectionRequest request,
2292 boolean isIncoming,
2293 boolean isUnknown) {
2294
2295 Conference conference = null;
2296 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
2297 : onCreateOutgoingConference(callManagerAccount, request);
2298
2299 Log.d(this, "createConference, conference: %s", conference);
2300 if (conference == null) {
2301 Log.i(this, "createConference, implementation returned null conference.");
2302 conference = Conference.createFailedConference(
2303 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
2304 request.getAccountHandle());
2305 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002306
2307 Bundle extras = request.getExtras();
2308 Bundle newExtras = new Bundle();
2309 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
2310 if (extras != null) {
2311 // If the request originated from a remote connection service, we will add some
2312 // tracking information that Telecom can use to keep informed of which package
2313 // made the remote request, and which remote connection service was used.
2314 if (extras.containsKey(Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2315 newExtras.putString(
2316 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2317 extras.getString(
2318 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME));
2319 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2320 request.getAccountHandle());
2321 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302322 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002323 conference.putExtras(newExtras);
2324
Ravi Paluri80aa2142019-12-02 11:57:37 +05302325 mConferenceById.put(callId, conference);
2326 mIdByConference.put(conference, callId);
Tyler Gunn460360d2020-07-29 10:21:45 -07002327
Ravi Paluri80aa2142019-12-02 11:57:37 +05302328 conference.addListener(mConferenceListener);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07002329 ParcelableConference parcelableConference = new ParcelableConference.Builder(
2330 request.getAccountHandle(), conference.getState())
2331 .setConnectionCapabilities(conference.getConnectionCapabilities())
2332 .setConnectionProperties(conference.getConnectionProperties())
2333 .setVideoAttributes(conference.getVideoProvider() == null
2334 ? null : conference.getVideoProvider().getInterface(),
2335 conference.getVideoState())
2336 .setConnectTimeMillis(conference.getConnectTimeMillis(),
2337 conference.getConnectionStartElapsedRealtimeMillis())
2338 .setStatusHints(conference.getStatusHints())
2339 .setExtras(conference.getExtras())
2340 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2341 .setCallerDisplayName(conference.getCallerDisplayName(),
2342 conference.getCallerDisplayNamePresentation())
2343 .setDisconnectCause(conference.getDisconnectCause())
2344 .setRingbackRequested(conference.isRingbackRequested())
2345 .build();
Ravi Paluri80aa2142019-12-02 11:57:37 +05302346 if (conference.getState() != Connection.STATE_DISCONNECTED) {
2347 conference.setTelecomCallId(callId);
2348 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
2349 mAdapter.setVideoState(callId, conference.getVideoState());
2350 onConferenceAdded(conference);
2351 }
2352
2353 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
2354 mAdapter.handleCreateConferenceComplete(
2355 callId,
2356 request,
2357 parcelableConference);
2358 }
2359
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002360 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002361 * This can be used by telecom to either create a new outgoing call or attach to an existing
2362 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002363 * createConnection util a connection service cancels the process or completes it successfully.
2364 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002365 private void createConnection(
2366 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002367 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07002368 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07002369 boolean isIncoming,
2370 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002371 boolean isLegacyHandover = request.getExtras() != null &&
2372 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
2373 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
2374 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Grace Jiae99fde92021-01-19 14:58:01 -08002375 boolean addSelfManaged = request.getExtras() != null && request.getExtras().getBoolean(
Grace Jia8b22bb42021-02-02 15:37:32 -08002376 PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
Grace Jiae99fde92021-01-19 14:58:01 -08002377 Log.i(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, "
2378 + "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b, "
2379 + " addSelfManaged: %b", callManagerAccount, callId, request, isIncoming,
2380 isUnknown, isLegacyHandover, isHandover, addSelfManaged);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002381
Sanket Padawee29a2662017-12-01 13:59:27 -08002382 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002383 if (isHandover) {
2384 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
2385 ? (PhoneAccountHandle) request.getExtras().getParcelable(
Hani Kazmi4f221e52022-06-20 09:38:26 +00002386 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT, android.telecom.PhoneAccountHandle.class) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08002387 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002388 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002389 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002390 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002391 }
2392 } else {
2393 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
2394 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
2395 : onCreateOutgoingConnection(callManagerAccount, request);
2396 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002397 Log.d(this, "createConnection, connection: %s", connection);
2398 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002399 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002400 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002401 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002402 } else {
2403 try {
2404 Bundle extras = request.getExtras();
2405 if (extras != null) {
2406 // If the request originated from a remote connection service, we will add some
2407 // tracking information that Telecom can use to keep informed of which package
2408 // made the remote request, and which remote connection service was used.
2409 if (extras.containsKey(
2410 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2411 Bundle newExtras = new Bundle();
2412 newExtras.putString(
2413 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2414 extras.getString(
2415 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME
2416 ));
2417 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2418 request.getAccountHandle());
2419 connection.putExtras(newExtras);
2420 }
2421 }
2422 } catch (UnsupportedOperationException ose) {
2423 // Do nothing; if the ConnectionService reported a failure it will be an instance
2424 // of an immutable Connection which we cannot edit, so we're out of luck.
2425 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002426 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002427
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002428 boolean isSelfManaged =
2429 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
2430 == Connection.PROPERTY_SELF_MANAGED;
2431 // Self-managed Connections should always use voip audio mode; we default here so that the
2432 // local state within the ConnectionService matches the default we assume in Telecom.
2433 if (isSelfManaged) {
2434 connection.setAudioModeIsVoip(true);
2435 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002436 connection.setTelecomCallId(callId);
Sungjae7f4137452020-09-16 17:01:54 +09002437 PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
2438 ? request.getAccountHandle() : connection.getPhoneAccountHandle();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002439 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Sungjae7f4137452020-09-16 17:01:54 +09002440 addConnection(phoneAccountHandle, callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07002441 }
2442
Andrew Lee100e2932014-09-08 15:34:24 -07002443 Uri address = connection.getAddress();
2444 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07002445 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002446 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002447 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07002448 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
2449 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002450
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002451 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07002452 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002453 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07002454 request,
2455 new ParcelableConnection(
Sungjae7f4137452020-09-16 17:01:54 +09002456 phoneAccountHandle,
Evan Charltonbf11f982014-07-20 22:06:28 -07002457 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002458 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002459 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002460 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07002461 connection.getAddress(),
2462 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07002463 connection.getCallerDisplayName(),
2464 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002465 connection.getVideoProvider() == null ?
2466 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002467 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07002468 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002469 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002470 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002471 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07002472 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002473 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002474 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002475 connection.getExtras(),
2476 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08002477
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002478 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002479 // Tell ConnectionService to show its incoming call UX.
2480 connection.onShowIncomingCallUi();
2481 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002482 if (isUnknown) {
2483 triggerConferenceRecalculate();
2484 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002485 }
2486
Tyler Gunn159f35c2017-03-02 09:28:37 -08002487 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
2488 final String callId, final ConnectionRequest request,
2489 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08002490
2491 Log.i(this, "createConnectionFailed %s", callId);
2492 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002493 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002494 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002495 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002496 }
2497 }
2498
Ravi Paluri80aa2142019-12-02 11:57:37 +05302499 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
2500 final String callId, final ConnectionRequest request,
2501 boolean isIncoming) {
2502
2503 Log.i(this, "createConferenceFailed %s", callId);
2504 if (isIncoming) {
2505 onCreateIncomingConferenceFailed(callManagerAccount, request);
2506 } else {
2507 onCreateOutgoingConferenceFailed(callManagerAccount, request);
2508 }
2509 }
2510
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08002511 private void handoverFailed(final String callId, final ConnectionRequest request,
2512 int reason) {
2513
2514 Log.i(this, "handoverFailed %s", callId);
2515 onHandoverFailed(request, reason);
2516 }
2517
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002518 /**
2519 * Called by Telecom when the creation of a new Connection has completed and it is now added
2520 * to Telecom.
2521 * @param callId The ID of the connection.
2522 */
2523 private void notifyCreateConnectionComplete(final String callId) {
2524 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07002525 if (callId == null) {
2526 // This could happen if the connection fails quickly and is removed from the
2527 // ConnectionService before Telecom sends the create connection complete callback.
2528 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
2529 return;
2530 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002531 onCreateConnectionComplete(findConnectionForAction(callId,
2532 "notifyCreateConnectionComplete"));
2533 }
2534
Ravi Paluri80aa2142019-12-02 11:57:37 +05302535 /**
2536 * Called by Telecom when the creation of a new Conference has completed and it is now added
2537 * to Telecom.
2538 * @param callId The ID of the connection.
2539 */
2540 private void notifyCreateConferenceComplete(final String callId) {
2541 Log.i(this, "notifyCreateConferenceComplete %s", callId);
2542 if (callId == null) {
2543 // This could happen if the conference fails quickly and is removed from the
2544 // ConnectionService before Telecom sends the create conference complete callback.
2545 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
2546 return;
2547 }
2548 onCreateConferenceComplete(findConferenceForAction(callId,
2549 "notifyCreateConferenceComplete"));
2550 }
2551
2552
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002553 private void abort(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002554 Log.i(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002555 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002556 }
2557
Tyler Gunnbe74de02014-08-29 14:51:48 -07002558 private void answerVideo(String callId, int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002559 Log.i(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302560 if (mConnectionById.containsKey(callId)) {
2561 findConnectionForAction(callId, "answer").onAnswer(videoState);
2562 } else {
2563 findConferenceForAction(callId, "answer").onAnswer(videoState);
2564 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002565 }
2566
Tyler Gunnbe74de02014-08-29 14:51:48 -07002567 private void answer(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002568 Log.i(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302569 if (mConnectionById.containsKey(callId)) {
2570 findConnectionForAction(callId, "answer").onAnswer();
2571 } else {
2572 findConferenceForAction(callId, "answer").onAnswer();
2573 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002574 }
2575
Pooja Jaind34698d2017-12-28 14:15:31 +05302576 private void deflect(String callId, Uri address) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002577 Log.i(this, "deflect %s", callId);
Pooja Jaind34698d2017-12-28 14:15:31 +05302578 findConnectionForAction(callId, "deflect").onDeflect(address);
2579 }
2580
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002581 private void reject(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002582 Log.i(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302583 if (mConnectionById.containsKey(callId)) {
2584 findConnectionForAction(callId, "reject").onReject();
2585 } else {
2586 findConferenceForAction(callId, "reject").onReject();
2587 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002588 }
2589
Bryce Lee81901682015-08-28 16:38:02 -07002590 private void reject(String callId, String rejectWithMessage) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002591 Log.i(this, "reject %s with message", callId);
Bryce Lee81901682015-08-28 16:38:02 -07002592 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2593 }
2594
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002595 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002596 Log.i(this, "reject %s with reason %d", callId, rejectReason);
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002597 findConnectionForAction(callId, "reject").onReject(rejectReason);
2598 }
2599
Ravi Palurif4b38e72020-02-05 12:35:41 +05302600 private void transfer(String callId, Uri number, boolean isConfirmationRequired) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002601 Log.i(this, "transfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302602 findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired);
2603 }
2604
2605 private void consultativeTransfer(String callId, String otherCallId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002606 Log.i(this, "consultativeTransfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302607 Connection connection1 = findConnectionForAction(callId, "consultativeTransfer");
2608 Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer");
2609 connection1.onTransfer(connection2);
2610 }
2611
Bryce Leecac50772015-11-17 15:13:29 -08002612 private void silence(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002613 Log.i(this, "silence %s", callId);
Bryce Leecac50772015-11-17 15:13:29 -08002614 findConnectionForAction(callId, "silence").onSilence();
2615 }
2616
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002617 private void disconnect(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002618 Log.i(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002619 if (mConnectionById.containsKey(callId)) {
2620 findConnectionForAction(callId, "disconnect").onDisconnect();
2621 } else {
2622 findConferenceForAction(callId, "disconnect").onDisconnect();
2623 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002624 }
2625
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002626 private void hold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002627 Log.i(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002628 if (mConnectionById.containsKey(callId)) {
2629 findConnectionForAction(callId, "hold").onHold();
2630 } else {
2631 findConferenceForAction(callId, "hold").onHold();
2632 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002633 }
2634
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002635 private void unhold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002636 Log.i(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002637 if (mConnectionById.containsKey(callId)) {
2638 findConnectionForAction(callId, "unhold").onUnhold();
2639 } else {
2640 findConferenceForAction(callId, "unhold").onUnhold();
2641 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002642 }
2643
Yorke Lee4af59352015-05-13 14:14:54 -07002644 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002645 Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002646 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002647 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2648 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002649 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002650 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2651 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002652 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002653 }
2654
Junhoedf3d822022-11-24 09:26:37 +00002655 private void onCallEndpointChanged(String callId, CallEndpoint callEndpoint) {
2656 Log.i(this, "onCallEndpointChanged %s %s", callId, callEndpoint);
2657 if (mConnectionById.containsKey(callId)) {
2658 findConnectionForAction(callId, "onCallEndpointChanged").setCallEndpoint(callEndpoint);
2659 } else {
2660 findConferenceForAction(callId, "onCallEndpointChanged").setCallEndpoint(callEndpoint);
2661 }
2662 }
2663
2664 private void onAvailableCallEndpointsChanged(String callId,
2665 List<CallEndpoint> availableCallEndpoints) {
2666 Log.i(this, "onAvailableCallEndpointsChanged %s", callId);
2667 if (mConnectionById.containsKey(callId)) {
2668 findConnectionForAction(callId, "onAvailableCallEndpointsChanged")
2669 .setAvailableCallEndpoints(availableCallEndpoints);
2670 } else {
2671 findConferenceForAction(callId, "onAvailableCallEndpointsChanged")
2672 .setAvailableCallEndpoints(availableCallEndpoints);
2673 }
2674 }
2675
2676 private void onMuteStateChanged(String callId, boolean isMuted) {
2677 Log.i(this, "onMuteStateChanged %s %s", callId, isMuted);
2678 if (mConnectionById.containsKey(callId)) {
2679 findConnectionForAction(callId, "onMuteStateChanged").setMuteState(isMuted);
2680 } else {
2681 findConferenceForAction(callId, "onMuteStateChanged").setMuteState(isMuted);
2682 }
2683 }
2684
Grace Jiae99fde92021-01-19 14:58:01 -08002685 private void onUsingAlternativeUi(String callId, boolean isUsingAlternativeUi) {
2686 Log.i(this, "onUsingAlternativeUi %s %s", callId, isUsingAlternativeUi);
2687 if (mConnectionById.containsKey(callId)) {
2688 findConnectionForAction(callId, "onUsingAlternativeUi")
2689 .onUsingAlternativeUi(isUsingAlternativeUi);
2690 }
2691 }
2692
2693 private void onTrackedByNonUiService(String callId, boolean isTracked) {
2694 Log.i(this, "onTrackedByNonUiService %s %s", callId, isTracked);
2695 if (mConnectionById.containsKey(callId)) {
2696 findConnectionForAction(callId, "onTrackedByNonUiService")
2697 .onTrackedByNonUiService(isTracked);
2698 }
2699 }
2700
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002701 private void playDtmfTone(String callId, char digit) {
Wenting Xiong7f9f3482020-08-27 18:16:06 +08002702 Log.i(this, "playDtmfTone %s %s", callId, Log.pii(digit));
Yorke Leea0d3ca92014-09-15 19:18:13 -07002703 if (mConnectionById.containsKey(callId)) {
2704 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2705 } else {
2706 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2707 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002708 }
2709
2710 private void stopDtmfTone(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002711 Log.i(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002712 if (mConnectionById.containsKey(callId)) {
2713 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2714 } else {
2715 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2716 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002717 }
2718
Santos Cordon823fd3c2014-08-07 18:35:18 -07002719 private void conference(String callId1, String callId2) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002720 Log.i(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002721
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002722 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002723 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002724 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002725 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002726 conference2 = findConferenceForAction(callId2, "conference");
2727 if (conference2 == getNullConference()) {
2728 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2729 callId2);
2730 return;
2731 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002732 }
Santos Cordonb6939982014-06-04 20:20:58 -07002733
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002734 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002735 Connection connection1 = findConnectionForAction(callId1, "conference");
2736 if (connection1 == getNullConnection()) {
2737 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2738 if (conference1 == getNullConference()) {
2739 Log.w(this,
2740 "Connection1 or Conference1 missing in conference request %s.",
2741 callId1);
2742 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002743 // Call 1 is a conference.
2744 if (connection2 != getNullConnection()) {
2745 // Call 2 is a connection so merge via call 1 (conference).
2746 conference1.onMerge(connection2);
2747 } else {
2748 // Call 2 is ALSO a conference; this should never happen.
2749 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2750 "merge two conferences.");
2751 return;
2752 }
Ihab Awad50e35062014-09-30 09:17:03 -07002753 }
2754 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002755 // Call 1 is a connection.
2756 if (conference2 != getNullConference()) {
2757 // Call 2 is a conference, so merge via call 2.
2758 conference2.onMerge(connection1);
2759 } else {
2760 // Call 2 is a connection, so merge together.
2761 onConference(connection1, connection2);
2762 }
Ihab Awad50e35062014-09-30 09:17:03 -07002763 }
Santos Cordon980acb92014-05-31 10:31:19 -07002764 }
2765
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002766 private void splitFromConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002767 Log.i(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002768
2769 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002770 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002771 Log.w(this, "Connection missing in conference request %s.", callId);
2772 return;
2773 }
2774
Santos Cordon0159ac02014-08-21 14:28:11 -07002775 Conference conference = connection.getConference();
2776 if (conference != null) {
2777 conference.onSeparate(connection);
2778 }
Santos Cordon980acb92014-05-31 10:31:19 -07002779 }
2780
Santos Cordona4868042014-09-04 17:39:22 -07002781 private void mergeConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002782 Log.i(this, "mergeConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002783 Conference conference = findConferenceForAction(callId, "mergeConference");
2784 if (conference != null) {
2785 conference.onMerge();
2786 }
2787 }
2788
2789 private void swapConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002790 Log.i(this, "swapConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002791 Conference conference = findConferenceForAction(callId, "swapConference");
2792 if (conference != null) {
2793 conference.onSwap();
2794 }
2795 }
2796
Ravi Paluri404babb2020-01-23 19:02:44 +05302797 private void addConferenceParticipants(String callId, List<Uri> participants) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002798 Log.i(this, "addConferenceParticipants(%s)", callId);
Ravi Paluri404babb2020-01-23 19:02:44 +05302799 if (mConnectionById.containsKey(callId)) {
2800 findConnectionForAction(callId, "addConferenceParticipants")
2801 .onAddConferenceParticipants(participants);
2802 } else {
2803 findConferenceForAction(callId, "addConferenceParticipants")
2804 .onAddConferenceParticipants(participants);
2805 }
2806 }
2807
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002808 /**
2809 * Notifies a {@link Connection} of a request to pull an external call.
2810 *
2811 * See {@link Call#pullExternalCall()}.
2812 *
2813 * @param callId The ID of the call to pull.
2814 */
2815 private void pullExternalCall(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002816 Log.i(this, "pullExternalCall(%s)", callId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002817 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2818 if (connection != null) {
2819 connection.onPullExternalCall();
2820 }
2821 }
2822
2823 /**
2824 * Notifies a {@link Connection} of a call event.
2825 *
2826 * See {@link Call#sendCallEvent(String, Bundle)}.
2827 *
2828 * @param callId The ID of the call receiving the event.
2829 * @param event The event.
2830 * @param extras Extras associated with the event.
2831 */
2832 private void sendCallEvent(String callId, String event, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002833 Log.i(this, "sendCallEvent(%s, %s)", callId, event);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002834 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2835 if (connection != null) {
2836 connection.onCallEvent(event, extras);
2837 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002838 }
2839
Hall Liu73903142021-02-18 18:41:41 -08002840 private void onCallFilteringCompleted(String callId, Connection.CallFilteringCompletionInfo
2841 callFilteringCompletionInfo) {
2842 Log.i(this, "onCallFilteringCompleted(%s, %s)", callId, callFilteringCompletionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08002843 Connection connection = findConnectionForAction(callId, "onCallFilteringCompleted");
2844 if (connection != null) {
Hall Liu73903142021-02-18 18:41:41 -08002845 connection.onCallFilteringCompleted(callFilteringCompletionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08002846 }
2847 }
2848
Tyler Gunndee56a82016-03-23 16:06:34 -07002849 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002850 * Notifies a {@link Connection} that a handover has completed.
2851 *
2852 * @param callId The ID of the call which completed handover.
2853 */
2854 private void notifyHandoverComplete(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002855 Log.i(this, "notifyHandoverComplete(%s)", callId);
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002856 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2857 if (connection != null) {
2858 connection.onHandoverComplete();
2859 }
2860 }
2861
2862 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002863 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2864 * <p>
2865 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2866 * the {@link android.telecom.Call#putExtra(String, boolean)},
2867 * {@link android.telecom.Call#putExtra(String, int)},
2868 * {@link android.telecom.Call#putExtra(String, String)},
2869 * {@link Call#removeExtras(List)}.
2870 *
2871 * @param callId The ID of the call receiving the event.
2872 * @param extras The new extras bundle.
2873 */
2874 private void handleExtrasChanged(String callId, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002875 Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002876 if (mConnectionById.containsKey(callId)) {
2877 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2878 } else if (mConferenceById.containsKey(callId)) {
2879 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2880 }
2881 }
2882
Hall Liub64ac4c2017-02-06 10:49:48 -08002883 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002884 Log.i(this, "startRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002885 if (mConnectionById.containsKey(callId)) {
2886 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2887 } else if (mConferenceById.containsKey(callId)) {
2888 Log.w(this, "startRtt called on a conference.");
2889 }
2890 }
2891
2892 private void stopRtt(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002893 Log.i(this, "stopRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002894 if (mConnectionById.containsKey(callId)) {
2895 findConnectionForAction(callId, "stopRtt").onStopRtt();
2896 } else if (mConferenceById.containsKey(callId)) {
2897 Log.w(this, "stopRtt called on a conference.");
2898 }
2899 }
2900
2901 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002902 Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
Hall Liub64ac4c2017-02-06 10:49:48 -08002903 if (mConnectionById.containsKey(callId)) {
2904 findConnectionForAction(callId, "handleRttUpgradeResponse")
2905 .handleRttUpgradeResponse(rttTextStream);
2906 } else if (mConferenceById.containsKey(callId)) {
2907 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2908 }
2909 }
2910
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002911 private void onPostDialContinue(String callId, boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002912 Log.i(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002913 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002914 }
2915
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002916 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002917 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002918 // No need to query again if we already did it.
2919 return;
2920 }
2921
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002922 String callingPackage = getOpPackageName();
2923
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002924 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002925 @Override
2926 public void onResult(
2927 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002928 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002929 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002930 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002931 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002932 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002933 mRemoteConnectionManager.addConnectionService(
2934 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002935 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002936 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002937 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002938 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002939 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002940 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002941 }
2942
2943 @Override
2944 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002945 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002946 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002947 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002948 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002949 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002950 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002951 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002952 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002953 }
2954
Ihab Awadf8b69882014-07-25 15:14:01 -07002955 /**
2956 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002957 * incoming request. This is used by {@code ConnectionService}s that are registered with
2958 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2959 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002960 *
2961 * @param connectionManagerPhoneAccount See description at
2962 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2963 * @param request Details about the incoming call.
2964 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2965 * not handle the call.
2966 */
Grace Jia41895152021-01-19 13:57:51 -08002967 public final @Nullable RemoteConnection createRemoteIncomingConnection(
2968 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
2969 @NonNull ConnectionRequest request) {
Ihab Awadf8b69882014-07-25 15:14:01 -07002970 return mRemoteConnectionManager.createRemoteConnection(
2971 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002972 }
2973
2974 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002975 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002976 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2977 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2978 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002979 *
2980 * @param connectionManagerPhoneAccount See description at
2981 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002982 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002983 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2984 * not handle the call.
2985 */
Grace Jia41895152021-01-19 13:57:51 -08002986 public final @Nullable RemoteConnection createRemoteOutgoingConnection(
2987 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
2988 @NonNull ConnectionRequest request) {
Ihab Awadf8b69882014-07-25 15:14:01 -07002989 return mRemoteConnectionManager.createRemoteConnection(
2990 connectionManagerPhoneAccount, request, false);
2991 }
2992
2993 /**
Grace Jia9a09c672020-08-04 12:52:09 -07002994 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2995 * incoming request. This is used by {@code ConnectionService}s that are registered with
2996 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2997 *
2998 * @param connectionManagerPhoneAccount See description at
2999 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
3000 * @param request Details about the incoming conference call.
3001 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
3002 * handle the call.
3003 */
3004 public final @Nullable RemoteConference createRemoteIncomingConference(
3005 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
3006 @Nullable ConnectionRequest request) {
3007 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
3008 request, true);
3009 }
3010
3011 /**
3012 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
3013 * outgoing request. This is used by {@code ConnectionService}s that are registered with
3014 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
3015 *
3016 * @param connectionManagerPhoneAccount See description at
3017 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
3018 * @param request Details about the outgoing conference call.
3019 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
3020 * handle the call.
3021 */
3022 public final @Nullable RemoteConference createRemoteOutgoingConference(
3023 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
3024 @Nullable ConnectionRequest request) {
3025 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
3026 request, false);
3027 }
3028
3029 /**
Santos Cordona663f862014-10-29 13:49:58 -07003030 * Indicates to the relevant {@code RemoteConnectionService} that the specified
3031 * {@link RemoteConnection}s should be merged into a conference call.
3032 * <p>
3033 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
3034 * be invoked.
3035 *
3036 * @param remoteConnection1 The first of the remote connections to conference.
3037 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07003038 */
3039 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07003040 RemoteConnection remoteConnection1,
3041 RemoteConnection remoteConnection2) {
3042 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07003043 }
3044
3045 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003046 * Adds a new conference call. When a conference call is created either as a result of an
3047 * explicit request via {@link #onConference} or otherwise, the connection service should supply
3048 * an instance of {@link Conference} by invoking this method. A conference call provided by this
3049 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
3050 *
3051 * @param conference The new conference object.
3052 */
3053 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07003054 Log.d(this, "addConference: conference=%s", conference);
3055
Santos Cordon823fd3c2014-08-07 18:35:18 -07003056 String id = addConferenceInternal(conference);
3057 if (id != null) {
3058 List<String> connectionIds = new ArrayList<>(2);
3059 for (Connection connection : conference.getConnections()) {
3060 if (mIdByConnection.containsKey(connection)) {
3061 connectionIds.add(mIdByConnection.get(connection));
3062 }
3063 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003064 conference.setTelecomCallId(id);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07003065 ParcelableConference parcelableConference = new ParcelableConference.Builder(
3066 conference.getPhoneAccountHandle(), conference.getState())
3067 .setConnectionCapabilities(conference.getConnectionCapabilities())
3068 .setConnectionProperties(conference.getConnectionProperties())
3069 .setConnectionIds(connectionIds)
3070 .setVideoAttributes(conference.getVideoProvider() == null
3071 ? null : conference.getVideoProvider().getInterface(),
3072 conference.getVideoState())
3073 .setConnectTimeMillis(conference.getConnectTimeMillis(),
3074 conference.getConnectionStartElapsedRealtimeMillis())
3075 .setStatusHints(conference.getStatusHints())
3076 .setExtras(conference.getExtras())
3077 .setAddress(conference.getAddress(), conference.getAddressPresentation())
3078 .setCallerDisplayName(conference.getCallerDisplayName(),
3079 conference.getCallerDisplayNamePresentation())
3080 .setDisconnectCause(conference.getDisconnectCause())
3081 .setRingbackRequested(conference.isRingbackRequested())
3082 .setCallDirection(conference.getCallDirection())
3083 .build();
Andrew Lee0f51da32015-04-16 13:11:55 -07003084
Santos Cordon823fd3c2014-08-07 18:35:18 -07003085 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07003086 mAdapter.setVideoProvider(id, conference.getVideoProvider());
3087 mAdapter.setVideoState(id, conference.getVideoState());
Tyler Gunn10362372020-04-08 13:12:30 -07003088 // In some instances a conference can start its life as a standalone call with just a
3089 // single participant; ensure we signal to Telecom in this case.
3090 if (!conference.isMultiparty()) {
3091 mAdapter.setConferenceState(id, conference.isMultiparty());
3092 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003093
3094 // Go through any child calls and set the parent.
3095 for (Connection connection : conference.getConnections()) {
3096 String connectionId = mIdByConnection.get(connection);
3097 if (connectionId != null) {
3098 mAdapter.setIsConferenced(connectionId, id);
3099 }
3100 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003101 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003102 }
3103 }
3104
3105 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003106 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
3107 * connection.
3108 *
3109 * @param phoneAccountHandle The phone account handle for the connection.
3110 * @param connection The connection to add.
3111 */
3112 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
3113 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07003114 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
3115 }
3116
3117 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003118 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
3119 * microphone, camera).
3120 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08003121 * <p>
3122 * The {@link ConnectionService} will be disconnected when it failed to call this method within
3123 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
3124 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08003125 * @see ConnectionService#onConnectionServiceFocusLost()
3126 */
3127 public final void connectionServiceFocusReleased() {
3128 mAdapter.onConnectionServiceFocusReleased();
3129 }
3130
3131 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07003132 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07003133 * connection, as well as adding that connection to the specified conference.
3134 * <p>
3135 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
3136 * IMS conference participants to be added to a conference in a single step; this helps ensure
3137 * UI updates happen atomically, rather than adding the connection and then adding it to
3138 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07003139 *
3140 * @param phoneAccountHandle The phone account handle for the connection.
3141 * @param connection The connection to add.
3142 * @param conference The parent conference of the new connection.
3143 * @hide
3144 */
Tyler Gunn5567d742019-10-31 13:04:37 -07003145 @SystemApi
3146 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
3147 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003148
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003149 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003150 if (id != null) {
3151 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07003152 String conferenceId = null;
3153 if (conference != null) {
3154 conferenceId = mIdByConference.get(conference);
3155 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003156
3157 ParcelableConnection parcelableConnection = new ParcelableConnection(
3158 phoneAccountHandle,
3159 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08003160 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07003161 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08003162 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003163 connection.getAddress(),
3164 connection.getAddressPresentation(),
3165 connection.getCallerDisplayName(),
3166 connection.getCallerDisplayNamePresentation(),
3167 connection.getVideoProvider() == null ?
3168 null : connection.getVideoProvider().getInterface(),
3169 connection.getVideoState(),
3170 connection.isRingbackRequested(),
3171 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07003172 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08003173 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003174 connection.getStatusHints(),
3175 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07003176 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07003177 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07003178 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07003179 connection.getCallDirection(),
3180 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003181 mAdapter.addExistingConnection(id, parcelableConnection);
3182 }
3183 }
3184
3185 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07003186 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
3187 * has taken responsibility.
3188 *
3189 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07003190 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07003191 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07003192 return mConnectionById.values();
3193 }
3194
3195 /**
Santos Cordona6018b92016-02-16 14:23:12 -08003196 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
3197 * has taken responsibility.
3198 *
3199 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
3200 */
3201 public final Collection<Conference> getAllConferences() {
3202 return mConferenceById.values();
3203 }
3204
3205 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07003206 * Create a {@code Connection} given an incoming request. This is used to attach to existing
3207 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07003208 *
Ihab Awadf8b69882014-07-25 15:14:01 -07003209 * @param connectionManagerPhoneAccount See description at
3210 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
3211 * @param request Details about the incoming call.
3212 * @return The {@code Connection} object to satisfy this call, or {@code null} to
3213 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07003214 */
Ihab Awadf8b69882014-07-25 15:14:01 -07003215 public Connection onCreateIncomingConnection(
3216 PhoneAccountHandle connectionManagerPhoneAccount,
3217 ConnectionRequest request) {
3218 return null;
3219 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05303220 /**
Grace Jia8587ee52020-07-10 15:42:32 -07003221 * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
3222 * conference call initiated via
3223 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303224 *
3225 * @param connectionManagerPhoneAccount See description at
3226 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Grace Jia8587ee52020-07-10 15:42:32 -07003227 * @param request Details about the incoming conference call.
Grace Jia41895152021-01-19 13:57:51 -08003228 * @return The {@code Conference} object to satisfy this call. If the conference attempt is
3229 * failed, the return value will be a result of an invocation of
3230 * {@link Connection#createFailedConnection(DisconnectCause)}.
3231 * Return {@code null} if the {@link ConnectionService} cannot handle the call.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303232 */
3233 public @Nullable Conference onCreateIncomingConference(
Grace Jia41895152021-01-19 13:57:51 -08003234 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
3235 @NonNull ConnectionRequest request) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05303236 return null;
3237 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07003238
3239 /**
Tyler Gunnda266f22023-12-21 21:23:31 +00003240 * Called by Telecom after the {@link Connection} returned by
Tyler Gunn041a1fe2017-05-12 10:04:49 -07003241 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
3242 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
3243 * added to the {@link ConnectionService} and sent to Telecom.
3244 *
Tyler Gunnda266f22023-12-21 21:23:31 +00003245 * @param connection the {@link Connection} which was added to Telecom.
Tyler Gunn041a1fe2017-05-12 10:04:49 -07003246 */
Tyler Gunnda266f22023-12-21 21:23:31 +00003247 @FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES)
3248 public void onCreateConnectionComplete(@NonNull Connection connection) {
Tyler Gunn041a1fe2017-05-12 10:04:49 -07003249 }
3250
3251 /**
Tyler Gunnda266f22023-12-21 21:23:31 +00003252 * Called by Telecom after the {@link Conference} returned by
Ravi Paluri80aa2142019-12-02 11:57:37 +05303253 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
3254 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
3255 * added to the {@link ConnectionService} and sent to Telecom.
3256 *
Tyler Gunnda266f22023-12-21 21:23:31 +00003257 * @param conference the {@link Conference} which was added to Telecom.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303258 */
Tyler Gunnda266f22023-12-21 21:23:31 +00003259 @FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES)
3260 public void onCreateConferenceComplete(@NonNull Conference conference) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05303261 }
3262
3263
3264 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08003265 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
3266 * incoming {@link Connection} was denied.
3267 * <p>
3268 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
3269 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
3270 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
3271 * {@link Connection}.
3272 * <p>
3273 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
3274 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08003275 * @param connectionManagerPhoneAccount See description at
3276 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08003277 * @param request The incoming connection request.
3278 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08003279 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
3280 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08003281 }
3282
3283 /**
3284 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
3285 * outgoing {@link Connection} was denied.
3286 * <p>
3287 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
3288 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
3289 * The {@link ConnectionService} is responisible for informing the user that the
3290 * {@link Connection} cannot be made at this time.
3291 * <p>
3292 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
3293 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08003294 * @param connectionManagerPhoneAccount See description at
3295 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08003296 * @param request The outgoing connection request.
3297 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08003298 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
3299 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08003300 }
3301
3302 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05303303 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
3304 * incoming {@link Conference} was denied.
3305 * <p>
3306 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
3307 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
3308 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
3309 * {@link Conference}.
3310 * <p>
3311 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
3312 *
3313 * @param connectionManagerPhoneAccount See description at
3314 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
3315 * @param request The incoming connection request.
3316 */
3317 public void onCreateIncomingConferenceFailed(
3318 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
3319 @Nullable ConnectionRequest request) {
3320 }
3321
3322 /**
3323 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
3324 * outgoing {@link Conference} was denied.
3325 * <p>
3326 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
3327 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
3328 * The {@link ConnectionService} is responisible for informing the user that the
3329 * {@link Conference} cannot be made at this time.
3330 * <p>
3331 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
3332 *
3333 * @param connectionManagerPhoneAccount See description at
3334 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
3335 * @param request The outgoing connection request.
3336 */
3337 public void onCreateOutgoingConferenceFailed(
Grace Jia41895152021-01-19 13:57:51 -08003338 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
3339 @NonNull ConnectionRequest request) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05303340 }
3341
3342
3343 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08003344 * Trigger recalculate functinality for conference calls. This is used when a Telephony
3345 * Connection is part of a conference controller but is not yet added to Connection
3346 * Service and hence cannot be added to the conference call.
3347 *
3348 * @hide
3349 */
3350 public void triggerConferenceRecalculate() {
3351 }
3352
3353 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07003354 * Create a {@code Connection} given an outgoing request. This is used to initiate new
3355 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07003356 *
Ihab Awadf8b69882014-07-25 15:14:01 -07003357 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3358 * this call.
3359 * <p>
3360 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
3361 * has registered one or more {@code PhoneAccount}s having
3362 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
3363 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
3364 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
3365 * making the connection.
3366 * <p>
3367 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
3368 * being asked to make a direct connection. The
3369 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3370 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3371 * making the connection.
3372 * @param request Details about the outgoing call.
3373 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07003374 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07003375 */
Ihab Awadf8b69882014-07-25 15:14:01 -07003376 public Connection onCreateOutgoingConnection(
3377 PhoneAccountHandle connectionManagerPhoneAccount,
3378 ConnectionRequest request) {
3379 return null;
3380 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003381
3382 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05303383 * Create a {@code Conference} given an outgoing request. This is used to initiate new
Grace Jia8587ee52020-07-10 15:42:32 -07003384 * outgoing conference call requested via
3385 * {@link TelecomManager#startConference(List, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303386 *
3387 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3388 * this call.
3389 * <p>
3390 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
3391 * has registered one or more {@code PhoneAccount}s having
3392 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
3393 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
3394 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
3395 * making the connection.
3396 * <p>
3397 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
3398 * being asked to make a direct connection. The
3399 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3400 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3401 * making the connection.
3402 * @param request Details about the outgoing call.
Grace Jia41895152021-01-19 13:57:51 -08003403 * @return The {@code Conference} object to satisfy this call. If the conference attempt is
3404 * failed, the return value will be a result of an invocation of
3405 * {@link Connection#createFailedConnection(DisconnectCause)}.
3406 * Return {@code null} if the {@link ConnectionService} cannot handle the call.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303407 */
3408 public @Nullable Conference onCreateOutgoingConference(
Grace Jia41895152021-01-19 13:57:51 -08003409 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
3410 @NonNull ConnectionRequest request) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05303411 return null;
3412 }
3413
3414
3415 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003416 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3417 * outgoing handover {@link Connection}.
3418 * <p>
3419 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3420 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3421 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3422 * is referred to as the source of the handover, and the video calling app is referred to as the
3423 * destination.
3424 * <p>
3425 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3426 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3427 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3428 * device.
3429 * <p>
3430 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
3431 * device when the user initiates a handover request from one app to another. The user request
3432 * originates in the {@link InCallService} via
3433 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3434 * <p>
3435 * For a full discussion of the handover process and the APIs involved, see
3436 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3437 * <p>
3438 * Implementations of this method should return an instance of {@link Connection} which
3439 * represents the handover. If your app does not wish to accept a handover to it at this time,
3440 * you can return {@code null}. The code below shows an example of how this is done.
3441 * <pre>
3442 * {@code
3443 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3444 * fromPhoneAccountHandle, ConnectionRequest request) {
3445 * if (!isHandoverAvailable()) {
3446 * return null;
3447 * }
3448 * MyConnection connection = new MyConnection();
3449 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3450 * connection.setVideoState(request.getVideoState());
3451 * return connection;
3452 * }
3453 * }
3454 * </pre>
3455 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003456 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3457 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08003458 * @param request Details about the call to handover.
3459 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003460 */
3461 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3462 ConnectionRequest request) {
3463 return null;
3464 }
3465
3466 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003467 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3468 * incoming handover {@link Connection}.
3469 * <p>
3470 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3471 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3472 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3473 * is referred to as the source of the handover, and the video calling app is referred to as the
3474 * destination.
3475 * <p>
3476 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3477 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3478 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3479 * device.
3480 * <p>
3481 * This method is called on the destination app on the <em>receiving</em> device when the
3482 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
3483 * accept an incoming handover from the <em>initiating</em> device.
3484 * <p>
3485 * For a full discussion of the handover process and the APIs involved, see
3486 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3487 * <p>
3488 * Implementations of this method should return an instance of {@link Connection} which
3489 * represents the handover. The code below shows an example of how this is done.
3490 * <pre>
3491 * {@code
3492 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3493 * fromPhoneAccountHandle, ConnectionRequest request) {
3494 * // Given that your app requested to accept the handover, you should not return null here.
3495 * MyConnection connection = new MyConnection();
3496 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3497 * connection.setVideoState(request.getVideoState());
3498 * return connection;
3499 * }
3500 * }
3501 * </pre>
3502 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003503 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3504 * ConnectionService which needs to handover the call.
3505 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08003506 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003507 */
3508 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3509 ConnectionRequest request) {
3510 return null;
3511 }
3512
3513 /**
3514 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
3515 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08003516 * <p>
3517 * For a full discussion of the handover process and the APIs involved, see
3518 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
3519 *
3520 * @param request Details about the call which failed to handover.
3521 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07003522 */
Tyler Gunn9d127732018-03-02 15:45:51 -08003523 public void onHandoverFailed(ConnectionRequest request,
3524 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07003525 return;
3526 }
3527
3528 /**
Roopa Sattiraju45de470c2022-01-27 21:31:35 -08003529 * Calls of this type are created using
3530 * {@link TelecomManager#addNewUnknownCall(PhoneAccountHandle, Bundle)}. Unknown calls
3531 * are used for representing calls which become known to the {@link ConnectionService}
3532 * midway through the call.
3533 *
3534 * For example, a call transferred from one device to answer would surface as an active
3535 * call in Telecom instead of going through a typical Ringing to Active transition, or
3536 * Dialing to Active transition.
3537 *
3538 * A {@link ConnectionService} can return {@code null} (the default behavior)
3539 * if it is not able to handle a request for the requested unknown connection.
3540 *
3541 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
Yorke Leec3cf9822014-10-02 09:38:39 -07003542 *
Etienne Ruffieuxb99333d2022-02-25 16:11:01 +00003543 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3544 * this call
3545 * @param request Details about the outgoing call
3546 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
3547 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call
Yorke Lee770ed6e2014-10-06 18:58:52 -07003548 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07003549 */
Etienne Ruffieuxb99333d2022-02-25 16:11:01 +00003550 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
Roopa Sattiraju45de470c2022-01-27 21:31:35 -08003551 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3552 public @Nullable Connection onCreateUnknownConnection(
3553 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
3554 @NonNull ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003555 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07003556 }
3557
3558 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003559 * Conference two specified connections. Invoked when the user has made a request to merge the
3560 * specified connections into a conference call. In response, the connection service should
3561 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07003562 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07003563 * @param connection1 A connection to merge into a conference call.
3564 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07003565 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07003566 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07003567
Santos Cordona663f862014-10-29 13:49:58 -07003568 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07003569 * Called when a connection is added.
3570 * @hide
3571 */
3572 public void onConnectionAdded(Connection connection) {}
3573
3574 /**
3575 * Called when a connection is removed.
3576 * @hide
3577 */
3578 public void onConnectionRemoved(Connection connection) {}
3579
3580 /**
3581 * Called when a conference is added.
3582 * @hide
3583 */
3584 public void onConferenceAdded(Conference conference) {}
3585
3586 /**
3587 * Called when a conference is removed.
3588 * @hide
3589 */
3590 public void onConferenceRemoved(Conference conference) {}
3591
3592 /**
Santos Cordona663f862014-10-29 13:49:58 -07003593 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
3594 * When this method is invoked, this {@link ConnectionService} should create its own
3595 * representation of the conference call and send it to telecom using {@link #addConference}.
3596 * <p>
3597 * This is only relevant to {@link ConnectionService}s which are registered with
3598 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
3599 *
3600 * @param conference The remote conference call.
3601 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07003602 public void onRemoteConferenceAdded(RemoteConference conference) {}
3603
Santos Cordon823fd3c2014-08-07 18:35:18 -07003604 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003605 * Called when an existing connection is added remotely.
3606 * @param connection The existing connection which was added.
3607 */
3608 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
3609
3610 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003611 * Called when the {@link ConnectionService} has lost the call focus.
3612 * The {@link ConnectionService} should release the call resources and invokes
3613 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
3614 * released the call resources.
3615 */
3616 public void onConnectionServiceFocusLost() {}
3617
3618 /**
3619 * Called when the {@link ConnectionService} has gained the call focus. The
3620 * {@link ConnectionService} can acquire the call resources at this time.
3621 */
3622 public void onConnectionServiceFocusGained() {}
3623
3624 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003625 * @hide
3626 */
3627 public boolean containsConference(Conference conference) {
3628 return mIdByConference.containsKey(conference);
3629 }
3630
Ihab Awadb8e85c72014-08-23 20:34:57 -07003631 /** {@hide} */
3632 void addRemoteConference(RemoteConference remoteConference) {
3633 onRemoteConferenceAdded(remoteConference);
3634 }
3635
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003636 /** {@hide} */
3637 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
3638 onRemoteExistingConnectionAdded(remoteConnection);
3639 }
3640
Ihab Awad5d0410f2014-07-30 10:07:40 -07003641 private void onAccountsInitialized() {
3642 mAreAccountsInitialized = true;
3643 for (Runnable r : mPreInitializationConnectionRequests) {
3644 r.run();
3645 }
3646 mPreInitializationConnectionRequests.clear();
3647 }
3648
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003649 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003650 * Adds an existing connection to the list of connections, identified by a new call ID unique
3651 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003652 *
3653 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003654 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003655 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003656 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
3657 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003658
3659 if (connection.getExtras() != null && connection.getExtras()
3660 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3661 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3662 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
3663 connection.getTelecomCallId(), id);
3664 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003665 // If no phone account handle was provided, we cannot be sure the call ID is unique,
3666 // so just use a random UUID.
3667 id = UUID.randomUUID().toString();
3668 } else {
3669 // Phone account handle was provided, so use the ConnectionService class name as a
3670 // prefix for a unique incremental call ID.
3671 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
3672 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003673 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003674 return id;
3675 }
3676
Pengquan Meng70c9885332017-10-02 18:09:03 -07003677 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003678 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003679 mConnectionById.put(callId, connection);
3680 mIdByConnection.put(connection, callId);
3681 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003682 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003683 connection.setPhoneAccountHandle(handle);
3684 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003685 }
3686
Anthony Lee30e65842014-11-06 16:30:53 -08003687 /** {@hide} */
3688 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003689 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003690 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003691 String id = mIdByConnection.get(connection);
3692 if (id != null) {
3693 mConnectionById.remove(id);
3694 mIdByConnection.remove(connection);
3695 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003696 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003697 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003698 }
3699
Santos Cordon823fd3c2014-08-07 18:35:18 -07003700 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003701 String originalId = null;
3702 if (conference.getExtras() != null && conference.getExtras()
3703 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3704 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3705 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3706 conference.getTelecomCallId(),
3707 originalId);
3708 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003709 if (mIdByConference.containsKey(conference)) {
3710 Log.w(this, "Re-adding an existing conference: %s.", conference);
3711 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003712 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3713 // cannot determine a ConnectionService class name to associate with the ID, so use
3714 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003715 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003716 mConferenceById.put(id, conference);
3717 mIdByConference.put(conference, id);
3718 conference.addListener(mConferenceListener);
3719 return id;
3720 }
3721
3722 return null;
3723 }
3724
3725 private void removeConference(Conference conference) {
3726 if (mIdByConference.containsKey(conference)) {
3727 conference.removeListener(mConferenceListener);
3728
3729 String id = mIdByConference.get(conference);
3730 mConferenceById.remove(id);
3731 mIdByConference.remove(conference);
3732 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003733
3734 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003735 }
3736 }
3737
Ihab Awad542e0ea2014-05-16 10:22:16 -07003738 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003739 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003740 return mConnectionById.get(callId);
3741 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003742 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003743 return getNullConnection();
3744 }
3745
3746 static synchronized Connection getNullConnection() {
3747 if (sNullConnection == null) {
3748 sNullConnection = new Connection() {};
3749 }
3750 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003751 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003752
3753 private Conference findConferenceForAction(String conferenceId, String action) {
3754 if (mConferenceById.containsKey(conferenceId)) {
3755 return mConferenceById.get(conferenceId);
3756 }
3757 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3758 return getNullConference();
3759 }
3760
Ihab Awadb8e85c72014-08-23 20:34:57 -07003761 private List<String> createConnectionIdList(List<Connection> connections) {
3762 List<String> ids = new ArrayList<>();
3763 for (Connection c : connections) {
3764 if (mIdByConnection.containsKey(c)) {
3765 ids.add(mIdByConnection.get(c));
3766 }
3767 }
3768 Collections.sort(ids);
3769 return ids;
3770 }
3771
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003772 /**
3773 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003774 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003775 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003776 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003777 * @return List of string conference and call Ids.
3778 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003779 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003780 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003781 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003782 // Only allow Connection and Conference conferenceables.
3783 if (c instanceof Connection) {
3784 Connection connection = (Connection) c;
3785 if (mIdByConnection.containsKey(connection)) {
3786 ids.add(mIdByConnection.get(connection));
3787 }
3788 } else if (c instanceof Conference) {
3789 Conference conference = (Conference) c;
3790 if (mIdByConference.containsKey(conference)) {
3791 ids.add(mIdByConference.get(conference));
3792 }
3793 }
3794 }
3795 Collections.sort(ids);
3796 return ids;
3797 }
3798
Santos Cordon0159ac02014-08-21 14:28:11 -07003799 private Conference getNullConference() {
3800 if (sNullConference == null) {
3801 sNullConference = new Conference(null) {};
3802 }
3803 return sNullConference;
3804 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003805
3806 private void endAllConnections() {
3807 // Unbound from telecomm. We should end all connections and conferences.
3808 for (Connection connection : mIdByConnection.keySet()) {
3809 // only operate on top-level calls. Conference calls will be removed on their own.
3810 if (connection.getConference() == null) {
3811 connection.onDisconnect();
3812 }
3813 }
3814 for (Conference conference : mIdByConference.keySet()) {
3815 conference.onDisconnect();
3816 }
3817 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003818
3819 /**
3820 * Retrieves the next call ID as maintainted by the connection service.
3821 *
3822 * @return The call ID.
3823 */
3824 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003825 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003826 return ++mId;
3827 }
3828 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003829
3830 /**
3831 * Returns this handler, ONLY FOR TESTING.
3832 * @hide
3833 */
3834 @VisibleForTesting
3835 public Handler getHandler() {
3836 return mHandler;
3837 }
Tyler Gunnc7e07b92021-04-06 11:40:57 -07003838
3839 /**
3840 * Sets this {@link ConnectionService} ready for testing purposes.
3841 * @hide
3842 */
3843 @VisibleForTesting
3844 public void setReadyForTest() {
3845 mAreAccountsInitialized = true;
3846 }
Santos Cordon980acb92014-05-31 10:31:19 -07003847}