blob: f341bc20fe0152bc8969052eb6f01a06e1e7863b [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
Tyler Gunn5567d742019-10-31 13:04:37 -070019import android.annotation.NonNull;
20import android.annotation.Nullable;
Roopa Sattiraju45de470c2022-01-27 21:31:35 -080021import android.annotation.RequiresPermission;
Santos Cordon5c6fa952014-07-20 17:47:12 -070022import android.annotation.SdkConstant;
Tyler Gunn5567d742019-10-31 13:04:37 -070023import android.annotation.SystemApi;
Hall Liueb7c9ea2021-03-09 20:24:50 -080024import android.annotation.TestApi;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070025import android.app.Service;
Santos Cordon52d8a152014-06-17 19:08:45 -070026import android.content.ComponentName;
Santos Cordon5c6fa952014-07-20 17:47:12 -070027import android.content.Intent;
Ihab Awad542e0ea2014-05-16 10:22:16 -070028import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070029import android.os.Bundle;
Santos Cordon52d8a152014-06-17 19:08:45 -070030import android.os.Handler;
31import android.os.IBinder;
32import android.os.Looper;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070033import android.os.Message;
Hall Liub64ac4c2017-02-06 10:49:48 -080034import android.os.ParcelFileDescriptor;
35import android.os.RemoteException;
Brad Ebingerb32d4f82016-10-24 16:40:49 -070036import android.telecom.Logging.Session;
Andrew Lee14185762014-07-25 09:41:56 -070037
Brad Ebinger99f17ce2019-09-11 18:06:51 -070038import com.android.internal.annotations.VisibleForTesting;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070039import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070040import com.android.internal.telecom.IConnectionService;
41import com.android.internal.telecom.IConnectionServiceAdapter;
42import com.android.internal.telecom.RemoteServiceCallback;
Santos Cordon52d8a152014-06-17 19:08:45 -070043
Ihab Awad5d0410f2014-07-30 10:07:40 -070044import java.util.ArrayList;
Santos Cordonb6939982014-06-04 20:20:58 -070045import java.util.Collection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070046import java.util.Collections;
Santos Cordon52d8a152014-06-17 19:08:45 -070047import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070048import java.util.Map;
Santos Cordon823fd3c2014-08-07 18:35:18 -070049import java.util.UUID;
mike dooley95e80702014-09-18 14:07:52 -070050import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070051
52/**
Tyler Gunnf5035432017-01-09 09:43:12 -080053 * An abstract service that should be implemented by any apps which either:
54 * <ol>
55 * <li>Can make phone calls (VoIP or otherwise) and want those calls to be integrated into the
56 * built-in phone app. Referred to as a <b>system managed</b> {@link ConnectionService}.</li>
57 * <li>Are a standalone calling app and don't want their calls to be integrated into the
58 * built-in phone app. Referred to as a <b>self managed</b> {@link ConnectionService}.</li>
59 * </ol>
60 * Once implemented, the {@link ConnectionService} needs to take the following steps so that Telecom
61 * will bind to it:
Santos Cordona663f862014-10-29 13:49:58 -070062 * <p>
63 * 1. <i>Registration in AndroidManifest.xml</i>
64 * <br/>
65 * <pre>
66 * &lt;service android:name="com.example.package.MyConnectionService"
67 * android:label="@string/some_label_for_my_connection_service"
Yorke Lee249c12e2015-05-13 15:59:29 -070068 * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"&gt;
Santos Cordona663f862014-10-29 13:49:58 -070069 * &lt;intent-filter&gt;
70 * &lt;action android:name="android.telecom.ConnectionService" /&gt;
71 * &lt;/intent-filter&gt;
72 * &lt;/service&gt;
73 * </pre>
74 * <p>
75 * 2. <i> Registration of {@link PhoneAccount} with {@link TelecomManager}.</i>
76 * <br/>
77 * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
78 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080079 * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
kopriva82c591b2018-10-08 15:57:00 -070080 * before Telecom will bind to them. Self-managed {@link ConnectionService}s must be granted the
Tyler Gunnf5035432017-01-09 09:43:12 -080081 * appropriate permission before Telecom will bind to them.
82 * <p>
83 * Once registered and enabled by the user in the phone app settings or granted permission, telecom
84 * will bind to a {@link ConnectionService} implementation when it wants that
85 * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
86 * call through {@link TelecomManager#addNewIncomingCall}. The {@link ConnectionService} can then
87 * expect a call to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection}
88 * wherein it should provide a new instance of a {@link Connection} object. It is through this
89 * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
Santos Cordona663f862014-10-29 13:49:58 -070090 * receives call-commands such as answer, reject, hold and disconnect.
91 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080092 * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
Ihab Awad542e0ea2014-05-16 10:22:16 -070093 */
Sailesh Nepal2a46b902014-07-04 17:21:07 -070094public abstract class ConnectionService extends Service {
Santos Cordon5c6fa952014-07-20 17:47:12 -070095 /**
96 * The {@link Intent} that must be declared as handled by the service.
97 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070098 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
Tyler Gunnef9f6f92014-09-12 22:16:17 -070099 public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
Santos Cordon5c6fa952014-07-20 17:47:12 -0700100
Tyler Gunn8bf76572017-04-06 15:30:08 -0700101 /**
102 * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
103 * being asked to create a new outgoing {@link Connection} is to perform a handover of an
104 * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}. Will
105 * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
106 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
107 * <p>
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700108 * When your {@link ConnectionService} receives this extra, it should communicate the fact that
109 * this is a handover to the other device's matching {@link ConnectionService}. That
Tyler Gunn8bf76572017-04-06 15:30:08 -0700110 * {@link ConnectionService} will continue the handover using
111 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700112 * {@link TelecomManager#EXTRA_IS_HANDOVER}. Telecom will match the phone numbers of the
113 * handover call on the other device with ongoing calls for {@link ConnectionService}s which
114 * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700115 * @hide
116 */
117 public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
118
Ihab Awad542e0ea2014-05-16 10:22:16 -0700119 // Flag controlling whether PII is emitted into the logs
Ihab Awad60ac30b2014-05-20 22:32:12 -0700120 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700121
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700122 // Session Definitions
123 private static final String SESSION_HANDLER = "H.";
124 private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
125 private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
126 private static final String SESSION_CREATE_CONN = "CS.crCo";
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700127 private static final String SESSION_CREATE_CONN_COMPLETE = "CS.crCoC";
Tyler Gunn44e01912017-01-31 10:49:05 -0800128 private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700129 private static final String SESSION_ABORT = "CS.ab";
130 private static final String SESSION_ANSWER = "CS.an";
131 private static final String SESSION_ANSWER_VIDEO = "CS.anV";
Pooja Jaind34698d2017-12-28 14:15:31 +0530132 private static final String SESSION_DEFLECT = "CS.def";
Ravi Palurif4b38e72020-02-05 12:35:41 +0530133 private static final String SESSION_TRANSFER = "CS.trans";
134 private static final String SESSION_CONSULTATIVE_TRANSFER = "CS.cTrans";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700135 private static final String SESSION_REJECT = "CS.r";
136 private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
137 private static final String SESSION_SILENCE = "CS.s";
138 private static final String SESSION_DISCONNECT = "CS.d";
139 private static final String SESSION_HOLD = "CS.h";
140 private static final String SESSION_UNHOLD = "CS.u";
141 private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
Grace Jiae99fde92021-01-19 14:58:01 -0800142 private static final String SESSION_USING_ALTERNATIVE_UI = "CS.uAU";
143 private static final String SESSION_TRACKED_BY_NON_UI_SERVICE = "CS.tBNUS";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700144 private static final String SESSION_PLAY_DTMF = "CS.pDT";
145 private static final String SESSION_STOP_DTMF = "CS.sDT";
146 private static final String SESSION_CONFERENCE = "CS.c";
147 private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
148 private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
149 private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
Ravi Paluri404babb2020-01-23 19:02:44 +0530150 private static final String SESSION_ADD_PARTICIPANT = "CS.aP";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700151 private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
152 private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
153 private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
Hall Liu49cabcc2021-01-15 11:41:48 -0800154 private static final String SESSION_CALL_FILTERING_COMPLETED = "CS.oCFC";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800155 private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700156 private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
Hall Liub64ac4c2017-02-06 10:49:48 -0800157 private static final String SESSION_START_RTT = "CS.+RTT";
Hall Liua549fed2018-02-09 16:40:03 -0800158 private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
Hall Liub64ac4c2017-02-06 10:49:48 -0800159 private static final String SESSION_STOP_RTT = "CS.-RTT";
160 private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
Pengquan Meng731c1a32017-11-21 18:01:13 -0800161 private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
162 private static final String SESSION_CONNECTION_SERVICE_FOCUS_GAINED = "CS.cSFG";
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800163 private static final String SESSION_HANDOVER_FAILED = "CS.haF";
Ravi Paluri80aa2142019-12-02 11:57:37 +0530164 private static final String SESSION_CREATE_CONF = "CS.crConf";
165 private static final String SESSION_CREATE_CONF_COMPLETE = "CS.crConfC";
166 private static final String SESSION_CREATE_CONF_FAILED = "CS.crConfF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700167
Ihab Awad8aecfed2014-08-08 17:06:11 -0700168 private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700169 private static final int MSG_CREATE_CONNECTION = 2;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700170 private static final int MSG_ABORT = 3;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700171 private static final int MSG_ANSWER = 4;
172 private static final int MSG_REJECT = 5;
173 private static final int MSG_DISCONNECT = 6;
174 private static final int MSG_HOLD = 7;
175 private static final int MSG_UNHOLD = 8;
Yorke Lee4af59352015-05-13 14:14:54 -0700176 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700177 private static final int MSG_PLAY_DTMF_TONE = 10;
178 private static final int MSG_STOP_DTMF_TONE = 11;
179 private static final int MSG_CONFERENCE = 12;
180 private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700181 private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700182 private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
Tyler Gunnbe74de02014-08-29 14:51:48 -0700183 private static final int MSG_ANSWER_VIDEO = 17;
Santos Cordona4868042014-09-04 17:39:22 -0700184 private static final int MSG_MERGE_CONFERENCE = 18;
185 private static final int MSG_SWAP_CONFERENCE = 19;
Bryce Lee81901682015-08-28 16:38:02 -0700186 private static final int MSG_REJECT_WITH_MESSAGE = 20;
Bryce Leecac50772015-11-17 15:13:29 -0800187 private static final int MSG_SILENCE = 21;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700188 private static final int MSG_PULL_EXTERNAL_CALL = 22;
189 private static final int MSG_SEND_CALL_EVENT = 23;
Tyler Gunndee56a82016-03-23 16:06:34 -0700190 private static final int MSG_ON_EXTRAS_CHANGED = 24;
Tyler Gunn44e01912017-01-31 10:49:05 -0800191 private static final int MSG_CREATE_CONNECTION_FAILED = 25;
Hall Liub64ac4c2017-02-06 10:49:48 -0800192 private static final int MSG_ON_START_RTT = 26;
193 private static final int MSG_ON_STOP_RTT = 27;
194 private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700195 private static final int MSG_CREATE_CONNECTION_COMPLETE = 29;
Pengquan Meng731c1a32017-11-21 18:01:13 -0800196 private static final int MSG_CONNECTION_SERVICE_FOCUS_LOST = 30;
197 private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800198 private static final int MSG_HANDOVER_FAILED = 32;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800199 private static final int MSG_HANDOVER_COMPLETE = 33;
Pooja Jaind34698d2017-12-28 14:15:31 +0530200 private static final int MSG_DEFLECT = 34;
Ravi Paluri80aa2142019-12-02 11:57:37 +0530201 private static final int MSG_CREATE_CONFERENCE = 35;
202 private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
203 private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800204 private static final int MSG_REJECT_WITH_REASON = 38;
Ravi Paluri404babb2020-01-23 19:02:44 +0530205 private static final int MSG_ADD_PARTICIPANT = 39;
Ravi Palurif4b38e72020-02-05 12:35:41 +0530206 private static final int MSG_EXPLICIT_CALL_TRANSFER = 40;
207 private static final int MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE = 41;
Hall Liu49cabcc2021-01-15 11:41:48 -0800208 private static final int MSG_ON_CALL_FILTERING_COMPLETED = 42;
Grace Jiae99fde92021-01-19 14:58:01 -0800209 private static final int MSG_ON_USING_ALTERNATIVE_UI = 43;
210 private static final int MSG_ON_TRACKED_BY_NON_UI_SERVICE = 44;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700211
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700212 private static Connection sNullConnection;
213
mike dooley95e80702014-09-18 14:07:52 -0700214 private final Map<String, Connection> mConnectionById = new ConcurrentHashMap<>();
215 private final Map<Connection, String> mIdByConnection = new ConcurrentHashMap<>();
216 private final Map<String, Conference> mConferenceById = new ConcurrentHashMap<>();
217 private final Map<Conference, String> mIdByConference = new ConcurrentHashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700218 private final RemoteConnectionManager mRemoteConnectionManager =
219 new RemoteConnectionManager(this);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700220 private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700221 private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
Ihab Awad542e0ea2014-05-16 10:22:16 -0700222
Santos Cordon823fd3c2014-08-07 18:35:18 -0700223 private boolean mAreAccountsInitialized = false;
Santos Cordon0159ac02014-08-21 14:28:11 -0700224 private Conference sNullConference;
Tyler Gunnf0500bd2015-09-01 10:59:48 -0700225 private Object mIdSyncRoot = new Object();
226 private int mId = 0;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700227
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700228 private final IBinder mBinder = new IConnectionService.Stub() {
229 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700230 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
231 Session.Info sessionInfo) {
232 Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
233 try {
234 SomeArgs args = SomeArgs.obtain();
235 args.arg1 = adapter;
236 args.arg2 = Log.createSubsession();
237 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
238 } finally {
239 Log.endSession();
240 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700241 }
242
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700243 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
244 Session.Info sessionInfo) {
245 Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
246 try {
247 SomeArgs args = SomeArgs.obtain();
248 args.arg1 = adapter;
249 args.arg2 = Log.createSubsession();
250 mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
251 } finally {
252 Log.endSession();
253 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700254 }
255
256 @Override
Ihab Awadf8b69882014-07-25 15:14:01 -0700257 public void createConnection(
258 PhoneAccountHandle connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700259 String id,
Ihab Awadf8b69882014-07-25 15:14:01 -0700260 ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700261 boolean isIncoming,
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700262 boolean isUnknown,
263 Session.Info sessionInfo) {
264 Log.startSession(sessionInfo, SESSION_CREATE_CONN);
265 try {
266 SomeArgs args = SomeArgs.obtain();
267 args.arg1 = connectionManagerPhoneAccount;
268 args.arg2 = id;
269 args.arg3 = request;
270 args.arg4 = Log.createSubsession();
271 args.argi1 = isIncoming ? 1 : 0;
272 args.argi2 = isUnknown ? 1 : 0;
273 mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
274 } finally {
275 Log.endSession();
276 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700277 }
278
279 @Override
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700280 public void createConnectionComplete(String id, Session.Info sessionInfo) {
281 Log.startSession(sessionInfo, SESSION_CREATE_CONN_COMPLETE);
282 try {
283 SomeArgs args = SomeArgs.obtain();
284 args.arg1 = id;
285 args.arg2 = Log.createSubsession();
286 mHandler.obtainMessage(MSG_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
287 } finally {
288 Log.endSession();
289 }
290 }
291
292 @Override
Tyler Gunn44e01912017-01-31 10:49:05 -0800293 public void createConnectionFailed(
Tyler Gunn159f35c2017-03-02 09:28:37 -0800294 PhoneAccountHandle connectionManagerPhoneAccount,
Tyler Gunn44e01912017-01-31 10:49:05 -0800295 String callId,
296 ConnectionRequest request,
297 boolean isIncoming,
298 Session.Info sessionInfo) {
299 Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
300 try {
301 SomeArgs args = SomeArgs.obtain();
302 args.arg1 = callId;
303 args.arg2 = request;
304 args.arg3 = Log.createSubsession();
Tyler Gunn159f35c2017-03-02 09:28:37 -0800305 args.arg4 = connectionManagerPhoneAccount;
Tyler Gunn44e01912017-01-31 10:49:05 -0800306 args.argi1 = isIncoming ? 1 : 0;
307 mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
308 } finally {
309 Log.endSession();
310 }
311 }
312
313 @Override
Ravi Paluri80aa2142019-12-02 11:57:37 +0530314 public void createConference(
315 PhoneAccountHandle connectionManagerPhoneAccount,
316 String id,
317 ConnectionRequest request,
318 boolean isIncoming,
319 boolean isUnknown,
320 Session.Info sessionInfo) {
321 Log.startSession(sessionInfo, SESSION_CREATE_CONF);
322 try {
323 SomeArgs args = SomeArgs.obtain();
324 args.arg1 = connectionManagerPhoneAccount;
325 args.arg2 = id;
326 args.arg3 = request;
327 args.arg4 = Log.createSubsession();
328 args.argi1 = isIncoming ? 1 : 0;
329 args.argi2 = isUnknown ? 1 : 0;
330 mHandler.obtainMessage(MSG_CREATE_CONFERENCE, args).sendToTarget();
331 } finally {
332 Log.endSession();
333 }
334 }
335
336 @Override
337 public void createConferenceComplete(String id, Session.Info sessionInfo) {
338 Log.startSession(sessionInfo, SESSION_CREATE_CONF_COMPLETE);
339 try {
340 SomeArgs args = SomeArgs.obtain();
341 args.arg1 = id;
342 args.arg2 = Log.createSubsession();
343 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_COMPLETE, args).sendToTarget();
344 } finally {
345 Log.endSession();
346 }
347 }
348
349 @Override
350 public void createConferenceFailed(
351 PhoneAccountHandle connectionManagerPhoneAccount,
352 String callId,
353 ConnectionRequest request,
354 boolean isIncoming,
355 Session.Info sessionInfo) {
356 Log.startSession(sessionInfo, SESSION_CREATE_CONF_FAILED);
357 try {
358 SomeArgs args = SomeArgs.obtain();
359 args.arg1 = callId;
360 args.arg2 = request;
361 args.arg3 = Log.createSubsession();
362 args.arg4 = connectionManagerPhoneAccount;
363 args.argi1 = isIncoming ? 1 : 0;
364 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_FAILED, args).sendToTarget();
365 } finally {
366 Log.endSession();
367 }
368 }
369
370 @Override
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800371 public void handoverFailed(String callId, ConnectionRequest request, int reason,
372 Session.Info sessionInfo) {
373 Log.startSession(sessionInfo, SESSION_HANDOVER_FAILED);
374 try {
375 SomeArgs args = SomeArgs.obtain();
376 args.arg1 = callId;
377 args.arg2 = request;
378 args.arg3 = Log.createSubsession();
379 args.arg4 = reason;
380 mHandler.obtainMessage(MSG_HANDOVER_FAILED, args).sendToTarget();
381 } finally {
382 Log.endSession();
383 }
384 }
385
386 @Override
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800387 public void handoverComplete(String callId, Session.Info sessionInfo) {
388 Log.startSession(sessionInfo, SESSION_HANDOVER_COMPLETE);
389 try {
390 SomeArgs args = SomeArgs.obtain();
391 args.arg1 = callId;
392 args.arg2 = Log.createSubsession();
393 mHandler.obtainMessage(MSG_HANDOVER_COMPLETE, args).sendToTarget();
394 } finally {
395 Log.endSession();
396 }
397 }
398
399 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700400 public void abort(String callId, Session.Info sessionInfo) {
401 Log.startSession(sessionInfo, SESSION_ABORT);
402 try {
403 SomeArgs args = SomeArgs.obtain();
404 args.arg1 = callId;
405 args.arg2 = Log.createSubsession();
406 mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
407 } finally {
408 Log.endSession();
409 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700410 }
411
412 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700413 public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
414 Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
415 try {
416 SomeArgs args = SomeArgs.obtain();
417 args.arg1 = callId;
418 args.arg2 = Log.createSubsession();
419 args.argi1 = videoState;
420 mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
421 } finally {
422 Log.endSession();
423 }
Tyler Gunnbe74de02014-08-29 14:51:48 -0700424 }
425
426 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700427 public void answer(String callId, Session.Info sessionInfo) {
428 Log.startSession(sessionInfo, SESSION_ANSWER);
429 try {
430 SomeArgs args = SomeArgs.obtain();
431 args.arg1 = callId;
432 args.arg2 = Log.createSubsession();
433 mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
434 } finally {
435 Log.endSession();
436 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700437 }
438
439 @Override
Pooja Jaind34698d2017-12-28 14:15:31 +0530440 public void deflect(String callId, Uri address, Session.Info sessionInfo) {
441 Log.startSession(sessionInfo, SESSION_DEFLECT);
442 try {
443 SomeArgs args = SomeArgs.obtain();
444 args.arg1 = callId;
445 args.arg2 = address;
446 args.arg3 = Log.createSubsession();
447 mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
448 } finally {
449 Log.endSession();
450 }
451 }
452
453 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700454 public void reject(String callId, Session.Info sessionInfo) {
455 Log.startSession(sessionInfo, SESSION_REJECT);
456 try {
457 SomeArgs args = SomeArgs.obtain();
458 args.arg1 = callId;
459 args.arg2 = Log.createSubsession();
460 mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
461 } finally {
462 Log.endSession();
463 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700464 }
465
466 @Override
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800467 public void rejectWithReason(String callId,
468 @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
469 Log.startSession(sessionInfo, SESSION_REJECT);
470 try {
471 SomeArgs args = SomeArgs.obtain();
472 args.arg1 = callId;
473 args.argi1 = rejectReason;
474 args.arg2 = Log.createSubsession();
475 mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
476 } finally {
477 Log.endSession();
478 }
479 }
480
481 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700482 public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
483 Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
484 try {
485 SomeArgs args = SomeArgs.obtain();
486 args.arg1 = callId;
487 args.arg2 = message;
488 args.arg3 = Log.createSubsession();
489 mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
490 } finally {
491 Log.endSession();
492 }
Bryce Lee81901682015-08-28 16:38:02 -0700493 }
494
495 @Override
Ravi Palurif4b38e72020-02-05 12:35:41 +0530496 public void transfer(@NonNull String callId, @NonNull Uri number,
497 boolean isConfirmationRequired, Session.Info sessionInfo) {
498 Log.startSession(sessionInfo, SESSION_TRANSFER);
499 try {
500 SomeArgs args = SomeArgs.obtain();
501 args.arg1 = callId;
502 args.arg2 = number;
503 args.argi1 = isConfirmationRequired ? 1 : 0;
504 args.arg3 = Log.createSubsession();
505 mHandler.obtainMessage(MSG_EXPLICIT_CALL_TRANSFER, args).sendToTarget();
506 } finally {
507 Log.endSession();
508 }
509 }
510
511 @Override
512 public void consultativeTransfer(@NonNull String callId, @NonNull String otherCallId,
513 Session.Info sessionInfo) {
514 Log.startSession(sessionInfo, SESSION_CONSULTATIVE_TRANSFER);
515 try {
516 SomeArgs args = SomeArgs.obtain();
517 args.arg1 = callId;
518 args.arg2 = otherCallId;
519 args.arg3 = Log.createSubsession();
520 mHandler.obtainMessage(
521 MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE, args).sendToTarget();
522 } finally {
523 Log.endSession();
524 }
525 }
526
527 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700528 public void silence(String callId, Session.Info sessionInfo) {
529 Log.startSession(sessionInfo, SESSION_SILENCE);
530 try {
531 SomeArgs args = SomeArgs.obtain();
532 args.arg1 = callId;
533 args.arg2 = Log.createSubsession();
534 mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
535 } finally {
536 Log.endSession();
537 }
Bryce Leecac50772015-11-17 15:13:29 -0800538 }
539
540 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700541 public void disconnect(String callId, Session.Info sessionInfo) {
542 Log.startSession(sessionInfo, SESSION_DISCONNECT);
543 try {
544 SomeArgs args = SomeArgs.obtain();
545 args.arg1 = callId;
546 args.arg2 = Log.createSubsession();
547 mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
548 } finally {
549 Log.endSession();
550 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700551 }
552
553 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700554 public void hold(String callId, Session.Info sessionInfo) {
555 Log.startSession(sessionInfo, SESSION_HOLD);
556 try {
557 SomeArgs args = SomeArgs.obtain();
558 args.arg1 = callId;
559 args.arg2 = Log.createSubsession();
560 mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
561 } finally {
562 Log.endSession();
563 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700564 }
565
566 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700567 public void unhold(String callId, Session.Info sessionInfo) {
568 Log.startSession(sessionInfo, SESSION_UNHOLD);
569 try {
570 SomeArgs args = SomeArgs.obtain();
571 args.arg1 = callId;
572 args.arg2 = Log.createSubsession();
573 mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
574 } finally {
575 Log.endSession();
576 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700577 }
578
579 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700580 public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
581 Session.Info sessionInfo) {
582 Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
583 try {
584 SomeArgs args = SomeArgs.obtain();
585 args.arg1 = callId;
586 args.arg2 = callAudioState;
587 args.arg3 = Log.createSubsession();
588 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
589 } finally {
590 Log.endSession();
591 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700592 }
593
594 @Override
Grace Jiae99fde92021-01-19 14:58:01 -0800595 public void onUsingAlternativeUi(String callId, boolean usingAlternativeUiShowing,
596 Session.Info sessionInfo) {
597 Log.startSession(sessionInfo, SESSION_USING_ALTERNATIVE_UI);
598 try {
599 SomeArgs args = SomeArgs.obtain();
600 args.arg1 = callId;
601 args.arg2 = usingAlternativeUiShowing;
602 args.arg3 = Log.createSubsession();
603 mHandler.obtainMessage(MSG_ON_USING_ALTERNATIVE_UI, args).sendToTarget();
604 } finally {
605 Log.endSession();
606 }
607 }
608
609 @Override
610 public void onTrackedByNonUiService(String callId, boolean isTracked,
611 Session.Info sessionInfo) {
612 Log.startSession(sessionInfo, SESSION_TRACKED_BY_NON_UI_SERVICE);
613 try {
614 SomeArgs args = SomeArgs.obtain();
615 args.arg1 = callId;
616 args.arg2 = isTracked;
617 args.arg3 = Log.createSubsession();
618 mHandler.obtainMessage(MSG_ON_TRACKED_BY_NON_UI_SERVICE, args).sendToTarget();
619 } finally {
620 Log.endSession();
621 }
622 }
623
624 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700625 public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
626 Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
627 try {
628 SomeArgs args = SomeArgs.obtain();
629 args.arg1 = digit;
630 args.arg2 = callId;
631 args.arg3 = Log.createSubsession();
632 mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, args).sendToTarget();
633 } finally {
634 Log.endSession();
635 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700636 }
637
638 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700639 public void stopDtmfTone(String callId, Session.Info sessionInfo) {
640 Log.startSession(sessionInfo, SESSION_STOP_DTMF);
641 try {
642 SomeArgs args = SomeArgs.obtain();
643 args.arg1 = callId;
644 args.arg2 = Log.createSubsession();
645 mHandler.obtainMessage(MSG_STOP_DTMF_TONE, args).sendToTarget();
646 } finally {
647 Log.endSession();
648 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700649 }
650
651 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700652 public void conference(String callId1, String callId2, Session.Info sessionInfo) {
653 Log.startSession(sessionInfo, SESSION_CONFERENCE);
654 try {
655 SomeArgs args = SomeArgs.obtain();
656 args.arg1 = callId1;
657 args.arg2 = callId2;
658 args.arg3 = Log.createSubsession();
659 mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
660 } finally {
661 Log.endSession();
662 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700663 }
664
665 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700666 public void splitFromConference(String callId, Session.Info sessionInfo) {
667 Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
668 try {
669 SomeArgs args = SomeArgs.obtain();
670 args.arg1 = callId;
671 args.arg2 = Log.createSubsession();
672 mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
673 } finally {
674 Log.endSession();
675 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700676 }
677
678 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700679 public void mergeConference(String callId, Session.Info sessionInfo) {
680 Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
681 try {
682 SomeArgs args = SomeArgs.obtain();
683 args.arg1 = callId;
684 args.arg2 = Log.createSubsession();
685 mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
686 } finally {
687 Log.endSession();
688 }
Santos Cordona4868042014-09-04 17:39:22 -0700689 }
690
691 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700692 public void swapConference(String callId, Session.Info sessionInfo) {
693 Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
694 try {
695 SomeArgs args = SomeArgs.obtain();
696 args.arg1 = callId;
697 args.arg2 = Log.createSubsession();
698 mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
699 } finally {
700 Log.endSession();
701 }
Santos Cordona4868042014-09-04 17:39:22 -0700702 }
703
704 @Override
Ravi Paluri404babb2020-01-23 19:02:44 +0530705 public void addConferenceParticipants(String callId, List<Uri> participants,
706 Session.Info sessionInfo) {
707 Log.startSession(sessionInfo, SESSION_ADD_PARTICIPANT);
708 try {
709 SomeArgs args = SomeArgs.obtain();
710 args.arg1 = callId;
711 args.arg2 = participants;
712 args.arg3 = Log.createSubsession();
713 mHandler.obtainMessage(MSG_ADD_PARTICIPANT, args).sendToTarget();
714 } finally {
715 Log.endSession();
716 }
717 }
718
719 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700720 public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
721 Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
722 try {
723 SomeArgs args = SomeArgs.obtain();
724 args.arg1 = callId;
725 args.arg2 = Log.createSubsession();
726 args.argi1 = proceed ? 1 : 0;
727 mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
728 } finally {
729 Log.endSession();
730 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700731 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700732
733 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700734 public void pullExternalCall(String callId, Session.Info sessionInfo) {
735 Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
736 try {
737 SomeArgs args = SomeArgs.obtain();
738 args.arg1 = callId;
739 args.arg2 = Log.createSubsession();
740 mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
741 } finally {
742 Log.endSession();
743 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700744 }
745
746 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700747 public void sendCallEvent(String callId, String event, Bundle extras,
748 Session.Info sessionInfo) {
749 Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
750 try {
751 SomeArgs args = SomeArgs.obtain();
752 args.arg1 = callId;
753 args.arg2 = event;
754 args.arg3 = extras;
755 args.arg4 = Log.createSubsession();
756 mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
757 } finally {
758 Log.endSession();
759 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700760 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700761
762 @Override
Hall Liu73903142021-02-18 18:41:41 -0800763 public void onCallFilteringCompleted(String callId,
764 Connection.CallFilteringCompletionInfo completionInfo,
Hall Liu49cabcc2021-01-15 11:41:48 -0800765 Session.Info sessionInfo) {
766 Log.startSession(sessionInfo, SESSION_CALL_FILTERING_COMPLETED);
767 try {
768 SomeArgs args = SomeArgs.obtain();
769 args.arg1 = callId;
Hall Liu73903142021-02-18 18:41:41 -0800770 args.arg2 = completionInfo;
771 args.arg3 = Log.createSubsession();
Hall Liu49cabcc2021-01-15 11:41:48 -0800772 mHandler.obtainMessage(MSG_ON_CALL_FILTERING_COMPLETED, args).sendToTarget();
773 } finally {
774 Log.endSession();
775 }
776 }
777
778 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700779 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
780 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
781 try {
782 SomeArgs args = SomeArgs.obtain();
783 args.arg1 = callId;
784 args.arg2 = extras;
785 args.arg3 = Log.createSubsession();
786 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
787 } finally {
788 Log.endSession();
789 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700790 }
Hall Liub64ac4c2017-02-06 10:49:48 -0800791
792 @Override
793 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
794 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
795 Log.startSession(sessionInfo, SESSION_START_RTT);
796 try {
797 SomeArgs args = SomeArgs.obtain();
798 args.arg1 = callId;
799 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
800 args.arg3 = Log.createSubsession();
801 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
802 } finally {
803 Log.endSession();
804 }
805 }
806
807 @Override
808 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
809 Log.startSession(sessionInfo, SESSION_STOP_RTT);
810 try {
811 SomeArgs args = SomeArgs.obtain();
812 args.arg1 = callId;
813 args.arg2 = Log.createSubsession();
814 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
815 } finally {
816 Log.endSession();
817 }
818 }
819
820 @Override
821 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
822 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
823 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
824 try {
825 SomeArgs args = SomeArgs.obtain();
826 args.arg1 = callId;
827 if (toInCall == null || fromInCall == null) {
828 args.arg2 = null;
829 } else {
830 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
831 }
832 args.arg3 = Log.createSubsession();
833 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
834 } finally {
835 Log.endSession();
836 }
837 }
Pengquan Meng731c1a32017-11-21 18:01:13 -0800838
839 @Override
840 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
841 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
842 try {
843 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
844 } finally {
845 Log.endSession();
846 }
847 }
848
849 @Override
850 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
851 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
852 try {
853 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
854 } finally {
855 Log.endSession();
856 }
857 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700858 };
859
860 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
861 @Override
862 public void handleMessage(Message msg) {
863 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700864 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
865 SomeArgs args = (SomeArgs) msg.obj;
866 try {
867 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
868 Log.continueSession((Session) args.arg2,
869 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
870 mAdapter.addAdapter(adapter);
871 onAdapterAttached();
872 } finally {
873 args.recycle();
874 Log.endSession();
875 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700876 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700877 }
878 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
879 SomeArgs args = (SomeArgs) msg.obj;
880 try {
881 Log.continueSession((Session) args.arg2,
882 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
883 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
884 } finally {
885 args.recycle();
886 Log.endSession();
887 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700888 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700889 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700890 case MSG_CREATE_CONNECTION: {
891 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700892 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -0700893 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700894 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -0700895 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700896 final String id = (String) args.arg2;
897 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700898 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -0700899 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700900 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700901 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700902 mPreInitializationConnectionRequests.add(
903 new android.telecom.Logging.Runnable(
904 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
905 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700906 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700907 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700908 createConnection(
909 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700910 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700911 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700912 isIncoming,
913 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700914 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700915 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -0700916 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700917 createConnection(
918 connectionManagerPhoneAccount,
919 id,
920 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700921 isIncoming,
922 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700923 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700924 } finally {
925 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700926 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -0700927 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700928 break;
Ihab Awadf8b69882014-07-25 15:14:01 -0700929 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700930 case MSG_CREATE_CONNECTION_COMPLETE: {
931 SomeArgs args = (SomeArgs) msg.obj;
932 Log.continueSession((Session) args.arg2,
933 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
934 try {
935 final String id = (String) args.arg1;
936 if (!mAreAccountsInitialized) {
937 Log.d(this, "Enqueueing pre-init request %s", id);
938 mPreInitializationConnectionRequests.add(
939 new android.telecom.Logging.Runnable(
940 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
941 + ".pICR",
942 null /*lock*/) {
943 @Override
944 public void loggedRun() {
945 notifyCreateConnectionComplete(id);
946 }
947 }.prepare());
948 } else {
949 notifyCreateConnectionComplete(id);
950 }
951 } finally {
952 args.recycle();
953 Log.endSession();
954 }
955 break;
956 }
Tyler Gunn44e01912017-01-31 10:49:05 -0800957 case MSG_CREATE_CONNECTION_FAILED: {
958 SomeArgs args = (SomeArgs) msg.obj;
959 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
960 SESSION_CREATE_CONN_FAILED);
961 try {
962 final String id = (String) args.arg1;
963 final ConnectionRequest request = (ConnectionRequest) args.arg2;
964 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800965 final PhoneAccountHandle connectionMgrPhoneAccount =
966 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -0800967 if (!mAreAccountsInitialized) {
968 Log.d(this, "Enqueueing pre-init request %s", id);
969 mPreInitializationConnectionRequests.add(
970 new android.telecom.Logging.Runnable(
971 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
972 null /*lock*/) {
973 @Override
974 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800975 createConnectionFailed(connectionMgrPhoneAccount, id,
976 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800977 }
978 }.prepare());
979 } else {
980 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -0800981 createConnectionFailed(connectionMgrPhoneAccount, id, request,
982 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800983 }
984 } finally {
985 args.recycle();
986 Log.endSession();
987 }
988 break;
989 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530990 case MSG_CREATE_CONFERENCE: {
991 SomeArgs args = (SomeArgs) msg.obj;
992 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
993 try {
994 final PhoneAccountHandle connectionManagerPhoneAccount =
995 (PhoneAccountHandle) args.arg1;
996 final String id = (String) args.arg2;
997 final ConnectionRequest request = (ConnectionRequest) args.arg3;
998 final boolean isIncoming = args.argi1 == 1;
999 final boolean isUnknown = args.argi2 == 1;
1000 if (!mAreAccountsInitialized) {
1001 Log.d(this, "Enqueueing pre-initconference request %s", id);
1002 mPreInitializationConnectionRequests.add(
1003 new android.telecom.Logging.Runnable(
1004 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
1005 null /*lock*/) {
1006 @Override
1007 public void loggedRun() {
1008 createConference(connectionManagerPhoneAccount,
1009 id,
1010 request,
1011 isIncoming,
1012 isUnknown);
1013 }
1014 }.prepare());
1015 } else {
1016 createConference(connectionManagerPhoneAccount,
1017 id,
1018 request,
1019 isIncoming,
1020 isUnknown);
1021 }
1022 } finally {
1023 args.recycle();
1024 Log.endSession();
1025 }
1026 break;
1027 }
1028 case MSG_CREATE_CONFERENCE_COMPLETE: {
1029 SomeArgs args = (SomeArgs) msg.obj;
1030 Log.continueSession((Session) args.arg2,
1031 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1032 try {
1033 final String id = (String) args.arg1;
1034 if (!mAreAccountsInitialized) {
1035 Log.d(this, "Enqueueing pre-init conference request %s", id);
1036 mPreInitializationConnectionRequests.add(
1037 new android.telecom.Logging.Runnable(
1038 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
1039 + ".pIConfR",
1040 null /*lock*/) {
1041 @Override
1042 public void loggedRun() {
1043 notifyCreateConferenceComplete(id);
1044 }
1045 }.prepare());
1046 } else {
1047 notifyCreateConferenceComplete(id);
1048 }
1049 } finally {
1050 args.recycle();
1051 Log.endSession();
1052 }
1053 break;
1054 }
1055 case MSG_CREATE_CONFERENCE_FAILED: {
1056 SomeArgs args = (SomeArgs) msg.obj;
1057 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1058 SESSION_CREATE_CONN_FAILED);
1059 try {
1060 final String id = (String) args.arg1;
1061 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1062 final boolean isIncoming = args.argi1 == 1;
1063 final PhoneAccountHandle connectionMgrPhoneAccount =
1064 (PhoneAccountHandle) args.arg4;
1065 if (!mAreAccountsInitialized) {
1066 Log.d(this, "Enqueueing pre-init conference request %s", id);
1067 mPreInitializationConnectionRequests.add(
1068 new android.telecom.Logging.Runnable(
1069 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
1070 + ".pIConfR",
1071 null /*lock*/) {
1072 @Override
1073 public void loggedRun() {
1074 createConferenceFailed(connectionMgrPhoneAccount, id,
1075 request, isIncoming);
1076 }
1077 }.prepare());
1078 } else {
1079 Log.i(this, "createConferenceFailed %s", id);
1080 createConferenceFailed(connectionMgrPhoneAccount, id, request,
1081 isIncoming);
1082 }
1083 } finally {
1084 args.recycle();
1085 Log.endSession();
1086 }
1087 break;
1088 }
1089
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001090 case MSG_HANDOVER_FAILED: {
1091 SomeArgs args = (SomeArgs) msg.obj;
1092 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1093 SESSION_HANDOVER_FAILED);
1094 try {
1095 final String id = (String) args.arg1;
1096 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1097 final int reason = (int) args.arg4;
1098 if (!mAreAccountsInitialized) {
1099 Log.d(this, "Enqueueing pre-init request %s", id);
1100 mPreInitializationConnectionRequests.add(
1101 new android.telecom.Logging.Runnable(
1102 SESSION_HANDLER
1103 + SESSION_HANDOVER_FAILED + ".pICR",
1104 null /*lock*/) {
1105 @Override
1106 public void loggedRun() {
1107 handoverFailed(id, request, reason);
1108 }
1109 }.prepare());
1110 } else {
1111 Log.i(this, "createConnectionFailed %s", id);
1112 handoverFailed(id, request, reason);
1113 }
1114 } finally {
1115 args.recycle();
1116 Log.endSession();
1117 }
1118 break;
1119 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001120 case MSG_ABORT: {
1121 SomeArgs args = (SomeArgs) msg.obj;
1122 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1123 try {
1124 abort((String) args.arg1);
1125 } finally {
1126 args.recycle();
1127 Log.endSession();
1128 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001129 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001130 }
1131 case MSG_ANSWER: {
1132 SomeArgs args = (SomeArgs) msg.obj;
1133 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1134 try {
1135 answer((String) args.arg1);
1136 } finally {
1137 args.recycle();
1138 Log.endSession();
1139 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001140 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001141 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001142 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001143 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001144 Log.continueSession((Session) args.arg2,
1145 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001146 try {
1147 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001148 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001149 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001150 } finally {
1151 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001152 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001153 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001154 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001155 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301156 case MSG_DEFLECT: {
1157 SomeArgs args = (SomeArgs) msg.obj;
1158 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1159 try {
1160 deflect((String) args.arg1, (Uri) args.arg2);
1161 } finally {
1162 args.recycle();
1163 Log.endSession();
1164 }
1165 break;
1166 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001167 case MSG_REJECT: {
1168 SomeArgs args = (SomeArgs) msg.obj;
1169 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1170 try {
1171 reject((String) args.arg1);
1172 } finally {
1173 args.recycle();
1174 Log.endSession();
1175 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001176 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001177 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001178 case MSG_REJECT_WITH_REASON: {
1179 SomeArgs args = (SomeArgs) msg.obj;
1180 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1181 try {
1182 reject((String) args.arg1, args.argi1);
1183 } finally {
1184 args.recycle();
1185 Log.endSession();
1186 }
1187 break;
1188 }
Bryce Lee81901682015-08-28 16:38:02 -07001189 case MSG_REJECT_WITH_MESSAGE: {
1190 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001191 Log.continueSession((Session) args.arg3,
1192 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001193 try {
1194 reject((String) args.arg1, (String) args.arg2);
1195 } finally {
1196 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001197 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001198 }
1199 break;
1200 }
Ravi Palurif4b38e72020-02-05 12:35:41 +05301201 case MSG_EXPLICIT_CALL_TRANSFER: {
1202 SomeArgs args = (SomeArgs) msg.obj;
1203 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_TRANSFER);
1204 try {
1205 final boolean isConfirmationRequired = args.argi1 == 1;
1206 transfer((String) args.arg1, (Uri) args.arg2, isConfirmationRequired);
1207 } finally {
1208 args.recycle();
1209 Log.endSession();
1210 }
1211 break;
1212 }
1213 case MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE: {
1214 SomeArgs args = (SomeArgs) msg.obj;
1215 Log.continueSession(
1216 (Session) args.arg3, SESSION_HANDLER + SESSION_CONSULTATIVE_TRANSFER);
1217 try {
1218 consultativeTransfer((String) args.arg1, (String) args.arg2);
1219 } finally {
1220 args.recycle();
1221 Log.endSession();
1222 }
1223 break;
1224 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001225 case MSG_DISCONNECT: {
1226 SomeArgs args = (SomeArgs) msg.obj;
1227 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1228 try {
1229 disconnect((String) args.arg1);
1230 } finally {
1231 args.recycle();
1232 Log.endSession();
1233 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001234 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001235 }
1236 case MSG_SILENCE: {
1237 SomeArgs args = (SomeArgs) msg.obj;
1238 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1239 try {
1240 silence((String) args.arg1);
1241 } finally {
1242 args.recycle();
1243 Log.endSession();
1244 }
Bryce Leecac50772015-11-17 15:13:29 -08001245 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001246 }
1247 case MSG_HOLD: {
1248 SomeArgs args = (SomeArgs) msg.obj;
1249 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1250 try {
1251 hold((String) args.arg1);
1252 } finally {
1253 args.recycle();
1254 Log.endSession();
1255 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001256 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001257 }
1258 case MSG_UNHOLD: {
1259 SomeArgs args = (SomeArgs) msg.obj;
1260 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1261 try {
1262 unhold((String) args.arg1);
1263 } finally {
1264 args.recycle();
1265 Log.endSession();
1266 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001267 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001268 }
Yorke Lee4af59352015-05-13 14:14:54 -07001269 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001270 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001271 Log.continueSession((Session) args.arg3,
1272 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001273 try {
1274 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001275 CallAudioState audioState = (CallAudioState) args.arg2;
1276 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001277 } finally {
1278 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001279 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001280 }
1281 break;
1282 }
Grace Jiae99fde92021-01-19 14:58:01 -08001283 case MSG_ON_USING_ALTERNATIVE_UI: {
1284 SomeArgs args = (SomeArgs) msg.obj;
1285 Log.continueSession((Session) args.arg3,
1286 SESSION_HANDLER + SESSION_USING_ALTERNATIVE_UI);
1287 try {
1288 String callId = (String) args.arg1;
1289 boolean isUsingAlternativeUi = (boolean) args.arg2;
1290 onUsingAlternativeUi(callId, isUsingAlternativeUi);
1291 } finally {
1292 args.recycle();
1293 Log.endSession();
1294 }
1295 break;
1296 }
1297 case MSG_ON_TRACKED_BY_NON_UI_SERVICE: {
1298 SomeArgs args = (SomeArgs) msg.obj;
1299 Log.continueSession((Session) args.arg3,
1300 SESSION_HANDLER + SESSION_TRACKED_BY_NON_UI_SERVICE);
1301 try {
1302 String callId = (String) args.arg1;
1303 boolean isTracked = (boolean) args.arg2;
1304 onTrackedByNonUiService(callId, isTracked);
1305 } finally {
1306 args.recycle();
1307 Log.endSession();
1308 }
1309 break;
1310 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001311 case MSG_PLAY_DTMF_TONE: {
1312 SomeArgs args = (SomeArgs) msg.obj;
1313 try {
1314 Log.continueSession((Session) args.arg3,
1315 SESSION_HANDLER + SESSION_PLAY_DTMF);
1316 playDtmfTone((String) args.arg2, (char) args.arg1);
1317 } finally {
1318 args.recycle();
1319 Log.endSession();
1320 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001321 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001322 }
1323 case MSG_STOP_DTMF_TONE: {
1324 SomeArgs args = (SomeArgs) msg.obj;
1325 try {
1326 Log.continueSession((Session) args.arg2,
1327 SESSION_HANDLER + SESSION_STOP_DTMF);
1328 stopDtmfTone((String) args.arg1);
1329 } finally {
1330 args.recycle();
1331 Log.endSession();
1332 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001333 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001334 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001335 case MSG_CONFERENCE: {
1336 SomeArgs args = (SomeArgs) msg.obj;
1337 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001338 Log.continueSession((Session) args.arg3,
1339 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001340 String callId1 = (String) args.arg1;
1341 String callId2 = (String) args.arg2;
1342 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001343 } finally {
1344 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001345 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001346 }
1347 break;
1348 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001349 case MSG_SPLIT_FROM_CONFERENCE: {
1350 SomeArgs args = (SomeArgs) msg.obj;
1351 try {
1352 Log.continueSession((Session) args.arg2,
1353 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1354 splitFromConference((String) args.arg1);
1355 } finally {
1356 args.recycle();
1357 Log.endSession();
1358 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001359 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001360 }
1361 case MSG_MERGE_CONFERENCE: {
1362 SomeArgs args = (SomeArgs) msg.obj;
1363 try {
1364 Log.continueSession((Session) args.arg2,
1365 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1366 mergeConference((String) args.arg1);
1367 } finally {
1368 args.recycle();
1369 Log.endSession();
1370 }
Santos Cordona4868042014-09-04 17:39:22 -07001371 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001372 }
1373 case MSG_SWAP_CONFERENCE: {
1374 SomeArgs args = (SomeArgs) msg.obj;
1375 try {
1376 Log.continueSession((Session) args.arg2,
1377 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1378 swapConference((String) args.arg1);
1379 } finally {
1380 args.recycle();
1381 Log.endSession();
1382 }
Santos Cordona4868042014-09-04 17:39:22 -07001383 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001384 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301385 case MSG_ADD_PARTICIPANT: {
1386 SomeArgs args = (SomeArgs) msg.obj;
1387 try {
1388 Log.continueSession((Session) args.arg3,
1389 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1390 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1391 } finally {
1392 args.recycle();
1393 Log.endSession();
1394 }
1395 break;
1396 }
1397
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001398 case MSG_ON_POST_DIAL_CONTINUE: {
1399 SomeArgs args = (SomeArgs) msg.obj;
1400 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001401 Log.continueSession((Session) args.arg2,
1402 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001403 String callId = (String) args.arg1;
1404 boolean proceed = (args.argi1 == 1);
1405 onPostDialContinue(callId, proceed);
1406 } finally {
1407 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001408 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001409 }
1410 break;
1411 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001412 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001413 SomeArgs args = (SomeArgs) msg.obj;
1414 try {
1415 Log.continueSession((Session) args.arg2,
1416 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1417 pullExternalCall((String) args.arg1);
1418 } finally {
1419 args.recycle();
1420 Log.endSession();
1421 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001422 break;
1423 }
1424 case MSG_SEND_CALL_EVENT: {
1425 SomeArgs args = (SomeArgs) msg.obj;
1426 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001427 Log.continueSession((Session) args.arg4,
1428 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001429 String callId = (String) args.arg1;
1430 String event = (String) args.arg2;
1431 Bundle extras = (Bundle) args.arg3;
1432 sendCallEvent(callId, event, extras);
1433 } finally {
1434 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001435 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001436 }
1437 break;
1438 }
Hall Liu49cabcc2021-01-15 11:41:48 -08001439 case MSG_ON_CALL_FILTERING_COMPLETED: {
1440 SomeArgs args = (SomeArgs) msg.obj;
1441 try {
Hall Liu73903142021-02-18 18:41:41 -08001442 Log.continueSession((Session) args.arg3,
Hall Liu49cabcc2021-01-15 11:41:48 -08001443 SESSION_HANDLER + SESSION_CALL_FILTERING_COMPLETED);
1444 String callId = (String) args.arg1;
Hall Liu73903142021-02-18 18:41:41 -08001445 Connection.CallFilteringCompletionInfo completionInfo =
1446 (Connection.CallFilteringCompletionInfo) args.arg2;
1447 onCallFilteringCompleted(callId, completionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08001448 } finally {
1449 args.recycle();
1450 Log.endSession();
1451 }
1452 break;
1453 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001454 case MSG_HANDOVER_COMPLETE: {
1455 SomeArgs args = (SomeArgs) msg.obj;
1456 try {
1457 Log.continueSession((Session) args.arg2,
1458 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1459 String callId = (String) args.arg1;
1460 notifyHandoverComplete(callId);
1461 } finally {
1462 args.recycle();
1463 Log.endSession();
1464 }
1465 break;
1466 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001467 case MSG_ON_EXTRAS_CHANGED: {
1468 SomeArgs args = (SomeArgs) msg.obj;
1469 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001470 Log.continueSession((Session) args.arg3,
1471 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001472 String callId = (String) args.arg1;
1473 Bundle extras = (Bundle) args.arg2;
1474 handleExtrasChanged(callId, extras);
1475 } finally {
1476 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001477 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001478 }
1479 break;
1480 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001481 case MSG_ON_START_RTT: {
1482 SomeArgs args = (SomeArgs) msg.obj;
1483 try {
1484 Log.continueSession((Session) args.arg3,
1485 SESSION_HANDLER + SESSION_START_RTT);
1486 String callId = (String) args.arg1;
1487 Connection.RttTextStream rttTextStream =
1488 (Connection.RttTextStream) args.arg2;
1489 startRtt(callId, rttTextStream);
1490 } finally {
1491 args.recycle();
1492 Log.endSession();
1493 }
1494 break;
1495 }
1496 case MSG_ON_STOP_RTT: {
1497 SomeArgs args = (SomeArgs) msg.obj;
1498 try {
1499 Log.continueSession((Session) args.arg2,
1500 SESSION_HANDLER + SESSION_STOP_RTT);
1501 String callId = (String) args.arg1;
1502 stopRtt(callId);
1503 } finally {
1504 args.recycle();
1505 Log.endSession();
1506 }
1507 break;
1508 }
1509 case MSG_RTT_UPGRADE_RESPONSE: {
1510 SomeArgs args = (SomeArgs) msg.obj;
1511 try {
1512 Log.continueSession((Session) args.arg3,
1513 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1514 String callId = (String) args.arg1;
1515 Connection.RttTextStream rttTextStream =
1516 (Connection.RttTextStream) args.arg2;
1517 handleRttUpgradeResponse(callId, rttTextStream);
1518 } finally {
1519 args.recycle();
1520 Log.endSession();
1521 }
1522 break;
1523 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001524 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1525 onConnectionServiceFocusGained();
1526 break;
1527 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1528 onConnectionServiceFocusLost();
1529 break;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001530 default:
1531 break;
1532 }
1533 }
1534 };
1535
Santos Cordon823fd3c2014-08-07 18:35:18 -07001536 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1537 @Override
1538 public void onStateChanged(Conference conference, int oldState, int newState) {
1539 String id = mIdByConference.get(conference);
1540 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301541 case Connection.STATE_RINGING:
1542 mAdapter.setRinging(id);
1543 break;
1544 case Connection.STATE_DIALING:
1545 mAdapter.setDialing(id);
1546 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001547 case Connection.STATE_ACTIVE:
1548 mAdapter.setActive(id);
1549 break;
1550 case Connection.STATE_HOLDING:
1551 mAdapter.setOnHold(id);
1552 break;
1553 case Connection.STATE_DISCONNECTED:
1554 // handled by onDisconnected
1555 break;
1556 }
1557 }
1558
1559 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001560 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001561 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001562 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001563 }
1564
1565 @Override
1566 public void onConnectionAdded(Conference conference, Connection connection) {
1567 }
1568
1569 @Override
1570 public void onConnectionRemoved(Conference conference, Connection connection) {
1571 }
1572
1573 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001574 public void onConferenceableConnectionsChanged(
1575 Conference conference, List<Connection> conferenceableConnections) {
1576 mAdapter.setConferenceableConnections(
1577 mIdByConference.get(conference),
1578 createConnectionIdList(conferenceableConnections));
1579 }
1580
1581 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001582 public void onDestroyed(Conference conference) {
1583 removeConference(conference);
1584 }
1585
1586 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001587 public void onConnectionCapabilitiesChanged(
1588 Conference conference,
1589 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001590 String id = mIdByConference.get(conference);
1591 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001592 Connection.capabilitiesToString(connectionCapabilities));
1593 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001594 }
Rekha Kumar07366812015-03-24 16:42:31 -07001595
1596 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001597 public void onConnectionPropertiesChanged(
1598 Conference conference,
1599 int connectionProperties) {
1600 String id = mIdByConference.get(conference);
1601 Log.d(this, "call capabilities: conference: %s",
1602 Connection.propertiesToString(connectionProperties));
1603 mAdapter.setConnectionProperties(id, connectionProperties);
1604 }
1605
1606 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001607 public void onVideoStateChanged(Conference c, int videoState) {
1608 String id = mIdByConference.get(c);
1609 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1610 mAdapter.setVideoState(id, videoState);
1611 }
1612
1613 @Override
1614 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1615 String id = mIdByConference.get(c);
1616 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1617 videoProvider);
1618 mAdapter.setVideoProvider(id, videoProvider);
1619 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001620
1621 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001622 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1623 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001624 if (id != null) {
1625 mAdapter.setStatusHints(id, statusHints);
1626 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001627 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001628
1629 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001630 public void onExtrasChanged(Conference c, Bundle extras) {
1631 String id = mIdByConference.get(c);
1632 if (id != null) {
1633 mAdapter.putExtras(id, extras);
1634 }
1635 }
1636
1637 @Override
1638 public void onExtrasRemoved(Conference c, List<String> keys) {
1639 String id = mIdByConference.get(c);
1640 if (id != null) {
1641 mAdapter.removeExtras(id, keys);
1642 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001643 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001644
1645 @Override
1646 public void onConferenceStateChanged(Conference c, boolean isConference) {
1647 String id = mIdByConference.get(c);
1648 if (id != null) {
1649 mAdapter.setConferenceState(id, isConference);
1650 }
1651 }
1652
1653 @Override
Brad Ebingere0c12f42020-04-08 16:25:12 -07001654 public void onCallDirectionChanged(Conference c, int direction) {
1655 String id = mIdByConference.get(c);
1656 if (id != null) {
1657 mAdapter.setCallDirection(id, direction);
1658 }
1659 }
1660
1661 @Override
Tyler Gunn68a73a42018-10-03 15:38:57 -07001662 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1663 String id = mIdByConference.get(c);
1664 if (id != null) {
1665 mAdapter.setAddress(id, newAddress, presentation);
1666 }
1667 }
1668
1669 @Override
1670 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1671 int presentation) {
1672 String id = mIdByConference.get(c);
1673 if (id != null) {
1674 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1675 }
1676 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001677
1678 @Override
1679 public void onConnectionEvent(Conference c, String event, Bundle extras) {
1680 String id = mIdByConference.get(c);
1681 if (id != null) {
1682 mAdapter.onConnectionEvent(id, event, extras);
1683 }
1684 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301685
1686 @Override
1687 public void onRingbackRequested(Conference c, boolean ringback) {
1688 String id = mIdByConference.get(c);
1689 Log.d(this, "Adapter conference onRingback %b", ringback);
1690 mAdapter.setRingbackRequested(id, ringback);
1691 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001692 };
1693
Ihab Awad542e0ea2014-05-16 10:22:16 -07001694 private final Connection.Listener mConnectionListener = new Connection.Listener() {
1695 @Override
1696 public void onStateChanged(Connection c, int state) {
1697 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07001698 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001699 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001700 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001701 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001702 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001703 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001704 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001705 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001706 case Connection.STATE_PULLING_CALL:
1707 mAdapter.setPulling(id);
1708 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001709 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001710 // Handled in onDisconnected()
1711 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001712 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001713 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001714 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001715 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001716 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07001717 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001718 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001719 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001720 break;
1721 }
1722 }
1723
1724 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001725 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07001726 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07001727 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001728 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001729 }
1730
1731 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07001732 public void onVideoStateChanged(Connection c, int videoState) {
1733 String id = mIdByConnection.get(c);
1734 Log.d(this, "Adapter set video state %d", videoState);
1735 mAdapter.setVideoState(id, videoState);
1736 }
1737
1738 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001739 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001740 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001741 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07001742 }
1743
1744 @Override
1745 public void onCallerDisplayNameChanged(
1746 Connection c, String callerDisplayName, int presentation) {
1747 String id = mIdByConnection.get(c);
1748 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001749 }
1750
1751 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07001752 public void onDestroyed(Connection c) {
1753 removeConnection(c);
1754 }
Ihab Awadf8358972014-05-28 16:46:42 -07001755
1756 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001757 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07001758 String id = mIdByConnection.get(c);
1759 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001760 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001761 }
1762
1763 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001764 public void onPostDialChar(Connection c, char nextChar) {
1765 String id = mIdByConnection.get(c);
1766 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
1767 mAdapter.onPostDialChar(id, nextChar);
1768 }
1769
1770 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001771 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07001772 String id = mIdByConnection.get(c);
1773 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07001774 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07001775 }
Santos Cordonb6939982014-06-04 20:20:58 -07001776
1777 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001778 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07001779 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001780 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001781 Connection.capabilitiesToString(capabilities));
1782 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07001783 }
1784
Santos Cordonb6939982014-06-04 20:20:58 -07001785 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001786 public void onConnectionPropertiesChanged(Connection c, int properties) {
1787 String id = mIdByConnection.get(c);
1788 Log.d(this, "properties: parcelableconnection: %s",
1789 Connection.propertiesToString(properties));
1790 mAdapter.setConnectionProperties(id, properties);
1791 }
1792
1793 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001794 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001795 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07001796 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1797 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001798 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001799 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001800
1801 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001802 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001803 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001804 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001805 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001806
1807 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001808 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001809 String id = mIdByConnection.get(c);
1810 mAdapter.setStatusHints(id, statusHints);
1811 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001812
1813 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001814 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001815 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001816 mAdapter.setConferenceableConnections(
1817 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001818 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001819 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001820
1821 @Override
1822 public void onConferenceChanged(Connection connection, Conference conference) {
1823 String id = mIdByConnection.get(connection);
1824 if (id != null) {
1825 String conferenceId = null;
1826 if (conference != null) {
1827 conferenceId = mIdByConference.get(conference);
1828 }
1829 mAdapter.setIsConferenced(id, conferenceId);
1830 }
1831 }
Anthony Lee17455a32015-04-24 15:25:29 -07001832
1833 @Override
1834 public void onConferenceMergeFailed(Connection connection) {
1835 String id = mIdByConnection.get(connection);
1836 if (id != null) {
1837 mAdapter.onConferenceMergeFailed(id);
1838 }
1839 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001840
1841 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001842 public void onExtrasChanged(Connection c, Bundle extras) {
1843 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001844 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07001845 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001846 }
1847 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001848
Tyler Gunnf5035432017-01-09 09:43:12 -08001849 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001850 public void onExtrasRemoved(Connection c, List<String> keys) {
1851 String id = mIdByConnection.get(c);
1852 if (id != null) {
1853 mAdapter.removeExtras(id, keys);
1854 }
1855 }
1856
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001857 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001858 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001859 String id = mIdByConnection.get(connection);
1860 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001861 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001862 }
1863 }
Tyler Gunnf5035432017-01-09 09:43:12 -08001864
1865 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08001866 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001867 String id = mIdByConnection.get(c);
1868 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08001869 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08001870 }
1871 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001872
1873 @Override
1874 public void onRttInitiationSuccess(Connection c) {
1875 String id = mIdByConnection.get(c);
1876 if (id != null) {
1877 mAdapter.onRttInitiationSuccess(id);
1878 }
1879 }
1880
1881 @Override
1882 public void onRttInitiationFailure(Connection c, int reason) {
1883 String id = mIdByConnection.get(c);
1884 if (id != null) {
1885 mAdapter.onRttInitiationFailure(id, reason);
1886 }
1887 }
1888
1889 @Override
1890 public void onRttSessionRemotelyTerminated(Connection c) {
1891 String id = mIdByConnection.get(c);
1892 if (id != null) {
1893 mAdapter.onRttSessionRemotelyTerminated(id);
1894 }
1895 }
1896
1897 @Override
1898 public void onRemoteRttRequest(Connection c) {
1899 String id = mIdByConnection.get(c);
1900 if (id != null) {
1901 mAdapter.onRemoteRttRequest(id);
1902 }
1903 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05301904
1905 @Override
1906 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
1907 String id = mIdByConnection.get(c);
1908 if (id != null) {
1909 mAdapter.onPhoneAccountChanged(id, pHandle);
1910 }
1911 }
Mengjun Leng25707742017-07-04 11:10:37 +08001912
1913 public void onConnectionTimeReset(Connection c) {
1914 String id = mIdByConnection.get(c);
1915 if (id != null) {
1916 mAdapter.resetConnectionTime(id);
1917 }
1918 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001919 };
1920
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001921 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07001922 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001923 public final IBinder onBind(Intent intent) {
Hall Liueb7c9ea2021-03-09 20:24:50 -08001924 onBindClient(intent);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001925 return mBinder;
1926 }
1927
Santos Cordon29f2f2e2014-09-11 19:50:24 -07001928 /** {@inheritDoc} */
1929 @Override
1930 public boolean onUnbind(Intent intent) {
1931 endAllConnections();
1932 return super.onUnbind(intent);
1933 }
1934
Hall Liueb7c9ea2021-03-09 20:24:50 -08001935 /**
1936 * Used for testing to let the test suite know when the connection service has been bound.
1937 * @hide
1938 */
1939 @TestApi
1940 public void onBindClient(@Nullable Intent intent) {
1941 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301942
1943 /**
1944 * This can be used by telecom to either create a new outgoing conference call or attach
1945 * to an existing incoming conference call. In either case, telecom will cycle through a
1946 * set of services and call createConference until a connection service cancels the process
1947 * or completes it successfully.
1948 */
1949 private void createConference(
1950 final PhoneAccountHandle callManagerAccount,
1951 final String callId,
1952 final ConnectionRequest request,
1953 boolean isIncoming,
1954 boolean isUnknown) {
1955
1956 Conference conference = null;
1957 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
1958 : onCreateOutgoingConference(callManagerAccount, request);
1959
1960 Log.d(this, "createConference, conference: %s", conference);
1961 if (conference == null) {
1962 Log.i(this, "createConference, implementation returned null conference.");
1963 conference = Conference.createFailedConference(
1964 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
1965 request.getAccountHandle());
1966 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001967
1968 Bundle extras = request.getExtras();
1969 Bundle newExtras = new Bundle();
1970 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
1971 if (extras != null) {
1972 // If the request originated from a remote connection service, we will add some
1973 // tracking information that Telecom can use to keep informed of which package
1974 // made the remote request, and which remote connection service was used.
1975 if (extras.containsKey(Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
1976 newExtras.putString(
1977 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
1978 extras.getString(
1979 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME));
1980 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
1981 request.getAccountHandle());
1982 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301983 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001984 conference.putExtras(newExtras);
1985
Ravi Paluri80aa2142019-12-02 11:57:37 +05301986 mConferenceById.put(callId, conference);
1987 mIdByConference.put(conference, callId);
Tyler Gunn460360d2020-07-29 10:21:45 -07001988
Ravi Paluri80aa2142019-12-02 11:57:37 +05301989 conference.addListener(mConferenceListener);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07001990 ParcelableConference parcelableConference = new ParcelableConference.Builder(
1991 request.getAccountHandle(), conference.getState())
1992 .setConnectionCapabilities(conference.getConnectionCapabilities())
1993 .setConnectionProperties(conference.getConnectionProperties())
1994 .setVideoAttributes(conference.getVideoProvider() == null
1995 ? null : conference.getVideoProvider().getInterface(),
1996 conference.getVideoState())
1997 .setConnectTimeMillis(conference.getConnectTimeMillis(),
1998 conference.getConnectionStartElapsedRealtimeMillis())
1999 .setStatusHints(conference.getStatusHints())
2000 .setExtras(conference.getExtras())
2001 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2002 .setCallerDisplayName(conference.getCallerDisplayName(),
2003 conference.getCallerDisplayNamePresentation())
2004 .setDisconnectCause(conference.getDisconnectCause())
2005 .setRingbackRequested(conference.isRingbackRequested())
2006 .build();
Ravi Paluri80aa2142019-12-02 11:57:37 +05302007 if (conference.getState() != Connection.STATE_DISCONNECTED) {
2008 conference.setTelecomCallId(callId);
2009 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
2010 mAdapter.setVideoState(callId, conference.getVideoState());
2011 onConferenceAdded(conference);
2012 }
2013
2014 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
2015 mAdapter.handleCreateConferenceComplete(
2016 callId,
2017 request,
2018 parcelableConference);
2019 }
2020
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002021 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002022 * This can be used by telecom to either create a new outgoing call or attach to an existing
2023 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002024 * createConnection util a connection service cancels the process or completes it successfully.
2025 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002026 private void createConnection(
2027 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002028 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07002029 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07002030 boolean isIncoming,
2031 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002032 boolean isLegacyHandover = request.getExtras() != null &&
2033 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
2034 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
2035 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Grace Jiae99fde92021-01-19 14:58:01 -08002036 boolean addSelfManaged = request.getExtras() != null && request.getExtras().getBoolean(
Grace Jia8b22bb42021-02-02 15:37:32 -08002037 PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
Grace Jiae99fde92021-01-19 14:58:01 -08002038 Log.i(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, "
2039 + "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b, "
2040 + " addSelfManaged: %b", callManagerAccount, callId, request, isIncoming,
2041 isUnknown, isLegacyHandover, isHandover, addSelfManaged);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002042
Sanket Padawee29a2662017-12-01 13:59:27 -08002043 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002044 if (isHandover) {
2045 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
2046 ? (PhoneAccountHandle) request.getExtras().getParcelable(
Hani Kazmi4f221e52022-06-20 09:38:26 +00002047 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT, android.telecom.PhoneAccountHandle.class) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08002048 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002049 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002050 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002051 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002052 }
2053 } else {
2054 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
2055 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
2056 : onCreateOutgoingConnection(callManagerAccount, request);
2057 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002058 Log.d(this, "createConnection, connection: %s", connection);
2059 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002060 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002061 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002062 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002063 } else {
2064 try {
2065 Bundle extras = request.getExtras();
2066 if (extras != null) {
2067 // If the request originated from a remote connection service, we will add some
2068 // tracking information that Telecom can use to keep informed of which package
2069 // made the remote request, and which remote connection service was used.
2070 if (extras.containsKey(
2071 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2072 Bundle newExtras = new Bundle();
2073 newExtras.putString(
2074 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2075 extras.getString(
2076 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME
2077 ));
2078 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2079 request.getAccountHandle());
2080 connection.putExtras(newExtras);
2081 }
2082 }
2083 } catch (UnsupportedOperationException ose) {
2084 // Do nothing; if the ConnectionService reported a failure it will be an instance
2085 // of an immutable Connection which we cannot edit, so we're out of luck.
2086 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002087 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002088
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002089 boolean isSelfManaged =
2090 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
2091 == Connection.PROPERTY_SELF_MANAGED;
2092 // Self-managed Connections should always use voip audio mode; we default here so that the
2093 // local state within the ConnectionService matches the default we assume in Telecom.
2094 if (isSelfManaged) {
2095 connection.setAudioModeIsVoip(true);
2096 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002097 connection.setTelecomCallId(callId);
Sungjae7f4137452020-09-16 17:01:54 +09002098 PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
2099 ? request.getAccountHandle() : connection.getPhoneAccountHandle();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002100 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Sungjae7f4137452020-09-16 17:01:54 +09002101 addConnection(phoneAccountHandle, callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07002102 }
2103
Andrew Lee100e2932014-09-08 15:34:24 -07002104 Uri address = connection.getAddress();
2105 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07002106 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002107 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002108 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07002109 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
2110 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002111
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002112 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07002113 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002114 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07002115 request,
2116 new ParcelableConnection(
Sungjae7f4137452020-09-16 17:01:54 +09002117 phoneAccountHandle,
Evan Charltonbf11f982014-07-20 22:06:28 -07002118 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002119 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002120 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002121 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07002122 connection.getAddress(),
2123 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07002124 connection.getCallerDisplayName(),
2125 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002126 connection.getVideoProvider() == null ?
2127 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002128 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07002129 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002130 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002131 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002132 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07002133 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002134 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002135 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002136 connection.getExtras(),
2137 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08002138
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002139 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002140 // Tell ConnectionService to show its incoming call UX.
2141 connection.onShowIncomingCallUi();
2142 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002143 if (isUnknown) {
2144 triggerConferenceRecalculate();
2145 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002146 }
2147
Tyler Gunn159f35c2017-03-02 09:28:37 -08002148 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
2149 final String callId, final ConnectionRequest request,
2150 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08002151
2152 Log.i(this, "createConnectionFailed %s", callId);
2153 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002154 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002155 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002156 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002157 }
2158 }
2159
Ravi Paluri80aa2142019-12-02 11:57:37 +05302160 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
2161 final String callId, final ConnectionRequest request,
2162 boolean isIncoming) {
2163
2164 Log.i(this, "createConferenceFailed %s", callId);
2165 if (isIncoming) {
2166 onCreateIncomingConferenceFailed(callManagerAccount, request);
2167 } else {
2168 onCreateOutgoingConferenceFailed(callManagerAccount, request);
2169 }
2170 }
2171
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08002172 private void handoverFailed(final String callId, final ConnectionRequest request,
2173 int reason) {
2174
2175 Log.i(this, "handoverFailed %s", callId);
2176 onHandoverFailed(request, reason);
2177 }
2178
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002179 /**
2180 * Called by Telecom when the creation of a new Connection has completed and it is now added
2181 * to Telecom.
2182 * @param callId The ID of the connection.
2183 */
2184 private void notifyCreateConnectionComplete(final String callId) {
2185 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07002186 if (callId == null) {
2187 // This could happen if the connection fails quickly and is removed from the
2188 // ConnectionService before Telecom sends the create connection complete callback.
2189 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
2190 return;
2191 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002192 onCreateConnectionComplete(findConnectionForAction(callId,
2193 "notifyCreateConnectionComplete"));
2194 }
2195
Ravi Paluri80aa2142019-12-02 11:57:37 +05302196 /**
2197 * Called by Telecom when the creation of a new Conference has completed and it is now added
2198 * to Telecom.
2199 * @param callId The ID of the connection.
2200 */
2201 private void notifyCreateConferenceComplete(final String callId) {
2202 Log.i(this, "notifyCreateConferenceComplete %s", callId);
2203 if (callId == null) {
2204 // This could happen if the conference fails quickly and is removed from the
2205 // ConnectionService before Telecom sends the create conference complete callback.
2206 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
2207 return;
2208 }
2209 onCreateConferenceComplete(findConferenceForAction(callId,
2210 "notifyCreateConferenceComplete"));
2211 }
2212
2213
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002214 private void abort(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002215 Log.i(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002216 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002217 }
2218
Tyler Gunnbe74de02014-08-29 14:51:48 -07002219 private void answerVideo(String callId, int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002220 Log.i(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302221 if (mConnectionById.containsKey(callId)) {
2222 findConnectionForAction(callId, "answer").onAnswer(videoState);
2223 } else {
2224 findConferenceForAction(callId, "answer").onAnswer(videoState);
2225 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002226 }
2227
Tyler Gunnbe74de02014-08-29 14:51:48 -07002228 private void answer(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002229 Log.i(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302230 if (mConnectionById.containsKey(callId)) {
2231 findConnectionForAction(callId, "answer").onAnswer();
2232 } else {
2233 findConferenceForAction(callId, "answer").onAnswer();
2234 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002235 }
2236
Pooja Jaind34698d2017-12-28 14:15:31 +05302237 private void deflect(String callId, Uri address) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002238 Log.i(this, "deflect %s", callId);
Pooja Jaind34698d2017-12-28 14:15:31 +05302239 findConnectionForAction(callId, "deflect").onDeflect(address);
2240 }
2241
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002242 private void reject(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002243 Log.i(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302244 if (mConnectionById.containsKey(callId)) {
2245 findConnectionForAction(callId, "reject").onReject();
2246 } else {
2247 findConferenceForAction(callId, "reject").onReject();
2248 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002249 }
2250
Bryce Lee81901682015-08-28 16:38:02 -07002251 private void reject(String callId, String rejectWithMessage) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002252 Log.i(this, "reject %s with message", callId);
Bryce Lee81901682015-08-28 16:38:02 -07002253 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2254 }
2255
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002256 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002257 Log.i(this, "reject %s with reason %d", callId, rejectReason);
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002258 findConnectionForAction(callId, "reject").onReject(rejectReason);
2259 }
2260
Ravi Palurif4b38e72020-02-05 12:35:41 +05302261 private void transfer(String callId, Uri number, boolean isConfirmationRequired) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002262 Log.i(this, "transfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302263 findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired);
2264 }
2265
2266 private void consultativeTransfer(String callId, String otherCallId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002267 Log.i(this, "consultativeTransfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302268 Connection connection1 = findConnectionForAction(callId, "consultativeTransfer");
2269 Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer");
2270 connection1.onTransfer(connection2);
2271 }
2272
Bryce Leecac50772015-11-17 15:13:29 -08002273 private void silence(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002274 Log.i(this, "silence %s", callId);
Bryce Leecac50772015-11-17 15:13:29 -08002275 findConnectionForAction(callId, "silence").onSilence();
2276 }
2277
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002278 private void disconnect(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002279 Log.i(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002280 if (mConnectionById.containsKey(callId)) {
2281 findConnectionForAction(callId, "disconnect").onDisconnect();
2282 } else {
2283 findConferenceForAction(callId, "disconnect").onDisconnect();
2284 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002285 }
2286
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002287 private void hold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002288 Log.i(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002289 if (mConnectionById.containsKey(callId)) {
2290 findConnectionForAction(callId, "hold").onHold();
2291 } else {
2292 findConferenceForAction(callId, "hold").onHold();
2293 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002294 }
2295
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002296 private void unhold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002297 Log.i(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002298 if (mConnectionById.containsKey(callId)) {
2299 findConnectionForAction(callId, "unhold").onUnhold();
2300 } else {
2301 findConferenceForAction(callId, "unhold").onUnhold();
2302 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002303 }
2304
Yorke Lee4af59352015-05-13 14:14:54 -07002305 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002306 Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002307 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002308 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2309 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002310 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002311 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2312 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002313 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002314 }
2315
Grace Jiae99fde92021-01-19 14:58:01 -08002316 private void onUsingAlternativeUi(String callId, boolean isUsingAlternativeUi) {
2317 Log.i(this, "onUsingAlternativeUi %s %s", callId, isUsingAlternativeUi);
2318 if (mConnectionById.containsKey(callId)) {
2319 findConnectionForAction(callId, "onUsingAlternativeUi")
2320 .onUsingAlternativeUi(isUsingAlternativeUi);
2321 }
2322 }
2323
2324 private void onTrackedByNonUiService(String callId, boolean isTracked) {
2325 Log.i(this, "onTrackedByNonUiService %s %s", callId, isTracked);
2326 if (mConnectionById.containsKey(callId)) {
2327 findConnectionForAction(callId, "onTrackedByNonUiService")
2328 .onTrackedByNonUiService(isTracked);
2329 }
2330 }
2331
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002332 private void playDtmfTone(String callId, char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002333 Log.i(this, "playDtmfTone %s %c", callId, digit);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002334 if (mConnectionById.containsKey(callId)) {
2335 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2336 } else {
2337 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2338 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002339 }
2340
2341 private void stopDtmfTone(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002342 Log.i(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002343 if (mConnectionById.containsKey(callId)) {
2344 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2345 } else {
2346 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2347 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002348 }
2349
Santos Cordon823fd3c2014-08-07 18:35:18 -07002350 private void conference(String callId1, String callId2) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002351 Log.i(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002352
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002353 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002354 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002355 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002356 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002357 conference2 = findConferenceForAction(callId2, "conference");
2358 if (conference2 == getNullConference()) {
2359 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2360 callId2);
2361 return;
2362 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002363 }
Santos Cordonb6939982014-06-04 20:20:58 -07002364
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002365 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002366 Connection connection1 = findConnectionForAction(callId1, "conference");
2367 if (connection1 == getNullConnection()) {
2368 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2369 if (conference1 == getNullConference()) {
2370 Log.w(this,
2371 "Connection1 or Conference1 missing in conference request %s.",
2372 callId1);
2373 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002374 // Call 1 is a conference.
2375 if (connection2 != getNullConnection()) {
2376 // Call 2 is a connection so merge via call 1 (conference).
2377 conference1.onMerge(connection2);
2378 } else {
2379 // Call 2 is ALSO a conference; this should never happen.
2380 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2381 "merge two conferences.");
2382 return;
2383 }
Ihab Awad50e35062014-09-30 09:17:03 -07002384 }
2385 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002386 // Call 1 is a connection.
2387 if (conference2 != getNullConference()) {
2388 // Call 2 is a conference, so merge via call 2.
2389 conference2.onMerge(connection1);
2390 } else {
2391 // Call 2 is a connection, so merge together.
2392 onConference(connection1, connection2);
2393 }
Ihab Awad50e35062014-09-30 09:17:03 -07002394 }
Santos Cordon980acb92014-05-31 10:31:19 -07002395 }
2396
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002397 private void splitFromConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002398 Log.i(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002399
2400 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002401 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002402 Log.w(this, "Connection missing in conference request %s.", callId);
2403 return;
2404 }
2405
Santos Cordon0159ac02014-08-21 14:28:11 -07002406 Conference conference = connection.getConference();
2407 if (conference != null) {
2408 conference.onSeparate(connection);
2409 }
Santos Cordon980acb92014-05-31 10:31:19 -07002410 }
2411
Santos Cordona4868042014-09-04 17:39:22 -07002412 private void mergeConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002413 Log.i(this, "mergeConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002414 Conference conference = findConferenceForAction(callId, "mergeConference");
2415 if (conference != null) {
2416 conference.onMerge();
2417 }
2418 }
2419
2420 private void swapConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002421 Log.i(this, "swapConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002422 Conference conference = findConferenceForAction(callId, "swapConference");
2423 if (conference != null) {
2424 conference.onSwap();
2425 }
2426 }
2427
Ravi Paluri404babb2020-01-23 19:02:44 +05302428 private void addConferenceParticipants(String callId, List<Uri> participants) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002429 Log.i(this, "addConferenceParticipants(%s)", callId);
Ravi Paluri404babb2020-01-23 19:02:44 +05302430 if (mConnectionById.containsKey(callId)) {
2431 findConnectionForAction(callId, "addConferenceParticipants")
2432 .onAddConferenceParticipants(participants);
2433 } else {
2434 findConferenceForAction(callId, "addConferenceParticipants")
2435 .onAddConferenceParticipants(participants);
2436 }
2437 }
2438
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002439 /**
2440 * Notifies a {@link Connection} of a request to pull an external call.
2441 *
2442 * See {@link Call#pullExternalCall()}.
2443 *
2444 * @param callId The ID of the call to pull.
2445 */
2446 private void pullExternalCall(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002447 Log.i(this, "pullExternalCall(%s)", callId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002448 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2449 if (connection != null) {
2450 connection.onPullExternalCall();
2451 }
2452 }
2453
2454 /**
2455 * Notifies a {@link Connection} of a call event.
2456 *
2457 * See {@link Call#sendCallEvent(String, Bundle)}.
2458 *
2459 * @param callId The ID of the call receiving the event.
2460 * @param event The event.
2461 * @param extras Extras associated with the event.
2462 */
2463 private void sendCallEvent(String callId, String event, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002464 Log.i(this, "sendCallEvent(%s, %s)", callId, event);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002465 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2466 if (connection != null) {
2467 connection.onCallEvent(event, extras);
2468 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002469 }
2470
Hall Liu73903142021-02-18 18:41:41 -08002471 private void onCallFilteringCompleted(String callId, Connection.CallFilteringCompletionInfo
2472 callFilteringCompletionInfo) {
2473 Log.i(this, "onCallFilteringCompleted(%s, %s)", callId, callFilteringCompletionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08002474 Connection connection = findConnectionForAction(callId, "onCallFilteringCompleted");
2475 if (connection != null) {
Hall Liu73903142021-02-18 18:41:41 -08002476 connection.onCallFilteringCompleted(callFilteringCompletionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08002477 }
2478 }
2479
Tyler Gunndee56a82016-03-23 16:06:34 -07002480 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002481 * Notifies a {@link Connection} that a handover has completed.
2482 *
2483 * @param callId The ID of the call which completed handover.
2484 */
2485 private void notifyHandoverComplete(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002486 Log.i(this, "notifyHandoverComplete(%s)", callId);
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002487 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2488 if (connection != null) {
2489 connection.onHandoverComplete();
2490 }
2491 }
2492
2493 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002494 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2495 * <p>
2496 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2497 * the {@link android.telecom.Call#putExtra(String, boolean)},
2498 * {@link android.telecom.Call#putExtra(String, int)},
2499 * {@link android.telecom.Call#putExtra(String, String)},
2500 * {@link Call#removeExtras(List)}.
2501 *
2502 * @param callId The ID of the call receiving the event.
2503 * @param extras The new extras bundle.
2504 */
2505 private void handleExtrasChanged(String callId, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002506 Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002507 if (mConnectionById.containsKey(callId)) {
2508 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2509 } else if (mConferenceById.containsKey(callId)) {
2510 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2511 }
2512 }
2513
Hall Liub64ac4c2017-02-06 10:49:48 -08002514 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002515 Log.i(this, "startRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002516 if (mConnectionById.containsKey(callId)) {
2517 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2518 } else if (mConferenceById.containsKey(callId)) {
2519 Log.w(this, "startRtt called on a conference.");
2520 }
2521 }
2522
2523 private void stopRtt(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002524 Log.i(this, "stopRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002525 if (mConnectionById.containsKey(callId)) {
2526 findConnectionForAction(callId, "stopRtt").onStopRtt();
2527 } else if (mConferenceById.containsKey(callId)) {
2528 Log.w(this, "stopRtt called on a conference.");
2529 }
2530 }
2531
2532 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002533 Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
Hall Liub64ac4c2017-02-06 10:49:48 -08002534 if (mConnectionById.containsKey(callId)) {
2535 findConnectionForAction(callId, "handleRttUpgradeResponse")
2536 .handleRttUpgradeResponse(rttTextStream);
2537 } else if (mConferenceById.containsKey(callId)) {
2538 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2539 }
2540 }
2541
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002542 private void onPostDialContinue(String callId, boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002543 Log.i(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002544 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002545 }
2546
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002547 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002548 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002549 // No need to query again if we already did it.
2550 return;
2551 }
2552
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002553 String callingPackage = getOpPackageName();
2554
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002555 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002556 @Override
2557 public void onResult(
2558 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002559 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002560 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002561 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002562 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002563 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002564 mRemoteConnectionManager.addConnectionService(
2565 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002566 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002567 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002568 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002569 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002570 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002571 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002572 }
2573
2574 @Override
2575 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002576 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002577 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002578 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002579 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002580 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002581 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002582 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002583 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002584 }
2585
Ihab Awadf8b69882014-07-25 15:14:01 -07002586 /**
2587 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002588 * incoming request. This is used by {@code ConnectionService}s that are registered with
2589 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2590 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002591 *
2592 * @param connectionManagerPhoneAccount See description at
2593 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2594 * @param request Details about the incoming call.
2595 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2596 * not handle the call.
2597 */
Grace Jia41895152021-01-19 13:57:51 -08002598 public final @Nullable RemoteConnection createRemoteIncomingConnection(
2599 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
2600 @NonNull ConnectionRequest request) {
Ihab Awadf8b69882014-07-25 15:14:01 -07002601 return mRemoteConnectionManager.createRemoteConnection(
2602 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002603 }
2604
2605 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002606 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002607 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2608 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2609 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002610 *
2611 * @param connectionManagerPhoneAccount See description at
2612 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002613 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002614 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2615 * not handle the call.
2616 */
Grace Jia41895152021-01-19 13:57:51 -08002617 public final @Nullable RemoteConnection createRemoteOutgoingConnection(
2618 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
2619 @NonNull ConnectionRequest request) {
Ihab Awadf8b69882014-07-25 15:14:01 -07002620 return mRemoteConnectionManager.createRemoteConnection(
2621 connectionManagerPhoneAccount, request, false);
2622 }
2623
2624 /**
Grace Jia9a09c672020-08-04 12:52:09 -07002625 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2626 * incoming request. This is used by {@code ConnectionService}s that are registered with
2627 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2628 *
2629 * @param connectionManagerPhoneAccount See description at
2630 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2631 * @param request Details about the incoming conference call.
2632 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2633 * handle the call.
2634 */
2635 public final @Nullable RemoteConference createRemoteIncomingConference(
2636 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2637 @Nullable ConnectionRequest request) {
2638 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2639 request, true);
2640 }
2641
2642 /**
2643 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2644 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2645 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2646 *
2647 * @param connectionManagerPhoneAccount See description at
2648 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2649 * @param request Details about the outgoing conference call.
2650 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2651 * handle the call.
2652 */
2653 public final @Nullable RemoteConference createRemoteOutgoingConference(
2654 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2655 @Nullable ConnectionRequest request) {
2656 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2657 request, false);
2658 }
2659
2660 /**
Santos Cordona663f862014-10-29 13:49:58 -07002661 * Indicates to the relevant {@code RemoteConnectionService} that the specified
2662 * {@link RemoteConnection}s should be merged into a conference call.
2663 * <p>
2664 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
2665 * be invoked.
2666 *
2667 * @param remoteConnection1 The first of the remote connections to conference.
2668 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07002669 */
2670 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07002671 RemoteConnection remoteConnection1,
2672 RemoteConnection remoteConnection2) {
2673 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07002674 }
2675
2676 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002677 * Adds a new conference call. When a conference call is created either as a result of an
2678 * explicit request via {@link #onConference} or otherwise, the connection service should supply
2679 * an instance of {@link Conference} by invoking this method. A conference call provided by this
2680 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
2681 *
2682 * @param conference The new conference object.
2683 */
2684 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07002685 Log.d(this, "addConference: conference=%s", conference);
2686
Santos Cordon823fd3c2014-08-07 18:35:18 -07002687 String id = addConferenceInternal(conference);
2688 if (id != null) {
2689 List<String> connectionIds = new ArrayList<>(2);
2690 for (Connection connection : conference.getConnections()) {
2691 if (mIdByConnection.containsKey(connection)) {
2692 connectionIds.add(mIdByConnection.get(connection));
2693 }
2694 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002695 conference.setTelecomCallId(id);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07002696 ParcelableConference parcelableConference = new ParcelableConference.Builder(
2697 conference.getPhoneAccountHandle(), conference.getState())
2698 .setConnectionCapabilities(conference.getConnectionCapabilities())
2699 .setConnectionProperties(conference.getConnectionProperties())
2700 .setConnectionIds(connectionIds)
2701 .setVideoAttributes(conference.getVideoProvider() == null
2702 ? null : conference.getVideoProvider().getInterface(),
2703 conference.getVideoState())
2704 .setConnectTimeMillis(conference.getConnectTimeMillis(),
2705 conference.getConnectionStartElapsedRealtimeMillis())
2706 .setStatusHints(conference.getStatusHints())
2707 .setExtras(conference.getExtras())
2708 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2709 .setCallerDisplayName(conference.getCallerDisplayName(),
2710 conference.getCallerDisplayNamePresentation())
2711 .setDisconnectCause(conference.getDisconnectCause())
2712 .setRingbackRequested(conference.isRingbackRequested())
2713 .setCallDirection(conference.getCallDirection())
2714 .build();
Andrew Lee0f51da32015-04-16 13:11:55 -07002715
Santos Cordon823fd3c2014-08-07 18:35:18 -07002716 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07002717 mAdapter.setVideoProvider(id, conference.getVideoProvider());
2718 mAdapter.setVideoState(id, conference.getVideoState());
Tyler Gunn10362372020-04-08 13:12:30 -07002719 // In some instances a conference can start its life as a standalone call with just a
2720 // single participant; ensure we signal to Telecom in this case.
2721 if (!conference.isMultiparty()) {
2722 mAdapter.setConferenceState(id, conference.isMultiparty());
2723 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002724
2725 // Go through any child calls and set the parent.
2726 for (Connection connection : conference.getConnections()) {
2727 String connectionId = mIdByConnection.get(connection);
2728 if (connectionId != null) {
2729 mAdapter.setIsConferenced(connectionId, id);
2730 }
2731 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002732 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002733 }
2734 }
2735
2736 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002737 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
2738 * connection.
2739 *
2740 * @param phoneAccountHandle The phone account handle for the connection.
2741 * @param connection The connection to add.
2742 */
2743 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
2744 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07002745 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
2746 }
2747
2748 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002749 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
2750 * microphone, camera).
2751 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08002752 * <p>
2753 * The {@link ConnectionService} will be disconnected when it failed to call this method within
2754 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
2755 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08002756 * @see ConnectionService#onConnectionServiceFocusLost()
2757 */
2758 public final void connectionServiceFocusReleased() {
2759 mAdapter.onConnectionServiceFocusReleased();
2760 }
2761
2762 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07002763 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07002764 * connection, as well as adding that connection to the specified conference.
2765 * <p>
2766 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
2767 * IMS conference participants to be added to a conference in a single step; this helps ensure
2768 * UI updates happen atomically, rather than adding the connection and then adding it to
2769 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07002770 *
2771 * @param phoneAccountHandle The phone account handle for the connection.
2772 * @param connection The connection to add.
2773 * @param conference The parent conference of the new connection.
2774 * @hide
2775 */
Tyler Gunn5567d742019-10-31 13:04:37 -07002776 @SystemApi
2777 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
2778 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002779
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002780 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002781 if (id != null) {
2782 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07002783 String conferenceId = null;
2784 if (conference != null) {
2785 conferenceId = mIdByConference.get(conference);
2786 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002787
2788 ParcelableConnection parcelableConnection = new ParcelableConnection(
2789 phoneAccountHandle,
2790 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002791 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002792 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002793 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002794 connection.getAddress(),
2795 connection.getAddressPresentation(),
2796 connection.getCallerDisplayName(),
2797 connection.getCallerDisplayNamePresentation(),
2798 connection.getVideoProvider() == null ?
2799 null : connection.getVideoProvider().getInterface(),
2800 connection.getVideoState(),
2801 connection.isRingbackRequested(),
2802 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002803 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002804 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002805 connection.getStatusHints(),
2806 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002807 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07002808 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07002809 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002810 connection.getCallDirection(),
2811 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002812 mAdapter.addExistingConnection(id, parcelableConnection);
2813 }
2814 }
2815
2816 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002817 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
2818 * has taken responsibility.
2819 *
2820 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07002821 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07002822 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07002823 return mConnectionById.values();
2824 }
2825
2826 /**
Santos Cordona6018b92016-02-16 14:23:12 -08002827 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
2828 * has taken responsibility.
2829 *
2830 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
2831 */
2832 public final Collection<Conference> getAllConferences() {
2833 return mConferenceById.values();
2834 }
2835
2836 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002837 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2838 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07002839 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002840 * @param connectionManagerPhoneAccount See description at
2841 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2842 * @param request Details about the incoming call.
2843 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2844 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002845 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002846 public Connection onCreateIncomingConnection(
2847 PhoneAccountHandle connectionManagerPhoneAccount,
2848 ConnectionRequest request) {
2849 return null;
2850 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302851 /**
Grace Jia8587ee52020-07-10 15:42:32 -07002852 * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
2853 * conference call initiated via
2854 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302855 *
2856 * @param connectionManagerPhoneAccount See description at
2857 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Grace Jia8587ee52020-07-10 15:42:32 -07002858 * @param request Details about the incoming conference call.
Grace Jia41895152021-01-19 13:57:51 -08002859 * @return The {@code Conference} object to satisfy this call. If the conference attempt is
2860 * failed, the return value will be a result of an invocation of
2861 * {@link Connection#createFailedConnection(DisconnectCause)}.
2862 * Return {@code null} if the {@link ConnectionService} cannot handle the call.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302863 */
2864 public @Nullable Conference onCreateIncomingConference(
Grace Jia41895152021-01-19 13:57:51 -08002865 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
2866 @NonNull ConnectionRequest request) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05302867 return null;
2868 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002869
2870 /**
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002871 * Called after the {@link Connection} returned by
2872 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
2873 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
2874 * added to the {@link ConnectionService} and sent to Telecom.
2875 *
2876 * @param connection the {@link Connection}.
2877 * @hide
2878 */
2879 public void onCreateConnectionComplete(Connection connection) {
2880 }
2881
2882 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302883 * Called after the {@link Conference} returned by
2884 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
2885 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
2886 * added to the {@link ConnectionService} and sent to Telecom.
2887 *
2888 * @param conference the {@link Conference}.
2889 * @hide
2890 */
2891 public void onCreateConferenceComplete(Conference conference) {
2892 }
2893
2894
2895 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002896 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2897 * incoming {@link Connection} was denied.
2898 * <p>
2899 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2900 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
2901 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2902 * {@link Connection}.
2903 * <p>
2904 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2905 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002906 * @param connectionManagerPhoneAccount See description at
2907 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002908 * @param request The incoming connection request.
2909 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002910 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2911 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002912 }
2913
2914 /**
2915 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2916 * outgoing {@link Connection} was denied.
2917 * <p>
2918 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2919 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
2920 * The {@link ConnectionService} is responisible for informing the user that the
2921 * {@link Connection} cannot be made at this time.
2922 * <p>
2923 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2924 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002925 * @param connectionManagerPhoneAccount See description at
2926 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002927 * @param request The outgoing connection request.
2928 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002929 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2930 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002931 }
2932
2933 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302934 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2935 * incoming {@link Conference} was denied.
2936 * <p>
2937 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2938 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
2939 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2940 * {@link Conference}.
2941 * <p>
2942 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2943 *
2944 * @param connectionManagerPhoneAccount See description at
2945 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2946 * @param request The incoming connection request.
2947 */
2948 public void onCreateIncomingConferenceFailed(
2949 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2950 @Nullable ConnectionRequest request) {
2951 }
2952
2953 /**
2954 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2955 * outgoing {@link Conference} was denied.
2956 * <p>
2957 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2958 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
2959 * The {@link ConnectionService} is responisible for informing the user that the
2960 * {@link Conference} cannot be made at this time.
2961 * <p>
2962 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2963 *
2964 * @param connectionManagerPhoneAccount See description at
2965 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2966 * @param request The outgoing connection request.
2967 */
2968 public void onCreateOutgoingConferenceFailed(
Grace Jia41895152021-01-19 13:57:51 -08002969 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
2970 @NonNull ConnectionRequest request) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05302971 }
2972
2973
2974 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002975 * Trigger recalculate functinality for conference calls. This is used when a Telephony
2976 * Connection is part of a conference controller but is not yet added to Connection
2977 * Service and hence cannot be added to the conference call.
2978 *
2979 * @hide
2980 */
2981 public void triggerConferenceRecalculate() {
2982 }
2983
2984 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002985 * Create a {@code Connection} given an outgoing request. This is used to initiate new
2986 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002987 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002988 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2989 * this call.
2990 * <p>
2991 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2992 * has registered one or more {@code PhoneAccount}s having
2993 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2994 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2995 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2996 * making the connection.
2997 * <p>
2998 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2999 * being asked to make a direct connection. The
3000 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3001 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3002 * making the connection.
3003 * @param request Details about the outgoing call.
3004 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07003005 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07003006 */
Ihab Awadf8b69882014-07-25 15:14:01 -07003007 public Connection onCreateOutgoingConnection(
3008 PhoneAccountHandle connectionManagerPhoneAccount,
3009 ConnectionRequest request) {
3010 return null;
3011 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003012
3013 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05303014 * Create a {@code Conference} given an outgoing request. This is used to initiate new
Grace Jia8587ee52020-07-10 15:42:32 -07003015 * outgoing conference call requested via
3016 * {@link TelecomManager#startConference(List, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303017 *
3018 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3019 * this call.
3020 * <p>
3021 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
3022 * has registered one or more {@code PhoneAccount}s having
3023 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
3024 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
3025 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
3026 * making the connection.
3027 * <p>
3028 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
3029 * being asked to make a direct connection. The
3030 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3031 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3032 * making the connection.
3033 * @param request Details about the outgoing call.
Grace Jia41895152021-01-19 13:57:51 -08003034 * @return The {@code Conference} object to satisfy this call. If the conference attempt is
3035 * failed, the return value will be a result of an invocation of
3036 * {@link Connection#createFailedConnection(DisconnectCause)}.
3037 * Return {@code null} if the {@link ConnectionService} cannot handle the call.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303038 */
3039 public @Nullable Conference onCreateOutgoingConference(
Grace Jia41895152021-01-19 13:57:51 -08003040 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
3041 @NonNull ConnectionRequest request) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05303042 return null;
3043 }
3044
3045
3046 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003047 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3048 * outgoing handover {@link Connection}.
3049 * <p>
3050 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3051 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3052 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3053 * is referred to as the source of the handover, and the video calling app is referred to as the
3054 * destination.
3055 * <p>
3056 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3057 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3058 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3059 * device.
3060 * <p>
3061 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
3062 * device when the user initiates a handover request from one app to another. The user request
3063 * originates in the {@link InCallService} via
3064 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3065 * <p>
3066 * For a full discussion of the handover process and the APIs involved, see
3067 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3068 * <p>
3069 * Implementations of this method should return an instance of {@link Connection} which
3070 * represents the handover. If your app does not wish to accept a handover to it at this time,
3071 * you can return {@code null}. The code below shows an example of how this is done.
3072 * <pre>
3073 * {@code
3074 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3075 * fromPhoneAccountHandle, ConnectionRequest request) {
3076 * if (!isHandoverAvailable()) {
3077 * return null;
3078 * }
3079 * MyConnection connection = new MyConnection();
3080 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3081 * connection.setVideoState(request.getVideoState());
3082 * return connection;
3083 * }
3084 * }
3085 * </pre>
3086 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003087 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3088 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08003089 * @param request Details about the call to handover.
3090 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003091 */
3092 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3093 ConnectionRequest request) {
3094 return null;
3095 }
3096
3097 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003098 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3099 * incoming handover {@link Connection}.
3100 * <p>
3101 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3102 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3103 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3104 * is referred to as the source of the handover, and the video calling app is referred to as the
3105 * destination.
3106 * <p>
3107 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3108 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3109 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3110 * device.
3111 * <p>
3112 * This method is called on the destination app on the <em>receiving</em> device when the
3113 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
3114 * accept an incoming handover from the <em>initiating</em> device.
3115 * <p>
3116 * For a full discussion of the handover process and the APIs involved, see
3117 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3118 * <p>
3119 * Implementations of this method should return an instance of {@link Connection} which
3120 * represents the handover. The code below shows an example of how this is done.
3121 * <pre>
3122 * {@code
3123 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3124 * fromPhoneAccountHandle, ConnectionRequest request) {
3125 * // Given that your app requested to accept the handover, you should not return null here.
3126 * MyConnection connection = new MyConnection();
3127 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3128 * connection.setVideoState(request.getVideoState());
3129 * return connection;
3130 * }
3131 * }
3132 * </pre>
3133 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003134 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3135 * ConnectionService which needs to handover the call.
3136 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08003137 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003138 */
3139 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3140 ConnectionRequest request) {
3141 return null;
3142 }
3143
3144 /**
3145 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
3146 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08003147 * <p>
3148 * For a full discussion of the handover process and the APIs involved, see
3149 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
3150 *
3151 * @param request Details about the call which failed to handover.
3152 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07003153 */
Tyler Gunn9d127732018-03-02 15:45:51 -08003154 public void onHandoverFailed(ConnectionRequest request,
3155 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07003156 return;
3157 }
3158
3159 /**
Roopa Sattiraju45de470c2022-01-27 21:31:35 -08003160 * Calls of this type are created using
3161 * {@link TelecomManager#addNewUnknownCall(PhoneAccountHandle, Bundle)}. Unknown calls
3162 * are used for representing calls which become known to the {@link ConnectionService}
3163 * midway through the call.
3164 *
3165 * For example, a call transferred from one device to answer would surface as an active
3166 * call in Telecom instead of going through a typical Ringing to Active transition, or
3167 * Dialing to Active transition.
3168 *
3169 * A {@link ConnectionService} can return {@code null} (the default behavior)
3170 * if it is not able to handle a request for the requested unknown connection.
3171 *
3172 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
Yorke Leec3cf9822014-10-02 09:38:39 -07003173 *
Etienne Ruffieuxb99333d2022-02-25 16:11:01 +00003174 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3175 * this call
3176 * @param request Details about the outgoing call
3177 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
3178 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call
Yorke Lee770ed6e2014-10-06 18:58:52 -07003179 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07003180 */
Etienne Ruffieuxb99333d2022-02-25 16:11:01 +00003181 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
Roopa Sattiraju45de470c2022-01-27 21:31:35 -08003182 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3183 public @Nullable Connection onCreateUnknownConnection(
3184 @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
3185 @NonNull ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003186 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07003187 }
3188
3189 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003190 * Conference two specified connections. Invoked when the user has made a request to merge the
3191 * specified connections into a conference call. In response, the connection service should
3192 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07003193 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07003194 * @param connection1 A connection to merge into a conference call.
3195 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07003196 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07003197 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07003198
Santos Cordona663f862014-10-29 13:49:58 -07003199 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07003200 * Called when a connection is added.
3201 * @hide
3202 */
3203 public void onConnectionAdded(Connection connection) {}
3204
3205 /**
3206 * Called when a connection is removed.
3207 * @hide
3208 */
3209 public void onConnectionRemoved(Connection connection) {}
3210
3211 /**
3212 * Called when a conference is added.
3213 * @hide
3214 */
3215 public void onConferenceAdded(Conference conference) {}
3216
3217 /**
3218 * Called when a conference is removed.
3219 * @hide
3220 */
3221 public void onConferenceRemoved(Conference conference) {}
3222
3223 /**
Santos Cordona663f862014-10-29 13:49:58 -07003224 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
3225 * When this method is invoked, this {@link ConnectionService} should create its own
3226 * representation of the conference call and send it to telecom using {@link #addConference}.
3227 * <p>
3228 * This is only relevant to {@link ConnectionService}s which are registered with
3229 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
3230 *
3231 * @param conference The remote conference call.
3232 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07003233 public void onRemoteConferenceAdded(RemoteConference conference) {}
3234
Santos Cordon823fd3c2014-08-07 18:35:18 -07003235 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003236 * Called when an existing connection is added remotely.
3237 * @param connection The existing connection which was added.
3238 */
3239 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
3240
3241 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003242 * Called when the {@link ConnectionService} has lost the call focus.
3243 * The {@link ConnectionService} should release the call resources and invokes
3244 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
3245 * released the call resources.
3246 */
3247 public void onConnectionServiceFocusLost() {}
3248
3249 /**
3250 * Called when the {@link ConnectionService} has gained the call focus. The
3251 * {@link ConnectionService} can acquire the call resources at this time.
3252 */
3253 public void onConnectionServiceFocusGained() {}
3254
3255 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003256 * @hide
3257 */
3258 public boolean containsConference(Conference conference) {
3259 return mIdByConference.containsKey(conference);
3260 }
3261
Ihab Awadb8e85c72014-08-23 20:34:57 -07003262 /** {@hide} */
3263 void addRemoteConference(RemoteConference remoteConference) {
3264 onRemoteConferenceAdded(remoteConference);
3265 }
3266
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003267 /** {@hide} */
3268 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
3269 onRemoteExistingConnectionAdded(remoteConnection);
3270 }
3271
Ihab Awad5d0410f2014-07-30 10:07:40 -07003272 private void onAccountsInitialized() {
3273 mAreAccountsInitialized = true;
3274 for (Runnable r : mPreInitializationConnectionRequests) {
3275 r.run();
3276 }
3277 mPreInitializationConnectionRequests.clear();
3278 }
3279
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003280 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003281 * Adds an existing connection to the list of connections, identified by a new call ID unique
3282 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003283 *
3284 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003285 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003286 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003287 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
3288 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003289
3290 if (connection.getExtras() != null && connection.getExtras()
3291 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3292 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3293 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
3294 connection.getTelecomCallId(), id);
3295 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003296 // If no phone account handle was provided, we cannot be sure the call ID is unique,
3297 // so just use a random UUID.
3298 id = UUID.randomUUID().toString();
3299 } else {
3300 // Phone account handle was provided, so use the ConnectionService class name as a
3301 // prefix for a unique incremental call ID.
3302 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
3303 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003304 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003305 return id;
3306 }
3307
Pengquan Meng70c9885332017-10-02 18:09:03 -07003308 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003309 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003310 mConnectionById.put(callId, connection);
3311 mIdByConnection.put(connection, callId);
3312 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003313 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003314 connection.setPhoneAccountHandle(handle);
3315 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003316 }
3317
Anthony Lee30e65842014-11-06 16:30:53 -08003318 /** {@hide} */
3319 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003320 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003321 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003322 String id = mIdByConnection.get(connection);
3323 if (id != null) {
3324 mConnectionById.remove(id);
3325 mIdByConnection.remove(connection);
3326 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003327 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003328 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003329 }
3330
Santos Cordon823fd3c2014-08-07 18:35:18 -07003331 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003332 String originalId = null;
3333 if (conference.getExtras() != null && conference.getExtras()
3334 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3335 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3336 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3337 conference.getTelecomCallId(),
3338 originalId);
3339 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003340 if (mIdByConference.containsKey(conference)) {
3341 Log.w(this, "Re-adding an existing conference: %s.", conference);
3342 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003343 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3344 // cannot determine a ConnectionService class name to associate with the ID, so use
3345 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003346 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003347 mConferenceById.put(id, conference);
3348 mIdByConference.put(conference, id);
3349 conference.addListener(mConferenceListener);
3350 return id;
3351 }
3352
3353 return null;
3354 }
3355
3356 private void removeConference(Conference conference) {
3357 if (mIdByConference.containsKey(conference)) {
3358 conference.removeListener(mConferenceListener);
3359
3360 String id = mIdByConference.get(conference);
3361 mConferenceById.remove(id);
3362 mIdByConference.remove(conference);
3363 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003364
3365 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003366 }
3367 }
3368
Ihab Awad542e0ea2014-05-16 10:22:16 -07003369 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003370 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003371 return mConnectionById.get(callId);
3372 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003373 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003374 return getNullConnection();
3375 }
3376
3377 static synchronized Connection getNullConnection() {
3378 if (sNullConnection == null) {
3379 sNullConnection = new Connection() {};
3380 }
3381 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003382 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003383
3384 private Conference findConferenceForAction(String conferenceId, String action) {
3385 if (mConferenceById.containsKey(conferenceId)) {
3386 return mConferenceById.get(conferenceId);
3387 }
3388 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3389 return getNullConference();
3390 }
3391
Ihab Awadb8e85c72014-08-23 20:34:57 -07003392 private List<String> createConnectionIdList(List<Connection> connections) {
3393 List<String> ids = new ArrayList<>();
3394 for (Connection c : connections) {
3395 if (mIdByConnection.containsKey(c)) {
3396 ids.add(mIdByConnection.get(c));
3397 }
3398 }
3399 Collections.sort(ids);
3400 return ids;
3401 }
3402
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003403 /**
3404 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003405 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003406 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003407 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003408 * @return List of string conference and call Ids.
3409 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003410 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003411 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003412 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003413 // Only allow Connection and Conference conferenceables.
3414 if (c instanceof Connection) {
3415 Connection connection = (Connection) c;
3416 if (mIdByConnection.containsKey(connection)) {
3417 ids.add(mIdByConnection.get(connection));
3418 }
3419 } else if (c instanceof Conference) {
3420 Conference conference = (Conference) c;
3421 if (mIdByConference.containsKey(conference)) {
3422 ids.add(mIdByConference.get(conference));
3423 }
3424 }
3425 }
3426 Collections.sort(ids);
3427 return ids;
3428 }
3429
Santos Cordon0159ac02014-08-21 14:28:11 -07003430 private Conference getNullConference() {
3431 if (sNullConference == null) {
3432 sNullConference = new Conference(null) {};
3433 }
3434 return sNullConference;
3435 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003436
3437 private void endAllConnections() {
3438 // Unbound from telecomm. We should end all connections and conferences.
3439 for (Connection connection : mIdByConnection.keySet()) {
3440 // only operate on top-level calls. Conference calls will be removed on their own.
3441 if (connection.getConference() == null) {
3442 connection.onDisconnect();
3443 }
3444 }
3445 for (Conference conference : mIdByConference.keySet()) {
3446 conference.onDisconnect();
3447 }
3448 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003449
3450 /**
3451 * Retrieves the next call ID as maintainted by the connection service.
3452 *
3453 * @return The call ID.
3454 */
3455 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003456 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003457 return ++mId;
3458 }
3459 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003460
3461 /**
3462 * Returns this handler, ONLY FOR TESTING.
3463 * @hide
3464 */
3465 @VisibleForTesting
3466 public Handler getHandler() {
3467 return mHandler;
3468 }
Tyler Gunnc7e07b92021-04-06 11:40:57 -07003469
3470 /**
3471 * Sets this {@link ConnectionService} ready for testing purposes.
3472 * @hide
3473 */
3474 @VisibleForTesting
3475 public void setReadyForTest() {
3476 mAreAccountsInitialized = true;
3477 }
Santos Cordon980acb92014-05-31 10:31:19 -07003478}